@nx/js 23.0.0-beta.22 → 23.0.0-beta.23

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.
@@ -8,17 +8,24 @@ const expectedNpmPublishJsonKeys = [
8
8
  'size',
9
9
  'filename',
10
10
  ];
11
- // Regular expression to match JSON-like objects, including nested objects (which the expected npm publish output will have, e.g. in its "files" array)
12
- // /{(?:[^{}]|{[^{}]*})*}/g
13
- // /{ : Matches the opening brace of a JSON object
14
- // (?: ) : Non-capturing group to apply quantifiers
15
- // [^{}] : Matches any character except for braces
16
- // | : OR
17
- // {[^{}]*} : Matches nested JSON objects
18
- // * : The non-capturing group (i.e. any character except for braces OR nested JSON objects) can repeat zero or more times
19
- // } : Matches the closing brace of a JSON object
20
- // /g : Global flag to match all occurrences in the string
21
- const jsonRegex = /{(?:[^{}]|{[^{}]*})*}/g;
11
+ // Regular expression to match JSON-like objects, including up to two levels of
12
+ // nested objects.
13
+ // /{(?:[^{}]|{(?:[^{}]|{[^{}]*})*})*}/g
14
+ // Two levels of nesting are required to support both shapes of npm/pnpm publish
15
+ // output:
16
+ // - Older npm (<= 11.13) prints the publish summary as a flat object whose only
17
+ // nesting is its own "files" array (one level deep).
18
+ // - Newer npm (>= 11.16, bundled with Node 26) nests that same summary under the
19
+ // package name, e.g. { "@scope/pkg": { ...id/name/files... } }, adding a
20
+ // second level. pnpm publish nests the same way when run from the workspace
21
+ // root. Matching two levels lets us capture the wrapper object in the nested
22
+ // case so its braces are not left behind in beforeJsonData/afterJsonData.
23
+ const jsonRegex = /{(?:[^{}]|{(?:[^{}]|{[^{}]*})*})*}/g;
24
+ function isNpmPublishSummary(value) {
25
+ return (typeof value === 'object' &&
26
+ value !== null &&
27
+ expectedNpmPublishJsonKeys.every((key) => value[key] !== undefined));
28
+ }
22
29
  function extractNpmPublishJsonData(str) {
23
30
  const jsonMatches = str.match(jsonRegex);
24
31
  if (jsonMatches) {
@@ -28,21 +35,39 @@ function extractNpmPublishJsonData(str) {
28
35
  continue;
29
36
  }
30
37
  // Full JSON parsing to identify the JSON object
38
+ let parsedJson;
31
39
  try {
32
- const parsedJson = JSON.parse(match);
33
- if (!expectedNpmPublishJsonKeys.every((key) => parsedJson[key] !== undefined)) {
34
- continue;
35
- }
36
- const jsonStartIndex = str.indexOf(match);
37
- return {
38
- beforeJsonData: str.slice(0, jsonStartIndex),
39
- jsonData: parsedJson,
40
- afterJsonData: str.slice(jsonStartIndex + match.length),
41
- };
40
+ parsedJson = JSON.parse(match);
42
41
  }
43
42
  catch {
44
43
  // Ignore parsing errors for unrelated JSON blocks
44
+ continue;
45
+ }
46
+ // npm <= 11.13 emits the summary as a flat object, while npm >= 11.16 (and
47
+ // pnpm publish run from the workspace root) nest it one level deep under the
48
+ // package name. Support both by unwrapping a single level when the matched
49
+ // object isn't itself the summary.
50
+ let publishData = null;
51
+ if (isNpmPublishSummary(parsedJson)) {
52
+ publishData = parsedJson;
53
+ }
54
+ else if (typeof parsedJson === 'object' && parsedJson !== null) {
55
+ for (const value of Object.values(parsedJson)) {
56
+ if (isNpmPublishSummary(value)) {
57
+ publishData = value;
58
+ break;
59
+ }
60
+ }
61
+ }
62
+ if (!publishData) {
63
+ continue;
45
64
  }
65
+ const jsonStartIndex = str.indexOf(match);
66
+ return {
67
+ beforeJsonData: str.slice(0, jsonStartIndex),
68
+ jsonData: publishData,
69
+ afterJsonData: str.slice(jsonStartIndex + match.length),
70
+ };
46
71
  }
47
72
  }
48
73
  // No applicable jsonData detected, the whole contents is the beforeJsonData
@@ -1,4 +1,4 @@
1
- import { type CreateDependencies, type CreateNodesV2 } from '@nx/devkit';
1
+ import { type CreateDependencies, type CreateNodes } from '@nx/devkit';
2
2
  export interface TscPluginOptions {
3
3
  compiler?: 'tsc' | 'tsgo';
4
4
  typecheck?: boolean | {
@@ -19,5 +19,5 @@ export interface TscPluginOptions {
19
19
  */
20
20
  export declare const createDependencies: CreateDependencies;
21
21
  export declare const PLUGIN_NAME = "@nx/js/typescript";
22
- export declare const createNodesV2: CreateNodesV2<TscPluginOptions>;
23
- export declare const createNodes: CreateNodesV2<TscPluginOptions>;
22
+ export declare const createNodesV2: CreateNodes<TscPluginOptions>;
23
+ export declare const createNodes: CreateNodes<TscPluginOptions>;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ensureProjectIsIncludedInPluginRegistrations = ensureProjectIsIncludedInPluginRegistrations;
4
4
  const devkit_internals_1 = require("nx/src/devkit-internals");
5
+ const picomatch = require("picomatch");
5
6
  function ensureProjectIsIncludedInPluginRegistrations(nxJson, projectRoot, buildTargetName) {
6
7
  nxJson.plugins ??= [];
7
8
  let isIncluded = false;
@@ -26,7 +27,13 @@ function ensureProjectIsIncludedInPluginRegistrations(nxJson, projectRoot, build
26
27
  }
27
28
  else {
28
29
  // check if the project would be included by the plugin registration
29
- const matchingConfigFiles = (0, devkit_internals_1.findMatchingConfigFiles)([`${projectRoot}/tsconfig.json`], '**/tsconfig.json', registration.include, registration.exclude);
30
+ // Only consider the tsconfig if the @nx/js/typescript plugin would
31
+ // actually process it (its path matches the plugin's createNodes glob)
32
+ // before the registration's include/exclude filters are applied.
33
+ const tsconfigPath = `${projectRoot}/tsconfig.json`;
34
+ const matchingConfigFiles = picomatch('**/tsconfig.json', { dot: true })(tsconfigPath)
35
+ ? (0, devkit_internals_1.findMatchingConfigFiles)([tsconfigPath], registration.include, registration.exclude)
36
+ : [];
30
37
  if (matchingConfigFiles.length) {
31
38
  // it's included by the plugin registration, check if the user-specified options would result
32
39
  // in the appropriate build task being inferred, if not, we need to exclude it
@@ -96,7 +96,7 @@ function resolvePathsBaseUrl(tsconfigPath) {
96
96
  const absolute = (0, path_1.resolve)(queue.shift());
97
97
  const dir = (0, path_1.dirname)(absolute);
98
98
  try {
99
- const raw = JSON.parse((0, fs_1.readFileSync)(absolute, 'utf-8'));
99
+ const raw = (0, devkit_1.readJsonFile)(absolute);
100
100
  chain.push({ dir, raw });
101
101
  const exts = raw.extends
102
102
  ? Array.isArray(raw.extends)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/js",
3
- "version": "23.0.0-beta.22",
3
+ "version": "23.0.0-beta.23",
4
4
  "private": false,
5
5
  "type": "commonjs",
6
6
  "files": [
@@ -144,11 +144,11 @@
144
144
  "source-map-support": "0.5.19",
145
145
  "tinyglobby": "^0.2.12",
146
146
  "tslib": "^2.3.0",
147
- "@nx/devkit": "23.0.0-beta.22",
148
- "@nx/workspace": "23.0.0-beta.22"
147
+ "@nx/workspace": "23.0.0-beta.23",
148
+ "@nx/devkit": "23.0.0-beta.23"
149
149
  },
150
150
  "devDependencies": {
151
- "nx": "23.0.0-beta.22"
151
+ "nx": "23.0.0-beta.23"
152
152
  },
153
153
  "peerDependencies": {
154
154
  "@swc/cli": ">=0.6.0 <0.9.0",