@decohere/create 0.0.1-dev.46 → 0.0.1-dev.48
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/pack-builder-tgz.mjs +68 -54
- package/package.json +2 -2
package/pack-builder-tgz.mjs
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* Vendor `@decohere/create` for the builder image: resolve `@decohere/*` from
|
|
4
|
+
* dist/release via `file:` (not `overrides`), `npm install --install-links`,
|
|
5
|
+
* then tar the installed tree including `node_modules`. `--install-links`
|
|
6
|
+
* materializes `file:` packages (and their deps) instead of leaving symlinks
|
|
7
|
+
* whose nested installs live outside the create directory.
|
|
6
8
|
*/
|
|
7
9
|
import { spawnSync } from "node:child_process";
|
|
8
|
-
import { readdirSync, readFileSync,
|
|
10
|
+
import { readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
9
11
|
import { dirname, join, relative, resolve } from "node:path";
|
|
10
12
|
import { fileURLToPath } from "node:url";
|
|
11
13
|
|
|
@@ -47,52 +49,42 @@ export function collectWorkspacePackages(rootDir) {
|
|
|
47
49
|
|
|
48
50
|
/**
|
|
49
51
|
* @param {string} fromDir
|
|
50
|
-
* @param {
|
|
51
|
-
* @returns {Record<string, string>}
|
|
52
|
+
* @param {string} pkgDir
|
|
52
53
|
*/
|
|
53
|
-
export function
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (resolve(pkg.dir) === from) continue;
|
|
59
|
-
let rel = relative(fromDir, pkg.dir) || ".";
|
|
60
|
-
rel = rel.replaceAll("\\", "/");
|
|
61
|
-
if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
62
|
-
overrides[pkg.name] = `file:${rel}`;
|
|
63
|
-
}
|
|
64
|
-
return overrides;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* @param {Record<string, unknown>} pkg
|
|
69
|
-
* @returns {string[]}
|
|
70
|
-
*/
|
|
71
|
-
export function productionDepNames(pkg) {
|
|
72
|
-
const deps = pkg.dependencies;
|
|
73
|
-
if (deps == null || typeof deps !== "object") return [];
|
|
74
|
-
return Object.keys(deps);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* @param {Record<string, unknown>} pkg
|
|
79
|
-
* @param {Record<string, string>} overrides
|
|
80
|
-
*/
|
|
81
|
-
export function withInstallOverrides(pkg, overrides) {
|
|
82
|
-
const existing = pkg.overrides;
|
|
83
|
-
const previous =
|
|
84
|
-
existing != null && typeof existing === "object" && !Array.isArray(existing)
|
|
85
|
-
? /** @type {Record<string, unknown>} */ (existing)
|
|
86
|
-
: {};
|
|
87
|
-
return { ...pkg, overrides: { ...previous, ...overrides } };
|
|
54
|
+
export function fileSpec(fromDir, pkgDir) {
|
|
55
|
+
let rel = relative(fromDir, pkgDir) || ".";
|
|
56
|
+
rel = rel.replaceAll("\\", "/");
|
|
57
|
+
if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
58
|
+
return `file:${rel}`;
|
|
88
59
|
}
|
|
89
60
|
|
|
90
61
|
/**
|
|
62
|
+
* Rewrite `@decohere/*` dependency specs to local `file:` paths.
|
|
63
|
+
* Must mutate `dependencies` (not `overrides`) — npm throws EOVERRIDE when an
|
|
64
|
+
* override conflicts with a direct dependency.
|
|
65
|
+
*
|
|
91
66
|
* @param {Record<string, unknown>} pkg
|
|
67
|
+
* @param {string} fromDir
|
|
68
|
+
* @param {WorkspacePackage[]} packages
|
|
92
69
|
*/
|
|
93
|
-
export function
|
|
94
|
-
const
|
|
95
|
-
|
|
70
|
+
export function rewriteDecohereDepsToFile(pkg, fromDir, packages) {
|
|
71
|
+
const byName = new Map(packages.map((item) => [item.name, item.dir]));
|
|
72
|
+
const from = resolve(fromDir);
|
|
73
|
+
const rewrite = (deps) => {
|
|
74
|
+
if (deps == null || typeof deps !== "object" || Array.isArray(deps)) return deps;
|
|
75
|
+
const next = { .../** @type {Record<string, unknown>} */ (deps) };
|
|
76
|
+
for (const name of Object.keys(next)) {
|
|
77
|
+
const dir = byName.get(name);
|
|
78
|
+
if (dir == null || resolve(dir) === from) continue;
|
|
79
|
+
next[name] = fileSpec(fromDir, dir);
|
|
80
|
+
}
|
|
81
|
+
return next;
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
...pkg,
|
|
85
|
+
dependencies: rewrite(pkg.dependencies),
|
|
86
|
+
optionalDependencies: rewrite(pkg.optionalDependencies),
|
|
87
|
+
};
|
|
96
88
|
}
|
|
97
89
|
|
|
98
90
|
function writeJson(path, value) {
|
|
@@ -109,22 +101,44 @@ function runNpm(cwd, args) {
|
|
|
109
101
|
return result.stdout.trim();
|
|
110
102
|
}
|
|
111
103
|
|
|
104
|
+
function packInstalledTree(outDir, dest) {
|
|
105
|
+
const result = spawnSync(
|
|
106
|
+
"tar",
|
|
107
|
+
["--create", "--gzip", "--dereference", "--file", dest, "-C", outDir, "."],
|
|
108
|
+
{ encoding: "utf8" },
|
|
109
|
+
);
|
|
110
|
+
if (result.status !== 0) {
|
|
111
|
+
throw new Error(`tar failed (exit ${result.status}):\n${result.stderr}${result.stdout}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
112
115
|
export function packBuilderTgz(options) {
|
|
113
116
|
const outDir = resolve(options.outDir);
|
|
114
117
|
const workspaceOut = resolve(options.workspaceOut);
|
|
115
118
|
const dest = resolve(options.dest);
|
|
116
119
|
const packageJsonPath = join(outDir, "package.json");
|
|
117
|
-
const
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
throw new Error(`npm pack did not print a tarball name:\n${packed}`);
|
|
120
|
+
const packages = collectWorkspacePackages(workspaceOut);
|
|
121
|
+
const originals = packages.map((pkg) => {
|
|
122
|
+
const path = join(pkg.dir, "package.json");
|
|
123
|
+
return { path, original: JSON.parse(readFileSync(path, "utf8")) };
|
|
124
|
+
});
|
|
125
|
+
const createOriginal = originals.find((entry) => entry.path === packageJsonPath)?.original;
|
|
126
|
+
if (createOriginal == null) {
|
|
127
|
+
throw new Error(`No @decohere package.json at ${packageJsonPath}`);
|
|
126
128
|
}
|
|
127
|
-
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
for (const { path, original } of originals) {
|
|
132
|
+
writeJson(path, rewriteDecohereDepsToFile(original, dirname(path), packages));
|
|
133
|
+
}
|
|
134
|
+
runNpm(outDir, ["install", "--omit=dev", "--ignore-scripts", "--install-links"]);
|
|
135
|
+
} finally {
|
|
136
|
+
for (const { path, original } of originals) {
|
|
137
|
+
writeJson(path, original);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
packInstalledTree(outDir, dest);
|
|
128
142
|
return dest;
|
|
129
143
|
}
|
|
130
144
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decohere/create",
|
|
3
|
-
"version": "0.0.1-dev.
|
|
3
|
+
"version": "0.0.1-dev.48",
|
|
4
4
|
"description": "Scaffold a new Decohere project — build with Forge, serve with Flux",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"decohere",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@decohere/nexus": "0.0.1-dev.
|
|
24
|
+
"@decohere/nexus": "0.0.1-dev.48",
|
|
25
25
|
"commander": "^13.1.0",
|
|
26
26
|
"openapi-to-postmanv2": "^5.0.0"
|
|
27
27
|
},
|