@prisma/composer-prisma-cloud 0.35.0-dev.2 → 0.35.0-dev.4
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/auth/pack.mjs +1 -1
- package/dist/auth/pack.mjs.map +1 -1
- package/dist/auth/testing.mjs +1 -1
- package/dist/auth/testing.mjs.map +1 -1
- package/dist/control.mjs +1 -1
- package/dist/control.mjs.map +1 -1
- package/dist/local-target.mjs +145 -124
- package/dist/local-target.mjs.map +1 -1
- package/dist/{s3-credentials-resource-C-8pDHBj-BukBd4TQ.mjs → s3-credentials-resource-C-8pDHBj-iR0k6man.mjs} +5 -5
- package/dist/{s3-credentials-resource-C-8pDHBj-BukBd4TQ.mjs.map → s3-credentials-resource-C-8pDHBj-iR0k6man.mjs.map} +1 -1
- package/package.json +19 -19
package/dist/local-target.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { j as blindCast$1, k as stashRows } from "./serializer-A2fOAuiz-BHwRF-Cz.mjs";
|
|
2
|
-
import { D as isWithin, S as Providers, T as ServiceKeyProvider, c as PgWarmProvider, d as S3CredentialsProvider, f as collectPreflightNames, g as prismaCloudContainerOf, l as PrismaCloudContainer, m as deserialize, n as GeneratedParamProvider, r as LocalOrmMigrationProvider, x as mintKeyPair, y as resourceId } from "./s3-credentials-resource-C-8pDHBj-
|
|
2
|
+
import { D as isWithin, S as Providers, T as ServiceKeyProvider, c as PgWarmProvider, d as S3CredentialsProvider, f as collectPreflightNames, g as prismaCloudContainerOf, l as PrismaCloudContainer, m as deserialize, n as GeneratedParamProvider, r as LocalOrmMigrationProvider, x as mintKeyPair, y as resourceId } from "./s3-credentials-resource-C-8pDHBj-iR0k6man.mjs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { blindCast } from "@prisma/composer/casts";
|
|
5
5
|
import * as Effect from "effect/Effect";
|
|
@@ -19,7 +19,7 @@ import { App, Bucket, BucketAccessKey, Connection, Database, Deployment, Environ
|
|
|
19
19
|
import * as fs$1$1 from "node:fs/promises";
|
|
20
20
|
import ro from "node:fs/promises";
|
|
21
21
|
import { spawn } from "node:child_process";
|
|
22
|
-
import { DEV_DIR } from "@prisma/composer/config";
|
|
22
|
+
import { DEV_DIR, DEV_ENVIRONMENT_NAME_FILE, devEnvironmentDir } from "@prisma/composer/config";
|
|
23
23
|
import { fileURLToPath } from "node:url";
|
|
24
24
|
import net from "node:net";
|
|
25
25
|
import ar, { dirname, parse } from "path";
|
|
@@ -5691,18 +5691,14 @@ var To = (s) => {
|
|
|
5691
5691
|
function containerNotResolvedError() {
|
|
5692
5692
|
return /* @__PURE__ */ new Error("local dev: no container was resolved for this provider — the extension's `localTarget.container` descriptor did not run before converge.");
|
|
5693
5693
|
}
|
|
5694
|
-
/**
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5702
|
-
*/
|
|
5703
|
-
function appNameOf(container) {
|
|
5704
|
-
if (container === void 0) throw containerNotResolvedError();
|
|
5705
|
-
return container.input.appName;
|
|
5694
|
+
/** The app and environment local dev runs, from the extension's resolved container. */
|
|
5695
|
+
function appScopeOf(input) {
|
|
5696
|
+
if (input.container === void 0) throw containerNotResolvedError();
|
|
5697
|
+
return {
|
|
5698
|
+
devDir: input.devDir,
|
|
5699
|
+
app: input.container.input.appName,
|
|
5700
|
+
environment: input.container.input.environment
|
|
5701
|
+
};
|
|
5706
5702
|
}
|
|
5707
5703
|
/**
|
|
5708
5704
|
* The shared dev-instance store (local-dev spec § 4): the JSON files under
|
|
@@ -5774,11 +5770,7 @@ function withAppPrefix(app, nodes) {
|
|
|
5774
5770
|
}
|
|
5775
5771
|
/** A record written before ADR-0057, with every node keyed by its full address. */
|
|
5776
5772
|
function withFullAddressKeys(record) {
|
|
5777
|
-
|
|
5778
|
-
return {
|
|
5779
|
-
current: record.current,
|
|
5780
|
-
apps
|
|
5781
|
-
};
|
|
5773
|
+
return { apps: Object.fromEntries(Object.entries(record.apps).map(([app, { nodes }]) => [app, { nodes: withAppPrefix(app, nodes) }])) };
|
|
5782
5774
|
}
|
|
5783
5775
|
/** Where local dev loads `@prisma/dev` from, for the Postgres emulator. */
|
|
5784
5776
|
function noPrismaDevError(cause) {
|
|
@@ -5801,8 +5793,9 @@ function resolvePrismaDevModulePath() {
|
|
|
5801
5793
|
}
|
|
5802
5794
|
}
|
|
5803
5795
|
/**
|
|
5804
|
-
* Which emulator instance backs each node of each app run
|
|
5805
|
-
* `prisma dev` records it in
|
|
5796
|
+
* Which emulator instance backs each node of each app run in one environment
|
|
5797
|
+
* from a directory. `prisma dev` records it in the environment's folder,
|
|
5798
|
+
* `<directory>/.prisma-composer/dev/<environment>/`, and every
|
|
5806
5799
|
* Composer operation on an emulator instance goes through it. The emulators
|
|
5807
5800
|
* know nothing about Composer: the labels written on create are for people
|
|
5808
5801
|
* reading an emulator listing, and nothing here reads them back.
|
|
@@ -5821,7 +5814,7 @@ function isAppInstances(value) {
|
|
|
5821
5814
|
return typeof value === "object" && value !== null && "nodes" in value && isNodes(value.nodes);
|
|
5822
5815
|
}
|
|
5823
5816
|
function isEmulatorInstances(value) {
|
|
5824
|
-
return typeof value === "object" && value !== null && "
|
|
5817
|
+
return typeof value === "object" && value !== null && "apps" in value && typeof value.apps === "object" && value.apps !== null && Object.values(value.apps).every(isAppInstances);
|
|
5825
5818
|
}
|
|
5826
5819
|
function isEarlierServiceNode(value) {
|
|
5827
5820
|
return typeof value === "object" && value !== null && "kind" in value && value.kind === "compute" && "id" in value && typeof value.id === "string" && "port" in value && typeof value.port === "number";
|
|
@@ -5832,6 +5825,8 @@ function isSingleAppRecord(value) {
|
|
|
5832
5825
|
function isStoredRecord(value) {
|
|
5833
5826
|
return isEmulatorInstances(value) || isSingleAppRecord(value);
|
|
5834
5827
|
}
|
|
5828
|
+
/** Format 2 differs from the current one only by its `current` app, which is dropped. */
|
|
5829
|
+
const FULL_ADDRESS_FORMAT_VERSIONS = /* @__PURE__ */ new Set([2, 3]);
|
|
5835
5830
|
/**
|
|
5836
5831
|
* A record without `formatVersion` was written before node keys were full addresses, so each of
|
|
5837
5832
|
* its keys reads with the app's name in front; a single-app record also reads as a record holding
|
|
@@ -5840,26 +5835,20 @@ function isStoredRecord(value) {
|
|
|
5840
5835
|
function normalized(stored) {
|
|
5841
5836
|
if (stored === void 0) return void 0;
|
|
5842
5837
|
if (isEmulatorInstances(stored)) {
|
|
5843
|
-
if (stored.formatVersion
|
|
5844
|
-
|
|
5845
|
-
apps: stored.apps
|
|
5846
|
-
};
|
|
5847
|
-
return withFullAddressKeys(stored);
|
|
5838
|
+
if (stored.formatVersion !== void 0 && FULL_ADDRESS_FORMAT_VERSIONS.has(stored.formatVersion)) return { apps: stored.apps };
|
|
5839
|
+
return withFullAddressKeys({ apps: stored.apps });
|
|
5848
5840
|
}
|
|
5849
5841
|
const nodes = Object.fromEntries(Object.entries(stored.nodes).map(([address, { id, port }]) => [address, {
|
|
5850
5842
|
kind: "service",
|
|
5851
5843
|
id,
|
|
5852
5844
|
port
|
|
5853
5845
|
}]));
|
|
5854
|
-
return withFullAddressKeys({
|
|
5855
|
-
current: stored.app,
|
|
5856
|
-
apps: { [stored.app]: { nodes } }
|
|
5857
|
-
});
|
|
5846
|
+
return withFullAddressKeys({ apps: { [stored.app]: { nodes } } });
|
|
5858
5847
|
}
|
|
5859
|
-
/** The project directory that holds
|
|
5848
|
+
/** The project directory that holds an environment's folder (`<directory>/.prisma-composer/dev/<environment>`). */
|
|
5860
5849
|
function directoryOf(devDir) {
|
|
5861
|
-
const
|
|
5862
|
-
return
|
|
5850
|
+
const devRoot = path$1.dirname(path$1.normalize(devDir));
|
|
5851
|
+
return devRoot.endsWith(DEV_DIR) ? devRoot.slice(0, -DEV_DIR.length - 1) : devRoot;
|
|
5863
5852
|
}
|
|
5864
5853
|
function store(devDir) {
|
|
5865
5854
|
return createStore(path$1.join(devDir, EMULATOR_INSTANCES_FILE), isStoredRecord, void 0);
|
|
@@ -5869,13 +5858,13 @@ async function readRecord(devDir) {
|
|
|
5869
5858
|
}
|
|
5870
5859
|
async function updateRecord(devDir, mutate) {
|
|
5871
5860
|
await store(devDir).update((stored) => ({
|
|
5872
|
-
formatVersion:
|
|
5861
|
+
formatVersion: 3,
|
|
5873
5862
|
...mutate(normalized(stored))
|
|
5874
5863
|
}));
|
|
5875
5864
|
}
|
|
5876
|
-
/** The record `prisma dev` left in
|
|
5877
|
-
function readEmulatorInstances(
|
|
5878
|
-
return readRecord(
|
|
5865
|
+
/** The record `prisma dev` left in an environment's folder; undefined when it has not run there. */
|
|
5866
|
+
function readEmulatorInstances(devDir) {
|
|
5867
|
+
return readRecord(devDir);
|
|
5879
5868
|
}
|
|
5880
5869
|
async function appNodes$1(scope) {
|
|
5881
5870
|
return (await readRecord(scope.devDir))?.apps[scope.app]?.nodes ?? {};
|
|
@@ -5884,19 +5873,17 @@ async function updateNodes(scope, mutate) {
|
|
|
5884
5873
|
await updateRecord(scope.devDir, (record) => {
|
|
5885
5874
|
const nodes = { ...record?.apps[scope.app]?.nodes ?? {} };
|
|
5886
5875
|
mutate(nodes);
|
|
5887
|
-
return {
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
[scope.app]: { nodes }
|
|
5892
|
-
}
|
|
5893
|
-
};
|
|
5876
|
+
return { apps: {
|
|
5877
|
+
...record?.apps,
|
|
5878
|
+
[scope.app]: { nodes }
|
|
5879
|
+
} };
|
|
5894
5880
|
});
|
|
5895
5881
|
}
|
|
5896
5882
|
function labelsFor(scope, address) {
|
|
5897
5883
|
return {
|
|
5898
5884
|
"composer.directory": directoryOf(scope.devDir),
|
|
5899
5885
|
"composer.app": scope.app,
|
|
5886
|
+
"composer.environment": scope.environment,
|
|
5900
5887
|
"composer.address": address
|
|
5901
5888
|
};
|
|
5902
5889
|
}
|
|
@@ -5942,25 +5929,6 @@ async function stopRunning(kind, ids) {
|
|
|
5942
5929
|
await client.stopInstances(ids);
|
|
5943
5930
|
return listed.filter((i) => i.status === "running").map((i) => i.id);
|
|
5944
5931
|
}
|
|
5945
|
-
/**
|
|
5946
|
-
* Makes `scope.app` the directory's current app. When another app ran here
|
|
5947
|
-
* last, its service processes and database servers are stopped and its
|
|
5948
|
-
* instances stay recorded, so running it again resumes them with their data
|
|
5949
|
-
* and ports. Returns the previous app's name when it changed.
|
|
5950
|
-
*/
|
|
5951
|
-
async function selectApp(scope) {
|
|
5952
|
-
const record = await readRecord(scope.devDir);
|
|
5953
|
-
const previous = record?.current;
|
|
5954
|
-
if (previous !== void 0 && previous !== scope.app) await stopNodes(record?.apps[previous]?.nodes ?? {});
|
|
5955
|
-
await updateRecord(scope.devDir, (latest) => ({
|
|
5956
|
-
current: scope.app,
|
|
5957
|
-
apps: {
|
|
5958
|
-
...latest?.apps,
|
|
5959
|
-
[scope.app]: latest?.apps[scope.app] ?? { nodes: {} }
|
|
5960
|
-
}
|
|
5961
|
-
}));
|
|
5962
|
-
return previous !== void 0 && previous !== scope.app ? previous : void 0;
|
|
5963
|
-
}
|
|
5964
5932
|
/** Each node of the app of `kind`, with the instance that backs it. */
|
|
5965
5933
|
async function nodeInstancesOf(scope, kind) {
|
|
5966
5934
|
return Object.entries(await appNodes$1(scope)).flatMap(([address, instance]) => isOfKind(instance, kind) ? [{
|
|
@@ -6043,14 +6011,16 @@ async function ensureDatabaseInstance(scope, address, prismaDevModulePath) {
|
|
|
6043
6011
|
}
|
|
6044
6012
|
/**
|
|
6045
6013
|
* The bucket for `address`. The recorded bucket is reused while the bucket
|
|
6046
|
-
* emulator still has it
|
|
6047
|
-
* recorded
|
|
6014
|
+
* emulator still has it over `dir`. Otherwise a new one is created over `dir`
|
|
6015
|
+
* and recorded, replacing a recorded one over another directory; the objects
|
|
6016
|
+
* already in `dir` are its objects.
|
|
6048
6017
|
*/
|
|
6049
6018
|
async function ensureBucketInstance(scope, address, dir) {
|
|
6050
6019
|
const client = bucketsClient();
|
|
6051
6020
|
const recorded = await recordedInstance(scope, address, "bucket");
|
|
6052
6021
|
const existing = recorded ? await client.getInstance(recorded.id) : void 0;
|
|
6053
|
-
if (existing) return existing;
|
|
6022
|
+
if (existing?.dir === dir) return existing;
|
|
6023
|
+
if (existing) await client.deleteInstance(existing.id);
|
|
6054
6024
|
const created = await client.createInstance({
|
|
6055
6025
|
labels: labelsFor(scope, address),
|
|
6056
6026
|
dir
|
|
@@ -6092,18 +6062,16 @@ async function recordedKinds(scope) {
|
|
|
6092
6062
|
}
|
|
6093
6063
|
/**
|
|
6094
6064
|
* `--fresh`: deletes the app's recorded instances of every kind and its
|
|
6095
|
-
* entry. Other apps' entries are left alone. A
|
|
6096
|
-
*
|
|
6065
|
+
* entry. Other apps' entries and other environments are left alone. A
|
|
6066
|
+
* bucket's objects live in the environment's folder, which `--fresh` removes
|
|
6067
|
+
* separately.
|
|
6097
6068
|
*/
|
|
6098
6069
|
async function deleteAppInstances(scope) {
|
|
6099
6070
|
for (const instance of Object.values(await appNodes$1(scope))) await deleteInstance(instance);
|
|
6100
6071
|
await updateRecord(scope.devDir, (record) => {
|
|
6101
6072
|
const apps = { ...record?.apps };
|
|
6102
6073
|
delete apps[scope.app];
|
|
6103
|
-
return {
|
|
6104
|
-
current: record?.current ?? scope.app,
|
|
6105
|
-
apps
|
|
6106
|
-
};
|
|
6074
|
+
return { apps };
|
|
6107
6075
|
});
|
|
6108
6076
|
}
|
|
6109
6077
|
/** When `prisma dev` ends: stops the app's service processes and database servers, keeping their data and ports. */
|
|
@@ -6148,21 +6116,15 @@ function bucketIdOfInput(value) {
|
|
|
6148
6116
|
}
|
|
6149
6117
|
const BUCKETS_DIR = "buckets";
|
|
6150
6118
|
/**
|
|
6151
|
-
* Where a bucket's objects live: in the
|
|
6119
|
+
* Where a bucket's objects live: in the environment's folder, under its app, so `--fresh`
|
|
6152
6120
|
* removes them with the app. The folder is named by the address below the app, which is the
|
|
6153
|
-
* name earlier releases gave it
|
|
6121
|
+
* name earlier releases gave it.
|
|
6154
6122
|
*/
|
|
6155
6123
|
function bucketDataDir(scope, address) {
|
|
6156
6124
|
const prefix = `${scope.app}.`;
|
|
6157
6125
|
if (!address.startsWith(prefix)) throw new Error(`local dev: bucket address "${address}" is not inside the app "${scope.app}".`);
|
|
6158
6126
|
return path$1.join(scope.devDir, BUCKETS_DIR, scope.app, address.slice(prefix.length));
|
|
6159
6127
|
}
|
|
6160
|
-
function appScopeOf$2(input) {
|
|
6161
|
-
return {
|
|
6162
|
-
devDir: input.devDir,
|
|
6163
|
-
app: appNameOf(input.container)
|
|
6164
|
-
};
|
|
6165
|
-
}
|
|
6166
6128
|
/**
|
|
6167
6129
|
* `Bucket` → the bucket instance the directory's record names for the
|
|
6168
6130
|
* resource, created when there is none, over an in-project data root. Its
|
|
@@ -6177,7 +6139,7 @@ function LocalBucketProvider(input) {
|
|
|
6177
6139
|
try: async () => {
|
|
6178
6140
|
const name = id;
|
|
6179
6141
|
return {
|
|
6180
|
-
bucketId: (await ensureBucketInstance(appScopeOf
|
|
6142
|
+
bucketId: (await ensureBucketInstance(appScopeOf(input), name, bucketDataDir(appScopeOf(input), name))).id,
|
|
6181
6143
|
name,
|
|
6182
6144
|
projectId: projectIdOfInput(news.project),
|
|
6183
6145
|
createdAt: DEV_TIMESTAMP,
|
|
@@ -6189,7 +6151,7 @@ function LocalBucketProvider(input) {
|
|
|
6189
6151
|
diff: ({ output }) => Effect.tryPromise({
|
|
6190
6152
|
try: async () => {
|
|
6191
6153
|
if (output === void 0) return void 0;
|
|
6192
|
-
return await recordedInstanceId(appScopeOf
|
|
6154
|
+
return await recordedInstanceId(appScopeOf(input), output.name) === output.bucketId ? void 0 : { action: "update" };
|
|
6193
6155
|
},
|
|
6194
6156
|
catch: (cause) => cause
|
|
6195
6157
|
}),
|
|
@@ -6449,11 +6411,8 @@ async function materializeEnv(devDir, address, port) {
|
|
|
6449
6411
|
if (process.env["HOME"] !== void 0) env["HOME"] = process.env["HOME"];
|
|
6450
6412
|
return env;
|
|
6451
6413
|
}
|
|
6452
|
-
function
|
|
6453
|
-
return
|
|
6454
|
-
devDir: input.devDir,
|
|
6455
|
-
app: appNameOf(input.container)
|
|
6456
|
-
};
|
|
6414
|
+
function artifactDirOf(devDir, artifactHash) {
|
|
6415
|
+
return path$1.join(devDir, "artifacts", artifactHash);
|
|
6457
6416
|
}
|
|
6458
6417
|
function localUrl(port) {
|
|
6459
6418
|
return `http://localhost:${String(port)}`;
|
|
@@ -6471,7 +6430,7 @@ function LocalAppProvider(input) {
|
|
|
6471
6430
|
reconcile: ({ id, news }) => Effect.tryPromise({
|
|
6472
6431
|
try: async () => {
|
|
6473
6432
|
const name = id;
|
|
6474
|
-
const { instance } = await ensureServiceInstance(appScopeOf
|
|
6433
|
+
const { instance } = await ensureServiceInstance(appScopeOf(input), name);
|
|
6475
6434
|
const url = localUrl(instance.port);
|
|
6476
6435
|
return {
|
|
6477
6436
|
appId: name,
|
|
@@ -6490,13 +6449,13 @@ function LocalAppProvider(input) {
|
|
|
6490
6449
|
diff: ({ output }) => Effect.tryPromise({
|
|
6491
6450
|
try: async () => {
|
|
6492
6451
|
if (output === void 0) return void 0;
|
|
6493
|
-
if ((await liveServiceInstance(appScopeOf
|
|
6452
|
+
if ((await liveServiceInstance(appScopeOf(input), output.name))?.url === output.appEndpointDomain) return void 0;
|
|
6494
6453
|
return { action: "update" };
|
|
6495
6454
|
},
|
|
6496
6455
|
catch: (cause) => cause
|
|
6497
6456
|
}),
|
|
6498
6457
|
delete: ({ output }) => Effect.tryPromise({
|
|
6499
|
-
try: () => deleteNodeInstance(appScopeOf
|
|
6458
|
+
try: () => deleteNodeInstance(appScopeOf(input), output.name),
|
|
6500
6459
|
catch: (cause) => cause
|
|
6501
6460
|
}),
|
|
6502
6461
|
read: ({ output }) => Effect.succeed(output)
|
|
@@ -6556,10 +6515,10 @@ function LocalDeploymentProvider(input) {
|
|
|
6556
6515
|
const appId = appIdOfInput(news.app);
|
|
6557
6516
|
if (news.artifactPath === void 0) throw new Error("local Deployment requires an artifactPath — nothing to run.");
|
|
6558
6517
|
const artifactHash = await artifactSha256(news.artifactPath);
|
|
6559
|
-
const artifactDir =
|
|
6518
|
+
const artifactDir = artifactDirOf(input.devDir, artifactHash);
|
|
6560
6519
|
if (!fs$2.existsSync(artifactDir)) extractComputeArtifact(news.artifactPath, artifactDir);
|
|
6561
6520
|
const { address, listens } = readComputeManifest(artifactDir);
|
|
6562
|
-
const { instance } = await ensureServiceInstance(appScopeOf
|
|
6521
|
+
const { instance } = await ensureServiceInstance(appScopeOf(input), appId);
|
|
6563
6522
|
const env = await materializeEnv(input.devDir, address, instance.port);
|
|
6564
6523
|
try {
|
|
6565
6524
|
await computeClient().putDeployment(instance.id, {
|
|
@@ -6590,8 +6549,10 @@ function LocalDeploymentProvider(input) {
|
|
|
6590
6549
|
diff: ({ output }) => Effect.tryPromise({
|
|
6591
6550
|
try: async () => {
|
|
6592
6551
|
if (output === void 0) return void 0;
|
|
6593
|
-
|
|
6594
|
-
|
|
6552
|
+
const live = await liveServiceInstance(appScopeOf(input), output.appId);
|
|
6553
|
+
const { artifactHash } = output;
|
|
6554
|
+
if (live?.artifactHash !== artifactHash) return { action: "update" };
|
|
6555
|
+
return artifactHash === void 0 || fs$2.existsSync(artifactDirOf(input.devDir, artifactHash)) ? void 0 : { action: "update" };
|
|
6595
6556
|
},
|
|
6596
6557
|
catch: (cause) => cause
|
|
6597
6558
|
}),
|
|
@@ -6624,6 +6585,45 @@ function LocalProjectProvider(_input) {
|
|
|
6624
6585
|
delete: () => Effect.void
|
|
6625
6586
|
}));
|
|
6626
6587
|
}
|
|
6588
|
+
/**
|
|
6589
|
+
* Releases before each environment had its own folder kept local dev state
|
|
6590
|
+
* directly in `.prisma-composer/dev/`. That state is the environment `dev`'s:
|
|
6591
|
+
* the first run after an upgrade moves the record, the environment variable
|
|
6592
|
+
* values, the placeholder secrets and the bucket objects into `dev`'s folder,
|
|
6593
|
+
* so its databases and objects are kept. Unpacked artifacts and the generated
|
|
6594
|
+
* stack file are regenerated, so they are removed instead. Delete this file
|
|
6595
|
+
* once no such folder remains.
|
|
6596
|
+
*/
|
|
6597
|
+
const PRE_ENVIRONMENT_ENVIRONMENT = "dev";
|
|
6598
|
+
const MOVED = [
|
|
6599
|
+
EMULATOR_INSTANCES_FILE,
|
|
6600
|
+
"env.json",
|
|
6601
|
+
"secrets.json",
|
|
6602
|
+
BUCKETS_DIR
|
|
6603
|
+
];
|
|
6604
|
+
const REMOVED = ["artifacts", "alchemy.run.ts"];
|
|
6605
|
+
function isFile(file) {
|
|
6606
|
+
return fs$2.statSync(file, { throwIfNoEntry: false })?.isFile() === true;
|
|
6607
|
+
}
|
|
6608
|
+
/** Moves a pre-environment `.prisma-composer/dev/` in `directory` into the environment `dev`; does nothing for any other folder. */
|
|
6609
|
+
function movePreEnvironmentDevState(directory) {
|
|
6610
|
+
const root = path$1.join(directory, DEV_DIR);
|
|
6611
|
+
const target = path$1.join(directory, devEnvironmentDir(PRE_ENVIRONMENT_ENVIRONMENT));
|
|
6612
|
+
if (!isFile(path$1.join(root, "emulator-instances.json"))) return;
|
|
6613
|
+
if (fs$2.existsSync(path$1.join(target, "emulator-instances.json"))) return;
|
|
6614
|
+
fs$2.mkdirSync(target, { recursive: true });
|
|
6615
|
+
for (const entry of MOVED) if (fs$2.existsSync(path$1.join(root, entry))) fs$2.renameSync(path$1.join(root, entry), path$1.join(target, entry));
|
|
6616
|
+
fs$2.writeFileSync(path$1.join(target, DEV_ENVIRONMENT_NAME_FILE), `${PRE_ENVIRONMENT_ENVIRONMENT}\n`);
|
|
6617
|
+
for (const entry of REMOVED) fs$2.rmSync(path$1.join(root, entry), {
|
|
6618
|
+
recursive: true,
|
|
6619
|
+
force: true
|
|
6620
|
+
});
|
|
6621
|
+
}
|
|
6622
|
+
/**
|
|
6623
|
+
* An app's local copy in one environment, read from the environment's
|
|
6624
|
+
* record alone: where each of its nodes runs, and stopping it. Behind
|
|
6625
|
+
* `prisma dev url` and `prisma dev stop`.
|
|
6626
|
+
*/
|
|
6627
6627
|
const CONDITION_OF = {
|
|
6628
6628
|
running: "running",
|
|
6629
6629
|
stopped: "stopped",
|
|
@@ -6684,12 +6684,16 @@ async function locate(address, node) {
|
|
|
6684
6684
|
condition: "running"
|
|
6685
6685
|
};
|
|
6686
6686
|
}
|
|
6687
|
-
/** The directory
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6687
|
+
/** The directory `prisma dev` ran in, from the environment's folder in it. */
|
|
6688
|
+
function directoryOf$1(devDir, environment) {
|
|
6689
|
+
return path$1.resolve(devDir, path$1.relative(devEnvironmentDir(environment), "."));
|
|
6690
|
+
}
|
|
6691
|
+
/** The app's local copy in the environment; undefined when `prisma dev` never ran it there. */
|
|
6692
|
+
async function currentApp(input) {
|
|
6693
|
+
const { devDir, app, environment } = input;
|
|
6694
|
+
movePreEnvironmentDevState(directoryOf$1(devDir, environment));
|
|
6695
|
+
const nodes = (await readEmulatorInstances(devDir))?.apps[app]?.nodes;
|
|
6696
|
+
if (nodes === void 0) return void 0;
|
|
6693
6697
|
return {
|
|
6694
6698
|
app,
|
|
6695
6699
|
addresses: Object.keys(nodes),
|
|
@@ -6699,7 +6703,8 @@ async function currentApp(devDir) {
|
|
|
6699
6703
|
},
|
|
6700
6704
|
stop: () => stopAppInstances({
|
|
6701
6705
|
devDir,
|
|
6702
|
-
app
|
|
6706
|
+
app,
|
|
6707
|
+
environment
|
|
6703
6708
|
})
|
|
6704
6709
|
};
|
|
6705
6710
|
}
|
|
@@ -6754,12 +6759,6 @@ function LocalDatabaseProvider(input) {
|
|
|
6754
6759
|
delete: () => Effect.void
|
|
6755
6760
|
}));
|
|
6756
6761
|
}
|
|
6757
|
-
function appScopeOf(input) {
|
|
6758
|
-
return {
|
|
6759
|
-
devDir: input.devDir,
|
|
6760
|
-
app: appNameOf(input.container)
|
|
6761
|
-
};
|
|
6762
|
-
}
|
|
6763
6762
|
function noRecordedInstanceError(databaseId) {
|
|
6764
6763
|
return /* @__PURE__ */ new Error(`no local Postgres instance recorded for databaseId "${databaseId}" — the Database provider did not run; converge is corrupt (try --fresh).`);
|
|
6765
6764
|
}
|
|
@@ -6834,9 +6833,25 @@ function removeLocalPaths(paths) {
|
|
|
6834
6833
|
});
|
|
6835
6834
|
}
|
|
6836
6835
|
/**
|
|
6837
|
-
* Removes
|
|
6838
|
-
*
|
|
6839
|
-
*
|
|
6836
|
+
* Removes one Alchemy stage's local state: the files directly in its folder,
|
|
6837
|
+
* then the folder once it is empty. Alchemy keeps the stage `feature/x` in
|
|
6838
|
+
* `feature/`'s folder, so a subfolder is another stage's and stays.
|
|
6839
|
+
*/
|
|
6840
|
+
function removeAlchemyStage(stageDir) {
|
|
6841
|
+
let entries;
|
|
6842
|
+
try {
|
|
6843
|
+
entries = fs$2.readdirSync(stageDir, { withFileTypes: true });
|
|
6844
|
+
} catch {
|
|
6845
|
+
return;
|
|
6846
|
+
}
|
|
6847
|
+
for (const entry of entries) if (!entry.isDirectory()) fs$2.rmSync(path$1.join(stageDir, entry.name), { force: true });
|
|
6848
|
+
if (entries.every((entry) => !entry.isDirectory())) fs$2.rmdirSync(stageDir);
|
|
6849
|
+
}
|
|
6850
|
+
/**
|
|
6851
|
+
* Removes an environment folder's contents for `--fresh`, except the
|
|
6852
|
+
* environment's recorded name and what other apps run in the environment
|
|
6853
|
+
* still use: the record of their emulator instances and their buckets'
|
|
6854
|
+
* objects. This app's objects go.
|
|
6840
6855
|
*/
|
|
6841
6856
|
function removeAppDevState(devDir, app) {
|
|
6842
6857
|
let entries;
|
|
@@ -6845,7 +6860,11 @@ function removeAppDevState(devDir, app) {
|
|
|
6845
6860
|
} catch {
|
|
6846
6861
|
return;
|
|
6847
6862
|
}
|
|
6848
|
-
const kept = /* @__PURE__ */ new Set([
|
|
6863
|
+
const kept = /* @__PURE__ */ new Set([
|
|
6864
|
+
DEV_ENVIRONMENT_NAME_FILE,
|
|
6865
|
+
EMULATOR_INSTANCES_FILE,
|
|
6866
|
+
BUCKETS_DIR
|
|
6867
|
+
]);
|
|
6849
6868
|
removeLocalPaths([...entries.filter((entry) => !kept.has(entry)).map((entry) => path$1.join(devDir, entry)), path$1.join(devDir, BUCKETS_DIR, app)]);
|
|
6850
6869
|
}
|
|
6851
6870
|
//#endregion
|
|
@@ -6944,9 +6963,12 @@ async function* mergedLogs(scope, signal, tail, addresses) {
|
|
|
6944
6963
|
}
|
|
6945
6964
|
}
|
|
6946
6965
|
async function devAttach(input) {
|
|
6966
|
+
const { appName: app, environment } = prismaCloudContainerOf(input.container).input;
|
|
6967
|
+
movePreEnvironmentDevState(directoryOf(input.devDir));
|
|
6947
6968
|
const scope = {
|
|
6948
6969
|
devDir: input.devDir,
|
|
6949
|
-
app
|
|
6970
|
+
app,
|
|
6971
|
+
environment
|
|
6950
6972
|
};
|
|
6951
6973
|
const client = computeClient();
|
|
6952
6974
|
return {
|
|
@@ -7051,12 +7073,7 @@ async function runDevEmulators(input) {
|
|
|
7051
7073
|
const { url: postgresUrl } = await ensureDaemon("postgres", daemonEntry("postgres"));
|
|
7052
7074
|
console.log(`[dev] postgres emulator ready at ${postgresUrl}`);
|
|
7053
7075
|
}
|
|
7054
|
-
const scope =
|
|
7055
|
-
devDir: input.devDir,
|
|
7056
|
-
app: appNameOf(input.container)
|
|
7057
|
-
};
|
|
7058
|
-
const previous = await selectApp(scope);
|
|
7059
|
-
if (previous !== void 0) console.log(`[dev] stopped the local services of "${previous}", the app run here before; its data is kept`);
|
|
7076
|
+
const scope = appScopeOf(input);
|
|
7060
7077
|
const portChanges = await ensureAppInstances(scope, nodes).catch(async (error) => {
|
|
7061
7078
|
await stopAppInstances(scope).catch(() => void 0);
|
|
7062
7079
|
throw error;
|
|
@@ -7073,7 +7090,8 @@ function missingEnvParamsError(missing) {
|
|
|
7073
7090
|
return /* @__PURE__ */ new Error(`local dev preflight failed — ${missing.length} env-sourced param(s) are not set in this shell:\n${lines.join("\n")}\n\nSet each in the shell you run \`prisma dev\` from.`);
|
|
7074
7091
|
}
|
|
7075
7092
|
async function runDevPreflight(input) {
|
|
7076
|
-
|
|
7093
|
+
movePreEnvironmentDevState(process.cwd());
|
|
7094
|
+
const store = secretsStore(`${process.cwd()}/${devEnvironmentDir(input.environment)}`);
|
|
7077
7095
|
const { secrets, envParams } = collectPreflightNames(input.graph);
|
|
7078
7096
|
await store.update((current) => {
|
|
7079
7097
|
const next = { ...current };
|
|
@@ -7109,18 +7127,21 @@ const DAEMON_OF = {
|
|
|
7109
7127
|
};
|
|
7110
7128
|
async function runDevTeardown(input) {
|
|
7111
7129
|
const app = prismaCloudContainerOf(input.container).input.appName;
|
|
7130
|
+
const { environment } = input;
|
|
7112
7131
|
const cwd = process.cwd();
|
|
7113
|
-
|
|
7132
|
+
movePreEnvironmentDevState(cwd);
|
|
7133
|
+
const devDir = `${cwd}/${devEnvironmentDir(environment)}`;
|
|
7114
7134
|
const scope = {
|
|
7115
7135
|
devDir,
|
|
7116
|
-
app
|
|
7136
|
+
app,
|
|
7137
|
+
environment
|
|
7117
7138
|
};
|
|
7118
7139
|
try {
|
|
7119
7140
|
for (const kind of await recordedKinds(scope)) await ensureDaemon(DAEMON_OF[kind], daemonEntry(DAEMON_OF[kind]));
|
|
7120
7141
|
await deleteAppInstances(scope);
|
|
7121
7142
|
} finally {
|
|
7122
7143
|
removeAppDevState(devDir, app);
|
|
7123
|
-
|
|
7144
|
+
removeAlchemyStage(`${cwd}/.alchemy/state/${app}/${environment}`);
|
|
7124
7145
|
}
|
|
7125
7146
|
}
|
|
7126
7147
|
/** `localTargetProviders()`'s `ProviderCollection` doesn't structurally unify with Alchemy's inferred providers Layer (a @internal/lowering typings gap); it satisfies it at runtime — mirrors `control/extension.ts`'s own `asProvidersLayer`, duplicated rather than shared so this module imports nothing from `./control`. */
|
|
@@ -7140,7 +7161,7 @@ function localTargetDescriptor() {
|
|
|
7140
7161
|
emulators: (input) => runDevEmulators(input),
|
|
7141
7162
|
attach: (input) => devAttach(input),
|
|
7142
7163
|
teardown: (input) => runDevTeardown(input),
|
|
7143
|
-
current: (input) => currentApp(input
|
|
7164
|
+
current: (input) => currentApp(input)
|
|
7144
7165
|
};
|
|
7145
7166
|
}
|
|
7146
7167
|
//#endregion
|