@volter/twin-standard 1.0.155 → 1.0.156
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/src/consumer.js +13 -2
- package/package.json +1 -1
- package/src/consumer.ts +12 -2
package/dist/src/consumer.js
CHANGED
|
@@ -3,7 +3,7 @@ import { createHash } from 'node:crypto';
|
|
|
3
3
|
import { existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, statSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { createRequire } from 'node:module';
|
|
5
5
|
import { basename, dirname, isAbsolute, join, relative, resolve } from 'node:path';
|
|
6
|
-
import { spawn } from 'node:child_process';
|
|
6
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
|
8
8
|
import { standardPackageFile } from "./package-file.js";
|
|
9
9
|
import { dependencyLock } from "./dependency-lock.js";
|
|
@@ -91,7 +91,7 @@ export function prepareConsumerApp(packDir, appDir, installation) {
|
|
|
91
91
|
throw new Error(`${name}: customer SDK dependencies require exact registry versions`);
|
|
92
92
|
}
|
|
93
93
|
const files = Object.entries(recipe.files).map(([path, content]) => {
|
|
94
|
-
if (isAbsolute(path) || path.includes('\\') || path.split('/').some((part) => !part || part === '.' || part === '..') || path.split('/').includes('node_modules') || ['.env', '.npmrc', '.volter/world.json'].includes(path))
|
|
94
|
+
if (isAbsolute(path) || path.includes('\\') || path.split('/').some((part) => !part || part === '.' || part === '..' || part === '.git') || path.split('/').includes('node_modules') || ['.env', '.npmrc', '.volter/world.json'].includes(path))
|
|
95
95
|
throw new Error(`Invalid consumer file: ${path}`);
|
|
96
96
|
if (typeof content !== 'string')
|
|
97
97
|
throw new Error('Consumer files must contain text');
|
|
@@ -113,6 +113,17 @@ export function prepareConsumerApp(packDir, appDir, installation) {
|
|
|
113
113
|
mkdirSync(dirname(join(appDir, path)), { recursive: true });
|
|
114
114
|
writeFileSync(join(appDir, path), content);
|
|
115
115
|
}
|
|
116
|
+
// World init reads committed example values. The recipe is this new application's source.
|
|
117
|
+
const gitEnv = Object.fromEntries(Object.entries(process.env).filter(([name]) => !name.startsWith('GIT_')));
|
|
118
|
+
for (const args of [
|
|
119
|
+
['init', '--quiet', '--template='],
|
|
120
|
+
['add', '--force', '--', ...files.map(([path]) => path)],
|
|
121
|
+
['-c', 'user.name=World consumer', '-c', 'user.email=consumer@world.test', '-c', 'commit.gpgsign=false', '-c', `core.hooksPath=${join(appDir, '.git/hooks')}`, 'commit', '--quiet', '-m', 'Materialize customer application'],
|
|
122
|
+
]) {
|
|
123
|
+
const result = spawnSync('git', ['-C', appDir, ...args], { env: gitEnv, encoding: 'utf8' });
|
|
124
|
+
if (result.error || result.status !== 0)
|
|
125
|
+
throw new Error(`Consumer source ${args[0]} failed: ${result.error?.message ?? result.stderr.trim()}`);
|
|
126
|
+
}
|
|
116
127
|
return { recipeSha256: createHash('sha256').update(JSON.stringify(recipe)).digest('hex'), dependencies: app.dependencies ?? {} };
|
|
117
128
|
}
|
|
118
129
|
export async function runConsumerWorkflow(packDir, options) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/twin-standard",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.156",
|
|
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",
|
package/src/consumer.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { createHash } from 'node:crypto';
|
|
|
3
3
|
import { existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, statSync, writeFileSync } from 'node:fs';
|
|
4
4
|
import { createRequire } from 'node:module';
|
|
5
5
|
import { basename, dirname, isAbsolute, join, relative, resolve } from 'node:path';
|
|
6
|
-
import { spawn } from 'node:child_process';
|
|
6
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
|
8
8
|
import { standardPackageFile } from './package-file.ts';
|
|
9
9
|
import { dependencyLock } from './dependency-lock.ts';
|
|
@@ -87,7 +87,7 @@ export function prepareConsumerApp(packDir: string, appDir: string, installation
|
|
|
87
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`);
|
|
88
88
|
}
|
|
89
89
|
const files = Object.entries(recipe.files).map(([path, content]) => {
|
|
90
|
-
if (isAbsolute(path) || path.includes('\\') || path.split('/').some((part) => !part || part === '.' || part === '..') || path.split('/').includes('node_modules') || ['.env', '.npmrc', '.volter/world.json'].includes(path)) throw new Error(`Invalid consumer file: ${path}`);
|
|
90
|
+
if (isAbsolute(path) || path.includes('\\') || path.split('/').some((part) => !part || part === '.' || part === '..' || part === '.git') || path.split('/').includes('node_modules') || ['.env', '.npmrc', '.volter/world.json'].includes(path)) throw new Error(`Invalid consumer file: ${path}`);
|
|
91
91
|
if (typeof content !== 'string') throw new Error('Consumer files must contain text');
|
|
92
92
|
return [path, content] as [string, string];
|
|
93
93
|
});
|
|
@@ -105,6 +105,16 @@ export function prepareConsumerApp(packDir: string, appDir: string, installation
|
|
|
105
105
|
mkdirSync(dirname(join(appDir, path)), { recursive: true });
|
|
106
106
|
writeFileSync(join(appDir, path), content);
|
|
107
107
|
}
|
|
108
|
+
// World init reads committed example values. The recipe is this new application's source.
|
|
109
|
+
const gitEnv = Object.fromEntries(Object.entries(process.env).filter(([name]) => !name.startsWith('GIT_')));
|
|
110
|
+
for (const args of [
|
|
111
|
+
['init', '--quiet', '--template='],
|
|
112
|
+
['add', '--force', '--', ...files.map(([path]) => path)],
|
|
113
|
+
['-c', 'user.name=World consumer', '-c', 'user.email=consumer@world.test', '-c', 'commit.gpgsign=false', '-c', `core.hooksPath=${join(appDir, '.git/hooks')}`, 'commit', '--quiet', '-m', 'Materialize customer application'],
|
|
114
|
+
]) {
|
|
115
|
+
const result = spawnSync('git', ['-C', appDir, ...args], { env: gitEnv, encoding: 'utf8' });
|
|
116
|
+
if (result.error || result.status !== 0) throw new Error(`Consumer source ${args[0]} failed: ${result.error?.message ?? result.stderr.trim()}`);
|
|
117
|
+
}
|
|
108
118
|
return { recipeSha256: createHash('sha256').update(JSON.stringify(recipe)).digest('hex'), dependencies: app.dependencies ?? {} };
|
|
109
119
|
}
|
|
110
120
|
|