@samebase/alchemy-convex 0.8.0 → 0.10.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 +60 -2
- package/lib/index.d.ts +26 -4
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +76 -21
- package/lib/index.js.map +1 -1
- package/package.json +3 -3
- package/src/Component.ts +54 -0
- package/src/Deployment.ts +20 -6
- package/src/State.ts +34 -29
- package/src/index.ts +1 -0
- package/src/store/convex/_generated/api.d.ts +4 -0
- package/src/store/convex/auth.config.ts +14 -0
- package/src/store/convex/reader.ts +131 -0
- package/src/store/convex/runRecord.ts +41 -0
- package/src/store/convex/schema.ts +3 -1
- package/src/store/convex/state.ts +47 -21
- package/src/store/convex/version.ts +6 -4
- package/src/store/package.json +1 -1
package/README.md
CHANGED
|
@@ -91,6 +91,55 @@ Effect.gen(function* () {
|
|
|
91
91
|
State always holds `rootDir`, `"."` included, so a reader of the state finds the app directory of
|
|
92
92
|
each deployment.
|
|
93
93
|
|
|
94
|
+
### Resources associated with an installed component
|
|
95
|
+
|
|
96
|
+
Keep the component's native Alchemy resource declarations. Connect their namespace to the installed
|
|
97
|
+
component name in the consuming app's stack. The name comes from the app's `convex.config.ts`:
|
|
98
|
+
`app.use(mail, { name: "mail" })` installs the component as `"mail"`.
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { bindComponent } from "@samebase/alchemy-convex";
|
|
102
|
+
import * as Effect from "effect/Effect";
|
|
103
|
+
|
|
104
|
+
// `production` is this app's Convex.Deployment. EmailInbox creates its resources under "Mail".
|
|
105
|
+
Effect.gen(function* () {
|
|
106
|
+
const inbox = yield* EmailInbox("Mail", {
|
|
107
|
+
convexSiteUrl: production.siteUrl,
|
|
108
|
+
zone,
|
|
109
|
+
sendingDomain,
|
|
110
|
+
});
|
|
111
|
+
yield* bindComponent({
|
|
112
|
+
deployment: production,
|
|
113
|
+
component: "mail",
|
|
114
|
+
namespace: inbox.worker.Namespace,
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The deployment's Alchemy state row stores this entry in its native `bindings` array:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"sid": "convex.component:[\"Mail\"]",
|
|
124
|
+
"data": { "type": "component", "path": "mail", "namespace": ["Mail"] }
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Readers inspect each binding's `data`. The deployment attributes identify the Convex deployment;
|
|
129
|
+
the row's stack and stage identify the Alchemy scope. The live repository reader includes the
|
|
130
|
+
binding through its existing resource JSON. No extra resource list, state table, or subscription
|
|
131
|
+
is needed.
|
|
132
|
+
|
|
133
|
+
Use actual namespace ancestry when grouping resources. A slash in a resource's logical ID is not a
|
|
134
|
+
namespace boundary. For a nested install, join the installed names with slashes, such as
|
|
135
|
+
`"workspace/mail"`. An undefined namespace means the stack root. Each namespace can be assigned to
|
|
136
|
+
one component per deployment; a component can have multiple namespaces. A more specific child
|
|
137
|
+
namespace takes precedence when displaying resources.
|
|
138
|
+
|
|
139
|
+
The connection is declared metadata. It does not check that the component is installed, push code,
|
|
140
|
+
set environment values, or change resource deletion policies. Removing the call removes the binding
|
|
141
|
+
on the next apply.
|
|
142
|
+
|
|
94
143
|
## Credentials
|
|
95
144
|
|
|
96
145
|
Credentials are a layer, never props, so they do not go into Alchemy state. `Convex.providers()`
|
|
@@ -135,11 +184,20 @@ is set must be the slug of that team, checked against its projects, and a token
|
|
|
135
184
|
fails the run. The Convex CLI login needs the slug or the id. The first run of a team creates
|
|
136
185
|
the project `alchemy-state` and pushes the store functions to its
|
|
137
186
|
production deployment with the Convex CLI of the app; a later version of this package pushes a
|
|
138
|
-
newer store when it finds an older one
|
|
187
|
+
newer store when it finds an older one. A store that is newer than the package fails the run with
|
|
188
|
+
both versions, so the repositories of a team upgrade the package together. Each run makes a
|
|
139
189
|
deploy key of that deployment that can only run the store's internal functions, and deletes it at
|
|
140
190
|
the end. Rows are in the tables `resources` and `outputs` in the dashboard, under the stack name.
|
|
141
191
|
The store has no lock: run one deploy of a stage at a time, such as with a CI concurrency group.
|
|
142
|
-
The
|
|
192
|
+
The store and its readers (Samebase) are released and upgraded together.
|
|
193
|
+
|
|
194
|
+
Store version 3 supports native subscriptions. A trusted server checks repository access, then
|
|
195
|
+
calls internal `reader:authorize({ repository, subject })` with a deployment credential. It gives
|
|
196
|
+
the returned token to a separate `ConvexClient` connected to the state deployment. The client
|
|
197
|
+
subscribes to `reader:repository({})`; the verified token selects the repository. The token has a
|
|
198
|
+
five-minute lifetime and permits redacted reads only. The server checks access again on renewal.
|
|
199
|
+
The store uses its own native signing key and JWKS, so no extra signing secret is required.
|
|
200
|
+
See [the reader contract](docs/design/convex-state.md#repository-subscriptions-090).
|
|
143
201
|
|
|
144
202
|
### What the output records about a run
|
|
145
203
|
|
package/lib/index.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Stack } from "alchemy/Stack";
|
|
2
2
|
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Schema from "effect/Schema";
|
|
4
|
+
import * as Context from "effect/Context";
|
|
3
5
|
import * as Layer from "effect/Layer";
|
|
4
6
|
import * as Redacted from "effect/Redacted";
|
|
5
|
-
import * as Schema from "effect/Schema";
|
|
6
7
|
import { Resource } from "alchemy";
|
|
7
8
|
import * as Provider from "alchemy/Provider";
|
|
8
9
|
import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner";
|
|
9
10
|
import { createDeploymentClient, createManagementClient } from "@convex-dev/platform";
|
|
10
11
|
import "effect/Scope";
|
|
11
12
|
import { State, StateStoreError } from "alchemy/State";
|
|
13
|
+
import { NamespaceNode } from "alchemy/Namespace";
|
|
12
14
|
import { InputProps } from "alchemy/Input";
|
|
13
15
|
import { components } from "@convex-dev/platform/managementApi";
|
|
14
16
|
//#region src/Credentials.d.ts
|
|
@@ -250,7 +252,7 @@ interface DeploymentAttributes extends DeploymentTarget {
|
|
|
250
252
|
/** The names of the `env` variables that this resource set on the deployment, sorted. */
|
|
251
253
|
readonly envNames: readonly string[];
|
|
252
254
|
}
|
|
253
|
-
export type Deployment = Resource<"Convex.Deployment", DeploymentProps, DeploymentAttributes,
|
|
255
|
+
export type Deployment = Resource<"Convex.Deployment", DeploymentProps, DeploymentAttributes, ComponentBinding, Providers>;
|
|
254
256
|
/** The props of a `Convex.Deployment` call: Alchemy inputs, with `rootDir` a plain string. */
|
|
255
257
|
type DeploymentInput = DeploymentProps extends (infer P) ? P extends DeploymentProps ? InputProps<P, "rootDir"> : never : never;
|
|
256
258
|
declare const AbsoluteRootDir_base: Schema.Class<AbsoluteRootDir, Schema.TaggedStruct<"AbsoluteRootDir", {
|
|
@@ -310,6 +312,26 @@ export declare class AmbiguousDeployment extends AmbiguousDeployment_base {
|
|
|
310
312
|
get message(): string;
|
|
311
313
|
}
|
|
312
314
|
//#endregion
|
|
315
|
+
//#region src/Component.d.ts
|
|
316
|
+
/** A component's resources occupy this namespace in the deployment's Alchemy stack and stage. */
|
|
317
|
+
interface ComponentBinding {
|
|
318
|
+
readonly type: "component";
|
|
319
|
+
readonly path: string;
|
|
320
|
+
readonly namespace: readonly string[];
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Associate a native namespace with an installed component. `component` is the
|
|
324
|
+
* installed name from the app's `convex.config.ts`; a nested install joins the
|
|
325
|
+
* names with slashes, such as `"workspace/mail"`. An undefined namespace
|
|
326
|
+
* associates the stack root. This records display metadata; it does not install
|
|
327
|
+
* the component, set its environment, or change removal policies.
|
|
328
|
+
*/
|
|
329
|
+
export declare const bindComponent: (options: {
|
|
330
|
+
deployment: Deployment;
|
|
331
|
+
component: string;
|
|
332
|
+
namespace: NamespaceNode | undefined;
|
|
333
|
+
}) => Effect.Effect<undefined, never, Stack>;
|
|
334
|
+
//#endregion
|
|
313
335
|
//#region src/Project.d.ts
|
|
314
336
|
/** Region names the Management API accepts, from the generated schema. */
|
|
315
337
|
type DeploymentRegion = components["schemas"]["RegionName"];
|
|
@@ -448,5 +470,5 @@ export declare const state: (options?: {
|
|
|
448
470
|
readonly team?: string | number;
|
|
449
471
|
}) => Layer.Layer<State, never, ChildProcessSpawner.ChildProcessSpawner>;
|
|
450
472
|
//#endregion
|
|
451
|
-
export type { DeploymentAttributes, DeploymentInput, DeploymentProps, DeploymentRegion, EnvValue, ProjectAttributes, ProjectProps, RunRecord, Source };
|
|
473
|
+
export type { ComponentBinding, DeploymentAttributes, DeploymentInput, DeploymentProps, DeploymentRegion, EnvValue, ProjectAttributes, ProjectProps, RunRecord, Source };
|
|
452
474
|
//# 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","../src/RunRecord.ts","../src/State.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/Component.ts","../src/Project.ts","../src/RunRecord.ts","../src/State.ts"],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
+
import { toPath } from "alchemy/FQN";
|
|
3
|
+
import { Stack } from "alchemy/Stack";
|
|
4
|
+
import * as Effect from "effect/Effect";
|
|
5
|
+
import * as Schema from "effect/Schema";
|
|
2
6
|
import { access, mkdtemp, readFile, realpath, rm, writeFile } from "node:fs/promises";
|
|
3
7
|
import { homedir, tmpdir } from "node:os";
|
|
4
8
|
import { dirname, join, posix, relative, resolve, sep, win32 } from "node:path";
|
|
5
9
|
import * as Config from "effect/Config";
|
|
6
10
|
import * as Context from "effect/Context";
|
|
7
|
-
import * as Effect from "effect/Effect";
|
|
8
11
|
import * as Layer from "effect/Layer";
|
|
9
12
|
import * as Option from "effect/Option";
|
|
10
13
|
import * as Redacted from "effect/Redacted";
|
|
11
14
|
import * as Result from "effect/Result";
|
|
12
|
-
import * as Schema from "effect/Schema";
|
|
13
15
|
import { Resource } from "alchemy";
|
|
14
16
|
import { AdoptPolicy, OwnedBySomeoneElse, Unowned } from "alchemy/AdoptPolicy";
|
|
15
|
-
import { isResolved } from "alchemy/Diff";
|
|
17
|
+
import { diffBindings, isResolved } from "alchemy/Diff";
|
|
16
18
|
import * as Provider from "alchemy/Provider";
|
|
17
19
|
import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner";
|
|
18
20
|
import { AlchemyContext } from "alchemy/AlchemyContext";
|
|
19
|
-
import { Stack } from "alchemy/Stack";
|
|
20
21
|
import { createDeploymentClient, createManagementClient } from "@convex-dev/platform";
|
|
21
22
|
import * as Schedule from "effect/Schedule";
|
|
22
23
|
import { createHash } from "node:crypto";
|
|
@@ -29,6 +30,31 @@ import { execFile } from "node:child_process";
|
|
|
29
30
|
import { fileURLToPath } from "node:url";
|
|
30
31
|
import * as Scope from "effect/Scope";
|
|
31
32
|
import { STATE_STORE_VERSION, State, StateStoreError, encodeState, reviveState } from "alchemy/State";
|
|
33
|
+
//#region src/Component.ts
|
|
34
|
+
/**
|
|
35
|
+
* Associate a native namespace with an installed component. `component` is the
|
|
36
|
+
* installed name from the app's `convex.config.ts`; a nested install joins the
|
|
37
|
+
* names with slashes, such as `"workspace/mail"`. An undefined namespace
|
|
38
|
+
* associates the stack root. This records display metadata; it does not install
|
|
39
|
+
* the component, set its environment, or change removal policies.
|
|
40
|
+
*/
|
|
41
|
+
const bindComponent = (options) => Effect.gen(function* () {
|
|
42
|
+
if (options.component === "") return yield* Effect.die(/* @__PURE__ */ new Error("The component name is empty."));
|
|
43
|
+
const namespace = toPath(options.namespace);
|
|
44
|
+
const sid = `convex.component:${JSON.stringify(namespace)}`;
|
|
45
|
+
const previous = (yield* Stack).bindings[options.deployment.FQN]?.find((binding) => binding.sid === sid);
|
|
46
|
+
if (previous !== void 0) {
|
|
47
|
+
const existing = Schema.decodeUnknownSync(Schema.Struct({ path: Schema.String }))(previous.data);
|
|
48
|
+
if (existing.path !== options.component) return yield* Effect.die(/* @__PURE__ */ new Error(`Alchemy namespace ${JSON.stringify(namespace)} is already bound to ${existing.path}.`));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
yield* options.deployment.bind(sid, {
|
|
52
|
+
type: "component",
|
|
53
|
+
path: options.component,
|
|
54
|
+
namespace
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
//#endregion
|
|
32
58
|
//#region src/Credentials.ts
|
|
33
59
|
var Credentials = class extends Context.Service()("@samebase/alchemy-convex/Credentials") {};
|
|
34
60
|
/** Environment variable for the access token, read by {@link fromConfig}. */
|
|
@@ -898,15 +924,34 @@ const DeploymentProvider = () => Provider.effect(DeploymentResource, Effect.gen(
|
|
|
898
924
|
"type",
|
|
899
925
|
"previewName"
|
|
900
926
|
],
|
|
901
|
-
diff: Effect.fn(function* ({ news, olds, output }) {
|
|
927
|
+
diff: Effect.fn(function* ({ news, olds, output, oldBindings, newBindings }) {
|
|
902
928
|
if (!isResolved(news) || output === void 0) return void 0;
|
|
903
929
|
yield* checkIdentity(output, news);
|
|
930
|
+
if (!isResolved(newBindings)) return void 0;
|
|
904
931
|
const rootDir = news.rootDir ?? ".";
|
|
905
932
|
if (news.source !== void 0) yield* checkSource(rootDir, news.source);
|
|
906
933
|
if (olds.rootDir !== rootDir) return { action: "update" };
|
|
907
934
|
const access = yield* accessFor(addressOf(news), changesEnv(news, output));
|
|
908
|
-
|
|
909
|
-
|
|
935
|
+
const current = yield* live(access, output);
|
|
936
|
+
if (current?.name !== output.name) return { action: "update" };
|
|
937
|
+
if ((yield* wantedHash(news, rootDir, output.name)) !== output.hash) return { action: "update" };
|
|
938
|
+
if (diffBindings(oldBindings, newBindings).every((binding) => binding.action === "noop")) return { action: "noop" };
|
|
939
|
+
return {
|
|
940
|
+
action: "update",
|
|
941
|
+
stables: [
|
|
942
|
+
"hash",
|
|
943
|
+
"envNames",
|
|
944
|
+
...[
|
|
945
|
+
"projectId",
|
|
946
|
+
"type",
|
|
947
|
+
"previewName",
|
|
948
|
+
"name",
|
|
949
|
+
"reference",
|
|
950
|
+
"url",
|
|
951
|
+
"siteUrl"
|
|
952
|
+
].filter((key) => current[key] === output[key])
|
|
953
|
+
]
|
|
954
|
+
};
|
|
910
955
|
}),
|
|
911
956
|
read: Effect.fn(function* ({ olds, output }) {
|
|
912
957
|
if (output !== void 0) {
|
|
@@ -1555,8 +1600,18 @@ const makeFunctionApi = (url, key) => ({ call: (path, args) => post(`${url}/api/
|
|
|
1555
1600
|
/** The value of a reply, or the Convex message, which names the function and the cause, such as a missing key action. */
|
|
1556
1601
|
const valueOf = (reply) => reply.status === "success" ? Effect.succeed(reply.value) : Effect.fail(failure(reply.errorMessage.trim()));
|
|
1557
1602
|
/** The functions of the store with Alchemy's encoding: the JSON text of encodeState. */
|
|
1558
|
-
const remoteOf = (api) => {
|
|
1603
|
+
const remoteOf = (api, record) => {
|
|
1559
1604
|
const run = (name, args) => api.call(`state:${name}`, args).pipe(Effect.flatMap(valueOf));
|
|
1605
|
+
const write = (name, args) => Effect.gen(function* () {
|
|
1606
|
+
const currentRun = record === void 0 ? void 0 : {
|
|
1607
|
+
...record,
|
|
1608
|
+
recordedAt: new Date(yield* Clock.currentTimeMillis).toISOString()
|
|
1609
|
+
};
|
|
1610
|
+
return yield* run(name, {
|
|
1611
|
+
...args,
|
|
1612
|
+
run: currentRun
|
|
1613
|
+
});
|
|
1614
|
+
});
|
|
1560
1615
|
const strings = (name, args) => run(name, args).pipe(Effect.flatMap(decode(Schema.Array(Schema.String), name)));
|
|
1561
1616
|
const optional = (name, args) => run(name, args).pipe(Effect.flatMap(decode(Schema.NullOr(Schema.String), name)));
|
|
1562
1617
|
const encode = (value) => JSON.stringify(encodeState(value));
|
|
@@ -1580,13 +1635,13 @@ const remoteOf = (api) => {
|
|
|
1580
1635
|
stack: r.stack,
|
|
1581
1636
|
stage: r.stage
|
|
1582
1637
|
}).pipe(Effect.map((text) => text === null ? void 0 : JSON.parse(text, reviveState))),
|
|
1583
|
-
set: (r) =>
|
|
1638
|
+
set: (r) => write("set", {
|
|
1584
1639
|
stack: r.stack,
|
|
1585
1640
|
stage: r.stage,
|
|
1586
1641
|
fqn: r.fqn,
|
|
1587
1642
|
value: encode(r.value)
|
|
1588
1643
|
}),
|
|
1589
|
-
delete: (r) =>
|
|
1644
|
+
delete: (r) => write("remove", {
|
|
1590
1645
|
stack: r.stack,
|
|
1591
1646
|
stage: r.stage,
|
|
1592
1647
|
fqn: r.fqn
|
|
@@ -1595,7 +1650,7 @@ const remoteOf = (api) => {
|
|
|
1595
1650
|
stack: r.stack,
|
|
1596
1651
|
stage: r.stage
|
|
1597
1652
|
}),
|
|
1598
|
-
setOutput: (r) =>
|
|
1653
|
+
setOutput: (r) => write("setOutput", {
|
|
1599
1654
|
stack: r.stack,
|
|
1600
1655
|
stage: r.stage,
|
|
1601
1656
|
value: encode(r.value)
|
|
@@ -1618,7 +1673,7 @@ const storeDirectory = () => join(dirname(fileURLToPath(import.meta.url)), "..",
|
|
|
1618
1673
|
*/
|
|
1619
1674
|
const pushStore = (options, deployment) => Effect.gen(function* () {
|
|
1620
1675
|
const cli = yield* installedCli(join(options.store, ".."));
|
|
1621
|
-
yield* Effect.logInfo(`Convex state: pushing the store version
|
|
1676
|
+
yield* Effect.logInfo(`Convex state: pushing the store version 3 to ${deployment.name}`);
|
|
1622
1677
|
yield* withPushKey(options.api, deployment.name, PUSH_KEY_ACTIONS, (key) => push(options.spawner, key, {
|
|
1623
1678
|
deployment: deployment.name,
|
|
1624
1679
|
url: deployment.deploymentUrl,
|
|
@@ -1681,17 +1736,17 @@ const makeConvexState = (options) => Effect.gen(function* () {
|
|
|
1681
1736
|
current = next;
|
|
1682
1737
|
return next.call(path, args);
|
|
1683
1738
|
})))) };
|
|
1684
|
-
|
|
1685
|
-
if (version === void 0 || version <
|
|
1739
|
+
let version = yield* storeVersion(functions);
|
|
1740
|
+
if (version === void 0 || version < 3) {
|
|
1686
1741
|
if (version === void 0 && deployment.lastDeployTime) return yield* failure(`project ${STORE_PROJECT_NAME} (${project.id}) of team ${team} has code that is not the state store, and Convex.state does not push over it. Rename that project in the Convex dashboard.`);
|
|
1687
|
-
|
|
1688
|
-
if (
|
|
1742
|
+
version = yield* storeVersion(functions);
|
|
1743
|
+
if (version === void 0 || version < 3) {
|
|
1689
1744
|
yield* pushStore(options, deployment);
|
|
1690
|
-
|
|
1691
|
-
if (pushed === void 0 || pushed < 2) return yield* failure(`${deployment.name} answers store version ${pushed ?? "none"} after the push of version 2.`);
|
|
1745
|
+
version = yield* storeVersion(functions);
|
|
1692
1746
|
}
|
|
1693
|
-
}
|
|
1694
|
-
|
|
1747
|
+
}
|
|
1748
|
+
if (version !== 3) return yield* failure(`${deployment.name} answers store version ${version ?? "none"}, and this package needs store version 3.`);
|
|
1749
|
+
const remote = remoteOf(functions, options.run);
|
|
1695
1750
|
/** The stack's output plus the record, when the run has one and the output has a place for it. */
|
|
1696
1751
|
const documentOf = (request) => Effect.gen(function* () {
|
|
1697
1752
|
const { run } = options;
|
|
@@ -1759,6 +1814,6 @@ const state = (options = {}) => Layer.effect(State, Effect.gen(function* () {
|
|
|
1759
1814
|
}).pipe(Effect.provideContext(context), Effect.orDie));
|
|
1760
1815
|
}));
|
|
1761
1816
|
//#endregion
|
|
1762
|
-
export { ACCESS_TOKEN_ENV, AbsoluteRootDir, AmbiguousDeployment, AmbiguousProject, CodePushFailed, ConvexApiError, ConvexAppNotFound, ConvexCliNotFound, CreatedProjectNotFound, Credentials, CredentialsError, DEPLOY_KEY_ENV, Deployment, DeploymentIdentityChange, EnvironmentNeedsDeployKey, ManagementApi, ProductionDeploymentNotFound, Project, ProjectDeploymentChange, ProjectNotFound, ProjectTeamChange, Providers, PushTargetMismatch, RUN_RECORD_KEY, RunRecordError, STORE_PROJECT_NAME, VariablesOwnedBySomeoneElse, fromConfig, fromValues, parseDeployOutput, providers, runRecord, state, withRunRecord };
|
|
1817
|
+
export { ACCESS_TOKEN_ENV, AbsoluteRootDir, AmbiguousDeployment, AmbiguousProject, CodePushFailed, ConvexApiError, ConvexAppNotFound, ConvexCliNotFound, CreatedProjectNotFound, Credentials, CredentialsError, DEPLOY_KEY_ENV, Deployment, DeploymentIdentityChange, EnvironmentNeedsDeployKey, ManagementApi, ProductionDeploymentNotFound, Project, ProjectDeploymentChange, ProjectNotFound, ProjectTeamChange, Providers, PushTargetMismatch, RUN_RECORD_KEY, RunRecordError, STORE_PROJECT_NAME, VariablesOwnedBySomeoneElse, bindComponent, fromConfig, fromValues, parseDeployOutput, providers, runRecord, state, withRunRecord };
|
|
1763
1818
|
|
|
1764
1819
|
//# sourceMappingURL=index.js.map
|