@prisma/composer-cli 0.25.0-dev.5 → 0.26.0-dev.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/{result-D9vIrN7i.mjs → composer-config-CY9fET8H-KpGjlYgO.mjs} +89 -89
- package/dist/composer-config-CY9fET8H-KpGjlYgO.mjs.map +1 -0
- package/dist/{pipeline-DAYhea3J-uuBciVDS.mjs → container-transport-HcvNOGZL-CHqecFc7.mjs} +83 -71
- package/dist/container-transport-HcvNOGZL-CHqecFc7.mjs.map +1 -0
- package/dist/{execute-deploy-destroy-CF6DR7sA-jdelm-y5.mjs → execute-deploy-destroy-c0eko3AO-9npuGXd3.mjs} +70 -73
- package/dist/execute-deploy-destroy-c0eko3AO-9npuGXd3.mjs.map +1 -0
- package/dist/{execute-dev-DAIUT0es-DTdnJdOi.mjs → execute-dev-BICPaq1g-CSoZJuhB.mjs} +70 -9
- package/dist/execute-dev-BICPaq1g-CSoZJuhB.mjs.map +1 -0
- package/dist/{family-DB2Uf88c-DWEm0USb.d.mts → family-CgeZQdNg-gH8LuqqL.d.mts} +46 -140
- package/dist/family-CgeZQdNg-gH8LuqqL.d.mts.map +1 -0
- package/dist/family.d.mts +3 -28
- package/dist/family.d.mts.map +1 -1
- package/dist/family.mjs +12 -461
- package/dist/family.mjs.map +1 -1
- package/dist/{generate-dev-stack-CPpjJdTG-W0N0YgsI.mjs → generate-dev-stack-BUadNY_w-DF_lHVaP.mjs} +4 -4
- package/dist/{generate-dev-stack-CPpjJdTG-W0N0YgsI.mjs.map → generate-dev-stack-BUadNY_w-DF_lHVaP.mjs.map} +1 -1
- package/dist/run-alchemy-BEvB2sYQ-BgV2deuO.mjs +154 -0
- package/dist/run-alchemy-BEvB2sYQ-BgV2deuO.mjs.map +1 -0
- package/dist/testing.d.mts +10 -24
- package/dist/testing.d.mts.map +1 -1
- package/dist/testing.mjs +17 -46
- package/dist/testing.mjs.map +1 -1
- package/package.json +5 -8
- package/src/exports/testing.ts +2 -2
- package/dist/bin.mjs +0 -987
- package/dist/bin.mjs.map +0 -1
- package/dist/container-transport-HcvNOGZL-CIoZc7Rs.mjs +0 -34
- package/dist/container-transport-HcvNOGZL-CIoZc7Rs.mjs.map +0 -1
- package/dist/execute-deploy-destroy-CF6DR7sA-DGs5poBA.mjs +0 -556
- package/dist/execute-deploy-destroy-CF6DR7sA-DGs5poBA.mjs.map +0 -1
- package/dist/execute-deploy-destroy-CF6DR7sA-jdelm-y5.mjs.map +0 -1
- package/dist/execute-dev-DAIUT0es-CVW9TfgX.mjs +0 -2060
- package/dist/execute-dev-DAIUT0es-CVW9TfgX.mjs.map +0 -1
- package/dist/execute-dev-DAIUT0es-DTdnJdOi.mjs.map +0 -1
- package/dist/execute-log-PLs9-Qn3-BUBx5KmY.mjs +0 -155
- package/dist/execute-log-PLs9-Qn3-BUBx5KmY.mjs.map +0 -1
- package/dist/execute-log-PLs9-Qn3-D8DRuvDr.mjs +0 -154
- package/dist/execute-log-PLs9-Qn3-D8DRuvDr.mjs.map +0 -1
- package/dist/family-DB2Uf88c-DWEm0USb.d.mts.map +0 -1
- package/dist/local-target-B9cBl_6r.mjs +0 -68
- package/dist/local-target-B9cBl_6r.mjs.map +0 -1
- package/dist/local-target-P4-n1Ovh.mjs +0 -68
- package/dist/local-target-P4-n1Ovh.mjs.map +0 -1
- package/dist/pipeline-DAYhea3J-BEnHHWp8.mjs +0 -979
- package/dist/pipeline-DAYhea3J-BEnHHWp8.mjs.map +0 -1
- package/dist/pipeline-DAYhea3J-uuBciVDS.mjs.map +0 -1
- package/dist/result-D9vIrN7i.mjs.map +0 -1
- package/dist/result-SF9LFOuR.mjs +0 -461
- package/dist/result-SF9LFOuR.mjs.map +0 -1
- package/dist/run-alchemy-pANK8XNX-CqXC1tbs.mjs +0 -99
- package/dist/run-alchemy-pANK8XNX-CqXC1tbs.mjs.map +0 -1
- package/dist/run-alchemy-pANK8XNX-T_pHNDBo.mjs +0 -99
- package/dist/run-alchemy-pANK8XNX-T_pHNDBo.mjs.map +0 -1
- package/dist/shared-BAIiDgXa-DYP7EOSk.mjs +0 -33
- package/dist/shared-BAIiDgXa-DYP7EOSk.mjs.map +0 -1
package/dist/family.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"family.d.mts","names":[],"sources":["../../../0-framework/3-tooling/cli/dist/family.d.mts"],"mappings":";;;;;cAKc
|
|
1
|
+
{"version":3,"file":"family.d.mts","names":[],"sources":["../../../0-framework/3-tooling/cli/dist/family.d.mts"],"mappings":";;;;;cAKc,iBAAiB,cAAc;;;;;;;;KAQxC,gBAAA;;iBAEY,cAAc,OAAO,gBAAgB"}
|
package/dist/family.mjs
CHANGED
|
@@ -1,64 +1,8 @@
|
|
|
1
|
-
import { i as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import spawn from "cross-spawn";
|
|
5
|
-
import { EnvironmentCredentialManager, createCli, defineCommand, defineCommandFamily, defineConfigSection, defineSessionCommand, exitWithChildStatus, flag, loadConfig, positional } from "@prisma/cli-engine";
|
|
1
|
+
import { i as sectionMissing, t as checkComposerConfig } from "./composer-config-CY9fET8H-KpGjlYgO.mjs";
|
|
2
|
+
import { a as devWithDeps, i as deployWithDeps, o as executionDiagnostics, t as alchemyCommandLine } from "./run-alchemy-BEvB2sYQ-BgV2deuO.mjs";
|
|
3
|
+
import { defineCommand, defineCommandFamily, defineConfigSection, defineSessionCommand, exitWithChildStatus, flag, positional } from "@prisma/cli-engine";
|
|
6
4
|
import { CliStructuredError, notOk, ok } from "@prisma/cli-engine/protocol";
|
|
7
|
-
//#region ../../0-framework/3-tooling/cli/dist/
|
|
8
|
-
/** In-package variant threading the injection seam (the CLI's RunDeps, unit
|
|
9
|
-
* tests). Deliberately NOT re-exported through `./control` — the seam mirrors
|
|
10
|
-
* internal types and is not part of the published surface. */
|
|
11
|
-
async function deployWithDeps(input, deps) {
|
|
12
|
-
const cwd = input.cwd ?? process.cwd();
|
|
13
|
-
let executor;
|
|
14
|
-
try {
|
|
15
|
-
executor = await import("./execute-deploy-destroy-CF6DR7sA-DGs5poBA.mjs");
|
|
16
|
-
} catch (error) {
|
|
17
|
-
return notOk$1(executorLoadFailure("deploy", error));
|
|
18
|
-
}
|
|
19
|
-
return executor.executeDeploy(input, deps, cwd);
|
|
20
|
-
}
|
|
21
|
-
/** In-package variant threading the injection seam (the CLI's RunDeps, unit
|
|
22
|
-
* tests). Deliberately NOT re-exported through `./control` — the seam mirrors
|
|
23
|
-
* internal types and is not part of the published surface. */
|
|
24
|
-
async function destroyWithDeps(input, deps) {
|
|
25
|
-
const cwd = input.cwd ?? process.cwd();
|
|
26
|
-
let executor;
|
|
27
|
-
try {
|
|
28
|
-
executor = await import("./execute-deploy-destroy-CF6DR7sA-DGs5poBA.mjs");
|
|
29
|
-
} catch (error) {
|
|
30
|
-
return notOk$1(executorLoadFailure("destroy", error));
|
|
31
|
-
}
|
|
32
|
-
return executor.executeDestroy(input, deps, cwd);
|
|
33
|
-
}
|
|
34
|
-
/** In-package variant threading the injection seam (the CLI's RunDeps, unit
|
|
35
|
-
* tests). Deliberately NOT re-exported through `./control` — the seam mirrors
|
|
36
|
-
* internal types and is not part of the published surface. */
|
|
37
|
-
async function devWithDeps(input, deps) {
|
|
38
|
-
const cwd = input.cwd ?? process.cwd();
|
|
39
|
-
let executor;
|
|
40
|
-
try {
|
|
41
|
-
executor = await import("./execute-dev-DAIUT0es-DTdnJdOi.mjs");
|
|
42
|
-
} catch (error) {
|
|
43
|
-
return notOk$1(executorLoadFailure("dev", error));
|
|
44
|
-
}
|
|
45
|
-
return executor.executeDev(input, deps, cwd);
|
|
46
|
-
}
|
|
47
|
-
/** In-package variant threading the injection seam (the CLI's LogRunDeps,
|
|
48
|
-
* unit tests). Deliberately NOT re-exported through `./control` — the seam
|
|
49
|
-
* mirrors internal types and is not part of the published surface. */
|
|
50
|
-
async function logWithDeps(input, deps) {
|
|
51
|
-
const cwd = input.cwd ?? process.cwd();
|
|
52
|
-
let executor;
|
|
53
|
-
try {
|
|
54
|
-
executor = await import("./execute-log-PLs9-Qn3-BUBx5KmY.mjs");
|
|
55
|
-
} catch (error) {
|
|
56
|
-
return notOk$1(executorLoadFailure("log", error));
|
|
57
|
-
}
|
|
58
|
-
return executor.executeLog(input, deps, cwd);
|
|
59
|
-
}
|
|
60
|
-
//#endregion
|
|
61
|
-
//#region ../../0-framework/3-tooling/cli/dist/engine-cli-Cxpb67l7.mjs
|
|
5
|
+
//#region ../../0-framework/3-tooling/cli/dist/family.mjs
|
|
62
6
|
/**
|
|
63
7
|
* The family boundary's error translation.
|
|
64
8
|
*
|
|
@@ -141,7 +85,7 @@ function reproduceHint(failure) {
|
|
|
141
85
|
}];
|
|
142
86
|
}
|
|
143
87
|
/**
|
|
144
|
-
* How a FAILED converge settles. `deploy
|
|
88
|
+
* How a FAILED converge settles. `deploy` and `dev` both end this
|
|
145
89
|
* way and must not drift apart, so the decision lives here once rather than
|
|
146
90
|
* inline in each handler.
|
|
147
91
|
*
|
|
@@ -221,23 +165,6 @@ const composerSection = defineConfigSection({
|
|
|
221
165
|
merge: (_parent, child) => child
|
|
222
166
|
});
|
|
223
167
|
/**
|
|
224
|
-
* `destroy`'s target, from its two mutually exclusive flags. Kept out of the
|
|
225
|
-
* grammar because the engine's flag layer has no "exactly one of these"
|
|
226
|
-
* construct — and because both wrong shapes need their own remedy, which a
|
|
227
|
-
* generic arity error could not give.
|
|
228
|
-
*/
|
|
229
|
-
function targetOf(stage, production) {
|
|
230
|
-
if (stage !== void 0 && production) return notOk(new CliStructuredError("DEPLOY.TARGET_CONFLICT", "Pass either --stage <name> or --production to `destroy`, not both."));
|
|
231
|
-
if (stage === void 0 && !production) return notOk(new CliStructuredError("DEPLOY.TARGET_MISSING", "`destroy` requires an explicit target.", { nextActions: [{
|
|
232
|
-
kind: "user-choice",
|
|
233
|
-
label: "Pass --stage <name> to tear down a branch environment, or --production to tear down the production environment."
|
|
234
|
-
}] }));
|
|
235
|
-
return ok(stage !== void 0 ? {
|
|
236
|
-
kind: "stage",
|
|
237
|
-
stage
|
|
238
|
-
} : { kind: "production" });
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
168
|
* The workspace the in-process leg acts in, from the engine's credential
|
|
242
169
|
* read. Handlers never decode a token and never read PRISMA_WORKSPACE_ID:
|
|
243
170
|
* whether the credential came from a stored session or the environment, the
|
|
@@ -252,156 +179,6 @@ async function workspaceIdOf(ctx) {
|
|
|
252
179
|
return (await ctx.activeCredential())?.workspaceId;
|
|
253
180
|
}
|
|
254
181
|
/**
|
|
255
|
-
* `destroy <entry>` — deploy's mirror: same derivation, alchemy destroy.
|
|
256
|
-
*
|
|
257
|
-
* No confirmation prompt, matching the CLI this replaces. The front door
|
|
258
|
-
* cannot know what the child will tear down, so a consent step here would be
|
|
259
|
-
* asking the user to approve a list nobody has computed yet; if destroy
|
|
260
|
-
* deserves one it belongs in composer's own operation, not in the grammar.
|
|
261
|
-
*/
|
|
262
|
-
const createDestroyCommand = (operations) => defineCommand({
|
|
263
|
-
help: {
|
|
264
|
-
summary: "Tear down the application whose root node is <entry>'s default export.",
|
|
265
|
-
description: "Same derivation as deploy. Requires an explicit target: --stage <name> for a branch environment, or --production for the production environment.",
|
|
266
|
-
examples: ["{bin} destroy module.ts --stage feat-auth", "{bin} destroy module.ts --production"]
|
|
267
|
-
},
|
|
268
|
-
args: {
|
|
269
|
-
positionals: { entry: positional.string({
|
|
270
|
-
brief: "The file whose default export is the application root module, built with module(...).",
|
|
271
|
-
placeholder: "entry"
|
|
272
|
-
}) },
|
|
273
|
-
flags: {
|
|
274
|
-
name: flag.string({
|
|
275
|
-
brief: "Override the root node's name — the application name to tear down.",
|
|
276
|
-
placeholder: "name"
|
|
277
|
-
}),
|
|
278
|
-
stage: flag.string({
|
|
279
|
-
brief: "Tear down this branch environment.",
|
|
280
|
-
placeholder: "stage"
|
|
281
|
-
}),
|
|
282
|
-
production: flag.boolean({ brief: "Tear down the project-level production environment." })
|
|
283
|
-
}
|
|
284
|
-
},
|
|
285
|
-
needs: {
|
|
286
|
-
config: composerSection,
|
|
287
|
-
credentials: "child"
|
|
288
|
-
},
|
|
289
|
-
maySpawn: true,
|
|
290
|
-
handler: async (args, ctx) => {
|
|
291
|
-
const target = targetOf(args.flags.stage, args.flags.production);
|
|
292
|
-
if (!target.ok) return target;
|
|
293
|
-
const alchemy = convergeSpawn(ctx);
|
|
294
|
-
return settleConverge(await operations.destroy({
|
|
295
|
-
entry: args.positionals.entry,
|
|
296
|
-
config: ctx.config,
|
|
297
|
-
name: args.flags.name,
|
|
298
|
-
target: target.value,
|
|
299
|
-
cwd: ctx.cwd,
|
|
300
|
-
onEvent: (event) => {
|
|
301
|
-
if (event.kind !== "no-local-deploy-state") return;
|
|
302
|
-
ctx.report({
|
|
303
|
-
kind: "message",
|
|
304
|
-
severity: "warn",
|
|
305
|
-
text: `No prior deploy state under ${event.cwd} — if you deployed from a different directory, run destroy from there; otherwise this is a no-op.`
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
}, operationDeps({
|
|
309
|
-
alchemy,
|
|
310
|
-
workspaceId: await workspaceIdOf(ctx),
|
|
311
|
-
client: ctx.api
|
|
312
|
-
})), ctx, () => ctx.present({ data: void 0 }, {
|
|
313
|
-
human: () => [{
|
|
314
|
-
kind: "summary",
|
|
315
|
-
status: "ok",
|
|
316
|
-
text: "Destroyed."
|
|
317
|
-
}],
|
|
318
|
-
stdout: () => [],
|
|
319
|
-
json: () => void 0,
|
|
320
|
-
next: () => []
|
|
321
|
-
}));
|
|
322
|
-
}
|
|
323
|
-
});
|
|
324
|
-
/**
|
|
325
|
-
* `log <entry> [address]` — a session command that tails the merged logs of
|
|
326
|
-
* the app running locally on this machine.
|
|
327
|
-
*
|
|
328
|
-
* It reads the LOCAL dev-emulator daemon, not the platform's logs surface, so
|
|
329
|
-
* it is credential-free. It hands the terminal to nothing, which is why it
|
|
330
|
-
* does not declare `maySpawn` and keeps json support: the log lines ARE its
|
|
331
|
-
* json surface.
|
|
332
|
-
*
|
|
333
|
-
* Windows is refused inside the operation itself (LOG.PLATFORM_UNSUPPORTED),
|
|
334
|
-
* which is why nothing here reads the platform.
|
|
335
|
-
*/
|
|
336
|
-
/** An empty screen reads as broken, so show a little recent history before going live. */
|
|
337
|
-
const DEFAULT_TAIL = 20;
|
|
338
|
-
const createLogCommand = (operations) => defineSessionCommand({
|
|
339
|
-
help: {
|
|
340
|
-
summary: "Tail the merged logs of the locally-running application whose root node is <entry>'s default export.",
|
|
341
|
-
examples: ["{bin} log module.ts", "{bin} log module.ts catalog.service"]
|
|
342
|
-
},
|
|
343
|
-
args: {
|
|
344
|
-
positionals: {
|
|
345
|
-
entry: positional.string({
|
|
346
|
-
brief: "The file whose default export is the application root module, built with module(...).",
|
|
347
|
-
placeholder: "entry"
|
|
348
|
-
}),
|
|
349
|
-
address: positional.optionalString({
|
|
350
|
-
brief: "Only this service's lines, by its dotted address (catalog.service); every service when absent.",
|
|
351
|
-
placeholder: "address"
|
|
352
|
-
})
|
|
353
|
-
},
|
|
354
|
-
flags: {
|
|
355
|
-
name: flag.string({
|
|
356
|
-
brief: "Override the root node's name — the dev instance's application name.",
|
|
357
|
-
placeholder: "name"
|
|
358
|
-
}),
|
|
359
|
-
tail: flag.number({
|
|
360
|
-
brief: `How many trailing history lines to show before live output (default ${String(DEFAULT_TAIL)}).`,
|
|
361
|
-
placeholder: "lines",
|
|
362
|
-
default: DEFAULT_TAIL
|
|
363
|
-
})
|
|
364
|
-
}
|
|
365
|
-
},
|
|
366
|
-
needs: { config: composerSection },
|
|
367
|
-
handler: async (args, ctx) => {
|
|
368
|
-
const reportLogEvent = (event) => {
|
|
369
|
-
ctx.report({
|
|
370
|
-
kind: "message",
|
|
371
|
-
severity: "warn",
|
|
372
|
-
text: event.kind === "stream-failed" ? `Stream failed: ${event.message}` : `Falling behind — dropped the ${String(event.count)} oldest lines.`
|
|
373
|
-
});
|
|
374
|
-
};
|
|
375
|
-
const result = await operations.log({
|
|
376
|
-
entry: args.positionals.entry,
|
|
377
|
-
config: ctx.config,
|
|
378
|
-
name: args.flags.name,
|
|
379
|
-
address: args.positionals.address,
|
|
380
|
-
tail: args.flags.tail ?? DEFAULT_TAIL,
|
|
381
|
-
cwd: ctx.cwd,
|
|
382
|
-
signal: ctx.signal,
|
|
383
|
-
onEvent: reportLogEvent
|
|
384
|
-
}, {});
|
|
385
|
-
if (!result.ok) return notOk(toEngineError(result.failure));
|
|
386
|
-
const attached = result.value;
|
|
387
|
-
if (attached.services.length === 0) {
|
|
388
|
-
ctx.report({
|
|
389
|
-
kind: "message",
|
|
390
|
-
severity: "warn",
|
|
391
|
-
text: `No running services for "${attached.appName}" — start it first with \`dev ${args.positionals.entry}\`.`
|
|
392
|
-
});
|
|
393
|
-
return ok(void 0);
|
|
394
|
-
}
|
|
395
|
-
for await (const { service, line } of attached.lines) ctx.report({
|
|
396
|
-
kind: "output",
|
|
397
|
-
source: service,
|
|
398
|
-
channel: "data",
|
|
399
|
-
line: `[${service}] ${line}`
|
|
400
|
-
});
|
|
401
|
-
return ok(void 0);
|
|
402
|
-
}
|
|
403
|
-
});
|
|
404
|
-
/**
|
|
405
182
|
* `deploy <entry>` — a result command that hands the terminal to alchemy.
|
|
406
183
|
*
|
|
407
184
|
* `--production` is gone. It was accepted and then always errored ("only
|
|
@@ -655,16 +432,14 @@ const createDevCommand = (operations) => defineSessionCommand({
|
|
|
655
432
|
}
|
|
656
433
|
});
|
|
657
434
|
/**
|
|
658
|
-
* Composer's `CommandFamily
|
|
659
|
-
* is composer's own CLI or the `prisma` bin.
|
|
435
|
+
* Composer's `CommandFamily`: the unit the `prisma` bin mounts.
|
|
660
436
|
*
|
|
661
437
|
* This module and everything it reaches statically must stay free of alchemy
|
|
662
438
|
* and of effect VALUE imports: the `prisma` bin imports the family directly,
|
|
663
439
|
* so anything in this static graph loads on `prisma --version`. The mechanism
|
|
664
440
|
* that holds it is the existing lazy boundary inside the operation modules —
|
|
665
|
-
* `operations/deploy.ts
|
|
666
|
-
*
|
|
667
|
-
* tree. Importing the operations here is therefore free; importing an
|
|
441
|
+
* `operations/deploy.ts` and `dev.ts` each `await import()` their executor,
|
|
442
|
+
* and it is the executors that reach the provider tree. Importing the operations here is therefore free; importing an
|
|
668
443
|
* executor, or flattening one of those dynamic imports, is not.
|
|
669
444
|
* scripts/check-family-static-graph.mjs enforces this against BUILT output,
|
|
670
445
|
* where type-only imports have already been erased.
|
|
@@ -673,16 +448,12 @@ const createDevCommand = (operations) => defineSessionCommand({
|
|
|
673
448
|
* mount this family against the test double and exercise real grammar, real
|
|
674
449
|
* arg validation and real handlers with no alchemy behind them.
|
|
675
450
|
*
|
|
676
|
-
* The family ships `deploy` and `dev` only
|
|
677
|
-
*
|
|
678
|
-
* — the `prisma` bin — never see them. They remain first-class commands of
|
|
679
|
-
* composer's own bin, mounted on top of the family in engine-cli.ts.
|
|
451
|
+
* The family ships `deploy` and `dev` only. `destroy` and `log` are
|
|
452
|
+
* programmatic operations in `@prisma/composer/control`, not commands.
|
|
680
453
|
*/
|
|
681
454
|
const realOperations = {
|
|
682
455
|
deploy: deployWithDeps,
|
|
683
|
-
|
|
684
|
-
dev: devWithDeps,
|
|
685
|
-
log: logWithDeps
|
|
456
|
+
dev: devWithDeps
|
|
686
457
|
};
|
|
687
458
|
/** The `prisma` CLI's error reference; the engine appends `/<CODE>` to it for every error envelope. */
|
|
688
459
|
const CLI_DOCS_BASE = "https://www.prisma.io/docs/cli/error-reference/";
|
|
@@ -697,227 +468,7 @@ function createComposerFamily(options = {}) {
|
|
|
697
468
|
docsBaseUrl: CLI_DOCS_BASE
|
|
698
469
|
});
|
|
699
470
|
}
|
|
700
|
-
/**
|
|
701
|
-
* Everything environmental the engine needs, assembled from a host process.
|
|
702
|
-
*
|
|
703
|
-
* The engine takes no globals: streams, cwd, env, TTY-ness, exit and signal
|
|
704
|
-
* subscription all arrive through `Runtime`, which is what lets a test drive a
|
|
705
|
-
* whole run without touching `process`. Composing one is the substantive part
|
|
706
|
-
* of hosting the engine — `createCli` and `Cli.run` are two calls.
|
|
707
|
-
*
|
|
708
|
-
* Credentials come from the engine's own environment-only manager, which
|
|
709
|
-
* composes a session from PRISMA_SERVICE_TOKEN / PRISMA_WORKSPACE_ID and
|
|
710
|
-
* refuses every mutation. That is the whole of composer's standalone auth
|
|
711
|
-
* story: this CLI has no login flow and mounts no auth commands, so there is
|
|
712
|
-
* nothing to store — the two variables ARE the credential.
|
|
713
|
-
*/
|
|
714
|
-
/** Where the management API lives. Matches the lowering client's default origin; the env var is the escape hatch for staging. */
|
|
715
|
-
const DEFAULT_MANAGEMENT_API_BASE_URL = "https://api.prisma.io";
|
|
716
|
-
const DEFAULT_AUTH_BASE_URL = "https://auth.prisma.io";
|
|
717
|
-
/**
|
|
718
|
-
* Starts the converge child: inherited stdio, this process's own group, no
|
|
719
|
-
* `detached` and no new console — which is what lets the terminal deliver
|
|
720
|
-
* Ctrl-C to the child natively instead of the CLI forwarding it. The engine
|
|
721
|
-
* never imports node:child_process; this adapter is the whole of the host's
|
|
722
|
-
* side of that seam.
|
|
723
|
-
*/
|
|
724
|
-
const spawnChild = (request) => {
|
|
725
|
-
const child = spawn(request.command, [...request.args], {
|
|
726
|
-
cwd: request.cwd,
|
|
727
|
-
stdio: "inherit",
|
|
728
|
-
env: request.env
|
|
729
|
-
});
|
|
730
|
-
return {
|
|
731
|
-
ended: new Promise((resolve, reject) => {
|
|
732
|
-
child.on("error", reject);
|
|
733
|
-
child.on("close", (exitCode, signal) => {
|
|
734
|
-
resolve({
|
|
735
|
-
exitCode,
|
|
736
|
-
signal
|
|
737
|
-
});
|
|
738
|
-
});
|
|
739
|
-
}),
|
|
740
|
-
kill: (signal) => {
|
|
741
|
-
child.kill(signal);
|
|
742
|
-
}
|
|
743
|
-
};
|
|
744
|
-
};
|
|
745
|
-
/**
|
|
746
|
-
* The SDK's client construction config. The engine requires all four fields
|
|
747
|
-
* whenever a credential manager is wired, but this host reaches none of the
|
|
748
|
-
* login paths: an environment credential carries no refresh token, so nothing
|
|
749
|
-
* ever refreshes and `clientId`/`redirectUri` are never read. They are
|
|
750
|
-
* env-overridable rather than hard-coded so a staging run can point the whole
|
|
751
|
-
* client somewhere else in one place.
|
|
752
|
-
*/
|
|
753
|
-
function clientConfig(env, apiBaseUrl) {
|
|
754
|
-
return {
|
|
755
|
-
clientId: env["PRISMA_CLIENT_ID"] ?? "prisma-composer-cli",
|
|
756
|
-
redirectUri: env["PRISMA_REDIRECT_URI"] ?? "http://127.0.0.1/callback",
|
|
757
|
-
apiBaseUrl,
|
|
758
|
-
authBaseUrl: env["PRISMA_AUTH_URL"] ?? DEFAULT_AUTH_BASE_URL
|
|
759
|
-
};
|
|
760
|
-
}
|
|
761
|
-
/**
|
|
762
|
-
* What this process runs on, for `ctx.host`. Bun and Deno both announce
|
|
763
|
-
* themselves in `versions`; nothing else does, so an absent marker means Node.
|
|
764
|
-
*/
|
|
765
|
-
function describeHost(host) {
|
|
766
|
-
const name = ["bun", "deno"].find((candidate) => host.versions[candidate] !== void 0) ?? "node";
|
|
767
|
-
return {
|
|
768
|
-
runtime: {
|
|
769
|
-
name,
|
|
770
|
-
version: host.versions[name] ?? host.version
|
|
771
|
-
},
|
|
772
|
-
platform: host.platform,
|
|
773
|
-
arch: host.arch
|
|
774
|
-
};
|
|
775
|
-
}
|
|
776
|
-
/**
|
|
777
|
-
* Which package manager invoked us, read from the `npm_config_user_agent`
|
|
778
|
-
* every major manager sets (`pnpm/10.27.0 npm/? node/v24.16.0 darwin arm64`).
|
|
779
|
-
* `undefined` when the CLI was run directly rather than through a manager — a
|
|
780
|
-
* normal case, not a failure, so nothing is inferred from the filesystem, and
|
|
781
|
-
* the engine falls back to its own detection from the project at cwd.
|
|
782
|
-
*/
|
|
783
|
-
function detectPackageManager(env) {
|
|
784
|
-
const agent = env["npm_config_user_agent"];
|
|
785
|
-
if (agent === void 0) return void 0;
|
|
786
|
-
const name = agent.split("/")[0];
|
|
787
|
-
switch (name) {
|
|
788
|
-
case "npm":
|
|
789
|
-
case "pnpm":
|
|
790
|
-
case "yarn":
|
|
791
|
-
case "bun":
|
|
792
|
-
case "deno": return name;
|
|
793
|
-
default: return;
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
/**
|
|
797
|
-
* The config loader arrives as a function rather than an already-loaded config
|
|
798
|
-
* because the engine reads `prisma.config.ts` on demand — only when the command
|
|
799
|
-
* it is about to run declares a config section, and with whatever file
|
|
800
|
-
* `--config` named. A host that loaded the file up front would read it for runs
|
|
801
|
-
* that never needed it, and would have nowhere to put `--config`.
|
|
802
|
-
*
|
|
803
|
-
* Nothing here answers "is this CI": the engine detects it from `env` itself,
|
|
804
|
-
* and `isCIOverride` exists only for hosts where that detection cannot be
|
|
805
|
-
* right — composer is not one.
|
|
806
|
-
*/
|
|
807
|
-
const nonEmpty = (value) => value !== void 0 && value.length > 0 ? value : void 0;
|
|
808
|
-
function createRuntime(host, loadConfig) {
|
|
809
|
-
const env = host.env;
|
|
810
|
-
const apiBaseUrl = nonEmpty(env["PRISMA_API_URL"]) ?? nonEmpty(env["PRISMA_MANAGEMENT_API_URL"]) ?? DEFAULT_MANAGEMENT_API_BASE_URL;
|
|
811
|
-
const packageManager = detectPackageManager(env);
|
|
812
|
-
return {
|
|
813
|
-
stdout: host.stdout,
|
|
814
|
-
stderr: host.stderr,
|
|
815
|
-
stdin: host.stdin,
|
|
816
|
-
cwd: host.cwd(),
|
|
817
|
-
env,
|
|
818
|
-
isTty: {
|
|
819
|
-
stdin: host.stdin.isTTY === true,
|
|
820
|
-
stdout: host.stdout.isTTY === true,
|
|
821
|
-
stderr: host.stderr.isTTY === true
|
|
822
|
-
},
|
|
823
|
-
exit: (code) => host.exit(code),
|
|
824
|
-
onSignal: (cb) => {
|
|
825
|
-
const onSigint = () => {
|
|
826
|
-
cb("SIGINT");
|
|
827
|
-
};
|
|
828
|
-
const onSigterm = () => {
|
|
829
|
-
cb("SIGTERM");
|
|
830
|
-
};
|
|
831
|
-
host.on("SIGINT", onSigint);
|
|
832
|
-
host.on("SIGTERM", onSigterm);
|
|
833
|
-
return () => {
|
|
834
|
-
host.off("SIGINT", onSigint);
|
|
835
|
-
host.off("SIGTERM", onSigterm);
|
|
836
|
-
};
|
|
837
|
-
},
|
|
838
|
-
loadConfig,
|
|
839
|
-
credentialManager: new EnvironmentCredentialManager({ env }),
|
|
840
|
-
managementApiClientConfig: clientConfig(env, apiBaseUrl),
|
|
841
|
-
spawn: spawnChild,
|
|
842
|
-
managementApi: { baseUrl: apiBaseUrl },
|
|
843
|
-
...packageManager !== void 0 && { packageManager },
|
|
844
|
-
host: describeHost(host)
|
|
845
|
-
};
|
|
846
|
-
}
|
|
847
|
-
/**
|
|
848
|
-
* Composer's own CLI, rebuilt as a thin composition of the family it
|
|
849
|
-
* publishes: `createCli` over `createComposerFamily()`, `Cli.run` with a
|
|
850
|
-
* Runtime. Grammar, help, arg validation, output framing, exit codes and
|
|
851
|
-
* signal ownership all belong to the engine now — this module contributes the
|
|
852
|
-
* family and the environment, and nothing else.
|
|
853
|
-
*
|
|
854
|
-
* Running composer's commands through the same path an external host uses is
|
|
855
|
-
* the point: it is what proves the family works standalone before the `prisma`
|
|
856
|
-
* bin mounts it.
|
|
857
|
-
*
|
|
858
|
-
* This IS composer's CLI. The clipanion shell it replaced, and the bespoke
|
|
859
|
-
* runner that shelled out to alchemy, are gone; `bin.ts` is a call into here.
|
|
860
|
-
*/
|
|
861
|
-
const BINARY_NAME = "prisma-composer";
|
|
862
|
-
/**
|
|
863
|
-
* Composer's commands mount at the top level of its own CLI (`prisma-composer
|
|
864
|
-
* deploy`). The bin mounts more than the family carries: `destroy` and `log`
|
|
865
|
-
* were retired from the family (the surface the `prisma` bin mounts, per the
|
|
866
|
-
* 2026-08-21 PM review) but stay first-class commands of `prisma-composer`
|
|
867
|
-
* itself, so their definitions are mounted here on top of the family.
|
|
868
|
-
*/
|
|
869
|
-
function mountedTree(family, operations) {
|
|
870
|
-
return {
|
|
871
|
-
...family.commands,
|
|
872
|
-
destroy: createDestroyCommand(operations),
|
|
873
|
-
log: createLogCommand(operations)
|
|
874
|
-
};
|
|
875
|
-
}
|
|
876
|
-
/**
|
|
877
|
-
* The ORM's slice of prisma.config.ts, declared so a config shared with the
|
|
878
|
-
* unified `prisma` CLI loads here: the engine rejects any top-level key no
|
|
879
|
-
* mounted family declares, and this bin does not mount the ORM family. The
|
|
880
|
-
* value passes through unvalidated — the ORM CLI owns its section's shape,
|
|
881
|
-
* and no composer command reads it.
|
|
882
|
-
*/
|
|
883
|
-
const foreignOrmSectionFamily = defineCommandFamily({
|
|
884
|
-
configSection: defineConfigSection({
|
|
885
|
-
name: "orm",
|
|
886
|
-
validate: (raw) => ({
|
|
887
|
-
ok: true,
|
|
888
|
-
value: raw,
|
|
889
|
-
diagnostics: []
|
|
890
|
-
})
|
|
891
|
-
}),
|
|
892
|
-
commands: {}
|
|
893
|
-
});
|
|
894
|
-
function createComposerCli(spec) {
|
|
895
|
-
const operations = spec.operations ?? realOperations;
|
|
896
|
-
const family = createComposerFamily({ operations });
|
|
897
|
-
return createCli({
|
|
898
|
-
name: BINARY_NAME,
|
|
899
|
-
version: spec.version,
|
|
900
|
-
commandFamilies: [family, foreignOrmSectionFamily],
|
|
901
|
-
groups: {},
|
|
902
|
-
commands: mountedTree(family, operations)
|
|
903
|
-
});
|
|
904
|
-
}
|
|
905
|
-
/**
|
|
906
|
-
* Composes the Runtime and runs one invocation. Returns the exit code rather
|
|
907
|
-
* than exiting, so the caller owns the process — a bin assigns it to
|
|
908
|
-
* `process.exitCode` and lets the streams drain, as composer's CLI has always
|
|
909
|
-
* done.
|
|
910
|
-
*
|
|
911
|
-
* `prisma.config.ts` is not read here. The loader goes in as a function, and the
|
|
912
|
-
* engine calls it only when the command it is about to run declares a config
|
|
913
|
-
* section, passing it the file `--config` named; the loader resolves that
|
|
914
|
-
* against the host's cwd.
|
|
915
|
-
*/
|
|
916
|
-
function runComposerCli(argv, host, spec, hooks) {
|
|
917
|
-
const runtime = createRuntime(host, (requestedFile) => loadConfig(host.cwd(), requestedFile));
|
|
918
|
-
return createComposerCli(spec).run(argv, runtime, hooks);
|
|
919
|
-
}
|
|
920
471
|
//#endregion
|
|
921
|
-
export {
|
|
472
|
+
export { composerSection, createComposerFamily, realOperations, toEngineError };
|
|
922
473
|
|
|
923
474
|
//# sourceMappingURL=family.mjs.map
|