From c2c9ca781c12d987478560fb2683a6d108b276eb Mon Sep 17 00:00:00 2001 From: Branden Rodgers Date: Wed, 11 Dec 2024 19:06:34 -0500 Subject: [PATCH] chore: port projectStructure to TS --- lib/projectStructure.ts | 147 +++++++++++++++++++++++++++++----------- 1 file changed, 109 insertions(+), 38 deletions(-) diff --git a/lib/projectStructure.ts b/lib/projectStructure.ts index dffb98af6..2df0d33ab 100644 --- a/lib/projectStructure.ts +++ b/lib/projectStructure.ts @@ -1,24 +1,91 @@ -// @ts-nocheck -const fs = require('fs'); -const path = require('path'); -const { walk } = require('@hubspot/local-dev-lib/fs'); -const { logger } = require('@hubspot/local-dev-lib/logger'); -const { logError } = require('./errorHandlers/index'); - -const COMPONENT_TYPES = Object.freeze({ +import * as fs from 'fs'; +import * as path from 'path'; +import { walk } from '@hubspot/local-dev-lib/fs'; +import { logger } from '@hubspot/local-dev-lib/logger'; +import { logError } from './errorHandlers/index'; + +type ComponentTypes = 'private-app' | 'public-app' | 'hubl-theme'; +type ValueOf = T[keyof T]; + +export type Component = { + type: ComponentTypes; + config: object; + runnable: boolean; + path: string; +}; + +type PrivateAppComponentConfigType = { + name: string; + description: string; + uid: string; + scopes: Array; + public: boolean; + extensions?: { + crm: { + cards: Array<{ file: string }>; + }; + }; +}; + +type PublicAppComponentConfigType = { + name: string; + uid: string; + description: string; + allowedUrls: Array; + auth: { + redirectUrls: Array; + requiredScopes: Array; + optionalScopes: Array; + conditionallyRequiredScopes: Array; + }; + support: { + supportEmail: string; + documentationUrl: string; + supportUrl: string; + supportPhone: string; + }; + extensions?: { + crm: { + cards: Array<{ file: string }>; + }; + }; + webhooks?: { + file: string; + }; +}; + +type AppCardComponentConfigType = { + type: 'crm-card'; + data: { + title: string; + uid: string; + location: string; + module: { + file: string; + }; + objectTypes: Array<{ name: string }>; + }; +}; + +export const COMPONENT_TYPES = { privateApp: 'private-app', publicApp: 'public-app', hublTheme: 'hubl-theme', -}); +} as const; -const CONFIG_FILES = { +export const CONFIG_FILES: { + [k in ValueOf]: string; +} = { [COMPONENT_TYPES.privateApp]: 'app.json', [COMPONENT_TYPES.publicApp]: 'public-app.json', [COMPONENT_TYPES.hublTheme]: 'theme.json', }; -function getTypeFromConfigFile(configFile) { - for (const key in CONFIG_FILES) { +function getTypeFromConfigFile( + configFile: ValueOf +): ComponentTypes | null { + let key: ComponentTypes; + for (key in CONFIG_FILES) { if (CONFIG_FILES[key] === configFile) { return key; } @@ -26,11 +93,11 @@ function getTypeFromConfigFile(configFile) { return null; } -function loadConfigFile(configPath) { +function loadConfigFile(configPath: string) { if (configPath) { try { const source = fs.readFileSync(configPath); - const parsedConfig = JSON.parse(source); + const parsedConfig = JSON.parse(source.toString()); return parsedConfig; } catch (e) { logger.debug(e); @@ -39,8 +106,11 @@ function loadConfigFile(configPath) { return null; } -function getAppCardConfigs(appConfig, appPath) { - const cardConfigs = []; +export function getAppCardConfigs( + appConfig: PublicAppComponentConfigType | PrivateAppComponentConfigType, + appPath: string +) { + const cardConfigs: Array = []; let cards; if (appConfig && appConfig.extensions && appConfig.extensions.crm) { @@ -48,7 +118,7 @@ function getAppCardConfigs(appConfig, appPath) { } if (cards) { - cards.forEach(({ file }) => { + cards.forEach(({ file }: { file?: string }) => { if (typeof file === 'string') { const cardConfigPath = path.join(appPath, file); const cardConfig = loadConfigFile(cardConfigPath); @@ -63,7 +133,10 @@ function getAppCardConfigs(appConfig, appPath) { return cardConfigs; } -function getIsLegacyApp(appConfig, appPath) { +function getIsLegacyApp( + appConfig: PublicAppComponentConfigType | PrivateAppComponentConfigType, + appPath: string +) { const cardConfigs = getAppCardConfigs(appConfig, appPath); if (!cardConfigs.length) { @@ -88,9 +161,11 @@ function getIsLegacyApp(appConfig, appPath) { return !hasAnyReactExtensions; } -async function findProjectComponents(projectSourceDir) { - const components = []; - let projectFiles = []; +export async function findProjectComponents( + projectSourceDir: string +): Promise> { + const components: Array = []; + let projectFiles: Array = []; try { projectFiles = await walk(projectSourceDir); @@ -108,13 +183,16 @@ async function findProjectComponents(projectSourceDir) { if (parsedAppConfig) { const isLegacy = getIsLegacyApp(parsedAppConfig, dir); const isHublTheme = base === CONFIG_FILES[COMPONENT_TYPES.hublTheme]; - - components.push({ - type: getTypeFromConfigFile(base), - config: parsedAppConfig, - runnable: !isLegacy && !isHublTheme, - path: dir, - }); + const type = getTypeFromConfigFile(base); + + if (type) { + components.push({ + type, + config: parsedAppConfig, + runnable: !isLegacy && !isHublTheme, + path: dir, + }); + } } } }); @@ -122,16 +200,9 @@ async function findProjectComponents(projectSourceDir) { return components; } -function getProjectComponentTypes(components) { - const projectContents = {}; +export function getProjectComponentTypes(components: Array) { + const projectContents: { [key in ComponentTypes]?: boolean } = {}; + components.forEach(({ type }) => (projectContents[type] = true)); return projectContents; } - -module.exports = { - CONFIG_FILES, - COMPONENT_TYPES, - findProjectComponents, - getAppCardConfigs, - getProjectComponentTypes, -};