@projitect/cli-internals 1.0.0 → 1.0.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/commands/init.d.ts +2 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +27 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/pm.d.ts +8 -3
- package/dist/pm.d.ts.map +1 -1
- package/dist/pm.js +35 -31
- package/dist/pm.js.map +1 -1
- package/package.json +10 -10
- package/src/commands/init.ts +42 -2
- package/src/pm.ts +42 -10
package/dist/commands/init.d.ts
CHANGED
|
@@ -15,7 +15,8 @@ export interface InitResult {
|
|
|
15
15
|
* `.pjt.ts` with the marker structure if absent, then delegates to `remodel` which runs the
|
|
16
16
|
* standard plan/apply/lockfile-write pipeline. The projitect blueprint (prepended automatically
|
|
17
17
|
* by `@projitect/cli`'s `pjt()`) writes the package.json entries and the `.pjt.ts` import region
|
|
18
|
-
* on its first apply.
|
|
18
|
+
* on its first apply. Before seeding or loading the config, missing local CLI and Effect
|
|
19
|
+
* dependencies are installed so an ephemeral dlx invocation can resolve those imports.
|
|
19
20
|
*
|
|
20
21
|
* With `yes: true`, both prerequisites are auto-bootstrapped instead of erroring:
|
|
21
22
|
* - Missing `.git/` → `git init -q` shell-out.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA,OAAO,EAAS,MAAM,EAAkB,MAAM,QAAQ,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAGtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AASjD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAA;IACrC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;IACjC,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAA;IACzC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;CAChC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,IAAI,GAAI,QAAQ;IAC3B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,eAAe,CAAA;IAChD,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CACvB,KAAG,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,cAAc,CA2B/C,CAAA"}
|
package/dist/commands/init.js
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { promises as fs } from "node:fs";
|
|
2
2
|
import { spawn } from "node:child_process";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
3
4
|
import path from "node:path";
|
|
4
|
-
import { Effect } from "effect";
|
|
5
|
+
import { Array, Effect, Option, Schema } from "effect";
|
|
5
6
|
import { Errors } from "@projitect/core";
|
|
7
|
+
import { detect, installDev as installDevelopment, installProject } from "../pm.js";
|
|
6
8
|
import { remodel } from "./remodel.js";
|
|
9
|
+
const manifest = Schema.decodeUnknownSync(Schema.Struct({
|
|
10
|
+
version: Schema.String,
|
|
11
|
+
peerDependencies: Schema.Struct({ effect: Schema.String }),
|
|
12
|
+
}))(createRequire(import.meta.url)("../../package.json"));
|
|
7
13
|
/**
|
|
8
14
|
* `pjt init` — bootstrap projitect in the current project.
|
|
9
15
|
*
|
|
@@ -11,7 +17,8 @@ import { remodel } from "./remodel.js";
|
|
|
11
17
|
* `.pjt.ts` with the marker structure if absent, then delegates to `remodel` which runs the
|
|
12
18
|
* standard plan/apply/lockfile-write pipeline. The projitect blueprint (prepended automatically
|
|
13
19
|
* by `@projitect/cli`'s `pjt()`) writes the package.json entries and the `.pjt.ts` import region
|
|
14
|
-
* on its first apply.
|
|
20
|
+
* on its first apply. Before seeding or loading the config, missing local CLI and Effect
|
|
21
|
+
* dependencies are installed so an ephemeral dlx invocation can resolve those imports.
|
|
15
22
|
*
|
|
16
23
|
* With `yes: true`, both prerequisites are auto-bootstrapped instead of erroring:
|
|
17
24
|
* - Missing `.git/` → `git init -q` shell-out.
|
|
@@ -25,8 +32,13 @@ import { remodel } from "./remodel.js";
|
|
|
25
32
|
export const init = (params) => Effect.gen(function* () {
|
|
26
33
|
const bootstrappedGit = yield* ensureGit(params.config.projectRoot, params.yes ?? false);
|
|
27
34
|
const bootstrappedPackageJson = yield* ensurePackageJson(params.config.projectRoot, params.yes ?? false);
|
|
35
|
+
const bootstrapPm = yield* ensureBootstrapDependencies(params.config.projectRoot);
|
|
28
36
|
const seededBlueprintFile = yield* seedBlueprintFileIfAbsent(params.config.projectRoot, params.config.blueprintFile);
|
|
29
37
|
const remodelResult = yield* remodel({ config: params.config });
|
|
38
|
+
yield* Option.match(bootstrapPm, {
|
|
39
|
+
onNone: () => Effect.void,
|
|
40
|
+
onSome: (pm) => installProject({ projectRoot: params.config.projectRoot, pm }),
|
|
41
|
+
});
|
|
30
42
|
return {
|
|
31
43
|
seededBlueprintFile,
|
|
32
44
|
bootstrappedGit,
|
|
@@ -34,6 +46,19 @@ export const init = (params) => Effect.gen(function* () {
|
|
|
34
46
|
remodel: remodelResult,
|
|
35
47
|
};
|
|
36
48
|
});
|
|
49
|
+
/** A dlx runner lives outside the project; generated imports must resolve locally first. */
|
|
50
|
+
const ensureBootstrapDependencies = (projectRoot) => Effect.forEach([
|
|
51
|
+
{ name: "@projitect/cli", spec: `@projitect/cli@${manifest.version}` },
|
|
52
|
+
{ name: "effect", spec: `effect@${manifest.peerDependencies.effect}` },
|
|
53
|
+
], ({ name, spec }) => Effect.gen(function* () {
|
|
54
|
+
const installed = yield* Effect.promise(() => fs.access(path.join(projectRoot, "node_modules", name, "package.json")).then(() => true, () => false));
|
|
55
|
+
if (installed) {
|
|
56
|
+
return Option.none();
|
|
57
|
+
}
|
|
58
|
+
const pm = yield* detect({ projectRoot });
|
|
59
|
+
yield* installDevelopment({ projectRoot, pm, pkg: spec });
|
|
60
|
+
return Option.some(pm);
|
|
61
|
+
})).pipe(Effect.map((results) => Array.head(Array.getSomes(results))));
|
|
37
62
|
const ensureGit = (projectRoot, yes) => Effect.gen(function* () {
|
|
38
63
|
const ok = yield* Effect.promise(() => fs.access(path.join(projectRoot, ".git")).then(() => true, () => false));
|
|
39
64
|
if (ok) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAA;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
package/dist/pm.d.ts
CHANGED
|
@@ -3,9 +3,9 @@ import { Errors } from "@projitect/core";
|
|
|
3
3
|
import type { ProjitectPackageMetadata } from "@projitect/blueprint";
|
|
4
4
|
export type PackageManager = "pnpm" | "npm" | "yarn" | "bun";
|
|
5
5
|
/**
|
|
6
|
-
* Detect the user's package manager
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* Detect the user's package manager from known lockfiles in `projectRoot`.
|
|
7
|
+
* Without a lockfile, uses the invoking package manager's user-agent, then `npm`.
|
|
8
|
+
* Used by `pjt add` and first-run bootstrap to select the install command.
|
|
9
9
|
*/
|
|
10
10
|
export declare const detect: (params: {
|
|
11
11
|
readonly projectRoot: string;
|
|
@@ -19,6 +19,11 @@ export declare const installDev: (params: {
|
|
|
19
19
|
readonly pm: PackageManager;
|
|
20
20
|
readonly pkg: string;
|
|
21
21
|
}) => Effect.Effect<void, Errors.PmInstallFailed>;
|
|
22
|
+
/** Synchronize the lockfile after bootstrap has applied its managed manifest ranges. */
|
|
23
|
+
export declare const installProject: (params: {
|
|
24
|
+
readonly projectRoot: string;
|
|
25
|
+
readonly pm: PackageManager;
|
|
26
|
+
}) => Effect.Effect<void, Errors.PmInstallFailed>;
|
|
22
27
|
/**
|
|
23
28
|
* Read the installed package's `package.json` and return its `"projitect"` metadata, if any.
|
|
24
29
|
* Returns null if the package doesn't have the field; `pjt add` falls back to install-only
|
package/dist/pm.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pm.d.ts","sourceRoot":"","sources":["../src/pm.ts"],"names":[],"mappings":"AAGA,OAAO,EAAS,MAAM,EAA4B,MAAM,QAAQ,CAAA;AAEhE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AAEpE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAA;AAS5D;;;;GAIG;AACH,eAAO,MAAM,MAAM,GAAI,QAAQ;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B,KAAG,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,aAAa,
|
|
1
|
+
{"version":3,"file":"pm.d.ts","sourceRoot":"","sources":["../src/pm.ts"],"names":[],"mappings":"AAGA,OAAO,EAAS,MAAM,EAA4B,MAAM,QAAQ,CAAA;AAEhE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AAEpE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAA;AAS5D;;;;GAIG;AACH,eAAO,MAAM,MAAM,GAAI,QAAQ;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B,KAAG,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,aAAa,CA6BnD,CAAA;AAEH;;;GAGG;AACH,eAAO,MAAM,UAAU,GAAI,QAAQ;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,EAAE,EAAE,cAAc,CAAA;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,eAAe,CAC4B,CAAA;AAE1E,wFAAwF;AACxF,eAAO,MAAM,cAAc,GAAI,QAAQ;IACrC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,EAAE,EAAE,cAAc,CAAA;CAC5B,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,eAAe,CAK1C,CAAA;AA0CJ;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ;IAC5C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB,KAAG,MAAM,CAAC,MAAM,CAAC,wBAAwB,GAAG,IAAI,CAqC7C,CAAA"}
|
package/dist/pm.js
CHANGED
|
@@ -11,45 +11,49 @@ const LOCKFILES = [
|
|
|
11
11
|
["package-lock.json", "npm"],
|
|
12
12
|
];
|
|
13
13
|
/**
|
|
14
|
-
* Detect the user's package manager
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* Detect the user's package manager from known lockfiles in `projectRoot`.
|
|
15
|
+
* Without a lockfile, uses the invoking package manager's user-agent, then `npm`.
|
|
16
|
+
* Used by `pjt add` and first-run bootstrap to select the install command.
|
|
17
17
|
*/
|
|
18
18
|
export const detect = (params) => Effect.map(Effect.findFirst(LOCKFILES, ([filename]) => Effect.promise(() => fs.access(path.join(params.projectRoot, filename)).then(() => true, () => false))), Option.match({
|
|
19
19
|
onSome: ([, pm]) => pm,
|
|
20
|
-
onNone: () => "npm",
|
|
20
|
+
onNone: () => Match.value(process.env["npm_config_user_agent"] ?? "").pipe(Match.when((agent) => agent.startsWith("pnpm/"), () => "pnpm"), Match.when((agent) => agent.startsWith("yarn/"), () => "yarn"), Match.when((agent) => agent.startsWith("bun/"), () => "bun"), Match.orElse(() => "npm")),
|
|
21
21
|
}));
|
|
22
22
|
/**
|
|
23
23
|
* Run `<pm> add -D <pkg>` in `projectRoot`. Wraps spawn failures (non-zero exit, PM not
|
|
24
24
|
* installed) as `pjt.pm.install-failed`.
|
|
25
25
|
*/
|
|
26
|
-
export const installDev = (params) => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
26
|
+
export const installDev = (params) => runInstallation({ ...params, args: installArgs(params.pm, params.pkg) });
|
|
27
|
+
/** Synchronize the lockfile after bootstrap has applied its managed manifest ranges. */
|
|
28
|
+
export const installProject = (params) => runInstallation({
|
|
29
|
+
...params,
|
|
30
|
+
pkg: "project dependencies",
|
|
31
|
+
args: params.pm === "pnpm" ? ["install", "--no-frozen-lockfile"] : ["install"],
|
|
32
|
+
});
|
|
33
|
+
const runInstallation = (params) => Effect.tryPromise({
|
|
34
|
+
try: () => new Promise((resolve, reject) => {
|
|
35
|
+
const child = spawn(params.pm, params.args, {
|
|
36
|
+
cwd: params.projectRoot,
|
|
37
|
+
stdio: "inherit",
|
|
38
|
+
});
|
|
39
|
+
child.on("error", reject);
|
|
40
|
+
child.on("close", (code) => {
|
|
41
|
+
if (code === 0) {
|
|
42
|
+
resolve();
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
reject(new Error(`${params.pm} ${params.args.join(" ")} exited with ${String(code)}`));
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}),
|
|
49
|
+
catch: (e) => new Errors.PmInstallFailed({
|
|
50
|
+
id: "pjt.pm.install-failed",
|
|
51
|
+
packageManager: params.pm,
|
|
52
|
+
pkg: params.pkg,
|
|
53
|
+
cause: e instanceof Error ? e.message : String(e),
|
|
54
|
+
message: `Failed to install \`${params.pkg}\` via ${params.pm}`,
|
|
55
|
+
}),
|
|
56
|
+
});
|
|
53
57
|
const installArgs = (pm, pkg) => Match.value(pm).pipe(Match.whenOr("pnpm", "yarn", () => ["add", "-D", pkg]), Match.when("bun", () => ["add", "-d", pkg]), Match.when("npm", () => ["install", "-D", pkg]), Match.exhaustive);
|
|
54
58
|
/**
|
|
55
59
|
* Read the installed package's `package.json` and return its `"projitect"` metadata, if any.
|
package/dist/pm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pm.js","sourceRoot":"","sources":["../src/pm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAA;AACxC,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAChE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAKxC,MAAM,SAAS,GAAmD;IAChE,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAC1B,CAAC,WAAW,EAAE,KAAK,CAAC;IACpB,CAAC,WAAW,EAAE,MAAM,CAAC;IACrB,CAAC,mBAAmB,EAAE,KAAK,CAAC;CAC7B,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAEtB,EAAuD,EAAE,CACxD,MAAM,CAAC,GAAG,CACR,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,CACzC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAClB,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CACrD,GAAG,EAAE,CAAC,IAAI,EACV,GAAG,EAAE,CAAC,KAAK,CACZ,CACF,CACF,EACD,MAAM,CAAC,KAAK,CAAC;IACX,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE;IACtB,MAAM,EAAE,GAAmB,EAAE,CAAC,KAAK;
|
|
1
|
+
{"version":3,"file":"pm.js","sourceRoot":"","sources":["../src/pm.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@projitect/cli-internals",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Engine for the projitect CLI — loader, planner, differ, applier, and command dispatchers.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -31,18 +31,18 @@
|
|
|
31
31
|
"@types/node": "22.19.19",
|
|
32
32
|
"effect": "4.0.0-rc.111",
|
|
33
33
|
"typescript": "5.9.3",
|
|
34
|
-
"@projitect/blueprint": "1.0.
|
|
35
|
-
"@projitect/blueprint-gitignore": "1.0.
|
|
36
|
-
"@projitect/blueprint-markdown": "1.0.
|
|
37
|
-
"@projitect/blueprint-next": "1.0.
|
|
38
|
-
"@projitect/blueprint-react": "1.0.
|
|
39
|
-
"@projitect/core": "1.0.
|
|
40
|
-
"@projitect/test-kit": "1.0.
|
|
34
|
+
"@projitect/blueprint": "1.0.1",
|
|
35
|
+
"@projitect/blueprint-gitignore": "1.0.1",
|
|
36
|
+
"@projitect/blueprint-markdown": "1.0.1",
|
|
37
|
+
"@projitect/blueprint-next": "1.0.1",
|
|
38
|
+
"@projitect/blueprint-react": "1.0.1",
|
|
39
|
+
"@projitect/core": "1.0.1",
|
|
40
|
+
"@projitect/test-kit": "1.0.1"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"effect": "4.0.0-rc.111",
|
|
44
|
-
"@projitect/blueprint": "1.0.
|
|
45
|
-
"@projitect/core": "1.0.
|
|
44
|
+
"@projitect/blueprint": "1.0.1",
|
|
45
|
+
"@projitect/core": "1.0.1"
|
|
46
46
|
},
|
|
47
47
|
"engines": {
|
|
48
48
|
"node": ">=22.12.0"
|
package/src/commands/init.ts
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import { promises as fs } from "node:fs"
|
|
2
2
|
import { spawn } from "node:child_process"
|
|
3
|
+
import { createRequire } from "node:module"
|
|
3
4
|
import path from "node:path"
|
|
4
|
-
import { Effect } from "effect"
|
|
5
|
+
import { Array, Effect, Option, Schema } from "effect"
|
|
5
6
|
import { Errors } from "@projitect/core"
|
|
6
7
|
import type { ProjitectConfig } from "@projitect/core"
|
|
8
|
+
import { detect, installDev as installDevelopment, installProject } from "../pm.js"
|
|
7
9
|
import { remodel } from "./remodel.js"
|
|
8
10
|
import type { RemodelResult } from "./remodel.js"
|
|
9
11
|
|
|
12
|
+
const manifest = Schema.decodeUnknownSync(
|
|
13
|
+
Schema.Struct({
|
|
14
|
+
version: Schema.String,
|
|
15
|
+
peerDependencies: Schema.Struct({ effect: Schema.String }),
|
|
16
|
+
}),
|
|
17
|
+
)(createRequire(import.meta.url)("../../package.json"))
|
|
18
|
+
|
|
10
19
|
export interface InitResult {
|
|
11
20
|
readonly seededBlueprintFile: boolean
|
|
12
21
|
readonly bootstrappedGit: boolean
|
|
@@ -21,7 +30,8 @@ export interface InitResult {
|
|
|
21
30
|
* `.pjt.ts` with the marker structure if absent, then delegates to `remodel` which runs the
|
|
22
31
|
* standard plan/apply/lockfile-write pipeline. The projitect blueprint (prepended automatically
|
|
23
32
|
* by `@projitect/cli`'s `pjt()`) writes the package.json entries and the `.pjt.ts` import region
|
|
24
|
-
* on its first apply.
|
|
33
|
+
* on its first apply. Before seeding or loading the config, missing local CLI and Effect
|
|
34
|
+
* dependencies are installed so an ephemeral dlx invocation can resolve those imports.
|
|
25
35
|
*
|
|
26
36
|
* With `yes: true`, both prerequisites are auto-bootstrapped instead of erroring:
|
|
27
37
|
* - Missing `.git/` → `git init -q` shell-out.
|
|
@@ -43,12 +53,18 @@ export const init = (params: {
|
|
|
43
53
|
params.yes ?? false,
|
|
44
54
|
)
|
|
45
55
|
|
|
56
|
+
const bootstrapPm = yield* ensureBootstrapDependencies(params.config.projectRoot)
|
|
57
|
+
|
|
46
58
|
const seededBlueprintFile = yield* seedBlueprintFileIfAbsent(
|
|
47
59
|
params.config.projectRoot,
|
|
48
60
|
params.config.blueprintFile,
|
|
49
61
|
)
|
|
50
62
|
|
|
51
63
|
const remodelResult = yield* remodel({ config: params.config })
|
|
64
|
+
yield* Option.match(bootstrapPm, {
|
|
65
|
+
onNone: () => Effect.void,
|
|
66
|
+
onSome: (pm) => installProject({ projectRoot: params.config.projectRoot, pm }),
|
|
67
|
+
})
|
|
52
68
|
|
|
53
69
|
return {
|
|
54
70
|
seededBlueprintFile,
|
|
@@ -58,6 +74,30 @@ export const init = (params: {
|
|
|
58
74
|
}
|
|
59
75
|
})
|
|
60
76
|
|
|
77
|
+
/** A dlx runner lives outside the project; generated imports must resolve locally first. */
|
|
78
|
+
const ensureBootstrapDependencies = (projectRoot: string) =>
|
|
79
|
+
Effect.forEach(
|
|
80
|
+
[
|
|
81
|
+
{ name: "@projitect/cli", spec: `@projitect/cli@${manifest.version}` },
|
|
82
|
+
{ name: "effect", spec: `effect@${manifest.peerDependencies.effect}` },
|
|
83
|
+
],
|
|
84
|
+
({ name, spec }) =>
|
|
85
|
+
Effect.gen(function* () {
|
|
86
|
+
const installed = yield* Effect.promise(() =>
|
|
87
|
+
fs.access(path.join(projectRoot, "node_modules", name, "package.json")).then(
|
|
88
|
+
() => true,
|
|
89
|
+
() => false,
|
|
90
|
+
),
|
|
91
|
+
)
|
|
92
|
+
if (installed) {
|
|
93
|
+
return Option.none()
|
|
94
|
+
}
|
|
95
|
+
const pm = yield* detect({ projectRoot })
|
|
96
|
+
yield* installDevelopment({ projectRoot, pm, pkg: spec })
|
|
97
|
+
return Option.some(pm)
|
|
98
|
+
}),
|
|
99
|
+
).pipe(Effect.map((results) => Array.head(Array.getSomes(results))))
|
|
100
|
+
|
|
61
101
|
const ensureGit = (
|
|
62
102
|
projectRoot: string,
|
|
63
103
|
yes: boolean,
|
package/src/pm.ts
CHANGED
|
@@ -16,9 +16,9 @@ const LOCKFILES: readonly (readonly [string, PackageManager])[] = [
|
|
|
16
16
|
]
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* Detect the user's package manager
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* Detect the user's package manager from known lockfiles in `projectRoot`.
|
|
20
|
+
* Without a lockfile, uses the invoking package manager's user-agent, then `npm`.
|
|
21
|
+
* Used by `pjt add` and first-run bootstrap to select the install command.
|
|
22
22
|
*/
|
|
23
23
|
export const detect = (params: {
|
|
24
24
|
readonly projectRoot: string
|
|
@@ -34,7 +34,22 @@ export const detect = (params: {
|
|
|
34
34
|
),
|
|
35
35
|
Option.match({
|
|
36
36
|
onSome: ([, pm]) => pm,
|
|
37
|
-
onNone: (): PackageManager =>
|
|
37
|
+
onNone: (): PackageManager =>
|
|
38
|
+
Match.value(process.env["npm_config_user_agent"] ?? "").pipe(
|
|
39
|
+
Match.when(
|
|
40
|
+
(agent) => agent.startsWith("pnpm/"),
|
|
41
|
+
() => "pnpm" as const,
|
|
42
|
+
),
|
|
43
|
+
Match.when(
|
|
44
|
+
(agent) => agent.startsWith("yarn/"),
|
|
45
|
+
() => "yarn" as const,
|
|
46
|
+
),
|
|
47
|
+
Match.when(
|
|
48
|
+
(agent) => agent.startsWith("bun/"),
|
|
49
|
+
() => "bun" as const,
|
|
50
|
+
),
|
|
51
|
+
Match.orElse(() => "npm" as const),
|
|
52
|
+
),
|
|
38
53
|
}),
|
|
39
54
|
)
|
|
40
55
|
|
|
@@ -46,12 +61,30 @@ export const installDev = (params: {
|
|
|
46
61
|
readonly projectRoot: string
|
|
47
62
|
readonly pm: PackageManager
|
|
48
63
|
readonly pkg: string
|
|
49
|
-
}): Effect.Effect<void, Errors.PmInstallFailed> =>
|
|
50
|
-
|
|
51
|
-
|
|
64
|
+
}): Effect.Effect<void, Errors.PmInstallFailed> =>
|
|
65
|
+
runInstallation({ ...params, args: installArgs(params.pm, params.pkg) })
|
|
66
|
+
|
|
67
|
+
/** Synchronize the lockfile after bootstrap has applied its managed manifest ranges. */
|
|
68
|
+
export const installProject = (params: {
|
|
69
|
+
readonly projectRoot: string
|
|
70
|
+
readonly pm: PackageManager
|
|
71
|
+
}): Effect.Effect<void, Errors.PmInstallFailed> =>
|
|
72
|
+
runInstallation({
|
|
73
|
+
...params,
|
|
74
|
+
pkg: "project dependencies",
|
|
75
|
+
args: params.pm === "pnpm" ? ["install", "--no-frozen-lockfile"] : ["install"],
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
const runInstallation = (params: {
|
|
79
|
+
readonly projectRoot: string
|
|
80
|
+
readonly pm: PackageManager
|
|
81
|
+
readonly pkg: string
|
|
82
|
+
readonly args: readonly string[]
|
|
83
|
+
}): Effect.Effect<void, Errors.PmInstallFailed> =>
|
|
84
|
+
Effect.tryPromise({
|
|
52
85
|
try: () =>
|
|
53
86
|
new Promise<void>((resolve, reject) => {
|
|
54
|
-
const child = spawn(params.pm, args, {
|
|
87
|
+
const child = spawn(params.pm, params.args, {
|
|
55
88
|
cwd: params.projectRoot,
|
|
56
89
|
stdio: "inherit",
|
|
57
90
|
})
|
|
@@ -60,7 +93,7 @@ export const installDev = (params: {
|
|
|
60
93
|
if (code === 0) {
|
|
61
94
|
resolve()
|
|
62
95
|
} else {
|
|
63
|
-
reject(new Error(`${params.pm} ${args.join(" ")} exited with ${String(code)}`))
|
|
96
|
+
reject(new Error(`${params.pm} ${params.args.join(" ")} exited with ${String(code)}`))
|
|
64
97
|
}
|
|
65
98
|
})
|
|
66
99
|
}),
|
|
@@ -73,7 +106,6 @@ export const installDev = (params: {
|
|
|
73
106
|
message: `Failed to install \`${params.pkg}\` via ${params.pm}`,
|
|
74
107
|
}),
|
|
75
108
|
})
|
|
76
|
-
}
|
|
77
109
|
|
|
78
110
|
const installArgs = (pm: PackageManager, pkg: string): readonly string[] =>
|
|
79
111
|
Match.value(pm).pipe(
|