@prisma/composer-prisma-cloud 0.1.0-dev.18 → 0.1.0-dev.3
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/control.d.mts +29 -6
- package/dist/control.mjs +67 -454
- package/dist/control.mjs.map +1 -1
- package/dist/cron/index.mjs +6 -14
- package/dist/cron/index.mjs.map +1 -1
- package/dist/cron/scheduler-entrypoint.mjs +21 -70
- package/dist/cron/scheduler-entrypoint.mjs.map +1 -1
- package/dist/cron/scheduler-service.mjs +6 -14
- package/dist/cron/scheduler-service.mjs.map +1 -1
- package/dist/index.d.mts +1 -40
- package/dist/index.mjs +2 -42
- package/dist/index.mjs.map +1 -1
- package/dist/{prisma-next-DlU01kXJ-2sP5mQb6.mjs → prisma-next-qPB8_Az6.mjs} +3 -3
- package/dist/prisma-next-qPB8_Az6.mjs.map +1 -0
- package/dist/prisma-next.d.mts +1 -1
- package/dist/prisma-next.mjs +1 -1
- package/dist/{provisioned-edges-DIQAR4q4-Bn9op-JG.mjs → provisioned-edges-Bb7WiV49-DeSPi3Ax.mjs} +4 -4
- package/dist/provisioned-edges-Bb7WiV49-DeSPi3Ax.mjs.map +1 -0
- package/dist/storage/index.d.mts +10 -11
- package/dist/storage/index.mjs +6 -14
- package/dist/storage/index.mjs.map +1 -1
- package/dist/storage/storage-entrypoint.mjs +1 -11
- package/dist/storage/storage-entrypoint.mjs.map +1 -1
- package/dist/storage/storage-service.mjs +6 -14
- package/dist/storage/storage-service.mjs.map +1 -1
- package/dist/storage/testing.mjs.map +1 -1
- package/dist/streams/index.d.mts +12 -13
- package/dist/streams/index.mjs +205 -489
- package/dist/streams/index.mjs.map +1 -1
- package/dist/streams/streams-entrypoint.mjs +1 -11
- package/dist/streams/streams-entrypoint.mjs.map +1 -1
- package/dist/streams/streams-service.mjs +6 -14
- package/dist/streams/streams-service.mjs.map +1 -1
- package/dist/streams/testing.d.mts +1 -1
- package/dist/streams/testing.mjs.map +1 -1
- package/dist/testing.d.mts +1 -1
- package/dist/testing.mjs.map +1 -1
- package/package.json +15 -15
- package/dist/prisma-next-DlU01kXJ-2sP5mQb6.mjs.map +0 -1
- package/dist/provisioned-edges-DIQAR4q4-Bn9op-JG.mjs.map +0 -1
package/dist/control.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { a as encodeParamPointer, c as secretName, i as encode, l as secretPointerRows, s as paramEntries, t as configKey } from "./serializer-CX4VYdf_-KKGoAxfx.mjs";
|
|
2
|
-
import { a as isEnvParamSource, c as provisionedEdges, n as STREAMS_API_KEY, o as paramBindingFor, s as paramName, t as RESERVED_PROVIDER_PARAMS } from "./provisioned-edges-
|
|
3
|
-
import { a as normalizeSslMode, n as isPnPostgresResourceNode, o as withConnectionRetry } from "./prisma-next-
|
|
2
|
+
import { a as isEnvParamSource, c as provisionedEdges, n as STREAMS_API_KEY, o as paramBindingFor, s as paramName, t as RESERVED_PROVIDER_PARAMS } from "./provisioned-edges-Bb7WiV49-DeSPi3Ax.mjs";
|
|
3
|
+
import { a as normalizeSslMode, n as isPnPostgresResourceNode, o as withConnectionRetry } from "./prisma-next-qPB8_Az6.mjs";
|
|
4
4
|
import { isParamSource, paramManifest, provisionManifest } from "@prisma/composer";
|
|
5
5
|
import { blindCast } from "@prisma/composer/casts";
|
|
6
|
-
import { RPC_PEER_KEY } from "@prisma/composer/
|
|
6
|
+
import { RPC_PEER_KEY } from "@prisma/composer/rpc";
|
|
7
7
|
import pg from "pg";
|
|
8
|
+
import * as Layer from "effect/Layer";
|
|
8
9
|
import { createManagementApiClient } from "@prisma/management-api-sdk";
|
|
9
10
|
import * as Context from "effect/Context";
|
|
10
11
|
import * as Effect from "effect/Effect";
|
|
11
|
-
import * as Layer from "effect/Layer";
|
|
12
12
|
import * as Redacted from "effect/Redacted";
|
|
13
13
|
import * as Config$1 from "effect/Config";
|
|
14
14
|
import * as Data from "effect/Data";
|
|
@@ -28,7 +28,7 @@ import { resolve } from "pathe";
|
|
|
28
28
|
import { readRef } from "@prisma-next/migration-tools/refs";
|
|
29
29
|
import { APP_SPACE_ID, readContractSpaceHeadRef, spaceMigrationDirectory, spaceRefsDirectory } from "@prisma-next/migration-tools/spaces";
|
|
30
30
|
import { createPostgresControlClient } from "@prisma-next/postgres/control";
|
|
31
|
-
//#region ../../1-prisma-cloud/0-lowering/lowering/dist/http-
|
|
31
|
+
//#region ../../1-prisma-cloud/0-lowering/lowering/dist/http-CxGdfSAP.mjs
|
|
32
32
|
/**
|
|
33
33
|
* The Prisma service token used to authenticate Management API calls. Kept
|
|
34
34
|
* as a Redacted value so it never lands in logs or error output.
|
|
@@ -68,84 +68,6 @@ const callOptional = (f) => attempt$1(f).pipe(Effect.flatMap((r) => r.response.s
|
|
|
68
68
|
/** Fire-and-forget a call, tolerating a 404 (already deleted). */
|
|
69
69
|
const callVoid = (f) => attempt$1(f).pipe(Effect.flatMap((r) => r.response.status === 404 || r.error === void 0 ? Effect.void : fail(r)));
|
|
70
70
|
//#endregion
|
|
71
|
-
//#region ../../1-prisma-cloud/0-lowering/lowering/dist/buckets.mjs
|
|
72
|
-
/** A Prisma **Object Store bucket** inside a project. */
|
|
73
|
-
const Bucket = Resource("Prisma.Bucket");
|
|
74
|
-
const BucketProvider = () => Provider.effect(Bucket, Effect.gen(function* () {
|
|
75
|
-
const client = yield* ManagementClient;
|
|
76
|
-
return {
|
|
77
|
-
stables: ["id"],
|
|
78
|
-
list: () => Effect.succeed([]),
|
|
79
|
-
reconcile: Effect.fn(function* ({ news, output }) {
|
|
80
|
-
const observed = output?.id ? yield* callOptional(() => client.GET("/v1/buckets/{bucketId}", { params: { path: { bucketId: output.id } } })) : void 0;
|
|
81
|
-
if (observed) return {
|
|
82
|
-
id: observed.data.id,
|
|
83
|
-
name: observed.data.name
|
|
84
|
-
};
|
|
85
|
-
const created = yield* call(() => client.POST("/v1/buckets", { body: {
|
|
86
|
-
projectId: news.projectId,
|
|
87
|
-
name: news.name,
|
|
88
|
-
...news.branchId !== void 0 ? { branchId: news.branchId } : {}
|
|
89
|
-
} }));
|
|
90
|
-
return {
|
|
91
|
-
id: created.data.id,
|
|
92
|
-
name: created.data.name
|
|
93
|
-
};
|
|
94
|
-
}),
|
|
95
|
-
delete: Effect.fn(function* ({ output }) {
|
|
96
|
-
yield* callVoid(() => client.DELETE("/v1/buckets/{bucketId}", { params: { path: { bucketId: output.id } } }));
|
|
97
|
-
}),
|
|
98
|
-
read: Effect.fn(function* ({ output }) {
|
|
99
|
-
if (!output?.id) return void 0;
|
|
100
|
-
const b = yield* callOptional(() => client.GET("/v1/buckets/{bucketId}", { params: { path: { bucketId: output.id } } }));
|
|
101
|
-
return b ? {
|
|
102
|
-
id: b.data.id,
|
|
103
|
-
name: b.data.name
|
|
104
|
-
} : void 0;
|
|
105
|
-
})
|
|
106
|
-
};
|
|
107
|
-
}));
|
|
108
|
-
/** A **bucket access key** for a Prisma Object Store bucket — yields the S3 credentials. */
|
|
109
|
-
const BucketKey = Resource("Prisma.BucketKey");
|
|
110
|
-
const BucketKeyProvider = () => Provider.effect(BucketKey, Effect.gen(function* () {
|
|
111
|
-
const client = yield* ManagementClient;
|
|
112
|
-
return {
|
|
113
|
-
stables: [
|
|
114
|
-
"id",
|
|
115
|
-
"bucketId",
|
|
116
|
-
"secretAccessKey",
|
|
117
|
-
"accessKeyId",
|
|
118
|
-
"endpoint",
|
|
119
|
-
"bucketName"
|
|
120
|
-
],
|
|
121
|
-
list: () => Effect.succeed([]),
|
|
122
|
-
reconcile: Effect.fn(function* ({ news, output }) {
|
|
123
|
-
if (output?.id) return output;
|
|
124
|
-
const created = yield* call(() => client.POST("/v1/buckets/{bucketId}/keys", {
|
|
125
|
-
params: { path: { bucketId: news.bucketId } },
|
|
126
|
-
body: {
|
|
127
|
-
name: news.name,
|
|
128
|
-
role: news.role
|
|
129
|
-
}
|
|
130
|
-
}));
|
|
131
|
-
return {
|
|
132
|
-
id: created.data.id,
|
|
133
|
-
bucketId: news.bucketId,
|
|
134
|
-
accessKeyId: created.data.accessKeyId,
|
|
135
|
-
secretAccessKey: Redacted.make(created.data.secretAccessKey),
|
|
136
|
-
endpoint: created.data.endpoint,
|
|
137
|
-
bucketName: created.data.bucketName
|
|
138
|
-
};
|
|
139
|
-
}),
|
|
140
|
-
delete: Effect.fn(function* ({ output }) {
|
|
141
|
-
yield* callVoid(() => client.DELETE("/v1/buckets/{bucketId}/keys/{keyId}", { params: { path: {
|
|
142
|
-
bucketId: output.bucketId,
|
|
143
|
-
keyId: output.id
|
|
144
|
-
} } }));
|
|
145
|
-
})
|
|
146
|
-
};
|
|
147
|
-
}));
|
|
148
|
-
//#endregion
|
|
149
71
|
//#region ../../1-prisma-cloud/0-lowering/lowering/dist/compute.mjs
|
|
150
72
|
/**
|
|
151
73
|
* Stopping a deployment before the app that owns it can be
|
|
@@ -548,23 +470,25 @@ const DatabaseProvider = () => Provider.effect(Database, Effect.gen(function* ()
|
|
|
548
470
|
list: () => Effect.succeed([]),
|
|
549
471
|
reconcile: Effect.fn(function* ({ news, output }) {
|
|
550
472
|
const observed = output?.id ? yield* callOptional(() => client.GET("/v1/databases/{databaseId}", { params: { path: { databaseId: output.id } } })) : void 0;
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
473
|
+
let result;
|
|
474
|
+
if (observed) result = {
|
|
475
|
+
id: observed.data.id,
|
|
476
|
+
name: observed.data.name
|
|
477
|
+
};
|
|
478
|
+
else {
|
|
479
|
+
const created = yield* call(() => client.POST("/v1/projects/{projectId}/databases", {
|
|
480
|
+
params: { path: { projectId: news.projectId } },
|
|
481
|
+
body: {
|
|
482
|
+
name: news.name,
|
|
483
|
+
region: news.region,
|
|
484
|
+
...news.isDefault !== void 0 && { isDefault: news.isDefault }
|
|
485
|
+
}
|
|
486
|
+
}));
|
|
487
|
+
result = {
|
|
560
488
|
id: created.data.id,
|
|
561
489
|
name: created.data.name
|
|
562
490
|
};
|
|
563
491
|
}
|
|
564
|
-
const result = {
|
|
565
|
-
id: observed.data.id,
|
|
566
|
-
name: observed.data.name
|
|
567
|
-
};
|
|
568
492
|
if (news.branchId !== void 0) {
|
|
569
493
|
const branchId = news.branchId;
|
|
570
494
|
yield* call(() => client.PATCH("/v1/databases/{databaseId}", {
|
|
@@ -622,107 +546,7 @@ const ProjectProvider = () => Provider.effect(Project, Effect.gen(function* () {
|
|
|
622
546
|
})
|
|
623
547
|
};
|
|
624
548
|
}));
|
|
625
|
-
|
|
626
|
-
//#region ../../1-prisma-cloud/0-lowering/lowering/dist/index.mjs
|
|
627
|
-
/** Raised with `ensure: false` when the app's Project (or a named stage's Branch) doesn't exist. */
|
|
628
|
-
var ContainerNotFoundError = class extends Data.TaggedError("ContainerNotFoundError") {};
|
|
629
|
-
const listAllProjects = (client) => Effect.gen(function* () {
|
|
630
|
-
const projects = [];
|
|
631
|
-
let cursor;
|
|
632
|
-
for (;;) {
|
|
633
|
-
const query = cursor === void 0 ? {} : { cursor };
|
|
634
|
-
const page = yield* call(() => client.GET("/v1/projects", { params: { query } }));
|
|
635
|
-
projects.push(...page.data);
|
|
636
|
-
if (!page.pagination.hasMore || page.pagination.nextCursor === null) break;
|
|
637
|
-
cursor = page.pagination.nextCursor;
|
|
638
|
-
}
|
|
639
|
-
return projects;
|
|
640
|
-
});
|
|
641
|
-
/**
|
|
642
|
-
* Workspace ids circulate in two shapes: `wksp_`-prefixed and bare. Compare
|
|
643
|
-
* bare-to-bare so a `wksp_`-prefixed API id still matches a bare configured
|
|
644
|
-
* one (the same normalization `state/bootstrap.ts` applies to the same
|
|
645
|
-
* `/v1/projects` listing).
|
|
646
|
-
*/
|
|
647
|
-
const bareWorkspaceId = (id) => id.startsWith("wksp_") ? id.slice(5) : id;
|
|
648
|
-
/**
|
|
649
|
-
* Finds the app's Project by name in the workspace — PDP allows duplicate
|
|
650
|
-
* project names, so more than one can match; the oldest wins. Creates one
|
|
651
|
-
* if none match, unless `ensure` is `false` (find-only — `destroy`), in
|
|
652
|
-
* which case an absent Project fails with `ContainerNotFoundError`. No
|
|
653
|
-
* ownership marker and no `--project` override (both deferred — see
|
|
654
|
-
* ADR-0019).
|
|
655
|
-
*/
|
|
656
|
-
const resolveProject = (client, workspaceId, appName, ensure) => Effect.gen(function* () {
|
|
657
|
-
const oldest = (yield* listAllProjects(client)).filter((p) => bareWorkspaceId(p.workspace.id) === bareWorkspaceId(workspaceId) && p.name === appName).sort((a, b) => a.createdAt.localeCompare(b.createdAt))[0];
|
|
658
|
-
if (oldest !== void 0) return oldest.id;
|
|
659
|
-
if (!ensure) return yield* Effect.fail(new ContainerNotFoundError({ appName }));
|
|
660
|
-
return (yield* call(() => client.POST("/v1/projects", { body: {
|
|
661
|
-
name: appName,
|
|
662
|
-
workspaceId
|
|
663
|
-
} }))).data.id;
|
|
664
|
-
});
|
|
665
|
-
const findBranchId = (client, projectId, gitName) => call(() => client.GET("/v1/projects/{projectId}/branches", { params: {
|
|
666
|
-
path: { projectId },
|
|
667
|
-
query: { gitName }
|
|
668
|
-
} })).pipe(Effect.map((page) => page.data[0]?.id));
|
|
669
|
-
/**
|
|
670
|
-
* Finds the stage's Branch by its exact `gitName`, creating it if absent
|
|
671
|
-
* unless `ensure` is `false` (find-only — `destroy`), in which case an
|
|
672
|
-
* absent Branch fails with `ContainerNotFoundError`. The Management API has
|
|
673
|
-
* no server-side "create-or-return" idempotency (`POST
|
|
674
|
-
* /v1/projects/:id/branches` 409s on a duplicate `gitName`, with no request
|
|
675
|
-
* field to make that a no-op), so idempotency is client-side: observe
|
|
676
|
-
* first, and on a racing 409 from create, re-observe rather than fail.
|
|
677
|
-
*/
|
|
678
|
-
const resolveBranch = (client, projectId, gitName, appName, ensure) => Effect.gen(function* () {
|
|
679
|
-
const existing = yield* findBranchId(client, projectId, gitName);
|
|
680
|
-
if (existing !== void 0) return existing;
|
|
681
|
-
if (!ensure) return yield* Effect.fail(new ContainerNotFoundError({
|
|
682
|
-
appName,
|
|
683
|
-
stage: gitName
|
|
684
|
-
}));
|
|
685
|
-
return yield* call(() => client.POST("/v1/projects/{projectId}/branches", {
|
|
686
|
-
params: { path: { projectId } },
|
|
687
|
-
body: { gitName }
|
|
688
|
-
})).pipe(Effect.map((r) => r.data.id), Effect.catch((err) => err.status === 409 ? findBranchId(client, projectId, gitName).pipe(Effect.flatMap((id) => id === void 0 ? Effect.fail(err) : Effect.succeed(id))) : Effect.fail(err)));
|
|
689
|
-
});
|
|
690
|
-
/**
|
|
691
|
-
* Resolves the two containers a stage's deploy runs into (ADR-0019): the
|
|
692
|
-
* app's **Project**, found-or-created by name, and — for a named stage
|
|
693
|
-
* only — its **Branch**, found-or-created by `gitName`. The default stage
|
|
694
|
-
* (no `stage`) creates no Branch; `branchId` is omitted. With `ensure:
|
|
695
|
-
* false` (`destroy`), nothing is created — an absent Project or Branch
|
|
696
|
-
* fails with `ContainerNotFoundError` instead.
|
|
697
|
-
*/
|
|
698
|
-
const resolveContainer = (opts) => Effect.gen(function* () {
|
|
699
|
-
const client = yield* ManagementClient;
|
|
700
|
-
const ensure = opts.ensure ?? true;
|
|
701
|
-
const projectId = yield* resolveProject(client, opts.workspaceId, opts.appName, ensure);
|
|
702
|
-
if (opts.stage === void 0) return { projectId };
|
|
703
|
-
return {
|
|
704
|
-
projectId,
|
|
705
|
-
branchId: yield* resolveBranch(client, projectId, opts.stage, opts.appName, ensure)
|
|
706
|
-
};
|
|
707
|
-
});
|
|
708
|
-
/**
|
|
709
|
-
* Soft-deletes a Branch. Tolerates a 404 (already gone). The API refuses if
|
|
710
|
-
* the Branch still has live members or is the production/default Branch —
|
|
711
|
-
* that surfaces as a `PrismaApiError`.
|
|
712
|
-
*/
|
|
713
|
-
const deleteBranch = (branchId) => Effect.gen(function* () {
|
|
714
|
-
const client = yield* ManagementClient;
|
|
715
|
-
yield* callVoid(() => client.DELETE("/v1/branches/{branchId}", { params: { path: { branchId } } }));
|
|
716
|
-
});
|
|
717
|
-
/**
|
|
718
|
-
* Deletes a Project. Tolerates a 404 (already gone). The API refuses with a
|
|
719
|
-
* 400 if the Project still has live dependencies (e.g. another stage's
|
|
720
|
-
* Branch/resources) — that surfaces as a `PrismaApiError`.
|
|
721
|
-
*/
|
|
722
|
-
const deleteProject = (projectId) => Effect.gen(function* () {
|
|
723
|
-
const client = yield* ManagementClient;
|
|
724
|
-
yield* callVoid(() => client.DELETE("/v1/projects/{id}", { params: { path: { id: projectId } } }));
|
|
725
|
-
});
|
|
549
|
+
Data.TaggedError("ContainerNotFoundError");
|
|
726
550
|
/** The collection of Prisma resource providers. */
|
|
727
551
|
var Providers = class extends Provider.ProviderCollection()("Prisma") {};
|
|
728
552
|
/**
|
|
@@ -736,10 +560,8 @@ const providers = () => Layer.effect(Providers, Provider.collection([
|
|
|
736
560
|
Connection,
|
|
737
561
|
ComputeService,
|
|
738
562
|
Deployment,
|
|
739
|
-
EnvironmentVariable
|
|
740
|
-
|
|
741
|
-
BucketKey
|
|
742
|
-
])).pipe(Layer.provide(Layer.mergeAll(ProjectProvider(), DatabaseProvider(), ConnectionProvider(), ComputeServiceProvider(), DeploymentProvider(), EnvironmentVariableProvider(), BucketProvider(), BucketKeyProvider())), Layer.provideMerge(layer()), Layer.provideMerge(fromEnv()), Layer.orDie);
|
|
563
|
+
EnvironmentVariable
|
|
564
|
+
])).pipe(Layer.provide(Layer.mergeAll(ProjectProvider(), DatabaseProvider(), ConnectionProvider(), ComputeServiceProvider(), DeploymentProvider(), EnvironmentVariableProvider())), Layer.provideMerge(layer()), Layer.provideMerge(fromEnv()), Layer.orDie);
|
|
743
565
|
//#endregion
|
|
744
566
|
//#region ../../1-prisma-cloud/0-lowering/lowering/dist/state.mjs
|
|
745
567
|
/** The framework-owned database a stage's deploy state lives in — a child of that stage's Branch (ADR-0034). */
|
|
@@ -1380,8 +1202,11 @@ const guardStateService = (service, checkLive, now = Date.now) => {
|
|
|
1380
1202
|
* StackServices>` contract and alchemy's own convention (e.g. a missing
|
|
1381
1203
|
* state store is `Effect.die` in `Stack.make`).
|
|
1382
1204
|
*/
|
|
1383
|
-
const
|
|
1384
|
-
const
|
|
1205
|
+
const prismaState = () => {
|
|
1206
|
+
const projectId = process.env["PRISMA_PROJECT_ID"];
|
|
1207
|
+
if (projectId === void 0 || projectId.length === 0) throw new Error("prismaState(): environment variable PRISMA_PROJECT_ID is required (the CLI sets it — deploy via `prisma-composer deploy`).");
|
|
1208
|
+
const branchIdEnv = process.env["PRISMA_BRANCH_ID"];
|
|
1209
|
+
const branchId = branchIdEnv === void 0 || branchIdEnv.length === 0 ? void 0 : branchIdEnv;
|
|
1385
1210
|
return Layer.effect(State, Effect.gen(function* () {
|
|
1386
1211
|
const stack = yield* Stack;
|
|
1387
1212
|
const container = branchId === void 0 ? projectId : `${projectId}/${branchId}`;
|
|
@@ -1404,218 +1229,18 @@ const prismaStateLayer = (ids) => {
|
|
|
1404
1229
|
};
|
|
1405
1230
|
//#endregion
|
|
1406
1231
|
//#region ../../1-prisma-cloud/1-extensions/target/dist/control.mjs
|
|
1407
|
-
const PRISMA_CLOUD_EXTENSION_ID = "@prisma/composer-prisma-cloud";
|
|
1408
|
-
var PrismaCloudContainer = class {
|
|
1409
|
-
input;
|
|
1410
|
-
projectId;
|
|
1411
|
-
branchId;
|
|
1412
|
-
constructor(input, projectId, branchId) {
|
|
1413
|
-
this.input = input;
|
|
1414
|
-
this.projectId = projectId;
|
|
1415
|
-
this.branchId = branchId;
|
|
1416
|
-
}
|
|
1417
|
-
serialize() {
|
|
1418
|
-
return JSON.stringify({
|
|
1419
|
-
input: this.input,
|
|
1420
|
-
projectId: this.projectId,
|
|
1421
|
-
...this.branchId !== void 0 ? { branchId: this.branchId } : {}
|
|
1422
|
-
});
|
|
1423
|
-
}
|
|
1424
|
-
};
|
|
1425
|
-
/** `instanceof` — parent-side instances and child-side deserialized instances are both constructed by this module. */
|
|
1426
|
-
function isPrismaCloudContainer(value) {
|
|
1427
|
-
return value instanceof PrismaCloudContainer;
|
|
1428
|
-
}
|
|
1429
|
-
/** Narrow-or-throw for hook inputs. */
|
|
1430
|
-
function prismaCloudContainerOf(value) {
|
|
1431
|
-
if (!isPrismaCloudContainer(value)) throw new Error("the Prisma Cloud container was not resolved — the extension's container descriptor did not run.");
|
|
1432
|
-
return value;
|
|
1433
|
-
}
|
|
1434
|
-
function isRecord(value) {
|
|
1435
|
-
return typeof value === "object" && value !== null;
|
|
1436
|
-
}
|
|
1437
|
-
function invalidPayloadError(reason) {
|
|
1438
|
-
return /* @__PURE__ */ new Error(`${PRISMA_CLOUD_EXTENSION_ID}: invalid container transport payload — ${reason}.`);
|
|
1439
|
-
}
|
|
1440
|
-
/** Reconstructs a `PrismaCloudContainer` from `serialize()`'s JSON output — real narrowing, no casts. */
|
|
1441
|
-
function deserialize(serialized) {
|
|
1442
|
-
let parsed;
|
|
1443
|
-
try {
|
|
1444
|
-
parsed = JSON.parse(serialized);
|
|
1445
|
-
} catch (error) {
|
|
1446
|
-
throw invalidPayloadError(`not valid JSON (${error instanceof Error ? error.message : String(error)})`);
|
|
1447
|
-
}
|
|
1448
|
-
if (!isRecord(parsed)) throw invalidPayloadError("not an object");
|
|
1449
|
-
const input = parsed["input"];
|
|
1450
|
-
if (!isRecord(input)) throw invalidPayloadError("\"input\" is not an object");
|
|
1451
|
-
const appName = input["appName"];
|
|
1452
|
-
if (typeof appName !== "string") throw invalidPayloadError("\"input.appName\" is not a string");
|
|
1453
|
-
const stage = input["stage"];
|
|
1454
|
-
if (stage !== void 0 && typeof stage !== "string") throw invalidPayloadError("\"input.stage\" is not a string or absent");
|
|
1455
|
-
const projectId = parsed["projectId"];
|
|
1456
|
-
if (typeof projectId !== "string") throw invalidPayloadError("\"projectId\" is not a string");
|
|
1457
|
-
const branchId = parsed["branchId"];
|
|
1458
|
-
if (branchId !== void 0 && typeof branchId !== "string") throw invalidPayloadError("\"branchId\" is not a string or absent");
|
|
1459
|
-
return new PrismaCloudContainer({
|
|
1460
|
-
appName,
|
|
1461
|
-
stage
|
|
1462
|
-
}, projectId, branchId);
|
|
1463
|
-
}
|
|
1464
|
-
const workspaceRequiredError = () => /* @__PURE__ */ new Error("environment variable PRISMA_WORKSPACE_ID is required.");
|
|
1465
|
-
const tokenRequiredError$2 = () => /* @__PURE__ */ new Error("environment variable PRISMA_SERVICE_TOKEN is required.");
|
|
1466
|
-
function requireWorkspaceId() {
|
|
1467
|
-
const workspaceId = process.env["PRISMA_WORKSPACE_ID"];
|
|
1468
|
-
if (workspaceId === void 0 || workspaceId.length === 0) throw workspaceRequiredError();
|
|
1469
|
-
return workspaceId;
|
|
1470
|
-
}
|
|
1471
|
-
function requireTokenUnlessInjected(deps) {
|
|
1472
|
-
if (deps?.client === void 0 && (process.env["PRISMA_SERVICE_TOKEN"] ?? "").length === 0) throw tokenRequiredError$2();
|
|
1473
|
-
}
|
|
1474
|
-
async function ensureContainer(input, deps) {
|
|
1475
|
-
const workspaceId = requireWorkspaceId();
|
|
1476
|
-
requireTokenUnlessInjected(deps);
|
|
1477
|
-
const program = resolveContainer({
|
|
1478
|
-
workspaceId,
|
|
1479
|
-
appName: input.appName,
|
|
1480
|
-
...input.stage !== void 0 ? { stage: input.stage } : {},
|
|
1481
|
-
ensure: true
|
|
1482
|
-
}).pipe(Effect.map((c) => ({
|
|
1483
|
-
ok: true,
|
|
1484
|
-
container: c
|
|
1485
|
-
})), Effect.catchTag("PrismaApiError", (e) => Effect.succeed({
|
|
1486
|
-
ok: false,
|
|
1487
|
-
message: `Prisma Management API error resolving containers: ${e.message}.`
|
|
1488
|
-
})));
|
|
1489
|
-
const provided = deps?.client !== void 0 ? program.pipe(Effect.provideService(ManagementClient, deps.client)) : program.pipe(Effect.provide(layer().pipe(Layer.provide(fromEnv()))));
|
|
1490
|
-
const outcome = await Effect.runPromise(provided);
|
|
1491
|
-
if (!outcome.ok) throw new Error(outcome.message);
|
|
1492
|
-
return new PrismaCloudContainer(input, outcome.container.projectId, outcome.container.branchId);
|
|
1493
|
-
}
|
|
1494
|
-
async function locateContainer(input, deps) {
|
|
1495
|
-
const workspaceId = requireWorkspaceId();
|
|
1496
|
-
requireTokenUnlessInjected(deps);
|
|
1497
|
-
const program = resolveContainer({
|
|
1498
|
-
workspaceId,
|
|
1499
|
-
appName: input.appName,
|
|
1500
|
-
...input.stage !== void 0 ? { stage: input.stage } : {},
|
|
1501
|
-
ensure: false
|
|
1502
|
-
}).pipe(Effect.map((c) => ({
|
|
1503
|
-
ok: true,
|
|
1504
|
-
container: c
|
|
1505
|
-
})), Effect.catchTag("ContainerNotFoundError", () => Effect.succeed({ ok: false })), Effect.catchTag("PrismaApiError", (e) => Effect.fail(/* @__PURE__ */ new Error(`Prisma Management API error resolving containers: ${e.message}.`))));
|
|
1506
|
-
const provided = deps?.client !== void 0 ? program.pipe(Effect.provideService(ManagementClient, deps.client)) : program.pipe(Effect.provide(layer().pipe(Layer.provide(fromEnv()))));
|
|
1507
|
-
const outcome = await Effect.runPromise(provided);
|
|
1508
|
-
if (!outcome.ok) return void 0;
|
|
1509
|
-
return new PrismaCloudContainer(input, outcome.container.projectId, outcome.container.branchId);
|
|
1510
|
-
}
|
|
1511
|
-
/**
|
|
1512
|
-
* Soft-deletes a named stage's Branch after a successful `alchemy destroy`
|
|
1513
|
-
* has removed its members — the Management API refuses to delete a Branch
|
|
1514
|
-
* that still has live members.
|
|
1515
|
-
*/
|
|
1516
|
-
async function removeStageBranch(branchId, deps) {
|
|
1517
|
-
requireTokenUnlessInjected(deps);
|
|
1518
|
-
const program = deleteBranch(branchId).pipe(Effect.map(() => ({ ok: true })), Effect.catchTag("PrismaApiError", (e) => Effect.succeed({
|
|
1519
|
-
ok: false,
|
|
1520
|
-
message: `Failed to delete the stage Branch: ${e.message}.`
|
|
1521
|
-
})));
|
|
1522
|
-
const provided = deps?.client !== void 0 ? program.pipe(Effect.provideService(ManagementClient, deps.client)) : program.pipe(Effect.provide(layer().pipe(Layer.provide(fromEnv()))));
|
|
1523
|
-
const outcome = await Effect.runPromise(provided);
|
|
1524
|
-
if (!outcome.ok) throw new Error(outcome.message);
|
|
1525
|
-
}
|
|
1526
|
-
/**
|
|
1527
|
-
* Best-effort cleanup after a successful `--production` destroy: removes
|
|
1528
|
-
* the app's Project so hand-run stacks don't accumulate as empty Projects
|
|
1529
|
-
* (they eventually hit the workspace's plan limit). Unlike `removeStageBranch`,
|
|
1530
|
-
* this never throws: the destroy itself already succeeded, and the API's own
|
|
1531
|
-
* 400 ("still has dependencies") is the only check that matters — failing
|
|
1532
|
-
* the command over a cleanup step would be worse than leaving a Project shell.
|
|
1533
|
-
*/
|
|
1534
|
-
async function removeAppProject(projectId, deps) {
|
|
1535
|
-
if (deps?.client === void 0 && (process.env["PRISMA_SERVICE_TOKEN"] ?? "").length === 0) {
|
|
1536
|
-
console.warn(`Skipped removing the Project (${projectId}): PRISMA_SERVICE_TOKEN is not set.`);
|
|
1537
|
-
return;
|
|
1538
|
-
}
|
|
1539
|
-
const program = deleteProject(projectId).pipe(Effect.map(() => ({ ok: true })), Effect.catchTag("PrismaApiError", (e) => Effect.succeed({
|
|
1540
|
-
ok: false,
|
|
1541
|
-
error: e
|
|
1542
|
-
})));
|
|
1543
|
-
const provided = deps?.client !== void 0 ? program.pipe(Effect.provideService(ManagementClient, deps.client)) : program.pipe(Effect.provide(layer().pipe(Layer.provide(fromEnv()))));
|
|
1544
|
-
const outcome = await Effect.runPromise(provided);
|
|
1545
|
-
if (outcome.ok) {
|
|
1546
|
-
console.log(`Removed the Project (${projectId}) — nothing was left in it.`);
|
|
1547
|
-
return;
|
|
1548
|
-
}
|
|
1549
|
-
if (outcome.error.status === 400) {
|
|
1550
|
-
console.log(`Kept the Project (${projectId}) — it still has another stage's resources.`);
|
|
1551
|
-
return;
|
|
1552
|
-
}
|
|
1553
|
-
console.warn(`Could not remove the Project (${projectId}) after destroy: ${outcome.error.message}.`);
|
|
1554
|
-
}
|
|
1555
|
-
function containerDescriptor(deps) {
|
|
1556
|
-
return {
|
|
1557
|
-
ensure: (input) => ensureContainer(input, deps),
|
|
1558
|
-
locate: (input) => locateContainer(input, deps),
|
|
1559
|
-
remove: (instance) => instance.input.stage !== void 0 ? removeStageBranch(instance.branchId ?? missingBranchId(instance), deps) : removeAppProject(instance.projectId, deps),
|
|
1560
|
-
deserialize
|
|
1561
|
-
};
|
|
1562
|
-
}
|
|
1563
|
-
/** Defensive: a named-stage container always resolves a Branch together with its stage — `ensure`/`locate`/`deserialize` never produce one without the other. */
|
|
1564
|
-
function missingBranchId(instance) {
|
|
1565
|
-
throw new Error(`${PRISMA_CLOUD_EXTENSION_ID}: a named-stage ("${instance.input.stage}") container instance is missing its branchId — this is a bug in ensure/locate/deserialize.`);
|
|
1566
|
-
}
|
|
1567
1232
|
const PRISMA_NAME_MIN = 3;
|
|
1568
1233
|
const PRISMA_NAME_MAX = 65;
|
|
1569
1234
|
function validateName(value, source) {
|
|
1570
1235
|
if (value.length < PRISMA_NAME_MIN || value.length > PRISMA_NAME_MAX) throw new Error(`prisma-cloud: ${source} "${value}" (${value.length} characters) is not a valid Prisma resource name — Prisma requires ${PRISMA_NAME_MIN}–${PRISMA_NAME_MAX} characters. Rename the provision id (or the deploy --name) to fit.`);
|
|
1571
1236
|
}
|
|
1572
1237
|
function isCloudApplication(value) {
|
|
1573
|
-
return typeof value === "object" && value !== null && "projectId" in value && typeof value.projectId === "string"
|
|
1238
|
+
return typeof value === "object" && value !== null && "projectId" in value && typeof value.projectId === "string";
|
|
1574
1239
|
}
|
|
1575
1240
|
/** Narrows `ctx.application`, which core hands over as `unknown`, to this extension's own product; throws naming the hook when it hasn't run. */
|
|
1576
|
-
function cloudApplicationOf(application) {
|
|
1577
|
-
if (!isCloudApplication(application)) throw new Error("prisma-cloud: ctx.application is not this extension's application product — the prismaCloud() application hook must run before any node lowers.");
|
|
1578
|
-
return application;
|
|
1579
|
-
}
|
|
1580
1241
|
function projectIdOf(application) {
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
/**
|
|
1584
|
-
* One Bucket per module-provisioned bucket resource — `id` is the module
|
|
1585
|
-
* provision id, so a resource shared by several consumers is created exactly
|
|
1586
|
-
* once. A BucketKey is minted for the bucket: it is the reveal-once credential
|
|
1587
|
-
* carrier, and its attributes (endpoint, bucketName, accessKeyId,
|
|
1588
|
-
* secretAccessKey) become the four S3Config outputs consumers resolve by name.
|
|
1589
|
-
*/
|
|
1590
|
-
function bucketDescriptor(_o) {
|
|
1591
|
-
const lowering = ({ id, application }) => Effect.gen(function* () {
|
|
1592
|
-
validateName(id, "resource name (from provision id)");
|
|
1593
|
-
const branchId = cloudApplicationOf(application).branchId;
|
|
1594
|
-
const bkt = yield* Bucket(`${id}-bucket`, {
|
|
1595
|
-
projectId: projectIdOf(application),
|
|
1596
|
-
name: id,
|
|
1597
|
-
...branchId !== void 0 ? { branchId } : {}
|
|
1598
|
-
});
|
|
1599
|
-
const key = yield* BucketKey(`${id}-key`, {
|
|
1600
|
-
bucketId: bkt.id,
|
|
1601
|
-
name: id,
|
|
1602
|
-
role: "read_write"
|
|
1603
|
-
});
|
|
1604
|
-
const secretAccessKey = Output.map(key.secretAccessKey, (v) => Redacted.value(v));
|
|
1605
|
-
return {
|
|
1606
|
-
outputs: {
|
|
1607
|
-
url: key.endpoint,
|
|
1608
|
-
bucket: key.bucketName,
|
|
1609
|
-
accessKeyId: key.accessKeyId,
|
|
1610
|
-
secretAccessKey
|
|
1611
|
-
},
|
|
1612
|
-
entities: [{
|
|
1613
|
-
kind: "bucket",
|
|
1614
|
-
id: bkt.id
|
|
1615
|
-
}]
|
|
1616
|
-
};
|
|
1617
|
-
});
|
|
1618
|
-
return Object.assign(lowering, { kind: "resource" });
|
|
1242
|
+
if (!isCloudApplication(application)) throw new Error("prisma-cloud: ctx.application is not this extension's application product — the prismaCloud() application hook must run before any node lowers.");
|
|
1243
|
+
return application.projectId;
|
|
1619
1244
|
}
|
|
1620
1245
|
/** The `compute` node kind's descriptor: the four service hooks — provision, serialize, package, deploy. */
|
|
1621
1246
|
/**
|
|
@@ -1630,22 +1255,20 @@ function computeDescriptor(o) {
|
|
|
1630
1255
|
provision: ({ id, application }) => Effect.gen(function* () {
|
|
1631
1256
|
validateName(id, "service name (from provision id)");
|
|
1632
1257
|
const projectId = projectIdOf(application);
|
|
1633
|
-
const branchId = cloudApplicationOf(application).branchId;
|
|
1634
1258
|
return {
|
|
1635
1259
|
serviceId: (yield* ComputeService(`${id}-svc`, {
|
|
1636
1260
|
projectId,
|
|
1637
1261
|
name: id,
|
|
1638
1262
|
region: o.region ?? "us-east-1",
|
|
1639
|
-
...branchId !== void 0 ? { branchId } : {}
|
|
1263
|
+
...o.branchId !== void 0 ? { branchId: o.branchId } : {}
|
|
1640
1264
|
})).id,
|
|
1641
1265
|
projectId
|
|
1642
1266
|
};
|
|
1643
1267
|
}),
|
|
1644
1268
|
serialize: (ctx, provisioned, config) => Effect.gen(function* () {
|
|
1645
1269
|
const { address, node, graph } = ctx;
|
|
1646
|
-
const
|
|
1647
|
-
const
|
|
1648
|
-
const branch = branchId !== void 0 ? { branchId } : {};
|
|
1270
|
+
const cls = o.branchId ? "preview" : "production";
|
|
1271
|
+
const branch = o.branchId !== void 0 ? { branchId: o.branchId } : {};
|
|
1649
1272
|
const projectId = provisioned.projectId;
|
|
1650
1273
|
const svc = node;
|
|
1651
1274
|
const records = [];
|
|
@@ -1785,12 +1408,11 @@ const PgWarmProvider = () => Provider.effect(PgWarm, Effect.succeed(pgWarmProvid
|
|
|
1785
1408
|
function postgresDescriptor(o) {
|
|
1786
1409
|
const lowering = ({ id, application }) => Effect.gen(function* () {
|
|
1787
1410
|
validateName(id, "resource name (from provision id)");
|
|
1788
|
-
const branchId = cloudApplicationOf(application).branchId;
|
|
1789
1411
|
const db = yield* Database(`${id}-db`, {
|
|
1790
1412
|
projectId: projectIdOf(application),
|
|
1791
1413
|
name: id,
|
|
1792
1414
|
region: o.region ?? "us-east-1",
|
|
1793
|
-
...branchId !== void 0 ? { branchId } : {}
|
|
1415
|
+
...o.branchId !== void 0 ? { branchId: o.branchId } : {}
|
|
1794
1416
|
});
|
|
1795
1417
|
const conn = yield* Connection(`${id}-conn`, {
|
|
1796
1418
|
databaseId: db.id,
|
|
@@ -2054,12 +1676,11 @@ const PnMigrationProvider = () => Provider.effect(PnMigration, Effect.succeed(pn
|
|
|
2054
1676
|
function prismaNextDescriptor(o) {
|
|
2055
1677
|
const lowering = ({ id, node, application }) => Effect.gen(function* () {
|
|
2056
1678
|
validateName(id, "resource name (from provision id)");
|
|
2057
|
-
const branchId = cloudApplicationOf(application).branchId;
|
|
2058
1679
|
const db = yield* Database(`${id}-db`, {
|
|
2059
1680
|
projectId: projectIdOf(application),
|
|
2060
1681
|
name: id,
|
|
2061
1682
|
region: o.region ?? "us-east-1",
|
|
2062
|
-
...branchId !== void 0 ? { branchId } : {}
|
|
1683
|
+
...o.branchId !== void 0 ? { branchId: o.branchId } : {}
|
|
2063
1684
|
});
|
|
2064
1685
|
const conn = yield* Connection(`${id}-conn`, {
|
|
2065
1686
|
databaseId: db.id,
|
|
@@ -2196,7 +1817,7 @@ function s3StoreDescriptor(o) {
|
|
|
2196
1817
|
*
|
|
2197
1818
|
* Control-plane only (imported by control.ts → prisma-composer.config.ts); runs
|
|
2198
1819
|
* in the CLI parent, so it builds its own Management API client from env — the
|
|
2199
|
-
* same credential path `
|
|
1820
|
+
* same credential path `ensureContainers` uses.
|
|
2200
1821
|
*/
|
|
2201
1822
|
/** production for the default stage; preview for a named stage — matching how the pack writes config rows. */
|
|
2202
1823
|
const classFor = (branchId) => branchId === void 0 ? "production" : "preview";
|
|
@@ -2239,21 +1860,21 @@ async function existsOnPlatform(client, projectId, branchId, key) {
|
|
|
2239
1860
|
* EnvironmentVariable.ts). A 409 means a concurrent deploy already provisioned
|
|
2240
1861
|
* it — tolerated. The value is never logged.
|
|
2241
1862
|
*/
|
|
2242
|
-
async function fillMissing(client,
|
|
1863
|
+
async function fillMissing(client, input, key, value) {
|
|
2243
1864
|
const res = await client.POST("/v1/environment-variables", { body: {
|
|
2244
|
-
projectId,
|
|
2245
|
-
class: classFor(branchId),
|
|
1865
|
+
projectId: input.projectId,
|
|
1866
|
+
class: classFor(input.branchId),
|
|
2246
1867
|
key,
|
|
2247
1868
|
value,
|
|
2248
|
-
...branchId !== void 0 ? { branchId } : {}
|
|
1869
|
+
...input.branchId !== void 0 ? { branchId: input.branchId } : {}
|
|
2249
1870
|
} });
|
|
2250
1871
|
if (res.error !== void 0 && res.response.status !== 409) throw fillFailedError(key, res.error);
|
|
2251
1872
|
}
|
|
2252
1873
|
const tokenRequiredError$1 = () => /* @__PURE__ */ new Error("environment variable PRISMA_SERVICE_TOKEN is required for deploy preflight.");
|
|
2253
1874
|
const listFailedError = (key, error) => /* @__PURE__ */ new Error(`deploy preflight: Prisma Management API error listing "${key}": ${JSON.stringify(error)}.`);
|
|
2254
1875
|
const fillFailedError = (key, error) => /* @__PURE__ */ new Error(`deploy preflight: failed to provision "${key}" from the deploy shell: ${JSON.stringify(error)}.`);
|
|
2255
|
-
function missingError(missing,
|
|
2256
|
-
const scope = branchId === void 0 ? "the production class (project-level template)" : `the preview class of stage "${stage ?? branchId}" (branch override or template)`;
|
|
1876
|
+
function missingError(missing, input) {
|
|
1877
|
+
const scope = input.branchId === void 0 ? "the production class (project-level template)" : `the preview class of stage "${input.stage ?? input.branchId}" (branch override or template)`;
|
|
2257
1878
|
const lines = missing.map((m) => ` - ${m.name} (required by service "${m.serviceAddress}")`);
|
|
2258
1879
|
return /* @__PURE__ */ new Error(`Deploy preflight failed — ${missing.length} env var(s) (secret or env-sourced param) are not provisioned on Prisma Cloud for ${scope}, and are absent from the deploy shell:\n${lines.join("\n")}\n\nSet each in the deploy shell environment (the CLI will provision it on deploy), or create it on the platform (Prisma Console or the Management API) in ${scope}.`);
|
|
2259
1880
|
}
|
|
@@ -2272,7 +1893,6 @@ async function managementClient$1() {
|
|
|
2272
1893
|
* from env.
|
|
2273
1894
|
*/
|
|
2274
1895
|
async function runPreflight(input, deps) {
|
|
2275
|
-
const { projectId, branchId } = prismaCloudContainerOf(input.container);
|
|
2276
1896
|
const names = /* @__PURE__ */ new Map();
|
|
2277
1897
|
for (const binding of provisionManifest(input.graph)) {
|
|
2278
1898
|
const name = secretName(binding);
|
|
@@ -2293,15 +1913,15 @@ async function runPreflight(input, deps) {
|
|
|
2293
1913
|
const client = deps?.client ?? await managementClient$1();
|
|
2294
1914
|
const missing = [];
|
|
2295
1915
|
for (const meta of names.values()) {
|
|
2296
|
-
if (await existsOnPlatform(client, projectId, branchId, meta.name)) continue;
|
|
1916
|
+
if (await existsOnPlatform(client, input.projectId, input.branchId, meta.name)) continue;
|
|
2297
1917
|
const shellValue = process.env[meta.name];
|
|
2298
1918
|
if (shellValue !== void 0 && shellValue.length > 0) {
|
|
2299
|
-
await fillMissing(client,
|
|
1919
|
+
await fillMissing(client, input, meta.name, shellValue);
|
|
2300
1920
|
continue;
|
|
2301
1921
|
}
|
|
2302
1922
|
missing.push(meta);
|
|
2303
1923
|
}
|
|
2304
|
-
if (missing.length > 0) throw missingError(missing,
|
|
1924
|
+
if (missing.length > 0) throw missingError(missing, input);
|
|
2305
1925
|
}
|
|
2306
1926
|
const tokenRequiredError = () => /* @__PURE__ */ new Error("environment variable PRISMA_SERVICE_TOKEN is required for destroy teardown.");
|
|
2307
1927
|
async function managementClient() {
|
|
@@ -2326,13 +1946,12 @@ async function managementClient() {
|
|
|
2326
1946
|
* builds a client from env and verifies against the real database.
|
|
2327
1947
|
*/
|
|
2328
1948
|
async function runTeardown(input, deps) {
|
|
2329
|
-
const
|
|
2330
|
-
const isNamedStage = branchId !== void 0;
|
|
1949
|
+
const isNamedStage = input.branchId !== void 0;
|
|
2331
1950
|
try {
|
|
2332
1951
|
const client = deps?.client ?? await managementClient();
|
|
2333
1952
|
await Effect.runPromise(deleteStateDatabaseWith({
|
|
2334
|
-
projectId,
|
|
2335
|
-
...branchId !== void 0 ? { branchId } : {}
|
|
1953
|
+
projectId: input.projectId,
|
|
1954
|
+
...input.branchId !== void 0 ? { branchId: input.branchId } : {}
|
|
2336
1955
|
}, deps?.verify ?? verifyOwnership).pipe(Effect.provideService(ManagementClient, client)));
|
|
2337
1956
|
} catch (error) {
|
|
2338
1957
|
const reason = error instanceof Error ? error.message : String(error);
|
|
@@ -2410,17 +2029,6 @@ const streamsApiKeyValue = (refs) => {
|
|
|
2410
2029
|
return distinct[0] ?? "";
|
|
2411
2030
|
});
|
|
2412
2031
|
};
|
|
2413
|
-
/** The user-facing state descriptor: `state: prismaState()` in `prisma-composer.config.ts` (ADR-0017). */
|
|
2414
|
-
const prismaState = () => ({
|
|
2415
|
-
extension: PRISMA_CLOUD_EXTENSION_ID,
|
|
2416
|
-
create: (container) => {
|
|
2417
|
-
const { projectId, branchId } = prismaCloudContainerOf(container);
|
|
2418
|
-
return prismaStateLayer(branchId !== void 0 ? {
|
|
2419
|
-
projectId,
|
|
2420
|
-
branchId
|
|
2421
|
-
} : { projectId });
|
|
2422
|
-
}
|
|
2423
|
-
});
|
|
2424
2032
|
const KNOWN_REGION_SET = new Set(COMPUTE_REGIONS);
|
|
2425
2033
|
function isComputeRegion(value) {
|
|
2426
2034
|
return KNOWN_REGION_SET.has(value);
|
|
@@ -2476,25 +2084,34 @@ function buildProviderParams(entries, values) {
|
|
|
2476
2084
|
const PROVIDER_PARAMS = buildProviderParams(RESERVED_PROVIDER_PARAMS, PROVIDER_PARAM_VALUES);
|
|
2477
2085
|
/**
|
|
2478
2086
|
* Resolves the factory's env-or-option inputs, failing fast with the exact
|
|
2479
|
-
* variable name.
|
|
2087
|
+
* variable name. `projectId`/`branchId` aren't required here — `prismaCloud()`
|
|
2088
|
+
* also runs in the CLI parent, before they're set; the required check lives in `application.provision`.
|
|
2480
2089
|
*/
|
|
2481
2090
|
function resolveOptions(opts) {
|
|
2482
2091
|
const workspaceId = opts.workspaceId ?? process.env["PRISMA_WORKSPACE_ID"];
|
|
2483
2092
|
if (workspaceId === void 0 || workspaceId.length === 0) throw new Error("prismaCloud(): environment variable PRISMA_WORKSPACE_ID is required.");
|
|
2093
|
+
const projectId = process.env["PRISMA_PROJECT_ID"] || void 0;
|
|
2094
|
+
const branchId = process.env["PRISMA_BRANCH_ID"] || void 0;
|
|
2484
2095
|
if (opts.region !== void 0) return {
|
|
2485
2096
|
workspaceId,
|
|
2486
2097
|
region: opts.region,
|
|
2098
|
+
projectId,
|
|
2099
|
+
branchId,
|
|
2487
2100
|
providerParams: PROVIDER_PARAMS
|
|
2488
2101
|
};
|
|
2489
2102
|
const region = process.env["PRISMA_REGION"];
|
|
2490
2103
|
if (region === void 0 || region.length === 0) return {
|
|
2491
2104
|
workspaceId,
|
|
2105
|
+
projectId,
|
|
2106
|
+
branchId,
|
|
2492
2107
|
providerParams: PROVIDER_PARAMS
|
|
2493
2108
|
};
|
|
2494
2109
|
if (!isComputeRegion(region)) throw new Error(`prismaCloud(): environment variable PRISMA_REGION="${region}" is not a known region (expected one of: ${COMPUTE_REGIONS.join(", ")}).`);
|
|
2495
2110
|
return {
|
|
2496
2111
|
workspaceId,
|
|
2497
2112
|
region,
|
|
2113
|
+
projectId,
|
|
2114
|
+
branchId,
|
|
2498
2115
|
providerParams: PROVIDER_PARAMS
|
|
2499
2116
|
};
|
|
2500
2117
|
}
|
|
@@ -2502,24 +2119,21 @@ function resolveOptions(opts) {
|
|
|
2502
2119
|
const prismaCloud = (opts = {}) => {
|
|
2503
2120
|
const o = resolveOptions(opts);
|
|
2504
2121
|
return {
|
|
2505
|
-
id:
|
|
2506
|
-
container: containerDescriptor(),
|
|
2122
|
+
id: "@prisma/composer-prisma-cloud",
|
|
2507
2123
|
providers: () => asProvidersLayer(Layer.mergeAll(providers(), PgWarmProvider(), PnMigrationProvider(), S3CredentialsProvider(), ServiceKeyProvider())),
|
|
2508
2124
|
preflight: (input) => runPreflight(input),
|
|
2509
2125
|
teardown: (input) => runTeardown(input),
|
|
2510
|
-
application: { provision: (
|
|
2511
|
-
const
|
|
2126
|
+
application: { provision: () => Effect.gen(function* () {
|
|
2127
|
+
const projectId = o.projectId;
|
|
2128
|
+
if (projectId === void 0 || projectId.length === 0) throw new Error("prismaCloud(): environment variable PRISMA_PROJECT_ID is required (the CLI sets it — deploy via `prisma-composer deploy`).");
|
|
2512
2129
|
for (const key of ["DATABASE_URL", "DATABASE_URL_POOLED"]) yield* EnvironmentVariable(`${key}-poison`, {
|
|
2513
2130
|
projectId,
|
|
2514
2131
|
key,
|
|
2515
2132
|
value: "-",
|
|
2516
|
-
class: branchId ? "preview" : "production",
|
|
2517
|
-
...branchId !== void 0 ? { branchId } : {}
|
|
2133
|
+
class: o.branchId ? "preview" : "production",
|
|
2134
|
+
...o.branchId !== void 0 ? { branchId: o.branchId } : {}
|
|
2518
2135
|
});
|
|
2519
|
-
return {
|
|
2520
|
-
projectId,
|
|
2521
|
-
branchId
|
|
2522
|
-
};
|
|
2136
|
+
return { projectId };
|
|
2523
2137
|
}) },
|
|
2524
2138
|
provisions: PROVISIONERS,
|
|
2525
2139
|
nodes: {
|
|
@@ -2527,8 +2141,7 @@ const prismaCloud = (opts = {}) => {
|
|
|
2527
2141
|
"prisma-next": prismaNextDescriptor(o),
|
|
2528
2142
|
compute: computeDescriptor(o),
|
|
2529
2143
|
credentials: s3CredentialsDescriptor(o),
|
|
2530
|
-
"s3-store": s3StoreDescriptor(o)
|
|
2531
|
-
s3: bucketDescriptor(o)
|
|
2144
|
+
"s3-store": s3StoreDescriptor(o)
|
|
2532
2145
|
}
|
|
2533
2146
|
};
|
|
2534
2147
|
};
|