@nx/js 23.1.0 → 23.2.0-beta.1
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.
- package/dist/babel.js +11 -0
- package/dist/src/executors/release-publish/extract-npm-publish-json-data.js +92 -52
- package/dist/src/executors/release-publish/log-tar.js +6 -2
- package/dist/src/executors/release-publish/release-publish.impl.js +15 -0
- package/dist/src/plugins/jest/start-local-registry.js +6 -1
- package/dist/src/utils/swc/add-swc-dependencies.js +6 -0
- package/package.json +7 -4
package/dist/babel.js
CHANGED
|
@@ -41,6 +41,17 @@ module.exports = function (api, options = {}) {
|
|
|
41
41
|
options.decorators ?? { legacy: true },
|
|
42
42
|
],
|
|
43
43
|
[require.resolve('@babel/plugin-transform-class-properties'), { loose }],
|
|
44
|
+
// class-properties runs babel's shared class-features plugin, which hard-errors
|
|
45
|
+
// on private methods and static blocks unless their transforms are loaded too.
|
|
46
|
+
// This bites when an ESM-only dep using that syntax is transformed (un-ignored
|
|
47
|
+
// via transformIgnorePatterns). private-property-in-object completes babel's
|
|
48
|
+
// loose-consistency trio so `loose` stays uniform across the class-features transforms.
|
|
49
|
+
[require.resolve('@babel/plugin-transform-private-methods'), { loose }],
|
|
50
|
+
[
|
|
51
|
+
require.resolve('@babel/plugin-transform-private-property-in-object'),
|
|
52
|
+
{ loose },
|
|
53
|
+
],
|
|
54
|
+
require.resolve('@babel/plugin-transform-class-static-block'),
|
|
44
55
|
].filter(Boolean);
|
|
45
56
|
return {
|
|
46
57
|
presets: [
|
|
@@ -8,67 +8,107 @@ const expectedNpmPublishJsonKeys = [
|
|
|
8
8
|
'size',
|
|
9
9
|
'filename',
|
|
10
10
|
];
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
|
|
11
|
+
// Pair each '{' with its matching '}' in the publish output. The output is npm's
|
|
12
|
+
// pretty-printed JSON summary interleaved with arbitrary lifecycle-script text,
|
|
13
|
+
// so we recognize only genuine JSON structure and treat everything else as
|
|
14
|
+
// opaque, without interpreting it as JSON (unlike a JSONC parser):
|
|
15
|
+
// - Braces and quotes inside a JSON string value are ignored, so a files[].path
|
|
16
|
+
// like "templates/{{name}}/file.txt" doesn't throw off the pairing (#36236).
|
|
17
|
+
// - '//' and '/*' are not comments; lifecycle output legitimately prints globs
|
|
18
|
+
// and paths such as dist/*.js, and npm/pnpm emit plain JSON.
|
|
19
|
+
// - A raw newline ends a string. A valid JSON string never contains one (it is
|
|
20
|
+
// escaped as \n), so this can't truncate a real value, but it stops a stray
|
|
21
|
+
// unpaired '"' in log text from swallowing the summary on a later line.
|
|
22
|
+
// - A quote only opens a string inside an object, so a lone '"' in the preamble
|
|
23
|
+
// or between objects stays inert.
|
|
24
|
+
// Stray unmatched braces are left unpaired.
|
|
25
|
+
function matchBracePositions(str) {
|
|
26
|
+
const matches = new Map();
|
|
27
|
+
const openBraceStack = [];
|
|
28
|
+
let inString = false;
|
|
29
|
+
for (let i = 0; i < str.length; i++) {
|
|
30
|
+
const char = str[i];
|
|
31
|
+
if (inString) {
|
|
32
|
+
if (char === '\\') {
|
|
33
|
+
i++; // skip the escaped character
|
|
34
|
+
}
|
|
35
|
+
else if (char === '"' || char === '\n' || char === '\r') {
|
|
36
|
+
inString = false;
|
|
37
|
+
}
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (char === '"') {
|
|
41
|
+
if (openBraceStack.length > 0) {
|
|
42
|
+
inString = true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else if (char === '{') {
|
|
46
|
+
openBraceStack.push(i);
|
|
47
|
+
}
|
|
48
|
+
else if (char === '}') {
|
|
49
|
+
const openIndex = openBraceStack.pop();
|
|
50
|
+
if (openIndex !== undefined) {
|
|
51
|
+
matches.set(openIndex, i);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return matches;
|
|
56
|
+
}
|
|
57
|
+
// Yield every balanced {...} object in the output, left to right by start
|
|
58
|
+
// position, so an outer wrapper is seen before the objects nested inside it.
|
|
59
|
+
function* iterateBalancedJsonObjects(str) {
|
|
60
|
+
const closeByOpen = matchBracePositions(str);
|
|
61
|
+
for (let i = 0; i < str.length; i++) {
|
|
62
|
+
const closeIndex = closeByOpen.get(i);
|
|
63
|
+
if (closeIndex !== undefined) {
|
|
64
|
+
yield { text: str.slice(i, closeIndex + 1), index: i };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
24
68
|
function isNpmPublishSummary(value) {
|
|
25
69
|
return (typeof value === 'object' &&
|
|
26
70
|
value !== null &&
|
|
27
71
|
expectedNpmPublishJsonKeys.every((key) => value[key] !== undefined));
|
|
28
72
|
}
|
|
29
73
|
function extractNpmPublishJsonData(str) {
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
publishData = value;
|
|
58
|
-
break;
|
|
59
|
-
}
|
|
74
|
+
for (const { text: match, index } of iterateBalancedJsonObjects(str)) {
|
|
75
|
+
// Cheap check to skip candidates that can't be the summary before parsing
|
|
76
|
+
if (!expectedNpmPublishJsonKeys.every((key) => match.includes(key))) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
// Full JSON parsing to identify the JSON object
|
|
80
|
+
let parsedJson;
|
|
81
|
+
try {
|
|
82
|
+
parsedJson = JSON.parse(match);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Ignore parsing errors for unrelated JSON blocks
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
// npm <= 11.13 emits the summary as a flat object, while npm >= 11.16 (and
|
|
89
|
+
// pnpm publish run from the workspace root) nest it one level deep under the
|
|
90
|
+
// package name. Support both by unwrapping a single level when the matched
|
|
91
|
+
// object isn't itself the summary.
|
|
92
|
+
let publishData = null;
|
|
93
|
+
if (isNpmPublishSummary(parsedJson)) {
|
|
94
|
+
publishData = parsedJson;
|
|
95
|
+
}
|
|
96
|
+
else if (typeof parsedJson === 'object' && parsedJson !== null) {
|
|
97
|
+
for (const value of Object.values(parsedJson)) {
|
|
98
|
+
if (isNpmPublishSummary(value)) {
|
|
99
|
+
publishData = value;
|
|
100
|
+
break;
|
|
60
101
|
}
|
|
61
102
|
}
|
|
62
|
-
if (!publishData) {
|
|
63
|
-
continue;
|
|
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
|
-
};
|
|
71
103
|
}
|
|
104
|
+
if (!publishData) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
beforeJsonData: str.slice(0, index),
|
|
109
|
+
jsonData: publishData,
|
|
110
|
+
afterJsonData: str.slice(index + match.length),
|
|
111
|
+
};
|
|
72
112
|
}
|
|
73
113
|
// No applicable jsonData detected, the whole contents is the beforeJsonData
|
|
74
114
|
return {
|
|
@@ -14,9 +14,13 @@ const logTar = (tarball, opts = {}) => {
|
|
|
14
14
|
console.log(chalk_1.default.magenta('=== Tarball Contents ==='));
|
|
15
15
|
if (tarball.files.length) {
|
|
16
16
|
console.log('');
|
|
17
|
-
const columnData = (0, columnify_1.default)(
|
|
17
|
+
const columnData = (0, columnify_1.default)(
|
|
18
|
+
// Sort for a stable listing: pnpm 11 orders files differently than
|
|
19
|
+
// npm and pnpm 10.
|
|
20
|
+
[...tarball.files]
|
|
21
|
+
.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0))
|
|
18
22
|
.map((f) => {
|
|
19
|
-
const bytes = (0, format_bytes_1.formatBytes)(f.size, false);
|
|
23
|
+
const bytes = typeof f.size === 'number' ? (0, format_bytes_1.formatBytes)(f.size, false) : '';
|
|
20
24
|
return /^node_modules\//.test(f.path)
|
|
21
25
|
? null
|
|
22
26
|
: { path: f.path, size: `${bytes}` };
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.default = runExecutor;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
5
|
const child_process_1 = require("child_process");
|
|
6
|
+
const fs_1 = require("fs");
|
|
6
7
|
const npm_run_path_1 = require("npm-run-path");
|
|
7
8
|
const path_1 = require("path");
|
|
8
9
|
const is_locally_linked_package_version_1 = require("../../utils/is-locally-linked-package-version");
|
|
@@ -349,6 +350,20 @@ function runPublish(ctx) {
|
|
|
349
350
|
success: false,
|
|
350
351
|
};
|
|
351
352
|
}
|
|
353
|
+
// pnpm 11 dropped the per-file size field from its publish --json output,
|
|
354
|
+
// so recover the sizes from disk for the tarball contents log.
|
|
355
|
+
if (Array.isArray(jsonData.files)) {
|
|
356
|
+
for (const file of jsonData.files) {
|
|
357
|
+
if (typeof file.size !== 'number' && typeof file.path === 'string') {
|
|
358
|
+
try {
|
|
359
|
+
file.size = (0, fs_1.statSync)((0, path_1.join)(packageRoot, file.path)).size;
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
// leave the size unknown, logTar omits it
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
352
367
|
if (isDryRun) {
|
|
353
368
|
for (const [key, val] of Object.entries(jsonData)) {
|
|
354
369
|
if (typeof val !== 'string') {
|
|
@@ -36,6 +36,11 @@ function startLocalRegistry({ localRegistryTarget, storage, verbose, clearStorag
|
|
|
36
36
|
(0, child_process_1.execSync)(`npm config set //${listenAddress}:${port}/:_authToken "${authToken}" --ws=false`, {
|
|
37
37
|
windowsHide: true,
|
|
38
38
|
});
|
|
39
|
+
// pnpm 11 reads pnpm_config_* env vars instead of npm_config_*, and
|
|
40
|
+
// they take precedence over any registry configured in ~/.npmrc
|
|
41
|
+
process.env.pnpm_config_registry = registry;
|
|
42
|
+
process.env[`pnpm_config_//${listenAddress}:${port}/:_authToken`] =
|
|
43
|
+
authToken;
|
|
39
44
|
// bun
|
|
40
45
|
process.env.BUN_CONFIG_REGISTRY = registry;
|
|
41
46
|
process.env.BUN_CONFIG_TOKEN = authToken;
|
|
@@ -44,7 +49,7 @@ function startLocalRegistry({ localRegistryTarget, storage, verbose, clearStorag
|
|
|
44
49
|
// yarnv2
|
|
45
50
|
process.env.YARN_NPM_REGISTRY_SERVER = registry;
|
|
46
51
|
process.env.YARN_UNSAFE_HTTP_WHITELIST = listenAddress;
|
|
47
|
-
console.log('Set npm, bun, and yarn config registry to ' + registry);
|
|
52
|
+
console.log('Set npm, pnpm, bun, and yarn config registry to ' + registry);
|
|
48
53
|
resolve(() => {
|
|
49
54
|
childProcess.kill();
|
|
50
55
|
(0, child_process_1.execSync)(`npm config delete //${listenAddress}:${port}/:_authToken --ws=false`, {
|
|
@@ -4,7 +4,11 @@ exports.getSwcDependencies = getSwcDependencies;
|
|
|
4
4
|
exports.addSwcDependencies = addSwcDependencies;
|
|
5
5
|
exports.addSwcRegisterDependencies = addSwcRegisterDependencies;
|
|
6
6
|
const devkit_1 = require("@nx/devkit");
|
|
7
|
+
const internal_1 = require("@nx/devkit/internal");
|
|
7
8
|
const versions_1 = require("../versions");
|
|
9
|
+
// @swc/core's postinstall only installs a wasm fallback for platforms not
|
|
10
|
+
// covered by its prebuilt optional dependencies, so skip it.
|
|
11
|
+
const swcAllowBuilds = { '@swc/core': false };
|
|
8
12
|
function getSwcDependencies() {
|
|
9
13
|
const dependencies = {
|
|
10
14
|
'@swc/helpers': versions_1.swcHelpersVersion,
|
|
@@ -17,8 +21,10 @@ function getSwcDependencies() {
|
|
|
17
21
|
}
|
|
18
22
|
function addSwcDependencies(tree) {
|
|
19
23
|
const { dependencies, devDependencies } = getSwcDependencies();
|
|
24
|
+
(0, internal_1.acknowledgeBuildScripts)(tree, (0, devkit_1.detectPackageManager)(tree.root), swcAllowBuilds);
|
|
20
25
|
return (0, devkit_1.addDependenciesToPackageJson)(tree, dependencies, devDependencies, undefined, true);
|
|
21
26
|
}
|
|
22
27
|
function addSwcRegisterDependencies(tree) {
|
|
28
|
+
(0, internal_1.acknowledgeBuildScripts)(tree, (0, devkit_1.detectPackageManager)(tree.root), swcAllowBuilds);
|
|
23
29
|
return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, { '@swc-node/register': versions_1.swcNodeVersion, '@swc/core': versions_1.swcCoreVersion }, undefined, true);
|
|
24
30
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/js",
|
|
3
|
-
"version": "23.
|
|
3
|
+
"version": "23.2.0-beta.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"files": [
|
|
@@ -123,6 +123,9 @@
|
|
|
123
123
|
"@babel/core": "^7.23.2",
|
|
124
124
|
"@babel/plugin-proposal-decorators": "^7.22.7",
|
|
125
125
|
"@babel/plugin-transform-class-properties": "^7.22.5",
|
|
126
|
+
"@babel/plugin-transform-class-static-block": "^7.22.5",
|
|
127
|
+
"@babel/plugin-transform-private-methods": "^7.22.5",
|
|
128
|
+
"@babel/plugin-transform-private-property-in-object": "^7.22.5",
|
|
126
129
|
"@babel/plugin-transform-runtime": "^7.23.2",
|
|
127
130
|
"@babel/preset-env": "^7.23.2",
|
|
128
131
|
"@babel/preset-typescript": "^7.22.5",
|
|
@@ -144,11 +147,11 @@
|
|
|
144
147
|
"source-map-support": "0.5.19",
|
|
145
148
|
"tinyglobby": "^0.2.12",
|
|
146
149
|
"tslib": "^2.3.0",
|
|
147
|
-
"@nx/devkit": "23.
|
|
148
|
-
"@nx/workspace": "23.
|
|
150
|
+
"@nx/devkit": "23.2.0-beta.1",
|
|
151
|
+
"@nx/workspace": "23.2.0-beta.1"
|
|
149
152
|
},
|
|
150
153
|
"devDependencies": {
|
|
151
|
-
"nx": "23.
|
|
154
|
+
"nx": "23.2.0-beta.1"
|
|
152
155
|
},
|
|
153
156
|
"peerDependencies": {
|
|
154
157
|
"@swc/cli": ">=0.6.0 <0.9.0",
|