Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,13 @@
"files": ["*.ts", "*.tsx"],
"extends": ["plugin:@nx/typescript"],
"rules": {
"@typescript-eslint/no-extra-semi": "error",
"no-extra-semi": "off"
}
},
{
"files": ["*.js", "*.jsx"],
"extends": ["plugin:@nx/javascript"],
"rules": {
"@typescript-eslint/no-extra-semi": "error",
"no-extra-semi": "off"
}
}
Expand Down
4 changes: 4 additions & 0 deletions packages/nx-forge/src/executors/build/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: {},
Expand Down Expand Up @@ -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;
Expand All @@ -132,7 +131,7 @@ function recursivelyCollectPeerDependencies(
list: { [packageName: string]: string } = {},
seen = new Set<string>()
) {
const npmPackage = graph.externalNodes[projectName];
const npmPackage = graph.externalNodes?.[projectName];
if (!npmPackage || seen.has(projectName)) {
return list;
}
Expand All @@ -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<typeof node> => !!node)
.forEach((node) => {
if (
!packageJson.peerDependenciesMeta?.[node.data.packageName]?.optional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ export async function processResourceDependencies(
options: Options,
context: ExecutorContext
): Promise<Resources> {
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,
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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}': '<replace-with-project-output-path>'}.`
`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}': '<replace-with-project-output-path>'}.`
);
};

Expand All @@ -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;
Expand Down
9 changes: 6 additions & 3 deletions packages/nx-forge/src/executors/deploy/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DeployExecutorOptions, 'outputPath' | 'verify'> & {
manifestTransform: string;
};

export const transformManifestYml = async (
options: Options,
Expand All @@ -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)
}`
);
}
Expand Down
4 changes: 4 additions & 0 deletions packages/nx-forge/src/executors/package/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down
31 changes: 17 additions & 14 deletions packages/nx-forge/src/executors/package/lib/create-package-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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';
Expand All @@ -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
);

Expand Down Expand Up @@ -112,7 +112,7 @@ export function createPackageJson(
section: 'devDependencies' | 'dependencies'
) => {
return (
packageJson[section][packageName] ||
packageJson?.[section]?.[packageName] ||
(isLibrary && rootPackageJson[section]?.[packageName]) ||
version
);
Expand Down Expand Up @@ -217,18 +217,18 @@ export function createPackageJson(
export function findProjectsNpmDependencies(
projectNode: ProjectGraphProjectNode,
graph: ProjectGraph,
target: string,
rootPackageJson: PackageJson,
options: {
helperDependencies?: string[];
ignoredDependencies?: string[];
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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -353,7 +356,7 @@ function recursivelyCollectPeerDependencies(
npmDeps: NpmDeps,
seen: Set<string>
) {
const npmPackage = graph.externalNodes[projectName];
const npmPackage = graph.externalNodes?.[projectName];
if (!npmPackage) {
return npmDeps;
}
Expand All @@ -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<typeof node> => !!node)
.forEach((node) => {
if (!seen.has(node.name)) {
seen.add(node.name);
Expand Down
4 changes: 4 additions & 0 deletions packages/nx-forge/src/executors/register/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down
6 changes: 5 additions & 1 deletion packages/nx-forge/src/executors/tunnel/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 };
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ export async function getCustomUiProjects(
async function extractVerifiedCustomUIProjects(
context: ExecutorContext
): Promise<ResourceWithTunnelPort[]> {
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,
Expand Down Expand Up @@ -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.`
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}`
}`
);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/nx-forge/src/generators/application/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand Down
Loading