@volter/twin-standard 1.0.152 → 1.0.154
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/client-sdks/package.json +8 -0
- package/client-sdks/pnpm-lock.yaml +2420 -0
- package/client-sdks/pnpm-workspace.yaml +9 -0
- package/dist/client-sdks/package.json +8 -0
- package/dist/client-sdks/pnpm-lock.yaml +2420 -0
- package/dist/client-sdks/pnpm-workspace.yaml +9 -0
- package/dist/src/clients/sentry.js +2 -2
- package/dist/src/conformance.js +1 -1
- package/dist/src/consumer.js +8 -5
- package/dist/src/dependency-lock.d.ts +16 -0
- package/dist/src/dependency-lock.js +30 -0
- package/dist/src/published.js +2 -2
- package/package.json +12 -3
- package/src/clients/sentry.ts +2 -2
- package/src/conformance.ts +1 -1
- package/src/consumer.ts +8 -5
- package/src/dependency-lock.ts +27 -0
- package/src/published.ts +2 -2
- package/client-sdks/bun.lock +0 -459
- package/dist/client-sdks/bun.lock +0 -459
|
@@ -19,9 +19,9 @@ import { standardPackageFile } from "../package-file.js";
|
|
|
19
19
|
const SDKS = standardPackageFile('client-sdks/');
|
|
20
20
|
async function sdkOf(name) {
|
|
21
21
|
if (!existsSync(new URL('node_modules/', SDKS))) {
|
|
22
|
-
const install = spawnSync('
|
|
22
|
+
const install = spawnSync('pnpm', ['install', '--frozen-lockfile', '--ignore-scripts'], { cwd: SDKS, stdio: 'inherit' });
|
|
23
23
|
if (install.status !== 0)
|
|
24
|
-
throw new Error('client-sdks:
|
|
24
|
+
throw new Error('client-sdks: pnpm install --frozen-lockfile failed');
|
|
25
25
|
}
|
|
26
26
|
return await import(__rewriteRelativeImportExtension(pathToFileURL(createRequire(new URL('package.json', SDKS)).resolve(name)).href));
|
|
27
27
|
}
|
package/dist/src/conformance.js
CHANGED
|
@@ -219,7 +219,7 @@ async function registered(pack, runtime) {
|
|
|
219
219
|
* journeys, read from the file list `npm pack` makes. Escaped once: seven packs published their lanes' src without
|
|
220
220
|
* their spec, so the catalog's conformance of the tarball never read those lanes. */
|
|
221
221
|
function published(pack) {
|
|
222
|
-
const run = spawnSync('npm', ['pack', '--dry-run', '--json', '--ignore-scripts'], { cwd: pack, encoding: 'utf8' });
|
|
222
|
+
const run = spawnSync('npm', ['pack', '--force', '--dry-run', '--json', '--ignore-scripts'], { cwd: pack, encoding: 'utf8' });
|
|
223
223
|
let files;
|
|
224
224
|
try {
|
|
225
225
|
files = new Set((JSON.parse(run.stdout)[0]?.files ?? []).map((f) => f.path));
|
package/dist/src/consumer.js
CHANGED
|
@@ -6,6 +6,7 @@ import { basename, dirname, isAbsolute, join, relative, resolve } from 'node:pat
|
|
|
6
6
|
import { spawn } from 'node:child_process';
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
|
8
8
|
import { standardPackageFile } from "./package-file.js";
|
|
9
|
+
import { dependencyLock } from "./dependency-lock.js";
|
|
9
10
|
function packageIdentity(entry, name) {
|
|
10
11
|
let directory = dirname(realpathSync(entry));
|
|
11
12
|
while (true) {
|
|
@@ -81,6 +82,8 @@ export function prepareConsumerApp(packDir, appDir, installation) {
|
|
|
81
82
|
if (existsSync(appDir))
|
|
82
83
|
throw new Error('Consumer app must be a new directory');
|
|
83
84
|
const app = JSON.parse(recipe.files['package.json']);
|
|
85
|
+
app.packageManager = 'pnpm@12.15.0';
|
|
86
|
+
app.devEngines = { packageManager: { name: 'pnpm', version: '12.15.0', onFail: 'error' } };
|
|
84
87
|
if (app.scripts || app.workspaces)
|
|
85
88
|
throw new Error('Consumer fixture supplies direct SDK commands, not install scripts or workspace links');
|
|
86
89
|
for (const [name, version] of Object.entries({ ...app.dependencies, ...app.devDependencies, ...app.optionalDependencies })) {
|
|
@@ -102,8 +105,9 @@ export function prepareConsumerApp(packDir, appDir, installation) {
|
|
|
102
105
|
if (Object.hasOwn(app.dependencies ?? {}, metadata.name))
|
|
103
106
|
throw new Error('Consumer SDK dependencies must not substitute the candidate package');
|
|
104
107
|
app.devDependencies = { ...app.devDependencies, '@volter/world-core': tools['@volter/world-core'], [metadata.name]: installation.artifact ? `file:${installation.artifact}` : metadata.version };
|
|
105
|
-
files.find(([path]) => path === 'package.json')[1] = JSON.stringify(app, null, 2) + '\n';
|
|
106
108
|
}
|
|
109
|
+
files.find(([path]) => path === 'package.json')[1] = JSON.stringify(app, null, 2) + '\n';
|
|
110
|
+
files.push(['pnpm-workspace.yaml', 'packages:\n - .\npackageImportMethod: hardlink\nnodeLinker: hoisted\nautoInstallPeers: false\nstrictPeerDependencies: false\n']);
|
|
107
111
|
mkdirSync(appDir, { recursive: true });
|
|
108
112
|
for (const [path, content] of files) {
|
|
109
113
|
mkdirSync(dirname(join(appDir, path)), { recursive: true });
|
|
@@ -127,11 +131,10 @@ export async function runConsumerWorkflow(packDir, options) {
|
|
|
127
131
|
if (location.startsWith('..') || isAbsolute(location))
|
|
128
132
|
throw new Error(`${name}: consumer resolves an evaluator or ancestor dependency; install it in the app`);
|
|
129
133
|
}
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
if (candidate.version !== metadata.version || appLock.packages?.[`node_modules/${metadata.name}`]?.integrity !== options.artifactIntegrity)
|
|
134
|
+
const appLock = dependencyLock(appRoot), appLockBytes = appLock.bytes;
|
|
135
|
+
if (candidate.version !== metadata.version || appLock.entry(metadata.name)?.integrity !== options.artifactIntegrity)
|
|
133
136
|
throw new Error('Consumer app candidate does not match the exact assessed artifact');
|
|
134
|
-
if (kernel.version !== tools['@volter/world-core'] || appLock.
|
|
137
|
+
if (kernel.version !== tools['@volter/world-core'] || appLock.entry('@volter/world-core')?.version !== kernel.version)
|
|
135
138
|
throw new Error('Consumer app kernel does not match the CLI kernel pin');
|
|
136
139
|
const application = { candidate: { package: metadata.name, version: candidate.version, integrity: options.artifactIntegrity }, kernel: { package: '@volter/world-core', version: kernel.version }, dependencyLockSha256: createHash('sha256').update(appLockBytes).digest('hex'), appLocal: true };
|
|
137
140
|
const facts = JSON.parse(readFileSync(join(packDir, 'generated/pack-facts.json'), 'utf8'));
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** The application's selected direct dependency, including the exact installer's integrity. */
|
|
2
|
+
export declare function dependencyLock(root: string): {
|
|
3
|
+
bytes: NonSharedBuffer;
|
|
4
|
+
file: string;
|
|
5
|
+
entry(name: string): {
|
|
6
|
+
version: any;
|
|
7
|
+
integrity: any;
|
|
8
|
+
} | undefined;
|
|
9
|
+
} | {
|
|
10
|
+
bytes: NonSharedBuffer;
|
|
11
|
+
file: string;
|
|
12
|
+
entry(name: string): {
|
|
13
|
+
version?: string;
|
|
14
|
+
integrity?: string;
|
|
15
|
+
} | undefined;
|
|
16
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { parseAllDocuments } from 'yaml';
|
|
4
|
+
/** The application's selected direct dependency, including the exact installer's integrity. */
|
|
5
|
+
export function dependencyLock(root) {
|
|
6
|
+
const pnpm = join(root, 'pnpm-lock.yaml');
|
|
7
|
+
if (existsSync(pnpm)) {
|
|
8
|
+
const bytes = readFileSync(pnpm);
|
|
9
|
+
const documents = parseAllDocuments(bytes.toString());
|
|
10
|
+
for (const doc of documents)
|
|
11
|
+
if (doc.errors.length)
|
|
12
|
+
throw doc.errors[0];
|
|
13
|
+
const lock = documents.map(doc => doc.toJS()).find(doc => doc?.importers?.['.'] && !doc.importers['.'].packageManagerDependencies);
|
|
14
|
+
if (!lock)
|
|
15
|
+
throw new Error('No pnpm application importer');
|
|
16
|
+
return { bytes, file: pnpm, entry(name) {
|
|
17
|
+
const importer = lock.importers['.'];
|
|
18
|
+
const selected = importer.dependencies?.[name] ?? importer.devDependencies?.[name] ?? importer.optionalDependencies?.[name];
|
|
19
|
+
if (!selected)
|
|
20
|
+
return undefined;
|
|
21
|
+
const selectedRef = String(selected.version);
|
|
22
|
+
const ref = lock.packages?.[`${name}@${selectedRef}`] ? selectedRef : selectedRef.replace(/\(.*$/, '');
|
|
23
|
+
const pkg = lock.packages?.[`${name}@${ref}`];
|
|
24
|
+
return { version: pkg?.version ?? ref, integrity: pkg?.resolution?.integrity };
|
|
25
|
+
} };
|
|
26
|
+
}
|
|
27
|
+
const file = join(root, 'package-lock.json'), bytes = readFileSync(file);
|
|
28
|
+
const lock = JSON.parse(bytes.toString());
|
|
29
|
+
return { bytes, file, entry(name) { return lock.packages?.[`node_modules/${name}`]; } };
|
|
30
|
+
}
|
package/dist/src/published.js
CHANGED
|
@@ -15,7 +15,7 @@ export const vendorOfPackage = (name) => name.replace(/^@[^/]+\//, '').replace(/
|
|
|
15
15
|
async function withPublished(spec, opts, use) {
|
|
16
16
|
const tmp = mkdtempSync(join(tmpdir(), 'twin-standard-'));
|
|
17
17
|
try {
|
|
18
|
-
const pack = spawnSync('npm', ['pack', spec, '--pack-destination', tmp, '--silent', ...(opts.registry ? ['--registry', opts.registry] : [])], { encoding: 'utf8' });
|
|
18
|
+
const pack = spawnSync('npm', ['pack', '--force', spec, '--pack-destination', tmp, '--silent', ...(opts.registry ? ['--registry', opts.registry] : [])], { encoding: 'utf8' });
|
|
19
19
|
const tarball = readdirSync(tmp).find((f) => f.endsWith('.tgz'));
|
|
20
20
|
if (pack.status !== 0 || !tarball)
|
|
21
21
|
throw new Error(`${spec}: the registry gave no tarball (${String(pack.stderr).trim().split('\n').at(-1) ?? ''})`);
|
|
@@ -72,7 +72,7 @@ export async function conformPublished(spec, opts = {}) {
|
|
|
72
72
|
const platform = Object.keys(deps).filter((d) => d.startsWith('@volter/'));
|
|
73
73
|
const others = Object.entries(deps).filter(([d]) => !d.startsWith('@volter/')).map(([d, v]) => `${d}@${v}`);
|
|
74
74
|
if (others.length) {
|
|
75
|
-
const install = spawnSync('
|
|
75
|
+
const install = spawnSync('pnpm', ['add', '--prod', '--config.autoInstallPeers=false', '--package-import-method=hardlink', '--config.nodeLinker=hoisted', '--ignore-scripts', ...(opts.registry ? ['--registry', opts.registry] : []), ...others], { cwd: dirname(dir), encoding: 'utf8' });
|
|
76
76
|
if (install.status !== 0)
|
|
77
77
|
throw new Error(`${spec}: its dependencies do not install (${String(install.stderr).trim().split('\n').at(-1) ?? ''})`);
|
|
78
78
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/twin-standard",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.154",
|
|
4
4
|
"description": "The Protocol 3 standard for Volter twin packs: the criteria a pack is graded by, the grader, the gate a pack repository and the twin catalog run on every change and submission, and the spec derivation the grade checks against. Pin a version: every place a pack is judged judges by that standard.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"twin",
|
|
@@ -20,8 +20,9 @@
|
|
|
20
20
|
"README.md",
|
|
21
21
|
"LICENSE",
|
|
22
22
|
"client-sdks/package.json",
|
|
23
|
-
"client-sdks/
|
|
23
|
+
"client-sdks/pnpm-lock.yaml",
|
|
24
24
|
"!**/*.test.ts",
|
|
25
|
+
"client-sdks/pnpm-workspace.yaml",
|
|
25
26
|
"dist"
|
|
26
27
|
],
|
|
27
28
|
"repository": {
|
|
@@ -75,7 +76,7 @@
|
|
|
75
76
|
"yaml": "2.9.0"
|
|
76
77
|
},
|
|
77
78
|
"peerDependencies": {
|
|
78
|
-
"@volter/world-core": "3.0.
|
|
79
|
+
"@volter/world-core": "3.0.161",
|
|
79
80
|
"@volter/world-runtime": "*",
|
|
80
81
|
"playwright": "^1.63.0"
|
|
81
82
|
},
|
|
@@ -112,5 +113,13 @@
|
|
|
112
113
|
},
|
|
113
114
|
"engines": {
|
|
114
115
|
"node": ">=22.6"
|
|
116
|
+
},
|
|
117
|
+
"packageManager": "pnpm@12.15.0",
|
|
118
|
+
"devEngines": {
|
|
119
|
+
"packageManager": {
|
|
120
|
+
"name": "pnpm",
|
|
121
|
+
"version": "12.15.0",
|
|
122
|
+
"onFail": "error"
|
|
123
|
+
}
|
|
115
124
|
}
|
|
116
125
|
}
|
package/src/clients/sentry.ts
CHANGED
|
@@ -13,8 +13,8 @@ import { standardPackageFile } from '../package-file.ts';
|
|
|
13
13
|
const SDKS = standardPackageFile('client-sdks/');
|
|
14
14
|
async function sdkOf(name: string): Promise<any> {
|
|
15
15
|
if (!existsSync(new URL('node_modules/', SDKS))) {
|
|
16
|
-
const install = spawnSync('
|
|
17
|
-
if (install.status !== 0) throw new Error('client-sdks:
|
|
16
|
+
const install = spawnSync('pnpm', ['install', '--frozen-lockfile', '--ignore-scripts'], { cwd: SDKS, stdio: 'inherit' });
|
|
17
|
+
if (install.status !== 0) throw new Error('client-sdks: pnpm install --frozen-lockfile failed');
|
|
18
18
|
}
|
|
19
19
|
return await import(pathToFileURL(createRequire(new URL('package.json', SDKS)).resolve(name)).href);
|
|
20
20
|
}
|
package/src/conformance.ts
CHANGED
|
@@ -211,7 +211,7 @@ async function registered(pack: string, runtime: Runtime): Promise<string[]> {
|
|
|
211
211
|
* journeys, read from the file list `npm pack` makes. Escaped once: seven packs published their lanes' src without
|
|
212
212
|
* their spec, so the catalog's conformance of the tarball never read those lanes. */
|
|
213
213
|
function published(pack: string): string[] {
|
|
214
|
-
const run = spawnSync('npm', ['pack', '--dry-run', '--json', '--ignore-scripts'], { cwd: pack, encoding: 'utf8' });
|
|
214
|
+
const run = spawnSync('npm', ['pack', '--force', '--dry-run', '--json', '--ignore-scripts'], { cwd: pack, encoding: 'utf8' });
|
|
215
215
|
let files: Set<string>;
|
|
216
216
|
try { files = new Set(((JSON.parse(run.stdout) as Array<{ files: Array<{ path: string }> }>)[0]?.files ?? []).map((f) => f.path)); } catch { return [`npm pack lists no files (${String(run.stderr).trim().split('\n').at(-1) ?? ''})`]; }
|
|
217
217
|
const out: string[] = [];
|
package/src/consumer.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { basename, dirname, isAbsolute, join, relative, resolve } from 'node:pat
|
|
|
6
6
|
import { spawn } from 'node:child_process';
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
|
8
8
|
import { standardPackageFile } from './package-file.ts';
|
|
9
|
+
import { dependencyLock } from './dependency-lock.ts';
|
|
9
10
|
|
|
10
11
|
export type ConsumerRecipe = {
|
|
11
12
|
schemaVersion: 1;
|
|
@@ -79,6 +80,8 @@ export function prepareConsumerApp(packDir: string, appDir: string, installation
|
|
|
79
80
|
const recipe = consumerRecipe(vendor, packDir);
|
|
80
81
|
if (existsSync(appDir)) throw new Error('Consumer app must be a new directory');
|
|
81
82
|
const app = JSON.parse(recipe.files['package.json']!);
|
|
83
|
+
app.packageManager = 'pnpm@12.15.0';
|
|
84
|
+
app.devEngines = { packageManager: { name: 'pnpm', version: '12.15.0', onFail: 'error' } };
|
|
82
85
|
if (app.scripts || app.workspaces) throw new Error('Consumer fixture supplies direct SDK commands, not install scripts or workspace links');
|
|
83
86
|
for (const [name, version] of Object.entries({ ...app.dependencies, ...app.devDependencies, ...app.optionalDependencies })) {
|
|
84
87
|
if (typeof version !== 'string' || !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(version)) throw new Error(`${name}: customer SDK dependencies require exact registry versions`);
|
|
@@ -94,8 +97,9 @@ export function prepareConsumerApp(packDir: string, appDir: string, installation
|
|
|
94
97
|
if (installation.artifact && (!isAbsolute(installation.artifact) || !statSync(installation.artifact).isFile())) throw new Error('Consumer candidate must be an absolute prepared archive path');
|
|
95
98
|
if (Object.hasOwn(app.dependencies ?? {}, metadata.name)) throw new Error('Consumer SDK dependencies must not substitute the candidate package');
|
|
96
99
|
app.devDependencies = { ...app.devDependencies, '@volter/world-core': tools['@volter/world-core'], [metadata.name]: installation.artifact ? `file:${installation.artifact}` : metadata.version };
|
|
97
|
-
files.find(([path]) => path === 'package.json')![1] = JSON.stringify(app, null, 2) + '\n';
|
|
98
100
|
}
|
|
101
|
+
files.find(([path]) => path === 'package.json')![1] = JSON.stringify(app, null, 2) + '\n';
|
|
102
|
+
files.push(['pnpm-workspace.yaml', 'packages:\n - .\npackageImportMethod: hardlink\nnodeLinker: hoisted\nautoInstallPeers: false\nstrictPeerDependencies: false\n']);
|
|
99
103
|
mkdirSync(appDir, { recursive: true });
|
|
100
104
|
for (const [path, content] of files) {
|
|
101
105
|
mkdirSync(dirname(join(appDir, path)), { recursive: true });
|
|
@@ -117,10 +121,9 @@ export async function runConsumerWorkflow(packDir: string, options: ConsumerOpti
|
|
|
117
121
|
const location = relative(join(appRoot, 'node_modules'), identity.directory);
|
|
118
122
|
if (location.startsWith('..') || isAbsolute(location)) throw new Error(`${name}: consumer resolves an evaluator or ancestor dependency; install it in the app`);
|
|
119
123
|
}
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
if (
|
|
123
|
-
if (kernel.version !== tools['@volter/world-core'] || appLock.packages?.['node_modules/@volter/world-core']?.version !== kernel.version) throw new Error('Consumer app kernel does not match the CLI kernel pin');
|
|
124
|
+
const appLock = dependencyLock(appRoot), appLockBytes = appLock.bytes;
|
|
125
|
+
if (candidate.version !== metadata.version || appLock.entry(metadata.name)?.integrity !== options.artifactIntegrity) throw new Error('Consumer app candidate does not match the exact assessed artifact');
|
|
126
|
+
if (kernel.version !== tools['@volter/world-core'] || appLock.entry('@volter/world-core')?.version !== kernel.version) throw new Error('Consumer app kernel does not match the CLI kernel pin');
|
|
124
127
|
const application = { candidate: { package: metadata.name, version: candidate.version, integrity: options.artifactIntegrity }, kernel: { package: '@volter/world-core', version: kernel.version }, dependencyLockSha256: createHash('sha256').update(appLockBytes).digest('hex'), appLocal: true };
|
|
125
128
|
const facts = JSON.parse(readFileSync(join(packDir, 'generated/pack-facts.json'), 'utf8'));
|
|
126
129
|
const vendor = Object.keys(facts.packs ?? {})[0];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { parseAllDocuments } from 'yaml';
|
|
4
|
+
|
|
5
|
+
/** The application's selected direct dependency, including the exact installer's integrity. */
|
|
6
|
+
export function dependencyLock(root: string) {
|
|
7
|
+
const pnpm = join(root, 'pnpm-lock.yaml');
|
|
8
|
+
if (existsSync(pnpm)) {
|
|
9
|
+
const bytes = readFileSync(pnpm);
|
|
10
|
+
const documents = parseAllDocuments(bytes.toString());
|
|
11
|
+
for (const doc of documents) if (doc.errors.length) throw doc.errors[0];
|
|
12
|
+
const lock = documents.map(doc => doc.toJS()).find(doc => doc?.importers?.['.'] && !doc.importers['.'].packageManagerDependencies);
|
|
13
|
+
if (!lock) throw new Error('No pnpm application importer');
|
|
14
|
+
return { bytes, file: pnpm, entry(name: string) {
|
|
15
|
+
const importer = lock.importers['.'];
|
|
16
|
+
const selected = importer.dependencies?.[name] ?? importer.devDependencies?.[name] ?? importer.optionalDependencies?.[name];
|
|
17
|
+
if (!selected) return undefined;
|
|
18
|
+
const selectedRef = String(selected.version);
|
|
19
|
+
const ref = lock.packages?.[`${name}@${selectedRef}`] ? selectedRef : selectedRef.replace(/\(.*$/, '');
|
|
20
|
+
const pkg = lock.packages?.[`${name}@${ref}`];
|
|
21
|
+
return { version: pkg?.version ?? ref, integrity: pkg?.resolution?.integrity };
|
|
22
|
+
} };
|
|
23
|
+
}
|
|
24
|
+
const file = join(root, 'package-lock.json'), bytes = readFileSync(file);
|
|
25
|
+
const lock = JSON.parse(bytes.toString());
|
|
26
|
+
return { bytes, file, entry(name: string) { return lock.packages?.[`node_modules/${name}`] as { version?: string; integrity?: string } | undefined; } };
|
|
27
|
+
}
|
package/src/published.ts
CHANGED
|
@@ -19,7 +19,7 @@ export const vendorOfPackage = (name: string): string => name.replace(/^@[^/]+\/
|
|
|
19
19
|
async function withPublished<T>(spec: string, opts: { registry?: string }, use: (dir: string, tmp: string) => Promise<T>): Promise<T> {
|
|
20
20
|
const tmp = mkdtempSync(join(tmpdir(), 'twin-standard-'));
|
|
21
21
|
try {
|
|
22
|
-
const pack = spawnSync('npm', ['pack', spec, '--pack-destination', tmp, '--silent', ...(opts.registry ? ['--registry', opts.registry] : [])], { encoding: 'utf8' });
|
|
22
|
+
const pack = spawnSync('npm', ['pack', '--force', spec, '--pack-destination', tmp, '--silent', ...(opts.registry ? ['--registry', opts.registry] : [])], { encoding: 'utf8' });
|
|
23
23
|
const tarball = readdirSync(tmp).find((f) => f.endsWith('.tgz'));
|
|
24
24
|
if (pack.status !== 0 || !tarball) throw new Error(`${spec}: the registry gave no tarball (${String(pack.stderr).trim().split('\n').at(-1) ?? ''})`);
|
|
25
25
|
const untar = spawnSync('tar', ['-xzf', join(tmp, tarball), '-C', tmp], { encoding: 'utf8' });
|
|
@@ -66,7 +66,7 @@ export async function conformPublished(spec: string, opts: { registry?: string }
|
|
|
66
66
|
const platform = Object.keys(deps).filter((d) => d.startsWith('@volter/'));
|
|
67
67
|
const others = Object.entries(deps).filter(([d]) => !d.startsWith('@volter/')).map(([d, v]) => `${d}@${v}`);
|
|
68
68
|
if (others.length) {
|
|
69
|
-
const install = spawnSync('
|
|
69
|
+
const install = spawnSync('pnpm', ['add', '--prod', '--config.autoInstallPeers=false', '--package-import-method=hardlink', '--config.nodeLinker=hoisted', '--ignore-scripts', ...(opts.registry ? ['--registry', opts.registry] : []), ...others], { cwd: dirname(dir), encoding: 'utf8' });
|
|
70
70
|
if (install.status !== 0) throw new Error(`${spec}: its dependencies do not install (${String(install.stderr).trim().split('\n').at(-1) ?? ''})`);
|
|
71
71
|
}
|
|
72
72
|
mkdirSync(join(dir, 'node_modules', '@volter'), { recursive: true });
|