@samebase/alchemy-convex 0.4.1 → 0.5.0
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/README.md +21 -0
- package/lib/index.d.ts +12 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +187 -1
- package/lib/index.js.map +1 -1
- package/package.json +5 -2
- package/src/State.ts +316 -0
- package/src/component/_generated/api.ts +50 -0
- package/src/component/_generated/component.ts +92 -0
- package/src/component/_generated/dataModel.ts +60 -0
- package/src/component/_generated/server.ts +169 -0
- package/src/component/convex.config.ts +5 -0
- package/src/component/schema.ts +19 -0
- package/src/component/state.ts +169 -0
- package/src/index.ts +1 -0
package/README.md
CHANGED
|
@@ -90,6 +90,27 @@ reads them through the stack's config provider (process env, `.env`, stack secre
|
|
|
90
90
|
A key that does not fit the deployment is not used: the provider uses the access token. To pass
|
|
91
91
|
values explicitly: `Convex.providers(Convex.fromValues({ accessToken, deployKey }))`.
|
|
92
92
|
|
|
93
|
+
## State in Convex
|
|
94
|
+
|
|
95
|
+
`state: Convex.state()` keeps the Alchemy state of every stage in the production deployment of the
|
|
96
|
+
project, so the stack needs no Cloudflare token.
|
|
97
|
+
[docs/design/convex-state.md](docs/design/convex-state.md) records the decisions.
|
|
98
|
+
|
|
99
|
+
1. Mount the state component in `convex/convex.config.ts` with its default name:
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import alchemyState from "@samebase/alchemy-convex/convex.config";
|
|
103
|
+
app.use(alchemyState);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
2. Set `CONVEX_STATE_DEPLOY_KEY` in every run, a preview run too, to a production deploy key. A key
|
|
107
|
+
with only the actions `deployment:data:view` and `deployment:data:write` is sufficient.
|
|
108
|
+
|
|
109
|
+
The first run starts with empty state, keeps it in memory until `Convex.Deployment` has pushed the
|
|
110
|
+
component, and then writes it. A run whose push does not mount the component fails at the end.
|
|
111
|
+
Rows are in the `alchemyState` component tables `resources` and `outputs` in the dashboard. The
|
|
112
|
+
store has no lock: run one deploy of a stage at a time, such as with a CI concurrency group.
|
|
113
|
+
|
|
93
114
|
## Resources
|
|
94
115
|
|
|
95
116
|
- `Convex.Project`: `{ team, name, deploymentRegion?, deploymentType? }` creates a project with its
|
package/lib/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { Resource } from "alchemy";
|
|
|
7
7
|
import * as Provider from "alchemy/Provider";
|
|
8
8
|
import "effect/process/ChildProcessSpawner";
|
|
9
9
|
import { createDeploymentClient, createManagementClient } from "@convex-dev/platform";
|
|
10
|
+
import { State, StateStoreError } from "alchemy/State";
|
|
10
11
|
import { components } from "@convex-dev/platform/managementApi";
|
|
11
12
|
//#region src/Credentials.d.ts
|
|
12
13
|
interface ResolvedCredentials {
|
|
@@ -339,5 +340,16 @@ export declare class ProjectNotFound extends ProjectNotFound_base {
|
|
|
339
340
|
get message(): string;
|
|
340
341
|
}
|
|
341
342
|
//#endregion
|
|
343
|
+
//#region src/State.d.ts
|
|
344
|
+
/** Environment variable with the deploy key of the deployment that holds the state. */
|
|
345
|
+
export declare const STATE_DEPLOY_KEY_ENV = "CONVEX_STATE_DEPLOY_KEY";
|
|
346
|
+
/**
|
|
347
|
+
* Alchemy state in the alchemyState component of the deployment that the
|
|
348
|
+
* deploy key in CONVEX_STATE_DEPLOY_KEY names: the production deployment of
|
|
349
|
+
* the project. The key needs the actions `deployment:data:view` and
|
|
350
|
+
* `deployment:data:write`.
|
|
351
|
+
*/
|
|
352
|
+
export declare const state: () => Layer.Layer<State>;
|
|
353
|
+
//#endregion
|
|
342
354
|
export type { DeploymentAttributes, DeploymentProps, DeploymentRegion, EnvValue, ProjectAttributes, ProjectProps, Source };
|
|
343
355
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/Credentials.ts","../src/ManagementApi.ts","../src/Providers.ts","../src/Push.ts","../src/Deployment.ts","../src/Project.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/Credentials.ts","../src/ManagementApi.ts","../src/Providers.ts","../src/Push.ts","../src/Deployment.ts","../src/Project.ts","../src/State.ts"],"mappings":";;;;;;;;;;;;UA6BiB;;WAEN,aAAa,SAAS;;WAEtB;;UAGM;;WAEN,aAAa,OAAO,OAAO;;WAE3B,gBAAgB,OAAO;;WAEvB,WAAW,OAAO,OAAO,SAAS;;;qBAGhC,oBAAoB;;qBAKpB;;qBAGA;;;;qBAOA,yBAAyB;;;;;;;;;qBAiCzB,kBAAiB,MAAM,MAAM;;qBA0B7B,aAAc;WAChB,cAAc,SAAS;WACvB,YAAY,SAAS;MAC5B,MAAM,MAAM;;;KC3GJ,mBAAmB,kBAAkB;KACrC,mBAAmB,kBAAkB;;UAGhC,YAAY;WAClB,OAAO;WACP;WACA,UAAU;;;;;;;;;;;;;qBAQR,uBAAuB;UAuBnB;;WAEN,UAAU,GACjB,mBACA,MAAM,QAAQ,qBAAqB,QAAQ,YAAY,QACpD,OAAO,OAAO,GAAG;;WAEb,cACP,mBACA,MAAM,QAAQ,qBAAqB,QAAQ,0BACxC,OAAO,aAAa;;WAEhB,oBAAoB,GAC3B,mBACA,6BACA,WAAW,SAAS,kBACpB,MAAM,QAAQ,qBAAqB,QAAQ,YAAY,QACpD,OAAO,OAAO,GAAG;;WAEb,gBAAgB,0BAA0B,OAAO,eAAe;;;;;;;;WAQhE,oBAAoB,mBAAmB,OAAO;;;;;WAK9C,YAAY,OAAO,SAAS,qBAAqB;;;qBAM/C,sBAAsB;;;;qBClFtB,kBAAkB;;;;;;qBAOlB,YAAa,cAAa,MAAM,MAAM,iBAA2B,MAAA,MAAA,8CAAA,mCAAA,oDAAA;;;;KC8BlE,oBAAoB,SAAS;;;;;KAM7B;;WAIG;;;;;;;;WAQA;;;;;;;WAOA;;;;;;qBA2BF,0BAA0B;MAIxB;;;;;;qBAMF,0BAA0B;MAIxB;;;;;;;;;qBAMF,uBAAuB;MAMrB;;;;;;;qBAQF,2BAA2B;MAIzB;;;;;;;qBAMF,oCAAoC;MAIlC;;;;;;qBAMF,kCAAkC;MAIhC;;;qBAuCF,oBACX;EACG;EAAa;;;;UCzHR;;WAEC;aAAoB;;;;;;;;WAOpB,SAAS;;WAET,MAAM,SAAS,eAAe;;KAG7B,mBACP;;WAEU;MAEV;;WAEU;;;;;WAKA;;;UAIL;WACC;WACA,MAAM;;WAEN;;WAEA;;WAEA;;WAEA;;WAEA;;UAGM,6BAA6B;;WAEnC;;WAEA;;YAGC,aAAa,8BAEvB,iBACA,6BAEA;qBAEW,8BAAU,cAAA;;;;;;;;;qBAKV,iCAAiC;MAU/B;;;;;;qBAMF,qCAAqC;MAInC;;;;;;;;;qBAMF,4BAA4B;MAS1B;;;;;KChJH,mBAAmB;KAEnB;;WAGG;;WAEA;;WAEA,mBAAmB;;WAEnB;;;WAIA;;WAEA;;UAGE;WACN;WACA;WACA;WACA;WACA;WACA;;YAGC,UAAU,2BAA2B,cAAc,0BAA0B;qBAC5E,2BAAO,cAAA;;;;;;;qBAGP,0BAA0B;MAIxB;;;;;;;;;;;;qBASF,gCAAgC;MAS9B;;;;;;;;qBAOF,yBAAyB;MAKvB;;;;;;qBAMF,+BAA+B;MAI7B;;;;;;;qBAMF,wBAAwB;MAItB;;;;;qBC7EF;;;;;;;qBAgQA,aAAY,MAAM,MAAM"}
|
package/lib/index.js
CHANGED
|
@@ -25,6 +25,7 @@ import { hashDirectory } from "alchemy/Command/Memo";
|
|
|
25
25
|
import * as Clock from "effect/Clock";
|
|
26
26
|
import * as ChildProcess from "effect/process/ChildProcess";
|
|
27
27
|
import * as Stream from "effect/Stream";
|
|
28
|
+
import { InMemoryService, STATE_STORE_VERSION, State, StateStoreError, encodeState, reviveState } from "alchemy/State";
|
|
28
29
|
//#region src/Credentials.ts
|
|
29
30
|
var Credentials = class extends Context.Service()("@samebase/alchemy-convex/Credentials") {};
|
|
30
31
|
/** Environment variable for the access token, read by {@link fromConfig}. */
|
|
@@ -1256,6 +1257,191 @@ var Providers = class extends Provider.ProviderCollection()("Convex") {};
|
|
|
1256
1257
|
*/
|
|
1257
1258
|
const providers = (credentials = fromConfig()) => Layer.effect(Providers, Provider.collection([Project, Deployment])).pipe(Layer.provide(Layer.mergeAll(ProjectProvider(), DeploymentProvider())), Layer.provide(ManagementApiLive()), Layer.provide(credentials), Layer.orDie);
|
|
1258
1259
|
//#endregion
|
|
1259
|
-
|
|
1260
|
+
//#region src/State.ts
|
|
1261
|
+
/** Environment variable with the deploy key of the deployment that holds the state. */
|
|
1262
|
+
const STATE_DEPLOY_KEY_ENV = "CONVEX_STATE_DEPLOY_KEY";
|
|
1263
|
+
/** The component path of alchemyState in the app: its default name. */
|
|
1264
|
+
const COMPONENT_PATH = "alchemyState";
|
|
1265
|
+
/** The body of POST /api/function and /api/query, with HTTP 200 or 560 for a function error. */
|
|
1266
|
+
const Reply = Schema.Union([Schema.Struct({
|
|
1267
|
+
status: Schema.Literal("success"),
|
|
1268
|
+
value: Schema.Unknown
|
|
1269
|
+
}), Schema.Struct({
|
|
1270
|
+
status: Schema.Literal("error"),
|
|
1271
|
+
errorMessage: Schema.String
|
|
1272
|
+
})]);
|
|
1273
|
+
/** The value of `_system/frontend/components:list`: the root has path "", a removed mount is "unmounted". */
|
|
1274
|
+
const Components = Schema.Array(Schema.Struct({
|
|
1275
|
+
path: Schema.String,
|
|
1276
|
+
state: Schema.String
|
|
1277
|
+
}));
|
|
1278
|
+
const failure = (message) => new StateStoreError({ message: `Convex state: ${message}` });
|
|
1279
|
+
/** No reply, HTTP 429, or HTTP 5xx: a new attempt can succeed. Every call of the store is idempotent. */
|
|
1280
|
+
const isTransient = (error) => error.http !== void 0 && (error.http.status === void 0 || error.http.status === 429 || error.http.status >= 500);
|
|
1281
|
+
const post = (url, headers, body) => Effect.tryPromise({
|
|
1282
|
+
try: () => fetch(url, {
|
|
1283
|
+
method: "POST",
|
|
1284
|
+
headers: {
|
|
1285
|
+
"Content-Type": "application/json",
|
|
1286
|
+
...headers
|
|
1287
|
+
},
|
|
1288
|
+
body: JSON.stringify(body)
|
|
1289
|
+
}),
|
|
1290
|
+
catch: () => new StateStoreError({
|
|
1291
|
+
message: `Convex state: POST ${url} failed`,
|
|
1292
|
+
http: {}
|
|
1293
|
+
})
|
|
1294
|
+
}).pipe(Effect.flatMap((response) => response.ok || response.status === 560 ? Effect.tryPromise({
|
|
1295
|
+
try: () => response.json(),
|
|
1296
|
+
catch: () => failure(`${url} gave no JSON`)
|
|
1297
|
+
}) : Effect.fail(new StateStoreError({
|
|
1298
|
+
message: `Convex state: POST ${url} failed with HTTP ${response.status}`,
|
|
1299
|
+
http: { status: response.status }
|
|
1300
|
+
}))), Effect.retry({
|
|
1301
|
+
while: isTransient,
|
|
1302
|
+
schedule: Schedule.exponential("100 millis").pipe(Schedule.jittered),
|
|
1303
|
+
times: 5
|
|
1304
|
+
}));
|
|
1305
|
+
const decode = (schema, what) => (value) => Schema.decodeUnknownEffect(schema)(value).pipe(Effect.mapError(() => failure(`bad ${what}`)));
|
|
1306
|
+
/**
|
|
1307
|
+
* The deployment URL of a deploy key. The Convex CLI makes the same unofficial
|
|
1308
|
+
* call for every deploy key (convex 1.46 `cli/lib/deploymentSelection.js`).
|
|
1309
|
+
*/
|
|
1310
|
+
const urlForKey = (key) => post("https://api.convex.dev/api/deployment/url_for_key", {}, { deployKey: Redacted.value(key) }).pipe(Effect.flatMap(decode(Schema.String, "deployment URL")));
|
|
1311
|
+
const makeFunctionApi = (url, key) => ({ call: (path, args, componentPath) => post(`${url}/api/${componentPath === void 0 ? "query" : "function"}`, { Authorization: `Convex ${Redacted.value(key)}` }, {
|
|
1312
|
+
...componentPath === void 0 ? {} : { componentPath },
|
|
1313
|
+
path,
|
|
1314
|
+
args,
|
|
1315
|
+
format: "json"
|
|
1316
|
+
}).pipe(Effect.flatMap(decode(Reply, `reply of ${path}`)), Effect.flatMap((reply) => reply.status === "success" ? Effect.succeed(reply.value) : Effect.fail(failure(reply.errorMessage.trim())))) });
|
|
1317
|
+
/** The state of the alchemyState mount: "active", "unmounted" (its rows are kept), or undefined. */
|
|
1318
|
+
const mountOf = (api) => api.call("_system/frontend/components:list", {}).pipe(Effect.flatMap(decode(Components, "component list")), Effect.map((components) => components.find((c) => c.path === COMPONENT_PATH)?.state));
|
|
1319
|
+
/** The component functions with Alchemy's encoding: the JSON text of encodeState. */
|
|
1320
|
+
const remoteOf = (api) => {
|
|
1321
|
+
const run = (name, args) => api.call(`state:${name}`, args, COMPONENT_PATH);
|
|
1322
|
+
const strings = (name, args) => run(name, args).pipe(Effect.flatMap(decode(Schema.Array(Schema.String), name)));
|
|
1323
|
+
const optional = (name, args) => run(name, args).pipe(Effect.flatMap(decode(Schema.NullOr(Schema.String), name)));
|
|
1324
|
+
const encode = (value) => JSON.stringify(encodeState(value));
|
|
1325
|
+
return {
|
|
1326
|
+
listStacks: () => strings("stacks", {}),
|
|
1327
|
+
listStages: (stack) => strings("stages", { stack }),
|
|
1328
|
+
list: (r) => strings("list", {
|
|
1329
|
+
stack: r.stack,
|
|
1330
|
+
stage: r.stage
|
|
1331
|
+
}),
|
|
1332
|
+
get: (r) => optional("get", {
|
|
1333
|
+
stack: r.stack,
|
|
1334
|
+
stage: r.stage,
|
|
1335
|
+
fqn: r.fqn
|
|
1336
|
+
}).pipe(Effect.map((text) => text === null ? void 0 : JSON.parse(text, reviveState))),
|
|
1337
|
+
getReplacedResources: (r) => strings("replaced", {
|
|
1338
|
+
stack: r.stack,
|
|
1339
|
+
stage: r.stage
|
|
1340
|
+
}).pipe(Effect.map((texts) => texts.map((text) => JSON.parse(text, reviveState)))),
|
|
1341
|
+
getOutput: (r) => optional("getOutput", {
|
|
1342
|
+
stack: r.stack,
|
|
1343
|
+
stage: r.stage
|
|
1344
|
+
}).pipe(Effect.map((text) => text === null ? void 0 : JSON.parse(text, reviveState))),
|
|
1345
|
+
set: (r) => run("set", {
|
|
1346
|
+
stack: r.stack,
|
|
1347
|
+
stage: r.stage,
|
|
1348
|
+
fqn: r.fqn,
|
|
1349
|
+
value: encode(r.value)
|
|
1350
|
+
}),
|
|
1351
|
+
delete: (r) => run("remove", {
|
|
1352
|
+
stack: r.stack,
|
|
1353
|
+
stage: r.stage,
|
|
1354
|
+
fqn: r.fqn
|
|
1355
|
+
}),
|
|
1356
|
+
deleteStack: (r) => run("removeStack", {
|
|
1357
|
+
stack: r.stack,
|
|
1358
|
+
stage: r.stage
|
|
1359
|
+
}),
|
|
1360
|
+
setOutput: (r) => run("setOutput", {
|
|
1361
|
+
stack: r.stack,
|
|
1362
|
+
stage: r.stage,
|
|
1363
|
+
value: encode(r.value)
|
|
1364
|
+
})
|
|
1365
|
+
};
|
|
1366
|
+
};
|
|
1367
|
+
const unmounted = failure(`the ${COMPONENT_PATH} component of the deployment is unmounted. Its rows are kept: mount @samebase/alchemy-convex/convex.config in convex/convex.config.ts again.`);
|
|
1368
|
+
/**
|
|
1369
|
+
* The StateService over `api`. Without an alchemyState component at
|
|
1370
|
+
* the start, the state of the run stays in memory until a write finds the
|
|
1371
|
+
* component active.
|
|
1372
|
+
*/
|
|
1373
|
+
const makeConvexState = (api) => Effect.gen(function* () {
|
|
1374
|
+
const remote = remoteOf(api);
|
|
1375
|
+
const mount = yield* mountOf(api);
|
|
1376
|
+
if (mount === "unmounted") return yield* unmounted;
|
|
1377
|
+
let pending = mount === void 0;
|
|
1378
|
+
const rows = {};
|
|
1379
|
+
const outputs = {};
|
|
1380
|
+
const memory = yield* InMemoryService(rows, outputs);
|
|
1381
|
+
/** Moves the memory to the component once it is active. Rows that the run did not read stop it. */
|
|
1382
|
+
const flush = Effect.gen(function* () {
|
|
1383
|
+
const now = yield* mountOf(api);
|
|
1384
|
+
if (now === void 0) return;
|
|
1385
|
+
if (now !== "active") return yield* unmounted;
|
|
1386
|
+
const stages = [.../* @__PURE__ */ new Set([...Object.keys(rows), ...Object.keys(outputs)])].flatMap((stack) => [.../* @__PURE__ */ new Set([...Object.keys(rows[stack] ?? {}), ...Object.keys(outputs[stack] ?? {})])].map((stage) => ({
|
|
1387
|
+
stack,
|
|
1388
|
+
stage
|
|
1389
|
+
})));
|
|
1390
|
+
for (const { stack, stage } of stages) {
|
|
1391
|
+
const found = yield* remote.list({
|
|
1392
|
+
stack,
|
|
1393
|
+
stage
|
|
1394
|
+
});
|
|
1395
|
+
if (found.length > 0) return yield* failure(`${stack}/${stage} has ${found.length} rows in the deployment that this run did not read, so the run wrote none. Run it again.`);
|
|
1396
|
+
}
|
|
1397
|
+
for (const { stack, stage } of stages) {
|
|
1398
|
+
for (const [fqn, value] of Object.entries(rows[stack]?.[stage] ?? {})) yield* remote.set({
|
|
1399
|
+
stack,
|
|
1400
|
+
stage,
|
|
1401
|
+
fqn,
|
|
1402
|
+
value
|
|
1403
|
+
});
|
|
1404
|
+
const byStage = outputs[stack];
|
|
1405
|
+
if (byStage !== void 0 && stage in byStage) yield* remote.setOutput({
|
|
1406
|
+
stack,
|
|
1407
|
+
stage,
|
|
1408
|
+
value: byStage[stage]
|
|
1409
|
+
});
|
|
1410
|
+
}
|
|
1411
|
+
pending = false;
|
|
1412
|
+
});
|
|
1413
|
+
const read = (inMemory, inConvex) => Effect.suspend(() => pending ? inMemory : inConvex);
|
|
1414
|
+
const write = (inMemory, inConvex, result) => Effect.suspend(() => pending ? Effect.tap(inMemory, () => flush) : Effect.as(inConvex, result));
|
|
1415
|
+
return {
|
|
1416
|
+
id: "convex",
|
|
1417
|
+
getVersion: () => Effect.succeed(STATE_STORE_VERSION),
|
|
1418
|
+
listStacks: () => read(memory.listStacks(), remote.listStacks()),
|
|
1419
|
+
listStages: (stack) => read(memory.listStages(stack), remote.listStages(stack)),
|
|
1420
|
+
list: (request) => read(memory.list(request), remote.list(request)),
|
|
1421
|
+
get: (request) => read(memory.get(request), remote.get(request)),
|
|
1422
|
+
getReplacedResources: (request) => read(memory.getReplacedResources(request), remote.getReplacedResources(request)),
|
|
1423
|
+
getOutput: (request) => read(memory.getOutput(request), remote.getOutput(request)),
|
|
1424
|
+
set: (request) => write(memory.set(request), remote.set(request), request.value),
|
|
1425
|
+
delete: (request) => write(memory.delete(request), remote.delete(request), void 0),
|
|
1426
|
+
deleteStack: (request) => write(memory.deleteStack(request), remote.deleteStack(request), void 0),
|
|
1427
|
+
setOutput: (request) => write(memory.setOutput(request), remote.setOutput(request), request.value).pipe(Effect.tap(() => pending ? Effect.fail(failure(`the deployment of ${STATE_DEPLOY_KEY_ENV} has no ${COMPONENT_PATH} component at the end of the run, so this run saved no state. Mount @samebase/alchemy-convex/convex.config in convex/convex.config.ts.`)) : Effect.void))
|
|
1428
|
+
};
|
|
1429
|
+
});
|
|
1430
|
+
/**
|
|
1431
|
+
* Alchemy state in the alchemyState component of the deployment that the
|
|
1432
|
+
* deploy key in CONVEX_STATE_DEPLOY_KEY names: the production deployment of
|
|
1433
|
+
* the project. The key needs the actions `deployment:data:view` and
|
|
1434
|
+
* `deployment:data:write`.
|
|
1435
|
+
*/
|
|
1436
|
+
const state = () => Layer.effect(State, Effect.gen(function* () {
|
|
1437
|
+
const context = yield* Effect.context();
|
|
1438
|
+
return yield* Effect.cached(Effect.gen(function* () {
|
|
1439
|
+
const key = yield* Config.Redacted(STATE_DEPLOY_KEY_ENV);
|
|
1440
|
+
if (keyTargetOf(Redacted.value(key)).kind !== "deployment") return yield* failure(`${STATE_DEPLOY_KEY_ENV} must be the deploy key of one deployment, such as prod:<name>|..., not a preview deploy key.`);
|
|
1441
|
+
return yield* makeConvexState(makeFunctionApi(yield* urlForKey(key), key));
|
|
1442
|
+
}).pipe(Effect.provideContext(context), Effect.orDie));
|
|
1443
|
+
}));
|
|
1444
|
+
//#endregion
|
|
1445
|
+
export { ACCESS_TOKEN_ENV, AmbiguousDeployment, AmbiguousProject, CodePushFailed, ConvexApiError, ConvexAppNotFound, ConvexCliNotFound, CreatedProjectNotFound, Credentials, CredentialsError, DEPLOY_KEY_ENV, Deployment, DeploymentIdentityChange, EnvironmentNeedsDeployKey, ManagementApi, ProductionDeploymentNotFound, Project, ProjectDeploymentChange, ProjectNotFound, ProjectTeamChange, Providers, PushTargetMismatch, STATE_DEPLOY_KEY_ENV, VariablesOwnedBySomeoneElse, fromConfig, fromValues, parseDeployOutput, providers, state };
|
|
1260
1446
|
|
|
1261
1447
|
//# sourceMappingURL=index.js.map
|