import { promises as fsp } from 'node:fs'; import path from 'node:path'; import { CollectionModuleStaticFileName } from '../../domain/collection-modules/collection-module-file-names'; import { existsAsync } from '../fs-helpers'; import { writeFile } from '../write-file'; interface CollectionModuleStaticFiles { packageJson?: Record; gitIgnore: string[]; tsConfig?: { compilerOptions?: Record; [k: string]: unknown; }; } export const readCollectionModuleStaticFiles = async (directory: string): Promise => { const packageJsonPath = path.join(directory, CollectionModuleStaticFileName.PackageJson); const readPackageJsonRaw = (await existsAsync(packageJsonPath)) ? fsp.readFile(packageJsonPath, 'utf8') : undefined; const gitIgnorePath = path.join(directory, CollectionModuleStaticFileName.GitIgnore); const readGitIgnoreRaw = (await existsAsync(gitIgnorePath)) ? fsp.readFile(gitIgnorePath, 'utf8') : undefined; const tsConfigPath = path.join(directory, CollectionModuleStaticFileName.TsConfig); const readTsConfigRaw = (await existsAsync(tsConfigPath)) ? fsp.readFile(tsConfigPath, 'utf8') : undefined; const [packageJsonRaw, gitIgnoreRaw, tsConfigRaw] = await Promise.all([ readPackageJsonRaw, readGitIgnoreRaw, readTsConfigRaw, ]); return { packageJson: packageJsonRaw ? JSON.parse(packageJsonRaw) : undefined, gitIgnore: gitIgnoreRaw ? gitIgnoreRaw.split('\n').map((l) => l.trim()) : [], tsConfig: tsConfigRaw ? JSON.parse(tsConfigRaw) : undefined, }; }; // NB: If dependencies change you also need to update the CM Lambda Layer, see: root-platform/ci.lambda-layer/README.md export const BASE_LAYER_DEPENDENCIES = { joi: '11.4.0', 'moment-timezone': '0.5.40', 'node-fetch': '2.6.7', phone: '2.4.22', stripe: '14.5.0', '@rootplatform/node-sdk': '^0.0.7', }; const standardPackageJson = { dependencies: BASE_LAYER_DEPENDENCIES, }; const standardGitIgnore = ['.root-auth', 'node_modules', 'code/**/env.*']; const standardTsConfig = { include: ['./code/**/*'], compilerOptions: { lib: ['es2022'], module: 'es2022', skipLibCheck: true, allowJs: true, strict: true, moduleResolution: 'Bundler', noEmit: true, }, }; export const writeCollectionModuleStaticFiles = async (params: { directory: string; existingStaticFiles?: CollectionModuleStaticFiles; }) => { const { directory, existingStaticFiles } = params; const { gitIgnore: existingGitIgnore, packageJson: existingPackageJson, tsConfig: existingTsConfig, } = existingStaticFiles || {}; // Merge dependencies properly - preserve custom deps, add base layer deps const existingDeps = (existingPackageJson as any)?.dependencies || {}; const mergedDependencies = { ...BASE_LAYER_DEPENDENCIES, ...existingDeps, }; const mergedPackageJson = { ...existingPackageJson, ...standardPackageJson, dependencies: mergedDependencies, }; const gitIgnoreItemsToMerge = standardGitIgnore.filter((e) => !(existingGitIgnore || []).includes(e)); const mergedGitIgnore = [...(existingGitIgnore || []), ...gitIgnoreItemsToMerge]; const mergedTsConfig = { ...existingTsConfig, ...standardTsConfig, compilerOptions: { ...existingTsConfig?.compilerOptions, ...standardTsConfig.compilerOptions, }, }; await Promise.all([ writeFile( path.join(directory, CollectionModuleStaticFileName.PackageJson), JSON.stringify(mergedPackageJson, null, 2), ), writeFile(path.join(directory, CollectionModuleStaticFileName.TsConfig), JSON.stringify(mergedTsConfig, null, 2)), writeFile(path.join(directory, CollectionModuleStaticFileName.GitIgnore), mergedGitIgnore.join('\n')), ]); };