@nx/js 16.4.0-beta.1 → 16.4.0-beta.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/babel.js +3 -1
  2. package/executors.json +1 -0
  3. package/generators.json +12 -0
  4. package/migrations.json +12 -0
  5. package/package.json +6 -5
  6. package/plugins/jest/local-registry.d.ts +1 -0
  7. package/plugins/jest/local-registry.js +4 -0
  8. package/src/executors/node/node.impl.d.ts +1 -0
  9. package/src/executors/node/node.impl.js +59 -11
  10. package/src/executors/tsc/lib/batch/build-task-info-per-tsconfig-map.d.ts +5 -0
  11. package/src/executors/tsc/lib/batch/build-task-info-per-tsconfig-map.js +59 -0
  12. package/src/executors/tsc/lib/batch/index.d.ts +4 -0
  13. package/src/executors/tsc/lib/batch/index.js +7 -0
  14. package/src/executors/tsc/lib/batch/normalize-tasks-options.d.ts +3 -0
  15. package/src/executors/tsc/lib/batch/normalize-tasks-options.js +14 -0
  16. package/src/executors/tsc/lib/batch/types.d.ts +17 -0
  17. package/src/executors/tsc/lib/batch/types.js +2 -0
  18. package/src/executors/tsc/lib/batch/watch.d.ts +3 -0
  19. package/src/executors/tsc/lib/batch/watch.js +63 -0
  20. package/src/executors/tsc/lib/get-custom-transformers-factory.d.ts +3 -0
  21. package/src/executors/tsc/lib/get-custom-transformers-factory.js +13 -0
  22. package/src/executors/tsc/lib/get-task-options.d.ts +8 -0
  23. package/src/executors/tsc/lib/get-task-options.js +51 -0
  24. package/src/executors/tsc/lib/get-tsconfig.d.ts +4 -0
  25. package/src/executors/tsc/lib/get-tsconfig.js +138 -0
  26. package/src/executors/tsc/lib/index.d.ts +4 -0
  27. package/src/executors/tsc/lib/index.js +7 -0
  28. package/src/executors/tsc/lib/normalize-options.d.ts +2 -0
  29. package/src/executors/tsc/lib/normalize-options.js +32 -0
  30. package/src/executors/tsc/lib/typescript-compilation.d.ts +29 -0
  31. package/src/executors/tsc/lib/typescript-compilation.js +206 -0
  32. package/src/executors/tsc/lib/typescript-diagnostic-reporters.d.ts +3 -0
  33. package/src/executors/tsc/lib/typescript-diagnostic-reporters.js +37 -0
  34. package/src/executors/tsc/tsc.batch-impl.d.ts +5 -0
  35. package/src/executors/tsc/tsc.batch-impl.js +137 -0
  36. package/src/executors/tsc/tsc.impl.d.ts +0 -1
  37. package/src/executors/tsc/tsc.impl.js +4 -39
  38. package/src/executors/verdaccio/verdaccio.impl.d.ts +1 -0
  39. package/src/executors/verdaccio/verdaccio.impl.js +93 -45
  40. package/src/generators/library/library.js +2 -10
  41. package/src/generators/library/schema.json +7 -6
  42. package/src/generators/setup-build/generator.d.ts +5 -0
  43. package/src/generators/setup-build/generator.js +133 -0
  44. package/src/generators/setup-build/schema.d.ts +7 -0
  45. package/src/generators/setup-build/schema.json +42 -0
  46. package/src/generators/setup-verdaccio/files/config.yml +5 -6
  47. package/src/generators/setup-verdaccio/generator.js +5 -1
  48. package/src/index.d.ts +1 -0
  49. package/src/index.js +1 -0
  50. package/src/plugins/jest/start-local-registry.d.ts +12 -0
  51. package/src/plugins/jest/start-local-registry.js +61 -0
  52. package/src/utils/add-babel-inputs.d.ts +1 -0
  53. package/src/utils/add-babel-inputs.js +2 -0
  54. package/src/utils/add-local-registry-scripts.d.ts +5 -0
  55. package/src/utils/add-local-registry-scripts.js +57 -0
  56. package/src/utils/assets/copy-assets-handler.d.ts +5 -1
  57. package/src/utils/assets/copy-assets-handler.js +34 -23
  58. package/src/utils/compiler-helper-dependency.d.ts +2 -1
  59. package/src/utils/compiler-helper-dependency.js +13 -2
  60. package/src/utils/inline.d.ts +1 -1
  61. package/src/utils/inline.js +3 -3
  62. package/src/utils/minimal-publish-script.js +2 -5
  63. package/src/utils/schema.d.ts +3 -2
  64. package/src/utils/swc/add-swc-config.d.ts +1 -1
  65. package/src/utils/versions.d.ts +1 -1
  66. package/src/utils/versions.js +1 -1
  67. package/src/generators/setup-verdaccio/files/htpasswd +0 -1
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getProcessedTaskTsConfigs = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const fileutils_1 = require("nx/src/utils/fileutils");
6
+ const path_1 = require("path");
7
+ const buildable_libs_utils_1 = require("../../../utils/buildable-libs-utils");
8
+ const get_task_options_1 = require("./get-task-options");
9
+ function getProcessedTaskTsConfigs(tasks, tasksOptions, context) {
10
+ const taskInMemoryTsConfigMap = {};
11
+ for (const task of tasks) {
12
+ generateTaskTsConfigOrGetDependentBuildableProjectNode(task, tasksOptions, context, taskInMemoryTsConfigMap);
13
+ }
14
+ return taskInMemoryTsConfigMap;
15
+ }
16
+ exports.getProcessedTaskTsConfigs = getProcessedTaskTsConfigs;
17
+ const taskTsConfigGenerationCache = new Map();
18
+ function generateTaskTsConfigOrGetDependentBuildableProjectNode(task, tasksOptions, context, taskInMemoryTsConfigMap) {
19
+ var _a, _b, _c;
20
+ if (taskTsConfigGenerationCache.has(task)) {
21
+ return taskTsConfigGenerationCache.get(task);
22
+ }
23
+ let tsConfig = (_b = (_a = tasksOptions[task]) === null || _a === void 0 ? void 0 : _a.tsConfig) !== null && _b !== void 0 ? _b : (0, get_task_options_1.getTaskOptions)(task, context).tsConfig;
24
+ let taskWithTsConfig = task;
25
+ if (!tsConfig) {
26
+ // check if other tasks in the task graph from the same project has a tsConfig
27
+ const otherTasksInProject = getDependencyTasksInSameProject(task, context);
28
+ const taskTsConfig = findTaskWithTsConfig(otherTasksInProject, context);
29
+ if (taskTsConfig) {
30
+ if (taskTsConfigGenerationCache.has(taskTsConfig.tsConfig)) {
31
+ return taskTsConfigGenerationCache.get(taskTsConfig.tsConfig);
32
+ }
33
+ tsConfig = taskTsConfig.tsConfig;
34
+ taskWithTsConfig = taskTsConfig.task;
35
+ }
36
+ }
37
+ if (tsConfig) {
38
+ const { projectReferences, dependentBuildableProjectNodes } = collectDependenciesFromTask(task, tasksOptions, context, taskInMemoryTsConfigMap);
39
+ taskInMemoryTsConfigMap[taskWithTsConfig] = getInMemoryTsConfig(tsConfig, (_c = tasksOptions[taskWithTsConfig]) !== null && _c !== void 0 ? _c : (0, get_task_options_1.getTaskOptions)(taskWithTsConfig, context), projectReferences, dependentBuildableProjectNodes);
40
+ const result = { tsConfig };
41
+ taskTsConfigGenerationCache.set(task, result);
42
+ return result;
43
+ }
44
+ // there's no tsConfig, return a buildable project node so the path mapping
45
+ // is remapped to the output
46
+ const result = taskToDependentBuildableProjectNode(task, context);
47
+ taskTsConfigGenerationCache.set(task, result);
48
+ return result;
49
+ }
50
+ const projectDependenciesCache = new Map();
51
+ function collectDependenciesFromTask(task, tasksOptions, context, taskInMemoryTsConfigMap) {
52
+ var _a;
53
+ const { project: taskProject } = (0, devkit_1.parseTargetString)(task, context.projectGraph);
54
+ if (projectDependenciesCache.has(taskProject)) {
55
+ return projectDependenciesCache.get(taskProject);
56
+ }
57
+ const dependentBuildableProjectNodes = [];
58
+ const projectReferences = new Set();
59
+ const allProjectTasks = [
60
+ task,
61
+ ...getDependencyTasksInSameProject(task, context),
62
+ ];
63
+ for (const projectTask of allProjectTasks) {
64
+ for (const depTask of (_a = context.taskGraph.dependencies[projectTask]) !== null && _a !== void 0 ? _a : []) {
65
+ if (task === depTask) {
66
+ continue;
67
+ }
68
+ const { project: depTaskProject } = (0, devkit_1.parseTargetString)(depTask, context.projectGraph);
69
+ if (depTaskProject === taskProject) {
70
+ // recursively collect dependencies for tasks in the same project
71
+ const result = collectDependenciesFromTask(depTask, tasksOptions, context, taskInMemoryTsConfigMap);
72
+ result.projectReferences.forEach((pr) => {
73
+ projectReferences.add(pr);
74
+ });
75
+ result.dependentBuildableProjectNodes.forEach((node) => {
76
+ dependentBuildableProjectNodes.push(node);
77
+ });
78
+ }
79
+ else {
80
+ // task is from a different project, get its project reference or buildable node
81
+ const result = generateTaskTsConfigOrGetDependentBuildableProjectNode(depTask, tasksOptions, context, taskInMemoryTsConfigMap);
82
+ if ('tsConfig' in result) {
83
+ projectReferences.add(result.tsConfig);
84
+ }
85
+ else {
86
+ dependentBuildableProjectNodes.push(result);
87
+ }
88
+ }
89
+ }
90
+ }
91
+ projectDependenciesCache.set(taskProject, {
92
+ projectReferences: Array.from(projectReferences),
93
+ dependentBuildableProjectNodes,
94
+ });
95
+ return projectDependenciesCache.get(taskProject);
96
+ }
97
+ function taskToDependentBuildableProjectNode(task, context) {
98
+ const target = context.taskGraph.tasks[task].target;
99
+ const projectGraphNode = context.projectGraph.nodes[target.project];
100
+ const libPackageJsonPath = (0, path_1.join)(context.root, projectGraphNode.data.root, 'package.json');
101
+ return {
102
+ name: (0, fileutils_1.fileExists)(libPackageJsonPath)
103
+ ? (0, devkit_1.readJsonFile)(libPackageJsonPath).name
104
+ : target.project,
105
+ outputs: (0, devkit_1.getOutputsForTargetAndConfiguration)({ overrides: {}, target }, projectGraphNode),
106
+ node: projectGraphNode,
107
+ };
108
+ }
109
+ function getInMemoryTsConfig(tsConfig, taskOptions, projectReferences, dependentBuildableProjectNodes) {
110
+ var _a, _b;
111
+ const originalTsConfig = (0, devkit_1.readJsonFile)(tsConfig, {
112
+ allowTrailingComma: true,
113
+ disallowComments: false,
114
+ });
115
+ const allProjectReferences = Array.from(new Set(((_a = originalTsConfig.references) !== null && _a !== void 0 ? _a : [])
116
+ .map((r) => r.path)
117
+ .concat(projectReferences)));
118
+ return {
119
+ content: JSON.stringify(Object.assign(Object.assign({}, originalTsConfig), { compilerOptions: Object.assign(Object.assign({}, originalTsConfig.compilerOptions), { rootDir: taskOptions.rootDir, outDir: taskOptions.outputPath, composite: true, declaration: true, declarationMap: true, tsBuildInfoFile: (0, path_1.join)(taskOptions.outputPath, 'tsconfig.tsbuildinfo'), paths: dependentBuildableProjectNodes.length
120
+ ? (0, buildable_libs_utils_1.computeCompilerOptionsPaths)(tsConfig, dependentBuildableProjectNodes)
121
+ : (_b = originalTsConfig.compilerOptions) === null || _b === void 0 ? void 0 : _b.paths }), references: allProjectReferences.map((pr) => ({ path: pr })) })),
122
+ path: tsConfig,
123
+ };
124
+ }
125
+ function findTaskWithTsConfig(tasks, context) {
126
+ for (const task of tasks) {
127
+ const depTaskOptions = (0, get_task_options_1.getTaskOptions)(task, context);
128
+ if (depTaskOptions === null || depTaskOptions === void 0 ? void 0 : depTaskOptions.tsConfig) {
129
+ return { task: task, tsConfig: depTaskOptions.tsConfig };
130
+ }
131
+ }
132
+ return null;
133
+ }
134
+ function getDependencyTasksInSameProject(task, context) {
135
+ const { project: taskProject } = (0, devkit_1.parseTargetString)(task, context.projectGraph);
136
+ return Object.keys(context.taskGraph.tasks).filter((t) => t !== task &&
137
+ (0, devkit_1.parseTargetString)(t, context.projectGraph).project === taskProject);
138
+ }
@@ -0,0 +1,4 @@
1
+ export * from './get-custom-transformers-factory';
2
+ export * from './get-tsconfig';
3
+ export * from './normalize-options';
4
+ export * from './typescript-compilation';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./get-custom-transformers-factory"), exports);
5
+ tslib_1.__exportStar(require("./get-tsconfig"), exports);
6
+ tslib_1.__exportStar(require("./normalize-options"), exports);
7
+ tslib_1.__exportStar(require("./typescript-compilation"), exports);
@@ -0,0 +1,2 @@
1
+ import type { ExecutorOptions, NormalizedExecutorOptions } from '../../../utils/schema';
2
+ export declare function normalizeOptions(options: ExecutorOptions, contextRoot: string, sourceRoot: string, projectRoot: string): NormalizedExecutorOptions;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeOptions = void 0;
4
+ const path_1 = require("path");
5
+ const assets_1 = require("../../../utils/assets/assets");
6
+ function normalizeOptions(options, contextRoot, sourceRoot, projectRoot) {
7
+ const outputPath = (0, path_1.join)(contextRoot, options.outputPath);
8
+ const rootDir = options.rootDir
9
+ ? (0, path_1.join)(contextRoot, options.rootDir)
10
+ : (0, path_1.join)(contextRoot, projectRoot);
11
+ if (options.watch == null) {
12
+ options.watch = false;
13
+ }
14
+ // TODO: put back when inlining story is more stable
15
+ // if (options.external == null) {
16
+ // options.external = 'all';
17
+ // } else if (Array.isArray(options.external) && options.external.length === 0) {
18
+ // options.external = 'none';
19
+ // }
20
+ if (Array.isArray(options.external) && options.external.length > 0) {
21
+ const firstItem = options.external[0];
22
+ if (firstItem === 'all' || firstItem === 'none') {
23
+ options.external = firstItem;
24
+ }
25
+ }
26
+ const files = (0, assets_1.assetGlobsToFiles)(options.assets, contextRoot, outputPath);
27
+ return Object.assign(Object.assign({}, options), { root: contextRoot, sourceRoot,
28
+ projectRoot,
29
+ files,
30
+ outputPath, tsConfig: (0, path_1.join)(contextRoot, options.tsConfig), rootDir, mainOutputPath: (0, path_1.resolve)(outputPath, options.main.replace(`${projectRoot}/`, '').replace('.ts', '.js')) });
31
+ }
32
+ exports.normalizeOptions = normalizeOptions;
@@ -0,0 +1,29 @@
1
+ import * as ts from 'typescript';
2
+ import type { TransformerEntry } from '../../../utils/typescript/types';
3
+ export interface TypescriptInMemoryTsConfig {
4
+ content: string;
5
+ path: string;
6
+ }
7
+ export interface TypescripCompilationLogger {
8
+ error: (message: string, tsConfig?: string) => void;
9
+ info: (message: string, tsConfig?: string) => void;
10
+ warn: (message: string, tsConfig?: string) => void;
11
+ }
12
+ export interface TypescriptProjectContext {
13
+ project: string;
14
+ tsConfig: TypescriptInMemoryTsConfig;
15
+ transformers: TransformerEntry[];
16
+ }
17
+ export interface TypescriptCompilationResult {
18
+ tsConfig: string;
19
+ success: boolean;
20
+ }
21
+ export type ReporterWithTsConfig<Fn extends (...args: any[]) => any> = (tsConfig: string | undefined, ...foo: Parameters<Fn>) => ReturnType<Fn>;
22
+ export declare function compileTypescriptSolution(context: Record<string, TypescriptProjectContext>, watch: boolean, logger: TypescripCompilationLogger, hooks?: {
23
+ beforeProjectCompilationCallback?: (tsConfig: string) => void;
24
+ afterProjectCompilationCallback?: (tsConfig: string, success: boolean) => void;
25
+ }, reporters?: {
26
+ diagnosticReporter?: ReporterWithTsConfig<ts.DiagnosticReporter>;
27
+ solutionBuilderStatusReporter?: ReporterWithTsConfig<ts.DiagnosticReporter>;
28
+ watchStatusReporter?: ReporterWithTsConfig<ts.WatchStatusReporter>;
29
+ }): AsyncIterable<TypescriptCompilationResult>;
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compileTypescriptSolution = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const async_iterable_1 = require("@nx/devkit/src/utils/async-iterable");
6
+ const ts = require("typescript");
7
+ const get_custom_transformers_factory_1 = require("./get-custom-transformers-factory");
8
+ const typescript_diagnostic_reporters_1 = require("./typescript-diagnostic-reporters");
9
+ // https://github.com/microsoft/TypeScript/blob/d45012c5e2ab122919ee4777a7887307c5f4a1e0/src/compiler/diagnosticMessages.json#L4050-L4053
10
+ // Typescript diagnostic message for 5083: Cannot read file '{0}'.
11
+ const TYPESCRIPT_CANNOT_READ_FILE = 5083;
12
+ // https://github.com/microsoft/TypeScript/blob/d45012c5e2ab122919ee4777a7887307c5f4a1e0/src/compiler/diagnosticMessages.json#L4211-4214
13
+ // Typescript diagnostic message for 6032: File change detected. Starting incremental compilation...
14
+ const TYPESCRIPT_FILE_CHANGE_DETECTED_STARTING_INCREMENTAL_COMPILATION = 6032;
15
+ function compileTypescriptSolution(context, watch, logger, hooks, reporters) {
16
+ if (watch) {
17
+ // create an AsyncIterable that doesn't complete, watch mode is only
18
+ // stopped by killing the process
19
+ return (0, async_iterable_1.createAsyncIterable)(({ next }) => tslib_1.__awaiter(this, void 0, void 0, function* () {
20
+ hooks !== null && hooks !== void 0 ? hooks : (hooks = {});
21
+ const callerAfterProjectCompilationCallback = hooks.afterProjectCompilationCallback;
22
+ hooks.afterProjectCompilationCallback = (tsConfig, success) => {
23
+ callerAfterProjectCompilationCallback === null || callerAfterProjectCompilationCallback === void 0 ? void 0 : callerAfterProjectCompilationCallback(tsConfig, success);
24
+ next({ tsConfig, success });
25
+ };
26
+ compileTSWithWatch(context, logger, hooks, reporters);
27
+ }));
28
+ }
29
+ // turn it into an AsyncIterable
30
+ const compilationGenerator = compileTS(context, logger, hooks, reporters);
31
+ return {
32
+ [Symbol.asyncIterator]() {
33
+ return {
34
+ next() {
35
+ return Promise.resolve(compilationGenerator.next());
36
+ },
37
+ };
38
+ },
39
+ };
40
+ }
41
+ exports.compileTypescriptSolution = compileTypescriptSolution;
42
+ function* compileTS(context, logger, hooks, reporters) {
43
+ var _a, _b, _c;
44
+ let project;
45
+ const formatDiagnosticsHost = {
46
+ getCurrentDirectory: () => ts.sys.getCurrentDirectory(),
47
+ getNewLine: () => ts.sys.newLine,
48
+ getCanonicalFileName: (filename) => ts.sys.useCaseSensitiveFileNames ? filename : filename.toLowerCase(),
49
+ };
50
+ const solutionBuilderHost = ts.createSolutionBuilderHost(getSystem(context),
51
+ /*createProgram*/ undefined, (diagnostic) => {
52
+ var _a;
53
+ const formattedDiagnostic = (0, typescript_diagnostic_reporters_1.formatDiagnosticReport)(diagnostic, formatDiagnosticsHost);
54
+ // handles edge case where a wrong a project reference path can't be read
55
+ if (diagnostic.code === TYPESCRIPT_CANNOT_READ_FILE) {
56
+ throw new Error(formattedDiagnostic);
57
+ }
58
+ logger.info(formattedDiagnostic, project.project);
59
+ (_a = reporters === null || reporters === void 0 ? void 0 : reporters.diagnosticReporter) === null || _a === void 0 ? void 0 : _a.call(reporters, project.project, diagnostic);
60
+ }, (diagnostic) => {
61
+ var _a;
62
+ const formattedDiagnostic = (0, typescript_diagnostic_reporters_1.formatSolutionBuilderStatusReport)(diagnostic);
63
+ logger.info(formattedDiagnostic, project.project);
64
+ (_a = reporters === null || reporters === void 0 ? void 0 : reporters.solutionBuilderStatusReporter) === null || _a === void 0 ? void 0 : _a.call(reporters, project.project, diagnostic);
65
+ });
66
+ const rootNames = Object.keys(context);
67
+ const solutionBuilder = ts.createSolutionBuilder(solutionBuilderHost, rootNames, {});
68
+ // eslint-disable-next-line no-constant-condition
69
+ while (true) {
70
+ project = solutionBuilder.getNextInvalidatedProject();
71
+ if (!project) {
72
+ break;
73
+ }
74
+ const projectContext = context[project.project];
75
+ const projectName = projectContext === null || projectContext === void 0 ? void 0 : projectContext.project;
76
+ /**
77
+ * This only applies when the deprecated `prepend` option is set to `true`.
78
+ * Skip support.
79
+ */
80
+ if (project.kind === ts.InvalidatedProjectKind.UpdateBundle) {
81
+ logger.warn(`The project ${projectName} ` +
82
+ `is using the deprecated "prepend" Typescript compiler option. ` +
83
+ `This option is not supported by the batch executor and it's ignored.\n`, project.project);
84
+ continue;
85
+ }
86
+ (_a = hooks === null || hooks === void 0 ? void 0 : hooks.beforeProjectCompilationCallback) === null || _a === void 0 ? void 0 : _a.call(hooks, project.project);
87
+ if (project.kind === ts.InvalidatedProjectKind.UpdateOutputFileStamps) {
88
+ logger.info(`Updating output timestamps of project "${projectName}"...\n`, project.project);
89
+ // update output timestamps and mark project as complete
90
+ const status = project.done();
91
+ const success = status === ts.ExitStatus.Success;
92
+ if (success) {
93
+ logger.info(`Done updating output timestamps of project "${projectName}"...\n`, project.project);
94
+ }
95
+ (_b = hooks === null || hooks === void 0 ? void 0 : hooks.afterProjectCompilationCallback) === null || _b === void 0 ? void 0 : _b.call(hooks, project.project, success);
96
+ yield { success, tsConfig: project.project };
97
+ continue;
98
+ }
99
+ logger.info(`Compiling TypeScript files for project "${projectName}"...\n`, project.project);
100
+ // build and mark project as complete
101
+ const status = project.done(undefined, undefined, (0, get_custom_transformers_factory_1.getCustomTrasformersFactory)(projectContext.transformers)(project.getProgram()));
102
+ const success = status === ts.ExitStatus.Success;
103
+ if (success) {
104
+ logger.info(`Done compiling TypeScript files for project "${projectName}".\n`, project.project);
105
+ }
106
+ (_c = hooks === null || hooks === void 0 ? void 0 : hooks.afterProjectCompilationCallback) === null || _c === void 0 ? void 0 : _c.call(hooks, project.project, success);
107
+ yield {
108
+ success: status === ts.ExitStatus.Success,
109
+ tsConfig: project.project,
110
+ };
111
+ }
112
+ }
113
+ function compileTSWithWatch(context, logger, hooks, reporters) {
114
+ let project;
115
+ const solutionHost = ts.createSolutionBuilderWithWatchHost(getSystem(context),
116
+ /*createProgram*/ undefined);
117
+ if (reporters === null || reporters === void 0 ? void 0 : reporters.diagnosticReporter) {
118
+ const originalDiagnosticReporter = solutionHost.reportDiagnostic;
119
+ solutionHost.reportDiagnostic = (diagnostic) => {
120
+ originalDiagnosticReporter(diagnostic);
121
+ reporters.diagnosticReporter(project.project, diagnostic);
122
+ };
123
+ }
124
+ if (reporters === null || reporters === void 0 ? void 0 : reporters.solutionBuilderStatusReporter) {
125
+ const originalSolutionBuilderStatusReporter = solutionHost.reportSolutionBuilderStatus;
126
+ solutionHost.reportDiagnostic = (diagnostic) => {
127
+ originalSolutionBuilderStatusReporter(diagnostic);
128
+ reporters.solutionBuilderStatusReporter(project.project, diagnostic);
129
+ };
130
+ }
131
+ const originalWatchStatusReporter = solutionHost.onWatchStatusChange;
132
+ solutionHost.onWatchStatusChange = (diagnostic, newLine, options, errorCount) => {
133
+ var _a;
134
+ originalWatchStatusReporter(diagnostic, newLine, options, errorCount);
135
+ if (diagnostic.code ===
136
+ TYPESCRIPT_FILE_CHANGE_DETECTED_STARTING_INCREMENTAL_COMPILATION) {
137
+ // there's a change, build invalidated projects
138
+ build();
139
+ }
140
+ (_a = reporters === null || reporters === void 0 ? void 0 : reporters.watchStatusReporter) === null || _a === void 0 ? void 0 : _a.call(reporters, project === null || project === void 0 ? void 0 : project.project, diagnostic, newLine, options, errorCount);
141
+ };
142
+ const rootNames = Object.keys(context);
143
+ const solutionBuilder = ts.createSolutionBuilderWithWatch(solutionHost, rootNames, {});
144
+ const build = () => {
145
+ var _a, _b;
146
+ while (true) {
147
+ project = solutionBuilder.getNextInvalidatedProject();
148
+ if (!project) {
149
+ break;
150
+ }
151
+ const projectContext = context[project.project];
152
+ const projectName = projectContext.project;
153
+ /**
154
+ * This only applies when the deprecated `prepend` option is set to `true`.
155
+ * Skip support.
156
+ */
157
+ if (project.kind === ts.InvalidatedProjectKind.UpdateBundle) {
158
+ logger.warn(`The project ${projectName} ` +
159
+ `is using the deprecated "prepend" Typescript compiler option. ` +
160
+ `This option is not supported by the batch executor and it's ignored.`);
161
+ continue;
162
+ }
163
+ hooks === null || hooks === void 0 ? void 0 : hooks.beforeProjectCompilationCallback(project.project);
164
+ if (project.kind === ts.InvalidatedProjectKind.UpdateOutputFileStamps) {
165
+ if (projectName) {
166
+ logger.info(`Updating output timestamps of project "${projectName}"...\n`, project.project);
167
+ }
168
+ // update output timestamps and mark project as complete
169
+ const status = project.done();
170
+ const success = status === ts.ExitStatus.Success;
171
+ if (projectName && success) {
172
+ logger.info(`Done updating output timestamps of project "${projectName}"...\n`, project.project);
173
+ }
174
+ (_a = hooks === null || hooks === void 0 ? void 0 : hooks.afterProjectCompilationCallback) === null || _a === void 0 ? void 0 : _a.call(hooks, project.project, success);
175
+ continue;
176
+ }
177
+ logger.info(`Compiling TypeScript files for project "${projectName}"...\n`, project.project);
178
+ // build and mark project as complete
179
+ const status = project.done(undefined, undefined, (0, get_custom_transformers_factory_1.getCustomTrasformersFactory)(projectContext.transformers)(project.getProgram()));
180
+ const success = status === ts.ExitStatus.Success;
181
+ if (success) {
182
+ logger.info(`Done compiling TypeScript files for project "${projectName}".\n`, project.project);
183
+ }
184
+ (_b = hooks === null || hooks === void 0 ? void 0 : hooks.afterProjectCompilationCallback) === null || _b === void 0 ? void 0 : _b.call(hooks, project.project, success);
185
+ }
186
+ };
187
+ // initial build
188
+ build();
189
+ /**
190
+ * This is a workaround to get the TS file watching to kick off. It won't
191
+ * build twice since the `build` call above will mark invalidated projects
192
+ * as completed and then, the implementation of the `solutionBuilder.build`
193
+ * skips them.
194
+ * We can't rely solely in `solutionBuilder.build()` because it doesn't
195
+ * accept custom transformers.
196
+ */
197
+ solutionBuilder.build();
198
+ }
199
+ function getSystem(context) {
200
+ return Object.assign(Object.assign({}, ts.sys), { readFile(path, encoding) {
201
+ if (context[path]) {
202
+ return context[path].tsConfig.content;
203
+ }
204
+ return ts.sys.readFile(path, encoding);
205
+ } });
206
+ }
@@ -0,0 +1,3 @@
1
+ import * as ts from 'typescript';
2
+ export declare function formatDiagnosticReport(diagnostic: ts.Diagnostic, host: ts.FormatDiagnosticsHost): string;
3
+ export declare function formatSolutionBuilderStatusReport(diagnostic: ts.Diagnostic): string;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatSolutionBuilderStatusReport = exports.formatDiagnosticReport = void 0;
4
+ const ts = require("typescript");
5
+ // adapted from TS default diagnostic reporter
6
+ function formatDiagnosticReport(diagnostic, host) {
7
+ const diagnostics = new Array(1);
8
+ diagnostics[0] = diagnostic;
9
+ const formattedDiagnostic = '\n' +
10
+ ts.formatDiagnosticsWithColorAndContext(diagnostics, host) +
11
+ host.getNewLine();
12
+ diagnostics[0] = undefined;
13
+ return formattedDiagnostic;
14
+ }
15
+ exports.formatDiagnosticReport = formatDiagnosticReport;
16
+ // adapted from TS default solution builder status reporter
17
+ function formatSolutionBuilderStatusReport(diagnostic) {
18
+ let formattedDiagnostic = `[${formatColorAndReset(getLocaleTimeString(), ForegroundColorEscapeSequences.Grey)}] `;
19
+ formattedDiagnostic += `${ts.flattenDiagnosticMessageText(diagnostic.messageText, ts.sys.newLine)}${ts.sys.newLine + ts.sys.newLine}`;
20
+ return formattedDiagnostic;
21
+ }
22
+ exports.formatSolutionBuilderStatusReport = formatSolutionBuilderStatusReport;
23
+ function formatColorAndReset(text, formatStyle) {
24
+ const resetEscapeSequence = '\u001b[0m';
25
+ return formatStyle + text + resetEscapeSequence;
26
+ }
27
+ function getLocaleTimeString() {
28
+ return new Date().toLocaleTimeString();
29
+ }
30
+ var ForegroundColorEscapeSequences;
31
+ (function (ForegroundColorEscapeSequences) {
32
+ ForegroundColorEscapeSequences["Grey"] = "\u001B[90m";
33
+ ForegroundColorEscapeSequences["Red"] = "\u001B[91m";
34
+ ForegroundColorEscapeSequences["Yellow"] = "\u001B[93m";
35
+ ForegroundColorEscapeSequences["Blue"] = "\u001B[94m";
36
+ ForegroundColorEscapeSequences["Cyan"] = "\u001B[96m";
37
+ })(ForegroundColorEscapeSequences || (ForegroundColorEscapeSequences = {}));
@@ -0,0 +1,5 @@
1
+ import { ExecutorContext, TaskGraph } from '@nx/devkit';
2
+ import type { BatchExecutorTaskResult } from 'nx/src/config/misc-interfaces';
3
+ import type { ExecutorOptions } from '../../utils/schema';
4
+ export declare function tscBatchExecutor(taskGraph: TaskGraph, inputs: Record<string, ExecutorOptions>, overrides: ExecutorOptions, context: ExecutorContext): AsyncGenerator<BatchExecutorTaskResult, any, unknown>;
5
+ export default tscBatchExecutor;
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tscBatchExecutor = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const devkit_1 = require("@nx/devkit");
6
+ const fs_1 = require("fs");
7
+ const async_iterator_1 = require("nx/src/utils/async-iterator");
8
+ const update_package_json_1 = require("../../utils/package-json/update-package-json");
9
+ const lib_1 = require("./lib");
10
+ const batch_1 = require("./lib/batch");
11
+ function tscBatchExecutor(taskGraph, inputs, overrides, context) {
12
+ return tslib_1.__asyncGenerator(this, arguments, function* tscBatchExecutor_1() {
13
+ const tasksOptions = (0, batch_1.normalizeTasksOptions)(inputs, context);
14
+ let shouldWatch = false;
15
+ Object.values(tasksOptions).forEach((taskOptions) => {
16
+ if (taskOptions.clean) {
17
+ (0, fs_1.rmSync)(taskOptions.outputPath, { force: true, recursive: true });
18
+ }
19
+ if (taskOptions.watch) {
20
+ shouldWatch = true;
21
+ }
22
+ });
23
+ const taskInMemoryTsConfigMap = (0, lib_1.getProcessedTaskTsConfigs)(Object.keys(taskGraph.tasks), tasksOptions, context);
24
+ const tsConfigTaskInfoMap = (0, batch_1.createTaskInfoPerTsConfigMap)(tasksOptions, context, Object.keys(taskGraph.tasks), taskInMemoryTsConfigMap);
25
+ const tsCompilationContext = createTypescriptCompilationContext(tsConfigTaskInfoMap, taskInMemoryTsConfigMap, context);
26
+ const logger = {
27
+ error: (message, tsConfig) => {
28
+ process.stderr.write(message);
29
+ if (tsConfig) {
30
+ tsConfigTaskInfoMap[tsConfig].terminalOutput += message;
31
+ }
32
+ },
33
+ info: (message, tsConfig) => {
34
+ process.stdout.write(message);
35
+ if (tsConfig) {
36
+ tsConfigTaskInfoMap[tsConfig].terminalOutput += message;
37
+ }
38
+ },
39
+ warn: (message, tsConfig) => {
40
+ process.stdout.write(message);
41
+ if (tsConfig) {
42
+ tsConfigTaskInfoMap[tsConfig].terminalOutput += message;
43
+ }
44
+ },
45
+ };
46
+ const typescriptCompilation = (0, lib_1.compileTypescriptSolution)(tsCompilationContext, shouldWatch, logger, {
47
+ beforeProjectCompilationCallback: (tsConfig) => {
48
+ if (tsConfigTaskInfoMap[tsConfig]) {
49
+ tsConfigTaskInfoMap[tsConfig].startTime = Date.now();
50
+ }
51
+ },
52
+ afterProjectCompilationCallback: (tsConfig) => {
53
+ if (tsConfigTaskInfoMap[tsConfig]) {
54
+ const taskInfo = tsConfigTaskInfoMap[tsConfig];
55
+ taskInfo.assetsHandler.processAllAssetsOnceSync();
56
+ (0, update_package_json_1.updatePackageJson)(taskInfo.options, taskInfo.context, taskInfo.projectGraphNode, taskInfo.buildableProjectNodeDependencies);
57
+ taskInfo.endTime = Date.now();
58
+ }
59
+ },
60
+ });
61
+ if (shouldWatch) {
62
+ const taskInfos = Object.values(tsConfigTaskInfoMap);
63
+ const watchAssetsChangesDisposer = yield tslib_1.__await((0, batch_1.watchTaskProjectsFileChangesForAssets)(taskInfos));
64
+ const watchProjectsChangesDisposer = yield tslib_1.__await((0, batch_1.watchTaskProjectsPackageJsonFileChanges)(taskInfos, (changedTaskInfos) => {
65
+ for (const t of changedTaskInfos) {
66
+ (0, update_package_json_1.updatePackageJson)(t.options, t.context, t.projectGraphNode, t.buildableProjectNodeDependencies);
67
+ }
68
+ }));
69
+ const handleTermination = (exitCode) => tslib_1.__awaiter(this, void 0, void 0, function* () {
70
+ watchAssetsChangesDisposer();
71
+ watchProjectsChangesDisposer();
72
+ process.exit(exitCode);
73
+ });
74
+ process.on('SIGINT', () => handleTermination(128 + 2));
75
+ process.on('SIGTERM', () => handleTermination(128 + 15));
76
+ return yield tslib_1.__await(yield tslib_1.__await(yield* tslib_1.__asyncDelegator(tslib_1.__asyncValues(mapAsyncIterable(typescriptCompilation, (iterator) => tslib_1.__awaiter(this, void 0, void 0, function* () {
77
+ // drain the iterator, we don't use the results
78
+ yield (0, async_iterator_1.getLastValueFromAsyncIterableIterator)(iterator);
79
+ return { value: undefined, done: true };
80
+ }))))));
81
+ }
82
+ return yield tslib_1.__await(yield tslib_1.__await(yield* tslib_1.__asyncDelegator(tslib_1.__asyncValues(mapAsyncIterable(typescriptCompilation, (iterator) => tslib_1.__awaiter(this, void 0, void 0, function* () {
83
+ const { value, done } = yield iterator.next();
84
+ if (done) {
85
+ return { value, done: true };
86
+ }
87
+ const taskResult = {
88
+ task: tsConfigTaskInfoMap[value.tsConfig].task,
89
+ result: {
90
+ success: value.success,
91
+ terminalOutput: tsConfigTaskInfoMap[value.tsConfig].terminalOutput,
92
+ startTime: tsConfigTaskInfoMap[value.tsConfig].startTime,
93
+ endTime: tsConfigTaskInfoMap[value.tsConfig].endTime,
94
+ },
95
+ };
96
+ return { value: taskResult, done: false };
97
+ }))))));
98
+ });
99
+ }
100
+ exports.tscBatchExecutor = tscBatchExecutor;
101
+ exports.default = tscBatchExecutor;
102
+ function mapAsyncIterable(iterable, nextFn) {
103
+ return tslib_1.__asyncGenerator(this, arguments, function* mapAsyncIterable_1() {
104
+ return yield tslib_1.__await(yield tslib_1.__await(yield* tslib_1.__asyncDelegator(tslib_1.__asyncValues({
105
+ [Symbol.asyncIterator]() {
106
+ const iterator = iterable[Symbol.asyncIterator].call(iterable);
107
+ return {
108
+ next() {
109
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
110
+ return yield nextFn(iterator);
111
+ });
112
+ },
113
+ };
114
+ },
115
+ }))));
116
+ });
117
+ }
118
+ function createTypescriptCompilationContext(tsConfigTaskInfoMap, taskInMemoryTsConfigMap, context) {
119
+ const tsCompilationContext = Object.entries(tsConfigTaskInfoMap).reduce((acc, [tsConfig, taskInfo]) => {
120
+ acc[tsConfig] = {
121
+ project: taskInfo.context.projectName,
122
+ tsConfig: taskInfo.tsConfig,
123
+ transformers: taskInfo.options.transformers,
124
+ };
125
+ return acc;
126
+ }, {});
127
+ Object.entries(taskInMemoryTsConfigMap).forEach(([task, tsConfig]) => {
128
+ if (!tsCompilationContext[tsConfig.path]) {
129
+ tsCompilationContext[tsConfig.path] = {
130
+ project: (0, devkit_1.parseTargetString)(task, context.projectGraph).project,
131
+ transformers: [],
132
+ tsConfig: tsConfig,
133
+ };
134
+ }
135
+ });
136
+ return tsCompilationContext;
137
+ }
@@ -1,7 +1,6 @@
1
1
  import { ExecutorContext } from '@nx/devkit';
2
2
  import type { TypeScriptCompilationOptions } from '@nx/workspace/src/utilities/typescript/compilation';
3
3
  import { ExecutorOptions, NormalizedExecutorOptions } from '../../utils/schema';
4
- export declare function normalizeOptions(options: ExecutorOptions, contextRoot: string, sourceRoot: string, projectRoot: string): NormalizedExecutorOptions;
5
4
  export declare function createTypeScriptCompilationOptions(normalizedOptions: NormalizedExecutorOptions, context: ExecutorContext): TypeScriptCompilationOptions;
6
5
  export declare function tscExecutor(_options: ExecutorOptions, context: ExecutorContext): AsyncGenerator<import("../../utils/typescript/compile-typescript-files").TypescriptCompilationResult, any, undefined>;
7
6
  export default tscExecutor;