@prisma/composer-cli 0.30.0 → 0.31.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.
Files changed (34) hide show
  1. package/dist/container-transport-HcvNOGZL-CIoZc7Rs.mjs +34 -0
  2. package/dist/container-transport-HcvNOGZL-CIoZc7Rs.mjs.map +1 -0
  3. package/dist/{dev-CqS1W82b-BF0YJc6a.mjs → dev-current-Bm7Yrsmt-TadtLg5x.mjs} +24 -5
  4. package/dist/dev-current-Bm7Yrsmt-TadtLg5x.mjs.map +1 -0
  5. package/dist/dist-j4X7U5yA.mjs +1788 -0
  6. package/dist/dist-j4X7U5yA.mjs.map +1 -0
  7. package/dist/{execute-deploy-destroy-D4UdieU1-C1P6X7uK.mjs → execute-deploy-destroy-BK4R2qCX-DU6ITsO0.mjs} +5 -4
  8. package/dist/execute-deploy-destroy-BK4R2qCX-DU6ITsO0.mjs.map +1 -0
  9. package/dist/execute-dev-current-nYH8EiKK-BcP2HhlW.mjs +126 -0
  10. package/dist/execute-dev-current-nYH8EiKK-BcP2HhlW.mjs.map +1 -0
  11. package/dist/{execute-dev-BSPnsEv--SNELmzE_.mjs → execute-dev-qKlYePGn-B3UnMfa5.mjs} +50 -65
  12. package/dist/execute-dev-qKlYePGn-B3UnMfa5.mjs.map +1 -0
  13. package/dist/{family-Dt7BgpVf-YyjGLli3.d.mts → family-BIyR33Uq-BEqJM2Vx.d.mts} +131 -29
  14. package/dist/family-BIyR33Uq-BEqJM2Vx.d.mts.map +1 -0
  15. package/dist/family.d.mts +47 -3
  16. package/dist/family.d.mts.map +1 -1
  17. package/dist/family.mjs +210 -9
  18. package/dist/family.mjs.map +1 -1
  19. package/dist/local-target-DZ6bu7Aj.mjs +48 -0
  20. package/dist/local-target-DZ6bu7Aj.mjs.map +1 -0
  21. package/dist/{container-transport-HcvNOGZL-ClGmzBIO.mjs → pipeline-Dpesfd2j-DKL3f1bj.mjs} +17 -39
  22. package/dist/pipeline-Dpesfd2j-DKL3f1bj.mjs.map +1 -0
  23. package/dist/testing.d.mts +7 -1
  24. package/dist/testing.d.mts.map +1 -1
  25. package/dist/testing.mjs +23 -2
  26. package/dist/testing.mjs.map +1 -1
  27. package/package.json +9 -5
  28. package/src/exports/family.ts +29 -0
  29. package/src/family/emulator-list.ts +112 -0
  30. package/dist/container-transport-HcvNOGZL-ClGmzBIO.mjs.map +0 -1
  31. package/dist/dev-CqS1W82b-BF0YJc6a.mjs.map +0 -1
  32. package/dist/execute-deploy-destroy-D4UdieU1-C1P6X7uK.mjs.map +0 -1
  33. package/dist/execute-dev-BSPnsEv--SNELmzE_.mjs.map +0 -1
  34. package/dist/family-Dt7BgpVf-YyjGLli3.d.mts.map +0 -1
@@ -158,7 +158,27 @@ declare namespace StandardSchemaV1 {
158
158
  type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;
159
159
  }
160
160
  //#endregion
161
- //#region ../../0-framework/1-core/core/dist/graph-types-BTTaRnih.d.mts
161
+ //#region ../../0-framework/1-core/core/dist/graph-types-Cegbwb_X.d.mts
162
+ //#region src/contract.d.ts
163
+ /**
164
+ * A Contract is the declared interface of a service-to-service dependency: a
165
+ * protocol brand (`kind`) plus an opaque comparison type (`Cmp`) the core
166
+ * never inspects. Wiring compatibility is plain TypeScript assignability on
167
+ * `Cmp`, checked at `ModuleBuilder.provision`'s call site (node.ts); `satisfies`
168
+ * is its runtime mirror, called at Load (graph.ts). Correctness comes from
169
+ * the kind's builder shaping `Cmp` so assignability means the right thing —
170
+ * see @prisma/composer/service-rpc's `contract()`/`rpc()`.
171
+ */
172
+ interface Contract<Kind extends string, Cmp> {
173
+ readonly kind: Kind;
174
+ readonly __cmp: Cmp;
175
+ /** How calls over this contract communicate, if it declares a style. Core only carries it onto the graph's ports. */
176
+ readonly style?: ContractStyle;
177
+ satisfies(required: Contract<Kind, unknown>): boolean;
178
+ }
179
+ /** How calls over a contract communicate. A style, not a kind. */
180
+ type ContractStyle = 'request-response' | 'stream';
181
+ //#endregion
162
182
  //#region src/config.d.ts
163
183
  /**
164
184
  * A declared config param — pure data: a caller-owned Standard Schema
@@ -206,22 +226,6 @@ interface Config {
206
226
  readonly inputs: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
207
227
  }
208
228
  //#endregion
209
- //#region src/contract.d.ts
210
- /**
211
- * A Contract is the declared interface of a service-to-service dependency: a
212
- * protocol brand (`kind`) plus an opaque comparison type (`Cmp`) the core
213
- * never inspects. Wiring compatibility is plain TypeScript assignability on
214
- * `Cmp`, checked at `ModuleBuilder.provision`'s call site (node.ts); `satisfies`
215
- * is its runtime mirror, called at Load (graph.ts). Correctness comes from
216
- * the kind's builder shaping `Cmp` so assignability means the right thing —
217
- * see @prisma/composer/service-rpc's `contract()`/`rpc()`.
218
- */
219
- interface Contract<Kind extends string, Cmp> {
220
- readonly kind: Kind;
221
- readonly __cmp: Cmp;
222
- satisfies(required: Contract<Kind, unknown>): boolean;
223
- }
224
- //#endregion
225
229
  //#region src/node.d.ts
226
230
  declare const NODE: unique symbol;
227
231
  declare const SECRET_NEED: unique symbol;
@@ -335,7 +339,7 @@ interface ServiceNode<D extends Deps = Deps, P extends Params = Params, E extend
335
339
  /**
336
340
  * A service's dependency slot. At Load the enclosing module wires a
337
341
  * producer's ref into it; at run it hydrates a client via Connection. `Req`
338
- * is the required contract (`unknown` for an untyped end like `http()`).
342
+ * is the required contract (`unknown` for an untyped end).
339
343
  */
340
344
  interface DependencyEnd<C = unknown, Req = unknown> {
341
345
  readonly [NODE]: true;
@@ -344,7 +348,7 @@ interface DependencyEnd<C = unknown, Req = unknown> {
344
348
  readonly name: string;
345
349
  readonly type: string;
346
350
  readonly connection: Connection<Params, C>;
347
- /** The required contract, or `undefined` for an untyped end (e.g. `http()`). */
351
+ /** The required contract, or `undefined` for an untyped end. */
348
352
  readonly required: Req | undefined;
349
353
  }
350
354
  /** A Module: the same Deps/Expose boundary a service has, around transparent wiring instead of a black-box body — its `body` runs at Load, not at authoring. */
@@ -516,9 +520,11 @@ interface PortEndpoint {
516
520
  * input/expose entry, or a resource's one anonymous output (`$out`).
517
521
  * `contractKind` is the protocol brand riding the port — a DependencyEnd's
518
522
  * `type` on an `in` port, the exposed Contract's `kind` on an `out` port.
523
+ * `style` is the exposed Contract's declared style; `in` ports carry none.
519
524
  */
520
525
  interface BoundaryPort extends PortEndpoint {
521
526
  readonly contractKind: string | undefined;
527
+ readonly style: ContractStyle | undefined;
522
528
  }
523
529
  /**
524
530
  * A pre-dereference edge, exactly as authored: module boundaries are
@@ -589,7 +595,7 @@ interface Graph {
589
595
  readonly params: readonly ParamBinding[];
590
596
  }
591
597
  //#endregion
592
- //#region ../../0-framework/1-core/core/dist/app-config-BqBRS3nH.d.mts
598
+ //#region ../../0-framework/1-core/core/dist/app-config-BBPLNnZX.d.mts
593
599
  //#region src/container-transport.d.ts
594
600
  /**
595
601
  * Carries resolved containers from the CLI process into the alchemy process
@@ -1074,6 +1080,56 @@ interface LocalTargetDescriptor {
1074
1080
  attach(input: LocalTargetAttachInput): Promise<LocalTargetAttachment>;
1075
1081
  /** `--fresh`: remove every local trace of the dev instance — emulator instances, state, data. */
1076
1082
  teardown?(input: TeardownInput): Promise<void>;
1083
+ /**
1084
+ * The app `prisma dev` last ran from a directory, read from its dev state
1085
+ * directory alone — no entry, no graph, no container — so a command can
1086
+ * find or stop a running app without running the pipeline. Undefined when
1087
+ * this extension recorded nothing there.
1088
+ */
1089
+ current?(input: LocalTargetCurrentInput): Promise<LocalTargetCurrentApp | undefined>;
1090
+ }
1091
+ interface LocalTargetCurrentInput {
1092
+ /** Absolute path of the dev state directory (`<cwd>/.prisma-composer/dev`). */
1093
+ readonly devDir: string;
1094
+ }
1095
+ /** The app `prisma dev` last ran from a directory, as one extension recorded it. */
1096
+ interface LocalTargetCurrentApp {
1097
+ readonly app: string;
1098
+ /** Every node address recorded for the app. */
1099
+ readonly addresses: readonly string[];
1100
+ /** Where the node at `address` runs locally; undefined for an address not recorded. */
1101
+ locate(address: string): Promise<LocalNodeLocation | undefined>;
1102
+ /** Stops everything the target runs for the app (emulators and data persist); returns the nodes it stopped. */
1103
+ stop(): Promise<readonly LocalNodeStopped[]>;
1104
+ }
1105
+ /** A node's local whereabouts. `kind` is the target's word for the node (for Prisma Cloud: `service`, `database` or `bucket`). */
1106
+ type LocalNodeLocation = {
1107
+ readonly address: string;
1108
+ readonly kind: string;
1109
+ readonly emulator: 'running';
1110
+ /** Absent when the emulator no longer has the node's instance. */
1111
+ readonly url?: string;
1112
+ /** The target's word for the node's state, shown to the user. */
1113
+ readonly state: string;
1114
+ readonly condition: LocalNodeCondition;
1115
+ /** Where the node's own output is written, when the target keeps it in a file. */
1116
+ readonly logPath?: string;
1117
+ } | {
1118
+ readonly address: string;
1119
+ readonly kind: string;
1120
+ /** The emulator that runs the node is not running, so it has no URL or state to report. */
1121
+ readonly emulator: 'not-running';
1122
+ };
1123
+ /**
1124
+ * What a node's state means for reaching it: `running` answers at its URL;
1125
+ * `stopped` was stopped and starts with the next `prisma dev`; `crashing`
1126
+ * exited and is being restarted or was held after repeated crashes;
1127
+ * `missing` is recorded but its emulator no longer has it.
1128
+ */
1129
+ type LocalNodeCondition = 'running' | 'stopped' | 'crashing' | 'missing';
1130
+ interface LocalNodeStopped {
1131
+ readonly address: string;
1132
+ readonly kind: string;
1077
1133
  }
1078
1134
  interface LocalTargetProvidersInput {
1079
1135
  /** This extension's resolved local-target container (its `input.appName` is the emulator app namespace). */
@@ -1107,8 +1163,8 @@ interface LocalTargetAttachment {
1107
1163
  readonly service: string;
1108
1164
  readonly line: string;
1109
1165
  }>;
1110
- /** Stop the app's service instances (emulators and data persist). */
1111
- stopServices(): Promise<void>;
1166
+ /** Stop everything the target runs for the app, so nothing of it keeps running after the session (emulators and data persist). */
1167
+ stopApp(): Promise<void>;
1112
1168
  }
1113
1169
  /**
1114
1170
  * What one registry entry can do. The `kind` discriminant is checked at every
@@ -1186,7 +1242,7 @@ type AssembleReport = (data: Readonly<Record<string, string | number>>) => void;
1186
1242
  /** Assembles one service node — the seam tests substitute to avoid a real build. */
1187
1243
  type RunAssembler = (node: ServiceNode, address: string, cwd: string, report?: AssembleReport) => Promise<Bundle>;
1188
1244
  //#endregion
1189
- //#region ../../0-framework/3-tooling/cli/dist/dev-BoBrmouf.d.mts
1245
+ //#region ../../0-framework/3-tooling/cli/dist/dev-current-ChYXqIRT.d.mts
1190
1246
  //#region src/composer-config.d.ts
1191
1247
  /** Composer's configuration and the `prisma.config.ts` that declares it. */
1192
1248
  interface ComposerConfigSource {
@@ -1414,6 +1470,12 @@ interface DevInput {
1414
1470
  readonly entry: string;
1415
1471
  readonly name?: string | undefined;
1416
1472
  readonly fresh?: boolean | undefined;
1473
+ /**
1474
+ * Return once every service answers and leave the app running, with no
1475
+ * watch loop: the session is already closed and stopping it stops nothing.
1476
+ * `devStop` stops the app later.
1477
+ */
1478
+ readonly detach?: boolean | undefined;
1417
1479
  readonly cwd?: string | undefined;
1418
1480
  readonly onEvent?: ((event: DevEvent) => void) | undefined;
1419
1481
  }
@@ -1424,9 +1486,9 @@ interface DevSession {
1424
1486
  /** The initial front door, already merged across attachments. */
1425
1487
  readonly endpoints: readonly ServiceEndpoint[];
1426
1488
  /** Stop the watch loop and the app's services (emulators and data stay up).
1427
- * Idempotent; emits 'stopping'/'stopped'; resolves `closed`. */
1489
+ * Idempotent; emits 'stopping'/'stopped'; resolves `closed`. A no-op for a detached session. */
1428
1490
  stop(): Promise<void>;
1429
- /** Settles when the session has fully stopped (via stop()). */
1491
+ /** Settles when the session has fully stopped (via stop()); already settled for a detached session. */
1430
1492
  readonly closed: Promise<void>;
1431
1493
  }
1432
1494
  /** In-package variant threading the injection seam, which the family's
@@ -1434,7 +1496,44 @@ interface DevSession {
1434
1496
  * internal types and is not part of the published surface. */
1435
1497
  declare function devWithDeps(input: DevInput, deps: OperationDeps): Promise<Result$1<DevSession, CliStructuredError>>;
1436
1498
  //#endregion
1437
- //#region ../../0-framework/3-tooling/cli/dist/family-Dt7BgpVf.d.mts
1499
+ //#region src/operations/dev-current.d.ts
1500
+ interface DevUrlInput {
1501
+ /** Composer's configuration: the `composer` section of `prisma.config.ts` and that file. It names the extensions whose local targets recorded the app. */
1502
+ readonly config: ComposerConfigSource;
1503
+ /** A node's dotted address in the app, such as `gateway` or `catalog.database`. */
1504
+ readonly address: string;
1505
+ /** The directory `prisma dev` ran from. Defaults to the process's working directory. */
1506
+ readonly cwd?: string | undefined;
1507
+ }
1508
+ interface DevUrl {
1509
+ readonly address: string;
1510
+ /** What the node is, in its target's words; Prisma Cloud's are `service`, `database` and `bucket`. */
1511
+ readonly kind: string;
1512
+ /** A service's URL, a database's connection string, or a bucket's S3 endpoint plus `/<bucket>`. */
1513
+ readonly url: string;
1514
+ /** Always `running`: a node that is not running is a failure. */
1515
+ readonly state: string;
1516
+ }
1517
+ interface DevStopInput {
1518
+ readonly config: ComposerConfigSource;
1519
+ /** The directory `prisma dev` ran from. Defaults to the process's working directory. */
1520
+ readonly cwd?: string | undefined;
1521
+ }
1522
+ interface DevStopped {
1523
+ /** The app that was stopped: the one `prisma dev` last ran from the directory. */
1524
+ readonly app: string;
1525
+ /** Each node whose process or server was stopped. Data and ports are kept. */
1526
+ readonly stopped: readonly {
1527
+ readonly address: string;
1528
+ readonly kind: string;
1529
+ }[];
1530
+ }
1531
+ /** Where the node at `input.address` of the directory's current app runs locally. */
1532
+ declare function devUrl(input: DevUrlInput): Promise<Result$1<DevUrl, CliStructuredError>>;
1533
+ /** Stops the directory's current app: its service processes and database servers. Data and ports stay. */
1534
+ declare function devStop(input: DevStopInput): Promise<Result$1<DevStopped, CliStructuredError>>;
1535
+ //#endregion
1536
+ //#region ../../0-framework/3-tooling/cli/dist/family-BIyR33Uq.d.mts
1438
1537
  //#region src/family/family.d.ts
1439
1538
  /**
1440
1539
  * The control-plane operations the family's handlers call. These are the
@@ -1447,13 +1546,16 @@ declare function devWithDeps(input: DevInput, deps: OperationDeps): Promise<Resu
1447
1546
  interface ComposerOperations {
1448
1547
  readonly deploy: typeof deployWithDeps;
1449
1548
  readonly dev: typeof devWithDeps;
1549
+ readonly devUrl: typeof devUrl;
1550
+ readonly devStop: typeof devStop;
1450
1551
  }
1451
1552
  declare const realOperations: ComposerOperations;
1452
1553
  interface CreateComposerFamilyOptions {
1453
1554
  /** Defaults to the real control operations. */
1454
1555
  readonly operations?: ComposerOperations | undefined;
1556
+ /** More commands to ship in the family, keyed by the path they are meant to mount at. */
1557
+ readonly commands?: CommandFamily['commands'] | undefined;
1455
1558
  }
1456
- declare function createComposerFamily(options?: CreateComposerFamilyOptions): CommandFamily;
1457
1559
  //#endregion
1458
- export { ComposerConfigSource as a, DeploySuccess as c, OperationDeps as d, ServiceEndpoint as f, CliStructuredError as h, realOperations as i, DevInput as l, Result$1 as m, CreateComposerFamilyOptions as n, DeployEvent as o, AssembledServices as p, createComposerFamily as r, DeployInput as s, ComposerOperations as t, DevSession as u };
1459
- //# sourceMappingURL=family-Dt7BgpVf-YyjGLli3.d.mts.map
1560
+ export { Result$1 as _, DeployEvent as a, DevInput as c, DevStopped as d, DevUrl as f, AssembledServices as g, ServiceEndpoint as h, ComposerConfigSource as i, DevSession as l, OperationDeps as m, CreateComposerFamilyOptions as n, DeployInput as o, DevUrlInput as p, realOperations as r, DeploySuccess as s, ComposerOperations as t, DevStopInput as u, CliStructuredError as v };
1561
+ //# sourceMappingURL=family-BIyR33Uq-BEqJM2Vx.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"family-BIyR33Uq-BEqJM2Vx.d.mts","names":[],"sources":["../../../0-framework/0-foundation/foundation/dist/errors.d.mts","../../../../node_modules/@standard-schema/spec/dist/index.d.ts","../../../0-framework/1-core/core/dist/graph-types-Cegbwb_X.d.mts","../../../0-framework/1-core/core/dist/app-config-BBPLNnZX.d.mts","../../../0-framework/3-tooling/cli/dist/deployment-summary-CU-eVvJM.d.mts","../../../0-framework/0-foundation/foundation/dist/result.d.mts","../../../0-framework/3-tooling/assemble/dist/index.d.mts","../../../0-framework/3-tooling/cli/dist/dev-current-ChYXqIRT.d.mts","../../../0-framework/3-tooling/cli/dist/family-BIyR33Uq.d.mts"],"x_google_ignoreList":[1],"mappings":"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"}
package/dist/family.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as ComposerConfigSource, h as CliStructuredError$1, i as realOperations, n as CreateComposerFamilyOptions, r as createComposerFamily, t as ComposerOperations } from "./family-Dt7BgpVf-YyjGLli3.mjs";
2
- import { ConfigSection } from "@prisma/cli-engine";
1
+ import { _ as Result, i as ComposerConfigSource, n as CreateComposerFamilyOptions$1, r as realOperations, t as ComposerOperations, v as CliStructuredError$1 } from "./family-BIyR33Uq-BEqJM2Vx.mjs";
2
+ import { CommandFamily, ConfigSection } from "@prisma/cli-engine";
3
3
  import { CliStructuredError } from "@prisma/cli-engine/protocol";
4
4
  //#region ../../0-framework/3-tooling/cli/dist/family.d.mts
5
5
  //#region src/family/section.d.ts
@@ -15,5 +15,49 @@ type ComposerError = CliStructuredError$1;
15
15
  /** Translates a composer failure into the engine's error type. Composer-side detail — `meta`, `where`, `docsUrl` — rides along untouched. */
16
16
  declare function toEngineError(error: ComposerError): CliStructuredError;
17
17
  //#endregion
18
- export { type ComposerOperations, type CreateComposerFamilyOptions, composerSection, createComposerFamily, realOperations, toEngineError };
18
+ //#region ../../1-prisma-cloud/0-lowering/dev-emulators/dist/index.d.mts
19
+ //#endregion
20
+ //#region src/emulator-list.d.ts
21
+ /** What an emulator's instances are. */
22
+ type EmulatorKind = 'service' | 'database' | 'bucket';
23
+ interface EmulatorInstance {
24
+ readonly id: string;
25
+ readonly kind: EmulatorKind;
26
+ /** A service's URL, a database's connection string, or a bucket's S3 endpoint plus `/<id>`. */
27
+ readonly url: string;
28
+ /** A service's status, a database's `running` or `stopped`, or `running` for a bucket. */
29
+ readonly state: string;
30
+ readonly labels: Readonly<Record<string, string>>;
31
+ }
32
+ /** Why a running emulator could not be listed: it did not answer, or it answered with an error. */
33
+ interface EmulatorListingError {
34
+ readonly code: string;
35
+ readonly message: string;
36
+ }
37
+ interface EmulatorListing {
38
+ readonly kind: EmulatorKind;
39
+ readonly running: boolean;
40
+ /** The emulator's admin URL; null when it is not running. */
41
+ readonly url: string | null;
42
+ /** Empty when the emulator is not running or could not be listed. */
43
+ readonly instances: readonly EmulatorInstance[];
44
+ /** Null unless the emulator runs but could not be listed. */
45
+ readonly error: EmulatorListingError | null;
46
+ }
47
+ interface EmulatorList {
48
+ readonly emulators: readonly EmulatorListing[];
49
+ }
50
+ //#endregion
51
+ //#region src/family/emulator-list.d.ts
52
+ type ListEmulators = () => Promise<Result<EmulatorList, CliStructuredError$1>>;
53
+ //#endregion
54
+ //#region src/exports/family.d.ts
55
+ interface CreateComposerFamilyOptions extends CreateComposerFamilyOptions$1 {
56
+ /** Defaults to the real listing of this machine's emulators. */
57
+ readonly listEmulators?: ListEmulators | undefined;
58
+ }
59
+ /** Composer's command family: `deploy`, `dev`, `dev url`, `dev stop` and `emulator list`, keyed by the path each is meant to mount at. */
60
+ declare function createComposerFamily(options?: CreateComposerFamilyOptions): CommandFamily;
61
+ //#endregion
62
+ export { type ComposerOperations, CreateComposerFamilyOptions, type ListEmulators, composerSection, createComposerFamily, realOperations, toEngineError };
19
63
  //# sourceMappingURL=family.d.mts.map
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"family.d.mts","names":[],"sources":["../../../0-framework/3-tooling/cli/dist/family.d.mts","../../../1-prisma-cloud/0-lowering/dev-emulators/dist/index.d.mts","../src/family/emulator-list.ts","../src/exports/family.ts"],"mappings":";;;;;cAKc,iBAAiB,cAAc;;;;;;;;KAQxC,gBAAA;;iBAEY,cAAc,OAAO,gBAAgB;;;;;;KC4JjD;UAEK;WACC;WACA,MAAM;;WAEN;;WAEA;WACA,QAAQ,SAAS;;;UAGlB;WACC;WACA;;UAED;WACC,MAAM;WACN;;WAEA;;WAEA,oBAAoB;;WAEpB,OAAO;;UAER;WACC,oBAAoB;;;;KCxLnB,sBAAsB,QAAQ,OAAO,cAAc;;;UCc9C,oCAAoC;;WAE1C,gBAAgB;;;iBAIX,qBAAqB,UAAS,8BAAmC"}
package/dist/family.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as alchemyCommandLine, i as sectionMissing, t as checkComposerConfig } from "./composer-config-CY9fET8H-CgnpfWc2.mjs";
2
- import { n as devWithDeps, r as executionDiagnostics, t as deployWithDeps } from "./dev-CqS1W82b-BF0YJc6a.mjs";
2
+ import { a as executionDiagnostics, i as devWithDeps, n as devStop, r as devUrl, t as deployWithDeps } from "./dev-current-Bm7Yrsmt-TadtLg5x.mjs";
3
3
  import { defineCommand, defineCommandFamily, defineConfigSection, defineSessionCommand, exitWithChildStatus, flag, positional } from "@prisma/cli-engine";
4
4
  import { CliStructuredError, notOk, ok } from "@prisma/cli-engine/protocol";
5
5
  //#region ../../0-framework/3-tooling/cli/dist/family.mjs
@@ -446,11 +446,28 @@ Generated stack file: ${event.stackFilePath}\nRun \`${event.reproduceCommand}\`
446
446
  }
447
447
  };
448
448
  }
449
+ /** A detached session owns nothing to stop, so a Ctrl-C before it was ready stops the app the way `prisma dev stop` does. */
450
+ async function stopDetachedApp(operations, ctx) {
451
+ const stopped = await operations.devStop({
452
+ config: ctx.config,
453
+ cwd: ctx.cwd
454
+ });
455
+ if (stopped.ok) return;
456
+ ctx.report({
457
+ kind: "message",
458
+ severity: "warn",
459
+ text: `The app could not be stopped: ${stopped.failure.message} Run \`prisma dev stop\`.`
460
+ });
461
+ }
449
462
  const createDevCommand = (operations) => defineSessionCommand({
450
463
  help: {
451
464
  summary: "Bring up the application whose root node is <entry>'s default export, entirely on this machine.",
452
- description: "Runs credential-free and watches the app for changes, reconverging on every edit.",
453
- examples: ["{bin} dev module.ts", "{bin} dev module.ts --fresh"]
465
+ description: "Runs credential-free and watches the app for changes, reconverging on every edit. A node is one service, database or bucket in the app. Each node runs on a local emulator: a program on this machine that stands in for Prisma Cloud and runs services, databases or S3-compatible buckets. A node's address is its name in the app, with dots for a nested node (catalog.database). The app and where each node runs are recorded in this directory: `prisma dev url` works from here while `prisma dev` runs, and `prisma dev stop` also works after `prisma dev` was killed. Ending `prisma dev` stops its services and database servers; data and ports are kept. With --detach it returns once every service answers and leaves the app running without watching for changes, until `prisma dev stop`.",
466
+ examples: [
467
+ "{bin} dev module.ts",
468
+ "{bin} dev module.ts --fresh",
469
+ "{bin} dev module.ts --detach"
470
+ ]
454
471
  },
455
472
  args: {
456
473
  positionals: { entry: positional.string({
@@ -462,7 +479,8 @@ const createDevCommand = (operations) => defineSessionCommand({
462
479
  brief: "Override the root node's name — the dev instance's application name.",
463
480
  placeholder: "name"
464
481
  }),
465
- fresh: flag.boolean({ brief: "Destroy the dev stack and wipe the dev state directory before starting." })
482
+ fresh: flag.boolean({ brief: "Destroy the dev stack and wipe the dev state directory before starting." }),
483
+ detach: flag.boolean({ brief: "Return once every service answers and leave the app running without watching for changes. Use it in scripts, agents and CI. `prisma dev stop` stops the app." })
466
484
  }
467
485
  },
468
486
  needs: { config: composerSection },
@@ -474,16 +492,93 @@ const createDevCommand = (operations) => defineSessionCommand({
474
492
  config: ctx.config,
475
493
  name: args.flags.name,
476
494
  fresh: args.flags.fresh,
495
+ detach: args.flags.detach,
477
496
  cwd: ctx.cwd,
478
497
  onEvent: reportDevEvent(ctx.report, ctx.lastChild)
479
498
  }, { alchemy: coalescedConverge(alchemy) });
480
499
  if (!result.ok) return settleConvergeFailure(result.failure, ctx);
500
+ if (args.flags.detach) {
501
+ if (ctx.signal.aborted) await stopDetachedApp(operations, ctx);
502
+ return ok(void 0);
503
+ }
481
504
  await stopRequested(ctx.signal);
482
505
  await result.value.stop();
483
506
  return ok(void 0);
484
507
  }
485
508
  });
486
509
  /**
510
+ * `dev stop` — stops the app `prisma dev` last ran from this directory, as
511
+ * ending `prisma dev` would: its service processes and database servers.
512
+ * For an app whose `prisma dev` was killed without the chance to stop it.
513
+ */
514
+ const createDevStopCommand = (operations) => defineCommand({
515
+ help: {
516
+ summary: "Stop the app `prisma dev` last ran from this directory: its service processes and local database servers. Data and ports are kept for the next `prisma dev`.",
517
+ description: "Ending `prisma dev` with Ctrl-C does the same. Run this when `prisma dev` was killed without a chance to stop the app, or before deleting the directory. The emulators keep running; other directories may be using them.",
518
+ examples: ["{bin} dev stop"]
519
+ },
520
+ args: {},
521
+ needs: { config: composerSection },
522
+ handler: async (_args, ctx) => {
523
+ const result = await operations.devStop({
524
+ config: ctx.config,
525
+ cwd: ctx.cwd
526
+ });
527
+ if (!result.ok) return notOk(toEngineError(result.failure));
528
+ const { app, stopped } = result.value;
529
+ return ok(ctx.present({ data: result.value }, {
530
+ human: (ui) => [{
531
+ kind: "summary",
532
+ status: "ok",
533
+ text: `Stopped ${ui.emphasize(app)}. Its data and ports are kept for the next \`prisma dev\`.`
534
+ }, ...stopped.length === 0 ? [] : [{
535
+ kind: "table",
536
+ columns: ["Address", "Kind"],
537
+ rows: stopped.map(({ address, kind }) => [address, kind])
538
+ }]],
539
+ stdout: () => [],
540
+ json: () => result.value,
541
+ next: () => []
542
+ }));
543
+ }
544
+ });
545
+ /**
546
+ * `dev url <address>` — where a node of the app `prisma dev` runs from this
547
+ * directory answers locally. A data command: the URL is its stdout line, so
548
+ * `$(prisma dev url gateway)` is the URL alone.
549
+ */
550
+ const createDevUrlCommand = (operations) => defineCommand({
551
+ help: {
552
+ summary: "Print the local URL of a node (a service, database or bucket in your app) that `prisma dev` runs from this directory: a service's HTTP URL, a database's connection string, or a bucket's S3 address.",
553
+ description: "Reads what the last `prisma dev` in this directory recorded and starts nothing, so run it while `prisma dev` is running; a node that is not running is an error. The URL alone goes to stdout, so a script can use it directly: curl \"$(prisma dev url gateway)\". With --json, stdout carries the full result instead.",
554
+ examples: ["{bin} dev url gateway", "{bin} dev url catalog.database --json"]
555
+ },
556
+ args: { positionals: { address: positional.string({
557
+ brief: "The node's address: its name in the app, with dots for a nested node, such as catalog.database.",
558
+ placeholder: "address"
559
+ }) } },
560
+ needs: { config: composerSection },
561
+ handler: async (args, ctx) => {
562
+ const result = await operations.devUrl({
563
+ config: ctx.config,
564
+ address: args.positionals.address,
565
+ cwd: ctx.cwd
566
+ });
567
+ if (!result.ok) return notOk(toEngineError(result.failure));
568
+ const node = result.value;
569
+ return ok(ctx.present({ data: node }, {
570
+ human: (ui) => [{
571
+ kind: "summary",
572
+ status: "ok",
573
+ text: `The ${node.kind} ${ui.emphasize(node.address)} is ${node.state} at ${node.url}`
574
+ }],
575
+ stdout: () => [node.url],
576
+ json: () => node,
577
+ next: () => []
578
+ }));
579
+ }
580
+ });
581
+ /**
487
582
  * Composer's `CommandFamily`: the unit the `prisma` bin mounts.
488
583
  *
489
584
  * This module and everything it reaches statically must stay free of alchemy
@@ -500,27 +595,133 @@ const createDevCommand = (operations) => defineSessionCommand({
500
595
  * mount this family against the test double and exercise real grammar, real
501
596
  * arg validation and real handlers with no alchemy behind them.
502
597
  *
503
- * The family ships `deploy` and `dev` only. `destroy` and `log` are
504
- * programmatic operations in `@prisma/composer/control`, not commands.
598
+ * The family ships `deploy`, `dev`, `dev url` and `dev stop`, keyed by the
599
+ * path they are meant to mount at; the host decides where each one mounts.
600
+ * A host may add commands of its own through `commands` — the published
601
+ * family adds `emulator list`, which needs no project. `destroy` and `log`
602
+ * are programmatic operations in `@prisma/composer/control`, not commands.
505
603
  */
506
604
  const realOperations = {
507
605
  deploy: deployWithDeps,
508
- dev: devWithDeps
606
+ dev: devWithDeps,
607
+ devUrl,
608
+ devStop
509
609
  };
510
610
  /** The `prisma` CLI's error reference; the engine appends `/<CODE>` to it for every error envelope. */
511
611
  const CLI_DOCS_BASE = "https://www.prisma.io/docs/cli/error-reference/";
512
- function createComposerFamily(options = {}) {
612
+ function createComposerFamily$1(options = {}) {
513
613
  const operations = options.operations ?? realOperations;
514
614
  return defineCommandFamily({
515
615
  configSection: composerSection,
516
616
  commands: {
517
617
  deploy: createDeployCommand(operations),
518
- dev: createDevCommand(operations)
618
+ dev: createDevCommand(operations),
619
+ "dev url": createDevUrlCommand(operations),
620
+ "dev stop": createDevStopCommand(operations),
621
+ ...options.commands
519
622
  },
520
623
  docsBaseUrl: CLI_DOCS_BASE
521
624
  });
522
625
  }
523
626
  //#endregion
627
+ //#region src/family/emulator-list.ts
628
+ /**
629
+ * `emulator list` — every local emulator on this machine and every
630
+ * instance it holds. It needs no project and no config. The listing comes
631
+ * from the Prisma Cloud domain, so the command is assembled into the
632
+ * family here, where both domains may be imported.
633
+ */
634
+ /** Loaded on first use, so nothing of the emulators' clients loads with the family. */
635
+ const listEmulators = async () => (await import("./dist-j4X7U5yA.mjs")).listEmulators();
636
+ const EMULATOR_NAMES = {
637
+ service: "Service emulator",
638
+ database: "Database emulator",
639
+ bucket: "Bucket emulator"
640
+ };
641
+ /** The node and directory that started an instance, when Composer's labels say. */
642
+ function startedBy(labels) {
643
+ const address = labels["composer.address"];
644
+ const directory = labels["composer.directory"];
645
+ if (address === void 0) return void 0;
646
+ return directory === void 0 ? address : `${address} in ${directory}`;
647
+ }
648
+ function labelOf(emulator, dim) {
649
+ const name = EMULATOR_NAMES[emulator.kind];
650
+ if (!emulator.running || emulator.url === null) return `${name} ${dim("(not running)")}`;
651
+ if (emulator.error !== null) return `${name} at ${emulator.url}: could not list its instances (${emulator.error.code}: ${emulator.error.message})`;
652
+ return `${name} at ${emulator.url}`;
653
+ }
654
+ function statusOf(emulator) {
655
+ if (emulator.error !== null) return "error";
656
+ return emulator.running ? "ok" : "info";
657
+ }
658
+ const createEmulatorListCommand = (list) => defineCommand({
659
+ help: {
660
+ summary: "List the local emulators on this machine — the programs `prisma dev` starts to run services, databases and S3-compatible buckets without Prisma Cloud — with every instance each one holds.",
661
+ description: "Needs no project: it shows every directory’s instances. An emulator that is not running is listed with no instances, and one that runs but cannot be listed is shown with the error. Each instance’s labels say which directory, app and node started it. A stopped instance keeps its port and data until it is deleted.",
662
+ examples: ["{bin} emulator list", "{bin} emulator list --json"]
663
+ },
664
+ args: {},
665
+ handler: async (_args, ctx) => {
666
+ const result = await list();
667
+ if (!result.ok) return notOk(toEngineError(result.failure));
668
+ const { emulators } = result.value;
669
+ return ok(ctx.present({ data: result.value }, {
670
+ human: (ui) => [{
671
+ kind: "tree",
672
+ roots: emulators.map((emulator) => ({
673
+ label: labelOf(emulator, ui.dim),
674
+ status: statusOf(emulator),
675
+ children: emulator.instances.map((instance) => {
676
+ const by = startedBy(instance.labels);
677
+ return { label: [
678
+ instance.id,
679
+ instance.url,
680
+ instance.state,
681
+ ...by ? [ui.dim(by)] : []
682
+ ].join(" ") };
683
+ })
684
+ }))
685
+ }],
686
+ stdout: () => emulators.flatMap((emulator) => emulator.instances.map((instance) => [
687
+ emulator.kind,
688
+ instance.id,
689
+ instance.url,
690
+ instance.state,
691
+ instance.labels["composer.address"] ?? "",
692
+ instance.labels["composer.directory"] ?? ""
693
+ ].join(" "))),
694
+ json: () => result.value,
695
+ next: () => []
696
+ }));
697
+ }
698
+ });
699
+ //#endregion
700
+ //#region src/exports/family.ts
701
+ /**
702
+ * Public surface (the `./family` subpath): composer's engine `CommandFamily`,
703
+ * for hosts that mount composer's commands into their own CLI — the `prisma`
704
+ * bin does exactly this.
705
+ *
706
+ * Kept apart from `@prisma/composer`'s `./control` on purpose. `./control` is
707
+ * the programmatic deploy pipeline; this is the command surface: grammar, help
708
+ * and arg validation belong to the engine, and the handlers behind them are
709
+ * the same operations `./control` exposes.
710
+ *
711
+ * Its static graph is alchemy-free and effect-free, so importing it costs a
712
+ * host nothing until a composer command actually runs.
713
+ */
714
+ /** Composer's command family: `deploy`, `dev`, `dev url`, `dev stop` and `emulator list`, keyed by the path each is meant to mount at. */
715
+ function createComposerFamily(options = {}) {
716
+ return createComposerFamily$1({
717
+ ...options,
718
+ commands: {
719
+ "emulator list": createEmulatorListCommand(options.listEmulators ?? listEmulators),
720
+ ...options.commands
721
+ }
722
+ });
723
+ }
724
+ //#endregion
524
725
  export { composerSection, createComposerFamily, realOperations, toEngineError };
525
726
 
526
727
  //# sourceMappingURL=family.mjs.map