diff --git a/.eslintrc.json b/.eslintrc.json index e4e4ed0..fa14d34 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -30,7 +30,6 @@ "files": ["*.ts", "*.tsx"], "extends": ["plugin:@nx/typescript"], "rules": { - "@typescript-eslint/no-extra-semi": "error", "no-extra-semi": "off" } }, @@ -38,7 +37,6 @@ "files": ["*.js", "*.jsx"], "extends": ["plugin:@nx/javascript"], "rules": { - "@typescript-eslint/no-extra-semi": "error", "no-extra-semi": "off" } } diff --git a/packages/nx-forge/src/executors/build/executor.ts b/packages/nx-forge/src/executors/build/executor.ts index 7725ae0..e71c693 100644 --- a/packages/nx-forge/src/executors/build/executor.ts +++ b/packages/nx-forge/src/executors/build/executor.ts @@ -35,6 +35,10 @@ export default async function runExecutor( Use a default Nx 'webpack' or 'esbuild' executor to build, and the 'package' executor to assemble the Forge app.` ); + if (context.projectName === undefined) { + throw new Error('No project name provided in executor context.'); + } + const { root, sourceRoot } = context.projectsConfigurations.projects[context.projectName]; diff --git a/packages/nx-forge/src/executors/build/lib/generate-package-json.ts b/packages/nx-forge/src/executors/build/lib/generate-package-json.ts index 7dce853..385a20f 100644 --- a/packages/nx-forge/src/executors/build/lib/generate-package-json.ts +++ b/packages/nx-forge/src/executors/build/lib/generate-package-json.ts @@ -54,12 +54,11 @@ function createPackageJson( projectRoot?: string; root?: string; } - // eslint-disable-next-line @typescript-eslint/no-explicit-any ): any { const customUIProjectNames = customUIResources.map((r) => r.path); const npmDeps = findAllNpmDeps(projectName, graph, customUIProjectNames); // default package.json if one does not exist - let packageJson = { + let packageJson: any = { name: projectName, version: '0.0.1', dependencies: {}, @@ -108,7 +107,7 @@ function findAllNpmDeps( seen.add(projectName); - const node = graph.externalNodes[projectName]; + const node = graph.externalNodes?.[projectName]; if (node) { list[node.data.packageName] = node.data.version; @@ -132,7 +131,7 @@ function recursivelyCollectPeerDependencies( list: { [packageName: string]: string } = {}, seen = new Set() ) { - const npmPackage = graph.externalNodes[projectName]; + const npmPackage = graph.externalNodes?.[projectName]; if (!npmPackage || seen.has(projectName)) { return list; } @@ -148,8 +147,8 @@ function recursivelyCollectPeerDependencies( Object.keys(packageJson.peerDependencies) .map((dependencyName) => `npm:${dependencyName}`) - .map((dependency) => graph.externalNodes[dependency]) - .filter(Boolean) + .map((dependency) => graph.externalNodes?.[dependency]) + .filter((node): node is NonNullable => !!node) .forEach((node) => { if ( !packageJson.peerDependenciesMeta?.[node.data.packageName]?.optional diff --git a/packages/nx-forge/src/executors/build/lib/process-resource-dependencies.ts b/packages/nx-forge/src/executors/build/lib/process-resource-dependencies.ts index 27725e5..0575dd0 100644 --- a/packages/nx-forge/src/executors/build/lib/process-resource-dependencies.ts +++ b/packages/nx-forge/src/executors/build/lib/process-resource-dependencies.ts @@ -35,6 +35,11 @@ export async function processResourceDependencies( options: Options, context: ExecutorContext ): Promise { + if (!context.projectName) { + throw new Error( + `Failed to process resource dependencies: No project name found in executor context.` + ); + } const manifestPath = joinPathFragments( context.root, context.projectsConfigurations.projects[context.projectName].root, @@ -71,18 +76,17 @@ const getResourceOutputPath = ( configurationName?: string ) => { const resourceProjectName = resourceProjectGraphNode.data.name; + if (!resourceProjectName) { + throw new Error('Resource project name is missing.'); + } const maybeResourceOutputPath = options.resourceOutputPathMap[resourceProjectName]; - if ( - maybeResourceOutputPath && - typeof maybeResourceOutputPath === 'string' && - maybeResourceOutputPath !== '' - ) { + if (maybeResourceOutputPath && maybeResourceOutputPath !== '') { return maybeResourceOutputPath; } const maybeBuildTargetOutputPathOption = - resourceProjectGraphNode.data.targets['build']?.options?.outputPath; + resourceProjectGraphNode.data.targets?.['build']?.options?.outputPath; if (maybeBuildTargetOutputPathOption) { return maybeBuildTargetOutputPathOption; } @@ -112,7 +116,7 @@ const getResourceOutputPath = ( } throw new Error( - `Failed to infer output path for resource project '${resourceProjectName}': Try to define an explicit output path mapping using the 'resourceOutputPathMap' option of this executor. Add an entry to the mapping object as follows: {'${resourceProjectName}': ''}.` + `Failed to infer the output path for resource project '${resourceProjectName}': Try to define an explicit output path mapping using the 'resourceOutputPathMap' option of this executor. Add an entry to the mapping object as follows: {'${resourceProjectName}': ''}.` ); }; @@ -122,6 +126,11 @@ const verifyAndCopyResourceDependency = ( options: Options ): void => { const resourceProjectName = resource.path; + if (!resourceProjectName) { + throw new Error( + `Resource ${resource.key} is missing a path. Make sure the resource path references a project in your Nx workspace.` + ); + } const resourceProjectGraphNode = context.projectGraph.nodes[resourceProjectName]; const resourceProjectConfiguration = resourceProjectGraphNode?.data; diff --git a/packages/nx-forge/src/executors/deploy/executor.ts b/packages/nx-forge/src/executors/deploy/executor.ts index fa931da..ed0b0c8 100644 --- a/packages/nx-forge/src/executors/deploy/executor.ts +++ b/packages/nx-forge/src/executors/deploy/executor.ts @@ -8,9 +8,9 @@ const normalizeOptions = ( context: ExecutorContext ): DeployExecutorOptions => { const isEnvironmentName = ( - c: string + c?: string ): c is DeployExecutorOptions['environment'] => - ['development', 'staging', 'production'].includes(c); + ['development', 'staging', 'production'].includes(c ?? ''); if (isEnvironmentName(context.configurationName)) { return { @@ -34,7 +34,10 @@ export default async function runExecutor( context.configurationName ? `(${context.configurationName})` : '' }: ${options.manifestTransform}` ); - await transformManifestYml(options, context); + await transformManifestYml( + { ...options, manifestTransform: options.manifestTransform }, + context + ); } const args = [ diff --git a/packages/nx-forge/src/executors/deploy/lib/transform-manifest-yml.ts b/packages/nx-forge/src/executors/deploy/lib/transform-manifest-yml.ts index 18af9db..1909981 100644 --- a/packages/nx-forge/src/executors/deploy/lib/transform-manifest-yml.ts +++ b/packages/nx-forge/src/executors/deploy/lib/transform-manifest-yml.ts @@ -7,10 +7,9 @@ import { } from '../../../utils/forge/manifest-yml'; import { ExecutorContext, joinPathFragments } from '@nx/devkit'; -type Options = Pick< - DeployExecutorOptions, - 'outputPath' | 'manifestTransform' | 'verify' ->; +type Options = Pick & { + manifestTransform: string; +}; export const transformManifestYml = async ( options: Options, @@ -22,7 +21,7 @@ export const transformManifestYml = async ( } catch (error) { throw new Error( `Failed to parse expression '${options.manifestTransform}': ${ - error.message ?? JSON.stringify(error) + error instanceof Error ? error.message : JSON.stringify(error) }` ); } diff --git a/packages/nx-forge/src/executors/package/executor.ts b/packages/nx-forge/src/executors/package/executor.ts index 51e80eb..40a0cd8 100644 --- a/packages/nx-forge/src/executors/package/executor.ts +++ b/packages/nx-forge/src/executors/package/executor.ts @@ -25,6 +25,10 @@ export default async function runExecutor( rawOptions: PackageExecutorSchema, context: ExecutorContext ) { + if (context.projectName === undefined) { + throw new Error('No project name provided in executor context.'); + } + const { root, sourceRoot } = context.projectsConfigurations.projects[context.projectName]; diff --git a/packages/nx-forge/src/executors/package/lib/create-package-json.ts b/packages/nx-forge/src/executors/package/lib/create-package-json.ts index 2275fbb..f925240 100644 --- a/packages/nx-forge/src/executors/package/lib/create-package-json.ts +++ b/packages/nx-forge/src/executors/package/lib/create-package-json.ts @@ -6,10 +6,10 @@ import { ProjectGraph, ProjectGraphProjectNode, readJsonFile, - readNxJson, workspaceRoot, } from '@nx/devkit'; import { PackageJson } from 'nx/src/utils/package-json'; +import { readNxJson } from 'nx/src/config/nx-json'; import { sortObjectByKeys } from 'nx/src/utils/object-sort'; import { readFileMapCache } from 'nx/src/project-graph/nx-deps-cache'; import { @@ -50,7 +50,7 @@ export function createPackageJson( isProduction?: boolean; helperDependencies?: string[]; } = {}, - fileMap: ProjectFileMap = null + fileMap: ProjectFileMap | undefined = undefined ): PackageJson { const projectNode = graph.nodes[projectName]; const isLibrary = projectNode.type === 'lib'; @@ -62,13 +62,13 @@ export function createPackageJson( const npmDeps = findProjectsNpmDependencies( projectNode, graph, - options.target, rootPackageJson, { helperDependencies: options.helperDependencies, isProduction: options.isProduction, }, manifestResources, + options.target, fileMap ); @@ -112,7 +112,7 @@ export function createPackageJson( section: 'devDependencies' | 'dependencies' ) => { return ( - packageJson[section][packageName] || + packageJson?.[section]?.[packageName] || (isLibrary && rootPackageJson[section]?.[packageName]) || version ); @@ -217,7 +217,6 @@ export function createPackageJson( export function findProjectsNpmDependencies( projectNode: ProjectGraphProjectNode, graph: ProjectGraph, - target: string, rootPackageJson: PackageJson, options: { helperDependencies?: string[]; @@ -225,10 +224,11 @@ export function findProjectsNpmDependencies( isProduction?: boolean; }, manifestResources: Resources, + target?: string, fileMap?: ProjectFileMap ): NpmDeps { - if (fileMap == null) { - fileMap = readFileMapCache()?.fileMap?.projectFileMap || {}; + if (fileMap === undefined) { + fileMap = readFileMapCache()?.fileMap?.projectFileMap ?? {}; } const { selfInputs, dependencyInputs } = target @@ -245,9 +245,12 @@ export function findProjectsNpmDependencies( options.helperDependencies?.forEach((dep) => { seen.add(dep); - npmDeps.dependencies[graph.externalNodes[dep].data.packageName] = - graph.externalNodes[dep].data.version; - recursivelyCollectPeerDependencies(dep, graph, npmDeps, seen); + const graphDependencyNode = graph.externalNodes?.[dep]; + if (graphDependencyNode) { + npmDeps.dependencies[graphDependencyNode.data.packageName] = + graphDependencyNode.data.version; + recursivelyCollectPeerDependencies(dep, graph, npmDeps, seen); + } }); // if it's production, we want to ignore all found devDependencies @@ -309,7 +312,7 @@ function findAllNpmDeps( ); for (const dep of projectDependencies) { - const node = graph.externalNodes[dep]; + const node = graph.externalNodes?.[dep]; if (seen.has(dep)) { // if it's in peerDependencies, move it to regular dependencies @@ -353,7 +356,7 @@ function recursivelyCollectPeerDependencies( npmDeps: NpmDeps, seen: Set ) { - const npmPackage = graph.externalNodes[projectName]; + const npmPackage = graph.externalNodes?.[projectName]; if (!npmPackage) { return npmDeps; } @@ -368,8 +371,8 @@ function recursivelyCollectPeerDependencies( Object.keys(packageJson.peerDependencies) .map((dependencyName) => `npm:${dependencyName}`) - .map((dependency) => graph.externalNodes[dependency]) - .filter(Boolean) + .map((dependency) => graph.externalNodes?.[dependency]) + .filter((node): node is NonNullable => !!node) .forEach((node) => { if (!seen.has(node.name)) { seen.add(node.name); diff --git a/packages/nx-forge/src/executors/register/executor.ts b/packages/nx-forge/src/executors/register/executor.ts index a81a7f7..7975b20 100644 --- a/packages/nx-forge/src/executors/register/executor.ts +++ b/packages/nx-forge/src/executors/register/executor.ts @@ -8,6 +8,10 @@ export default async function runExecutor( rawOptions: RegisterExecutorOptions, context: ExecutorContext ) { + if (context.projectName === undefined) { + throw new Error('No project name provided in executor context.'); + } + const { root, sourceRoot } = context.projectsConfigurations.projects[context.projectName]; diff --git a/packages/nx-forge/src/executors/tunnel/executor.ts b/packages/nx-forge/src/executors/tunnel/executor.ts index 8c15bc7..470d209 100644 --- a/packages/nx-forge/src/executors/tunnel/executor.ts +++ b/packages/nx-forge/src/executors/tunnel/executor.ts @@ -21,6 +21,10 @@ export default async function runTunnelExecutor( options: TunnelExecutorOptions, context: ExecutorContext ) { + if (context.projectName === undefined) { + throw new Error('No project name provided in executor context.'); + } + const customUIProjectConfigs = await getCustomUiProjects(context); const customUIIters = await startCustomUIs(customUIProjectConfigs, context); @@ -41,7 +45,7 @@ export default async function runTunnelExecutor( const preTunnelTimeout = options.preTunnelTimeout ?? 5000; await isTunnelPreparationComplete(options.outputPath, preTunnelTimeout); } catch (err) { - logger.error(err.message); + logger.error(err instanceof Error ? err.message : String(err)); return { success: false }; } diff --git a/packages/nx-forge/src/executors/tunnel/lib/extract-custom-ui-projects.ts b/packages/nx-forge/src/executors/tunnel/lib/extract-custom-ui-projects.ts index 23be5ba..97a894c 100644 --- a/packages/nx-forge/src/executors/tunnel/lib/extract-custom-ui-projects.ts +++ b/packages/nx-forge/src/executors/tunnel/lib/extract-custom-ui-projects.ts @@ -37,6 +37,10 @@ export async function getCustomUiProjects( async function extractVerifiedCustomUIProjects( context: ExecutorContext ): Promise { + if (context.projectName === undefined) { + throw new Error('No project name provided in executor context.'); + } + const manifestPath = joinPathFragments( context.root, context.projectsConfigurations.projects[context.projectName].root, @@ -65,7 +69,7 @@ const verifyCustomUIDependency = ); } - if (!customUIProjectConfiguration.targets['serve']) { + if (!customUIProjectConfiguration.targets?.['serve']) { throw new Error( `Custom UI project '${customUIProjectName}' targets is missing a 'serve' executor. Make sure the the project has a 'serve' target inferred, or the 'targets' property in the project's 'project.json' has a 'serve' executor configured.` ); diff --git a/packages/nx-forge/src/executors/tunnel/lib/wait-until-server-is-listening.ts b/packages/nx-forge/src/executors/tunnel/lib/wait-until-server-is-listening.ts index 6d7c223..4465651 100644 --- a/packages/nx-forge/src/executors/tunnel/lib/wait-until-server-is-listening.ts +++ b/packages/nx-forge/src/executors/tunnel/lib/wait-until-server-is-listening.ts @@ -29,17 +29,17 @@ export function waitUntilServerIsListening( cleanup(); resolve(); }); - client.on('error', (err) => { + client.on('error', (err: NodeJS.ErrnoException) => { if ( attempts > maxAttempts || - !allowedErrorCodes.includes(err['code']) + !allowedErrorCodes.includes(err.code ?? '') ) { if (context.isVerbose) { logger.error( `Could not wait for server to start on port ${port}: ${ attempts > maxAttempts ? `Max attempts (${maxAttempts}) exceeded` - : `Server returned unexpected error code ${err['code']}` + : `Server returned unexpected error code ${err.code}` }` ); } diff --git a/packages/nx-forge/src/generators/application/generator.ts b/packages/nx-forge/src/generators/application/generator.ts index fc62750..2449fbc 100644 --- a/packages/nx-forge/src/generators/application/generator.ts +++ b/packages/nx-forge/src/generators/application/generator.ts @@ -9,7 +9,7 @@ import { updateJson, updateTsConfigsToJs, } from '@nx/devkit'; -import { Linter, lintProjectGenerator } from '@nx/eslint'; +import { lintProjectGenerator } from '@nx/eslint'; import { configurationGenerator } from '@nx/jest'; import { initGenerator as jsInitGenerator, tsConfigBaseOptions } from '@nx/js'; import initGenerator from '../init/generator'; @@ -95,7 +95,7 @@ export async function applicationGeneratorInternal( updateTsConfigOptions(tree, options); - if (options.linter === Linter.EsLint) { + if (options.linter === 'eslint') { const lintTask = await lintProjectGenerator(tree, { linter: options.linter, project: options.name, diff --git a/packages/nx-forge/src/generators/application/lib/add-app-files.ts b/packages/nx-forge/src/generators/application/lib/add-app-files.ts index f1a3395..a164992 100644 --- a/packages/nx-forge/src/generators/application/lib/add-app-files.ts +++ b/packages/nx-forge/src/generators/application/lib/add-app-files.ts @@ -27,7 +27,8 @@ export function addAppFiles(tree: Tree, options: NormalizedOptions): void { ? { outputPath: joinPathFragments( 'dist', - options.rootProject ? options.name : options.appProjectRoot, + (options.rootProject ? options.name : options.appProjectRoot) ?? + '', 'src' ), main: './src/index' + (options.js ? '.js' : '.ts'), diff --git a/packages/nx-forge/src/generators/application/lib/add-project-dependencies.ts b/packages/nx-forge/src/generators/application/lib/add-project-dependencies.ts index 15b7726..d57955b 100644 --- a/packages/nx-forge/src/generators/application/lib/add-project-dependencies.ts +++ b/packages/nx-forge/src/generators/application/lib/add-project-dependencies.ts @@ -44,9 +44,20 @@ export async function addProjectDependencies( '@forge/resolver' ); + if (!latestForgeApiVersion) { + logger.warn( + `Failed to fetch latest version of @forge/api. Using 'latest' tag as version` + ); + } + + if (!latestForgeResolverVersion) { + logger.warn( + `Failed to fetch latest version of @forge/resolver. Using 'latest' tag as version` + ); + } const forgeDependencies = { - '@forge/api': latestForgeApiVersion, - '@forge/resolver': latestForgeResolverVersion, + '@forge/api': latestForgeApiVersion ?? 'latest', + '@forge/resolver': latestForgeResolverVersion ?? 'latest', }; return addDependenciesToPackageJson( @@ -56,7 +67,7 @@ export async function addProjectDependencies( tslib: tsLibVersion, }, { - ...bundlers[options.bundler], + ...bundlers[options.bundler ?? 'webpack'], '@types/node': typesNodeVersion, } ); diff --git a/packages/nx-forge/src/generators/application/lib/add-project.ts b/packages/nx-forge/src/generators/application/lib/add-project.ts index 7bba11b..fb123c9 100644 --- a/packages/nx-forge/src/generators/application/lib/add-project.ts +++ b/packages/nx-forge/src/generators/application/lib/add-project.ts @@ -22,16 +22,16 @@ function getWebpackBuildConfig( compiler: 'tsc', outputPath: joinPathFragments( 'dist', - options.rootProject ? options.name : options.appProjectRoot, + (options.rootProject ? options.name : options.appProjectRoot) ?? '', 'src' ), main: joinPathFragments( - project.sourceRoot, + project.sourceRoot ?? '', 'index' + (options.js ? '.js' : '.ts') ), outputFileName: 'index.js', tsConfig: joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'), - assets: [joinPathFragments(project.sourceRoot, 'assets')], + assets: [joinPathFragments(project.sourceRoot ?? '', 'assets')], webpackConfig: joinPathFragments( options.appProjectRoot, 'webpack.config.js' @@ -56,19 +56,19 @@ function getEsBuildConfig( platform: 'node', outputPath: joinPathFragments( 'dist', - options.rootProject ? options.name : options.appProjectRoot, + (options.rootProject ? options.name : options.appProjectRoot) ?? '', 'src' ), // Use CJS for Node apps for widest compatibility. format: ['cjs'], bundle: true, main: joinPathFragments( - project.sourceRoot, + project.sourceRoot ?? '', 'index' + (options.js ? '.js' : '.ts') ), outputFileName: 'index.js', tsConfig: joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'), - assets: [joinPathFragments(project.sourceRoot, 'assets')], + assets: [joinPathFragments(project.sourceRoot ?? '', 'assets')], generatePackageJson: false, esbuildOptions: { sourcemap: true, @@ -104,17 +104,19 @@ export function addProject(tree: Tree, options: NormalizedOptions) { if (options.bundler === 'esbuild') { addBuildTargetDefaults(tree, '@nx/esbuild:esbuild'); + project.targets ??= {}; project.targets.build = getEsBuildConfig(project, options); } else if (options.bundler === 'webpack') { if (!hasWebpackPlugin(tree)) { addBuildTargetDefaults(tree, `@nx/webpack:webpack`); + project.targets ??= {}; project.targets.build = getWebpackBuildConfig(project, options); } } addProjectConfiguration( tree, - options.name, + options.name || '', project, options.standaloneConfig ); diff --git a/packages/nx-forge/src/generators/application/lib/normalize-options.ts b/packages/nx-forge/src/generators/application/lib/normalize-options.ts index 4f74a4b..e6eb9ab 100644 --- a/packages/nx-forge/src/generators/application/lib/normalize-options.ts +++ b/packages/nx-forge/src/generators/application/lib/normalize-options.ts @@ -1,16 +1,11 @@ -import { Linter } from '@nx/eslint'; import { readNxJson, Tree } from '@nx/devkit'; import type { ApplicationGeneratorOptions, NormalizedOptions } from '../schema'; -import { - determineProjectNameAndRootOptions, - ensureProjectName, -} from '@nx/devkit/src/generators/project-name-and-root-utils'; +import { determineProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils'; export async function normalizeOptions( tree: Tree, options: ApplicationGeneratorOptions ): Promise { - await ensureProjectName(tree, options, 'application'); const { projectName: appProjectName, projectRoot: appProjectRoot } = await determineProjectNameAndRootOptions(tree, { name: options.name, @@ -29,7 +24,7 @@ export async function normalizeOptions( const nxJson = readNxJson(tree); const addPlugin = process.env.NX_ADD_PLUGINS !== 'false' && - nxJson.useInferencePlugins !== false; + nxJson?.useInferencePlugins !== false; return { addPlugin, @@ -37,7 +32,7 @@ export async function normalizeOptions( name: appProjectName, appProjectRoot, parsedTags, - linter: options.linter ?? Linter.EsLint, + linter: options.linter ?? 'eslint', unitTestRunner: options.unitTestRunner ?? 'jest', rootProject: options.rootProject ?? false, }; diff --git a/packages/nx-forge/src/generators/application/schema.d.ts b/packages/nx-forge/src/generators/application/schema.d.ts index 6aac4a5..2aa3b15 100644 --- a/packages/nx-forge/src/generators/application/schema.d.ts +++ b/packages/nx-forge/src/generators/application/schema.d.ts @@ -1,11 +1,11 @@ -import type { Linter } from '@nx/eslint'; +import type { LinterType } from '@nx/eslint'; interface ApplicationGeneratorOptions { directory: string; name?: string; skipFormat?: boolean; skipPackageJson?: boolean; - linter?: Linter; + linter?: LinterType; standaloneConfig?: boolean; tags?: string; bundler?: 'esbuild' | 'webpack'; @@ -20,9 +20,10 @@ interface ApplicationGeneratorOptions { } interface NormalizedOptions extends ApplicationGeneratorOptions { + name: string; addPlugin: boolean; appProjectRoot: string; - linter: Linter; + linter: LinterType; unitTestRunner: 'jest' | 'none'; parsedTags: string[]; } diff --git a/packages/nx-forge/src/generators/init/generator.ts b/packages/nx-forge/src/generators/init/generator.ts index 2477740..6f1920d 100644 --- a/packages/nx-forge/src/generators/init/generator.ts +++ b/packages/nx-forge/src/generators/init/generator.ts @@ -50,7 +50,7 @@ export default async function ( ); const addDependenciesTask = await addDependencies( tree, - options.keepExistingVersions + options.keepExistingVersions ?? false ); tasks.push(addDependenciesTask); } diff --git a/packages/nx-forge/src/graph/create-dependencies.ts b/packages/nx-forge/src/graph/create-dependencies.ts index 266d6e2..78b6811 100644 --- a/packages/nx-forge/src/graph/create-dependencies.ts +++ b/packages/nx-forge/src/graph/create-dependencies.ts @@ -48,16 +48,19 @@ const getUIResourceDependencies = async ( }; }; - return uiResourceProjectNames.reduce((acc, uiResourceProjectName) => { - return (manifestFile.deps || []).find( - ([source, target, type]) => - type === 'static' && - target === uiResourceProjectName && - source === projectName - ) - ? acc // Dependency already exists, skip adding it again. - : [...acc, getUIResourceStaticDependency(uiResourceProjectName)]; - }, []); + return uiResourceProjectNames.reduce( + (acc, uiResourceProjectName) => { + return (manifestFile.deps ?? []).some( + ([source, target, type]) => + type === 'static' && + target === uiResourceProjectName && + source === projectName + ) + ? acc // Dependency already exists, skip adding it again. + : [...acc, getUIResourceStaticDependency(uiResourceProjectName)]; + }, + [] + ); }; export const createDependencies: CreateDependencies = async ( @@ -68,7 +71,7 @@ export const createDependencies: CreateDependencies = async ( for (const projectName in context.filesToProcess.projectFileMap) { const changed = context.filesToProcess.projectFileMap[projectName]; - for await (const manifestFile of changed.filter((f) => + for (const manifestFile of changed.filter((f) => f.file.endsWith('manifest.yml') )) { logger.info(`[nx-forge] Processing ${projectName}:${manifestFile.file}`); diff --git a/packages/nx-forge/src/graph/create-nodes.ts b/packages/nx-forge/src/graph/create-nodes.ts index dd39b19..56a5764 100644 --- a/packages/nx-forge/src/graph/create-nodes.ts +++ b/packages/nx-forge/src/graph/create-nodes.ts @@ -1,7 +1,7 @@ import { readdirSync } from 'fs'; import { dirname, join } from 'path'; import { - CreateNodesContext, + CreateNodesContextV2, createNodesFromFiles, CreateNodesV2, ProjectConfiguration, @@ -51,7 +51,7 @@ export const createNodesV2: CreateNodesV2 = [ function createNodesInternal( manifestFilePath: string, options: unknown, - context: CreateNodesContext + context: CreateNodesContextV2 ) { const projectRoot = dirname(manifestFilePath); diff --git a/packages/nx-forge/src/migrations/update-2-3-0/remove-implicit-custom-ui-dependencies.ts b/packages/nx-forge/src/migrations/update-2-3-0/remove-implicit-custom-ui-dependencies.ts index b7f83bf..66604f3 100644 --- a/packages/nx-forge/src/migrations/update-2-3-0/remove-implicit-custom-ui-dependencies.ts +++ b/packages/nx-forge/src/migrations/update-2-3-0/remove-implicit-custom-ui-dependencies.ts @@ -21,7 +21,10 @@ export default async function update(host: Tree) { for (const [name, config] of projects.entries()) { if (config && isForgeProject(config)) { - if (config.implicitDependencies?.length > 0) { + if ( + config.implicitDependencies && + config.implicitDependencies.length > 0 + ) { const manifest = await readManifestYml( host, joinPathFragments(config.root, 'manifest.yml') diff --git a/packages/nx-forge/src/migrations/update-2-3-0/utils/manifest.ts b/packages/nx-forge/src/migrations/update-2-3-0/utils/manifest.ts index 0d16e92..90e16bb 100644 --- a/packages/nx-forge/src/migrations/update-2-3-0/utils/manifest.ts +++ b/packages/nx-forge/src/migrations/update-2-3-0/utils/manifest.ts @@ -7,12 +7,15 @@ const manifestSchemaValidator = new SchemaValidator( FULL_SCHEMA ); -export const readManifestYml = async (tree: Tree, path: string) => { +export const readManifestYml = async ( + tree: Tree, + path: string +): Promise => { const result = await manifestSchemaValidator.validate({ yamlContent: readYaml(tree, path), }); - if (result.success) { + if (result.success && result.manifestObject?.typedContent) { return result.manifestObject.typedContent; } diff --git a/packages/nx-forge/src/migrations/update-2-3-0/utils/yml.ts b/packages/nx-forge/src/migrations/update-2-3-0/utils/yml.ts index efb617c..48399d5 100644 --- a/packages/nx-forge/src/migrations/update-2-3-0/utils/yml.ts +++ b/packages/nx-forge/src/migrations/update-2-3-0/utils/yml.ts @@ -18,9 +18,11 @@ export const readYaml = ( throw new Error(`Cannot find ${path}`); } try { - return load(tree.read(path, 'utf-8'), options) as ManifestSchema; + return load(tree.read(path, 'utf-8') ?? '', options) as ManifestSchema; } catch (e) { - throw new Error(`Cannot parse ${path}: ${e.message}`); + throw new Error( + `Cannot parse ${path}: ${e instanceof Error ? e.message : String(e)}` + ); } }; diff --git a/packages/nx-forge/src/migrations/update-3-0-0-webpack-config-setup/update-3-0-0-webpack-config-setup.ts b/packages/nx-forge/src/migrations/update-3-0-0-webpack-config-setup/update-3-0-0-webpack-config-setup.ts index 4b93ece..744b169 100644 --- a/packages/nx-forge/src/migrations/update-3-0-0-webpack-config-setup/update-3-0-0-webpack-config-setup.ts +++ b/packages/nx-forge/src/migrations/update-3-0-0-webpack-config-setup/update-3-0-0-webpack-config-setup.ts @@ -12,7 +12,7 @@ export default async function (tree: Tree) { options: BuildExecutorOptions, projectName: string, targetName: string, - configurationName: string + configurationName?: string ) => { // There should not be any configurations, if there are skip the update - only handle the default config if (configurationName) return; @@ -35,7 +35,8 @@ export default async function (tree: Tree) { ` ); - projectConfiguration.targets[targetName].options = options; + const targets = (projectConfiguration.targets ??= {}); + targets[targetName] = { ...targets[targetName], options }; updateProjectConfiguration(tree, projectName, projectConfiguration); } }; diff --git a/packages/nx-forge/src/shared/manifest/util-manifest.ts b/packages/nx-forge/src/shared/manifest/util-manifest.ts index f4ab2c6..56941bf 100644 --- a/packages/nx-forge/src/shared/manifest/util-manifest.ts +++ b/packages/nx-forge/src/shared/manifest/util-manifest.ts @@ -21,11 +21,11 @@ export type ResourceType = 'ui-kit' | 'custom-ui' | 'static'; * @param moduleDefinition Module definition to analyze */ const resourceTypeByModuleDefinition = ( - moduleDefinition: object + moduleDefinition: any ): ResourceType => { - if (!!moduleDefinition['resource'] && moduleDefinition['render'] === 'native') + if (moduleDefinition.resource && moduleDefinition.render === 'native') return 'ui-kit'; - if (!!moduleDefinition['resource'] && moduleDefinition['render'] !== 'native') + if (moduleDefinition.resource && moduleDefinition.render !== 'native') return 'custom-ui'; return 'static'; }; @@ -90,8 +90,8 @@ export const resourceTypeByResourceDefinition = ( if ( isObject(moduleDefinition) && Object.hasOwn(moduleDefinition, 'resource') && - typeof moduleDefinition['resource'] === 'string' && - moduleDefinition['resource'] === resource.key + typeof (moduleDefinition as any).resource === 'string' && + (moduleDefinition as any).resource === resource.key ) { return resourceTypeByModuleDefinition(moduleDefinition); } diff --git a/packages/nx-forge/src/utils/forge/yaml-validator.ts b/packages/nx-forge/src/utils/forge/yaml-validator.ts index efab27a..01db10f 100644 --- a/packages/nx-forge/src/utils/forge/yaml-validator.ts +++ b/packages/nx-forge/src/utils/forge/yaml-validator.ts @@ -66,7 +66,9 @@ class YamlValidator success: false, errors: [ { - message: errors.invalidManifest(e.message), + message: errors.invalidManifest( + e instanceof Error ? e.message : String(e) + ), reference: References.InvalidManifest, level: 'error', line: 0, diff --git a/packages/nx-forge/src/utils/has-webpack-plugin.ts b/packages/nx-forge/src/utils/has-webpack-plugin.ts index 7519a9b..7b3dc5e 100644 --- a/packages/nx-forge/src/utils/has-webpack-plugin.ts +++ b/packages/nx-forge/src/utils/has-webpack-plugin.ts @@ -2,7 +2,7 @@ import { readNxJson, Tree } from '@nx/devkit'; export function hasWebpackPlugin(tree: Tree) { const nxJson = readNxJson(tree); - return !!nxJson.plugins?.some((p) => + return !!nxJson?.plugins?.some((p) => typeof p === 'string' ? p === '@nx/webpack/plugin' : p.plugin === '@nx/webpack/plugin' diff --git a/packages/nx-forge/tsconfig.lib.json b/packages/nx-forge/tsconfig.lib.json index a5ef959..f6be4d3 100644 --- a/packages/nx-forge/tsconfig.lib.json +++ b/packages/nx-forge/tsconfig.lib.json @@ -3,7 +3,8 @@ "compilerOptions": { "outDir": "../../dist/out-tsc", "declaration": true, - "types": ["node"] + "types": ["node"], + "strict": true }, "include": ["**/*.ts"], "exclude": ["**/*.spec.ts", "**/*.test.ts", "jest.config.ts"]