@tulipes/core 0.1.7 → 0.1.9
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/README.md +11 -2
- package/dist/cli/main.js +11 -5
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/package-info.d.ts +6 -0
- package/dist/cli/package-info.js +18 -2
- package/dist/cli/package-info.js.map +1 -1
- package/dist/cli/update.d.ts +12 -6
- package/dist/cli/update.js +90 -34
- package/dist/cli/update.js.map +1 -1
- package/package.json +1 -1
- package/templates/CLAUDE.md +1 -1
package/README.md
CHANGED
|
@@ -254,8 +254,8 @@ tulipes init [dir] scaffold a new application (needs mongo + redis)
|
|
|
254
254
|
tulipes sync regenerate types/config.d.ts and .env.example
|
|
255
255
|
tulipes env:check validate env against every meta contract — CI gate, exit 1 on failure
|
|
256
256
|
tulipes new module <name> scaffold a module (scope auto-detected from siblings)
|
|
257
|
-
tulipes update upgrade
|
|
258
|
-
tulipes -v print the
|
|
257
|
+
tulipes update upgrade the global cli and, inside an app, the app itself
|
|
258
|
+
tulipes -v print the cli version (and the app's, when they differ)
|
|
259
259
|
tulipes dev [entry] sync, then run the entry under tsx watch
|
|
260
260
|
```
|
|
261
261
|
|
|
@@ -274,6 +274,15 @@ would otherwise guess wrong: declaring variables instead of reaching for
|
|
|
274
274
|
`process.env`, where global middleware belongs, why `mongoose.model()` is
|
|
275
275
|
never called directly, and how to read an aggregate boot report.
|
|
276
276
|
|
|
277
|
+
The global CLI on your PATH and the `@tulipes/core` an app installs are
|
|
278
|
+
**separate installs** that drift apart. `tulipes update` handles both: it
|
|
279
|
+
reinstalls the global CLI into the prefix it already lives in (which is what
|
|
280
|
+
makes it work under nvm, where a plain `npm install -g` may target a
|
|
281
|
+
different node version than the one holding your `tulipes` binary), and,
|
|
282
|
+
when run inside an app, rewrites the range in the app root and every module
|
|
283
|
+
before installing. Outside an app it still updates the CLI. `tulipes -v`
|
|
284
|
+
prints both numbers whenever they differ.
|
|
285
|
+
|
|
277
286
|
`sync` output — committed, marked generated:
|
|
278
287
|
|
|
279
288
|
- **`types/config.d.ts`** — augments `KnownVariables` (every variable typed from its spec) and `GlobalConfig` (each namespace typed as its factory's return type via `typeof import(...)` — inference, never execution).
|
package/dist/cli/main.js
CHANGED
|
@@ -4,7 +4,7 @@ import { runEnvCheck } from "./env-check.js";
|
|
|
4
4
|
import { runNewModule } from "./new-module.js";
|
|
5
5
|
import { runDev } from "./dev.js";
|
|
6
6
|
import { runUpdate } from "./update.js";
|
|
7
|
-
import { coreVersion } from "./package-info.js";
|
|
7
|
+
import { appCoreVersion, coreVersion } from "./package-info.js";
|
|
8
8
|
/**
|
|
9
9
|
* The `tulipes` CLI. Deliberately dependency-free argument handling — a
|
|
10
10
|
* handful of commands don't justify a parser library.
|
|
@@ -18,8 +18,8 @@ Usage:
|
|
|
18
18
|
tulipes sync regenerate types/config.d.ts and .env.example
|
|
19
19
|
tulipes env:check validate env against every meta.variables.json (CI-friendly)
|
|
20
20
|
tulipes new module <name> scaffold a module under ./modules
|
|
21
|
-
tulipes update upgrade
|
|
22
|
-
tulipes -v print the
|
|
21
|
+
tulipes update upgrade the global cli and, inside an app, the app itself
|
|
22
|
+
tulipes -v print the cli version (and the app's, when they differ)
|
|
23
23
|
`;
|
|
24
24
|
export async function main(argv) {
|
|
25
25
|
const [command, ...rest] = argv;
|
|
@@ -44,9 +44,15 @@ export async function main(argv) {
|
|
|
44
44
|
return runDev(rootDir, rest[0] ?? "app.ts");
|
|
45
45
|
case "-v":
|
|
46
46
|
case "--version":
|
|
47
|
-
case "version":
|
|
48
|
-
|
|
47
|
+
case "version": {
|
|
48
|
+
const cli = coreVersion();
|
|
49
|
+
const app = appCoreVersion(rootDir);
|
|
50
|
+
// The CLI on your PATH and the copy an app installs are separate
|
|
51
|
+
// installs. Printing one number would hide a mismatch that explains
|
|
52
|
+
// otherwise baffling behaviour, so say both whenever they differ.
|
|
53
|
+
console.log(app && app !== cli ? `cli ${cli}\napp ${app}` : cli);
|
|
49
54
|
return;
|
|
55
|
+
}
|
|
50
56
|
case undefined:
|
|
51
57
|
case "help":
|
|
52
58
|
case "--help":
|
package/dist/cli/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhE;;;;GAIG;AACH,MAAM,IAAI,GAAG;;;;;;;;;;CAUZ,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAuB;IAChD,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAChC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE9B,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1B,KAAK,WAAW;YACd,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;QAC9B,KAAK,QAAQ;YACX,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC;QAC5B,KAAK,KAAK;YACR,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrC,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;gBAClD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;YACD,OAAO,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,KAAK,KAAK;YACR,OAAO,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC;QAC9C,KAAK,IAAI,CAAC;QACV,KAAK,WAAW,CAAC;QACjB,KAAK,SAAS,EAAE,CAAC;YACf,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;YACpC,iEAAiE;YACjE,oEAAoE;YACpE,kEAAkE;YAClE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QACD,KAAK,SAAS,CAAC;QACf,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ;YACX,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClB,OAAO;QACT;YACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,QAAQ,IAAI,EAAE,CAAC,CAAC;YACzD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACzB,CAAC;AACH,CAAC"}
|
|
@@ -6,3 +6,9 @@
|
|
|
6
6
|
export declare function packageRoot(): string;
|
|
7
7
|
/** Version of the @tulipes/core running this CLI. */
|
|
8
8
|
export declare function coreVersion(): string;
|
|
9
|
+
/**
|
|
10
|
+
* Version of the core installed in an app, which is a different install
|
|
11
|
+
* from the global CLI and can therefore be a different version. Undefined
|
|
12
|
+
* when the directory is not an app, or its dependencies aren't installed.
|
|
13
|
+
*/
|
|
14
|
+
export declare function appCoreVersion(rootDir: string): string | undefined;
|
package/dist/cli/package-info.js
CHANGED
|
@@ -11,7 +11,23 @@ export function packageRoot() {
|
|
|
11
11
|
}
|
|
12
12
|
/** Version of the @tulipes/core running this CLI. */
|
|
13
13
|
export function coreVersion() {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
return versionAt(packageRoot()) ?? "unknown";
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Version of the core installed in an app, which is a different install
|
|
18
|
+
* from the global CLI and can therefore be a different version. Undefined
|
|
19
|
+
* when the directory is not an app, or its dependencies aren't installed.
|
|
20
|
+
*/
|
|
21
|
+
export function appCoreVersion(rootDir) {
|
|
22
|
+
return versionAt(join(rootDir, "node_modules", "@tulipes", "core"));
|
|
23
|
+
}
|
|
24
|
+
function versionAt(packageDir) {
|
|
25
|
+
try {
|
|
26
|
+
const pkg = JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8"));
|
|
27
|
+
return typeof pkg.version === "string" ? pkg.version : undefined;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
16
32
|
}
|
|
17
33
|
//# sourceMappingURL=package-info.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-info.js","sourceRoot":"","sources":["../../src/cli/package-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;GAIG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,WAAW;IACzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"package-info.js","sourceRoot":"","sources":["../../src/cli/package-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;GAIG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,WAAW;IACzB,OAAO,SAAS,CAAC,WAAW,EAAE,CAAC,IAAI,SAAS,CAAC;AAC/C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,SAAS,CAAC,UAAkB;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAE5E,CAAC;QACF,OAAO,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
|
package/dist/cli/update.d.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `tulipes update` — move
|
|
2
|
+
* `tulipes update` — move to the latest published core.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* There are two things that can be out of date, and they are genuinely
|
|
5
|
+
* separate installs:
|
|
6
|
+
*
|
|
7
|
+
* the CLI the globally installed `tulipes` on your PATH
|
|
8
|
+
* the app @tulipes/core in the app root and in every module, since
|
|
9
|
+
* modules are workspace packages that declare it themselves
|
|
10
|
+
*
|
|
11
|
+
* Updating only the app leaves you typing an old CLI against a new
|
|
12
|
+
* framework; updating only the CLI leaves the app behind. This does both,
|
|
13
|
+
* and either alone when only one applies — so it is also useful outside an
|
|
14
|
+
* app, where it upgrades just the CLI.
|
|
9
15
|
*/
|
|
10
16
|
export declare function runUpdate(rootDir: string): Promise<void>;
|
package/dist/cli/update.js
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { existsSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { join, relative } from "node:path";
|
|
4
|
-
import { coreVersion } from "./package-info.js";
|
|
3
|
+
import { join, relative, resolve, sep } from "node:path";
|
|
4
|
+
import { appCoreVersion, coreVersion, packageRoot } from "./package-info.js";
|
|
5
5
|
const PACKAGE = "@tulipes/core";
|
|
6
6
|
const REGISTRY = "https://registry.npmjs.org";
|
|
7
7
|
/**
|
|
8
|
-
* `tulipes update` — move
|
|
8
|
+
* `tulipes update` — move to the latest published core.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* There are two things that can be out of date, and they are genuinely
|
|
11
|
+
* separate installs:
|
|
12
|
+
*
|
|
13
|
+
* the CLI the globally installed `tulipes` on your PATH
|
|
14
|
+
* the app @tulipes/core in the app root and in every module, since
|
|
15
|
+
* modules are workspace packages that declare it themselves
|
|
16
|
+
*
|
|
17
|
+
* Updating only the app leaves you typing an old CLI against a new
|
|
18
|
+
* framework; updating only the CLI leaves the app behind. This does both,
|
|
19
|
+
* and either alone when only one applies — so it is also useful outside an
|
|
20
|
+
* app, where it upgrades just the CLI.
|
|
15
21
|
*/
|
|
16
22
|
export async function runUpdate(rootDir) {
|
|
17
23
|
const current = coreVersion();
|
|
@@ -24,23 +30,87 @@ export async function runUpdate(rootDir) {
|
|
|
24
30
|
process.exitCode = 1;
|
|
25
31
|
return;
|
|
26
32
|
}
|
|
33
|
+
const cliRoot = packageRoot();
|
|
34
|
+
// Updatable-as-a-CLI means: an installed package (it lives under some
|
|
35
|
+
// node_modules) that is NOT this app's own copy — the app's copy is
|
|
36
|
+
// covered by the dependency update below. A source checkout matches
|
|
37
|
+
// neither and is left alone, since git owns its version, not npm.
|
|
38
|
+
const cliIsGlobal = !cliRoot.startsWith(resolve(rootDir) + sep) &&
|
|
39
|
+
cliRoot.includes(`${sep}node_modules${sep}`);
|
|
40
|
+
let didSomething = false;
|
|
41
|
+
if (cliIsGlobal) {
|
|
42
|
+
didSomething = true;
|
|
43
|
+
if (current === latest) {
|
|
44
|
+
console.log(`cli already on ${latest}`);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
await updateGlobalCli(cliRoot, current, latest);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
27
50
|
const manifests = findManifests(rootDir);
|
|
28
|
-
if (manifests.length
|
|
29
|
-
|
|
51
|
+
if (manifests.length > 0) {
|
|
52
|
+
didSomething = true;
|
|
53
|
+
// The app's installed version, not the CLI's — they are separate
|
|
54
|
+
// installs, and reporting one as the other is how this whole confusion
|
|
55
|
+
// started.
|
|
56
|
+
await updateApp(rootDir, manifests, appCoreVersion(rootDir), latest);
|
|
57
|
+
}
|
|
58
|
+
if (!didSomething) {
|
|
59
|
+
console.error(`no package.json in ${rootDir} depends on ${PACKAGE}, and this CLI is not a global install — run it from an app root`);
|
|
30
60
|
process.exitCode = 1;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Reinstalls the global CLI into the prefix it already lives in.
|
|
65
|
+
*
|
|
66
|
+
* That prefix matters: with a version manager, `npm install -g` installs
|
|
67
|
+
* for whichever node is *active*, which may not be the one whose bin
|
|
68
|
+
* directory holds the `tulipes` on your PATH. Deriving the prefix from the
|
|
69
|
+
* running CLI's own location updates the binary you actually type.
|
|
70
|
+
*/
|
|
71
|
+
async function updateGlobalCli(cliRoot, current, latest) {
|
|
72
|
+
console.log(`cli: ${current} → ${latest}`);
|
|
73
|
+
const prefix = globalPrefixOf(cliRoot);
|
|
74
|
+
const args = ["install", "-g", ...(prefix ? ["--prefix", prefix] : []), `${PACKAGE}@${latest}`];
|
|
75
|
+
const code = await run("npm", args, cliRoot);
|
|
76
|
+
if (code !== 0) {
|
|
77
|
+
console.error(`\ncould not update the global cli — try: npm install -g ${PACKAGE}@${latest}`);
|
|
78
|
+
process.exitCode = code === -1 ? 1 : code;
|
|
31
79
|
return;
|
|
32
80
|
}
|
|
81
|
+
console.log(`cli updated — the next \`tulipes\` invocation runs ${latest}\n`);
|
|
82
|
+
}
|
|
83
|
+
/** `<prefix>/lib/node_modules/@tulipes/core` → `<prefix>`, for npm layouts. */
|
|
84
|
+
function globalPrefixOf(cliRoot) {
|
|
85
|
+
const marker = `${sep}lib${sep}node_modules${sep}`;
|
|
86
|
+
const index = cliRoot.indexOf(marker);
|
|
87
|
+
// pnpm and bun keep globals elsewhere; without a recognisable prefix we
|
|
88
|
+
// let npm pick its own, which is right for a plain npm install.
|
|
89
|
+
return index === -1 ? undefined : cliRoot.slice(0, index);
|
|
90
|
+
}
|
|
91
|
+
async function updateApp(rootDir, manifests, current, latest) {
|
|
33
92
|
const range = `^${latest}`;
|
|
34
93
|
const changed = manifests.filter(({ path }) => rewrite(path, range));
|
|
35
94
|
if (changed.length === 0) {
|
|
36
|
-
console.log(`already on ${PACKAGE}@${range}
|
|
95
|
+
console.log(`app already on ${PACKAGE}@${range}`);
|
|
37
96
|
return;
|
|
38
97
|
}
|
|
39
98
|
for (const { path } of changed) {
|
|
40
99
|
console.log(` update ${relative(rootDir, path) || "package.json"} → ${range}`);
|
|
41
100
|
}
|
|
42
|
-
console.log(`\
|
|
43
|
-
|
|
101
|
+
console.log(`\napp: ${current ?? "not installed"} → ${latest}\n`);
|
|
102
|
+
// Rewriting manifests without installing would leave the app claiming a
|
|
103
|
+
// version it does not have.
|
|
104
|
+
const manager = detectManager(rootDir);
|
|
105
|
+
console.log(`running ${manager} install…\n`);
|
|
106
|
+
const code = await run(manager, ["install"], rootDir);
|
|
107
|
+
if (code === -1) {
|
|
108
|
+
console.error(`\ncould not run "${manager}" — manifests are updated, install manually`);
|
|
109
|
+
process.exitCode = 1;
|
|
110
|
+
}
|
|
111
|
+
else if (code !== 0) {
|
|
112
|
+
process.exitCode = code;
|
|
113
|
+
}
|
|
44
114
|
}
|
|
45
115
|
async function fetchLatest() {
|
|
46
116
|
// The scoped name has to be encoded for the registry's document route.
|
|
@@ -83,8 +153,7 @@ function dependsOnCore(path) {
|
|
|
83
153
|
}
|
|
84
154
|
/** Returns true when the file actually changed. */
|
|
85
155
|
function rewrite(path, range) {
|
|
86
|
-
const
|
|
87
|
-
const manifest = JSON.parse(raw);
|
|
156
|
+
const manifest = JSON.parse(readFileSync(path, "utf8"));
|
|
88
157
|
let touched = false;
|
|
89
158
|
for (const field of ["dependencies", "devDependencies"]) {
|
|
90
159
|
const deps = manifest[field];
|
|
@@ -98,26 +167,13 @@ function rewrite(path, range) {
|
|
|
98
167
|
writeFileSync(path, JSON.stringify(manifest, null, 2) + "\n");
|
|
99
168
|
return true;
|
|
100
169
|
}
|
|
101
|
-
/**
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const manager = detectManager(rootDir);
|
|
108
|
-
console.log(`running ${manager} install…\n`);
|
|
109
|
-
const code = await new Promise((resolve) => {
|
|
110
|
-
const child = spawn(manager, ["install"], { cwd: rootDir, stdio: "inherit" });
|
|
111
|
-
child.on("error", () => resolve(-1));
|
|
112
|
-
child.on("exit", (status) => resolve(status ?? 1));
|
|
170
|
+
/** Resolves to the exit code, or -1 when the command could not be spawned. */
|
|
171
|
+
async function run(command, args, cwd) {
|
|
172
|
+
return new Promise((resolve_) => {
|
|
173
|
+
const child = spawn(command, args, { cwd, stdio: "inherit" });
|
|
174
|
+
child.on("error", () => resolve_(-1));
|
|
175
|
+
child.on("exit", (status) => resolve_(status ?? 1));
|
|
113
176
|
});
|
|
114
|
-
if (code === -1) {
|
|
115
|
-
console.error(`\ncould not run "${manager}" — manifests are updated, install manually`);
|
|
116
|
-
process.exitCode = 1;
|
|
117
|
-
}
|
|
118
|
-
else if (code !== 0) {
|
|
119
|
-
process.exitCode = code;
|
|
120
|
-
}
|
|
121
177
|
}
|
|
122
178
|
function detectManager(rootDir) {
|
|
123
179
|
if (existsSync(join(rootDir, "yarn.lock")))
|
package/dist/cli/update.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/cli/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC/E,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/cli/update.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/templates/CLAUDE.md
CHANGED
|
@@ -63,7 +63,7 @@ queues → routes. If code needs something another module provides, declare
|
|
|
63
63
|
| `yarn check` | validate the environment without booting |
|
|
64
64
|
| `yarn typecheck` | typecheck the whole app |
|
|
65
65
|
| `yarn tulipes new module <name>` | scaffold a module |
|
|
66
|
-
| `
|
|
66
|
+
| `tulipes update` | upgrade the global cli and the framework in every manifest |
|
|
67
67
|
| `yarn script scripts/x.ts` | run a one-off script against the real app |
|
|
68
68
|
|
|
69
69
|
## Verifying your work
|