@terraforge/core 0.0.18 → 0.0.19
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/index.d.mts +8 -2
- package/dist/index.mjs +68 -17
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -162,6 +162,11 @@ type ResourceStatusInfo = {
|
|
|
162
162
|
tag: 'resource' | 'data';
|
|
163
163
|
status: ResourceStatus;
|
|
164
164
|
};
|
|
165
|
+
type StackStatusInfo = {
|
|
166
|
+
name: string;
|
|
167
|
+
urn: URN;
|
|
168
|
+
resources: ResourceStatusInfo[];
|
|
169
|
+
};
|
|
165
170
|
//#endregion
|
|
166
171
|
//#region src/backend/lock.d.ts
|
|
167
172
|
type LockBackend = {
|
|
@@ -176,6 +181,7 @@ type AppState = {
|
|
|
176
181
|
version?: number;
|
|
177
182
|
idempotentToken?: UUID;
|
|
178
183
|
stacks: Record<URN, StackState>;
|
|
184
|
+
pendingDeletes?: Record<URN, NodeState>;
|
|
179
185
|
};
|
|
180
186
|
type StackState = {
|
|
181
187
|
name: string;
|
|
@@ -338,7 +344,7 @@ declare class WorkSpace {
|
|
|
338
344
|
/**
|
|
339
345
|
* Get the status of all resources in the app by comparing current config with state file.
|
|
340
346
|
*/
|
|
341
|
-
status(app: App): Promise<
|
|
347
|
+
status(app: App): Promise<StackStatusInfo[]>;
|
|
342
348
|
protected destroyProviders(): Promise<void>;
|
|
343
349
|
}
|
|
344
350
|
//#endregion
|
|
@@ -465,4 +471,4 @@ type CustomResourceProvider = Partial<{
|
|
|
465
471
|
}>;
|
|
466
472
|
declare const createCustomProvider: (providerId: string, resourceProviders: Record<string, CustomResourceProvider>) => Provider;
|
|
467
473
|
//#endregion
|
|
468
|
-
export { App, AppError, type Config, type CreateProps, type CustomResourceProvider, type DataSource, type DataSourceFunction, type DataSourceMeta, type DeleteProps, DynamoLockBackend, FileLockBackend, FileStateBackend, Future, type GetDataProps, type GetProps, Group, type Input, LockBackend, MemoryLockBackend, MemoryStateBackend, type Meta, type Node, type OptionalInput, type OptionalOutput, Output, type PlanProps, type ProcedureOptions, type Provider, type Resource, ResourceAlreadyExists, type ResourceClass, type ResourceConfig, ResourceError, type ResourceMeta, ResourceNotFound, type ResourceStatus, type ResourceStatusInfo, S3StateBackend, Stack, type State, StateBackend, type Tag, type URN, type UpdateProps, WorkSpace, type WorkSpaceOptions, createCustomProvider, createCustomResourceClass, createDebugger, createMeta, deferredOutput, enableDebug, findInputDeps, getMeta, isDataSource, isNode, isResource, nodeMetaSymbol, output, resolveInputs };
|
|
474
|
+
export { App, AppError, type Config, type CreateProps, type CustomResourceProvider, type DataSource, type DataSourceFunction, type DataSourceMeta, type DeleteProps, DynamoLockBackend, FileLockBackend, FileStateBackend, Future, type GetDataProps, type GetProps, Group, type Input, LockBackend, MemoryLockBackend, MemoryStateBackend, type Meta, type Node, type OptionalInput, type OptionalOutput, Output, type PlanProps, type ProcedureOptions, type Provider, type Resource, ResourceAlreadyExists, type ResourceClass, type ResourceConfig, ResourceError, type ResourceMeta, ResourceNotFound, type ResourceStatus, type ResourceStatusInfo, S3StateBackend, Stack, type StackStatusInfo, type State, StateBackend, type Tag, type URN, type UpdateProps, WorkSpace, type WorkSpaceOptions, createCustomProvider, createCustomResourceClass, createDebugger, createMeta, deferredOutput, enableDebug, findInputDeps, getMeta, isDataSource, isNode, isResource, nodeMetaSymbol, output, resolveInputs };
|
package/dist/index.mjs
CHANGED
|
@@ -623,6 +623,16 @@ const deleteApp = async (app, opt) => {
|
|
|
623
623
|
delete stackState.nodes[urn];
|
|
624
624
|
});
|
|
625
625
|
const errors = await graph.run();
|
|
626
|
+
if (errors.length === 0 && appState.pendingDeletes) {
|
|
627
|
+
for (const [urn, nodeState] of entries(appState.pendingDeletes)) try {
|
|
628
|
+
await deleteResource(appState.idempotentToken, urn, nodeState, opt);
|
|
629
|
+
delete appState.pendingDeletes[urn];
|
|
630
|
+
} catch (error) {
|
|
631
|
+
if (error instanceof Error) errors.push(error);
|
|
632
|
+
else errors.push(/* @__PURE__ */ new Error(`${error}`));
|
|
633
|
+
}
|
|
634
|
+
if (Object.keys(appState.pendingDeletes).length === 0) delete appState.pendingDeletes;
|
|
635
|
+
}
|
|
626
636
|
removeEmptyStackStates(appState);
|
|
627
637
|
delete appState.idempotentToken;
|
|
628
638
|
await opt.backend.state.update(app.urn, appState);
|
|
@@ -813,7 +823,8 @@ const updateResource = async (resource, appToken, priorInputState, priorOutputSt
|
|
|
813
823
|
const idempotantToken = createIdempotantToken(appToken, meta.urn, "update");
|
|
814
824
|
let result;
|
|
815
825
|
debug$2(meta.type);
|
|
816
|
-
debug$2(
|
|
826
|
+
debug$2("prior state", priorOutputState);
|
|
827
|
+
debug$2("proposed state", proposedState);
|
|
817
828
|
try {
|
|
818
829
|
await opt.hooks?.beforeResourceUpdate?.({
|
|
819
830
|
urn: resource.urn,
|
|
@@ -883,7 +894,6 @@ const deployApp = async (app, opt) => {
|
|
|
883
894
|
}
|
|
884
895
|
const queue = createConcurrencyQueue(opt.concurrency ?? 10);
|
|
885
896
|
const graph = new DependencyGraph();
|
|
886
|
-
const replacementDeletes = /* @__PURE__ */ new Map();
|
|
887
897
|
const allNodes = {};
|
|
888
898
|
for (const stackState of Object.values(appState.stacks)) for (const [urn, nodeState] of entries(stackState.nodes)) allNodes[urn] = nodeState;
|
|
889
899
|
for (const stack of filteredOutStacks) {
|
|
@@ -966,10 +976,33 @@ const deployApp = async (app, opt) => {
|
|
|
966
976
|
let newResourceState;
|
|
967
977
|
const ignoreReplace = forcedUpdateDependents.has(meta$1.urn);
|
|
968
978
|
if (!ignoreReplace && requiresReplacement(nodeState.input, input, meta$1.config?.replaceOnChanges ?? [])) if (meta$1.config?.createBeforeReplace) {
|
|
979
|
+
for (const [dependentUrn, dependentNode] of nodeByUrn.entries()) {
|
|
980
|
+
if (!isResource(dependentNode)) continue;
|
|
981
|
+
const dependentMeta = getMeta(dependentNode);
|
|
982
|
+
if (!dependentMeta.dependencies.has(meta$1.urn)) continue;
|
|
983
|
+
const dependentStackState = stackStates.get(dependentMeta.stack.urn);
|
|
984
|
+
const dependentState = dependentStackState?.nodes[dependentUrn];
|
|
985
|
+
if (!dependentStackState || !dependentState) continue;
|
|
986
|
+
const dependencyPaths = findDependencyPaths(dependentMeta.input, meta$1.urn);
|
|
987
|
+
if (dependencyPaths.length === 0) continue;
|
|
988
|
+
const dependentProvider = findProvider(opt.providers, dependentMeta.provider);
|
|
989
|
+
if (dependentProvider.planResourceChange) {
|
|
990
|
+
if ((await dependentProvider.planResourceChange({
|
|
991
|
+
type: dependentMeta.type,
|
|
992
|
+
priorState: dependentState.output,
|
|
993
|
+
proposedState: input
|
|
994
|
+
})).requiresReplacement) {
|
|
995
|
+
if (!allowsDependentReplace(dependentMeta.config?.replaceOnChanges, dependencyPaths)) throw ResourceError.wrap(dependentMeta.urn, dependentMeta.type, "update", /* @__PURE__ */ new Error(`Replacing ${meta$1.urn} requires ${dependentMeta.urn} to set replaceOnChanges for its dependency fields.`));
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
}
|
|
969
999
|
const priorState = { ...nodeState };
|
|
970
1000
|
newResourceState = await createResource(node, appState.idempotentToken, input, opt);
|
|
971
1001
|
if (newResourceState.output) meta$1.resolve(newResourceState.output);
|
|
972
|
-
if (!meta$1.config?.retainOnDelete)
|
|
1002
|
+
if (!meta$1.config?.retainOnDelete) {
|
|
1003
|
+
appState.pendingDeletes ??= {};
|
|
1004
|
+
appState.pendingDeletes[meta$1.urn] = priorState;
|
|
1005
|
+
}
|
|
973
1006
|
} else {
|
|
974
1007
|
for (const [dependentUrn, dependentNode] of nodeByUrn.entries()) {
|
|
975
1008
|
if (!isResource(dependentNode)) continue;
|
|
@@ -1028,11 +1061,15 @@ const deployApp = async (app, opt) => {
|
|
|
1028
1061
|
}
|
|
1029
1062
|
}
|
|
1030
1063
|
const errors = await graph.run();
|
|
1031
|
-
if (errors.length === 0 &&
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1064
|
+
if (errors.length === 0 && appState.pendingDeletes) {
|
|
1065
|
+
for (const [urn, nodeState] of entries(appState.pendingDeletes)) try {
|
|
1066
|
+
await deleteResource(appState.idempotentToken, urn, nodeState, opt);
|
|
1067
|
+
delete appState.pendingDeletes[urn];
|
|
1068
|
+
} catch (error) {
|
|
1069
|
+
if (error instanceof Error) errors.push(error);
|
|
1070
|
+
else errors.push(/* @__PURE__ */ new Error(`${error}`));
|
|
1071
|
+
}
|
|
1072
|
+
if (Object.keys(appState.pendingDeletes).length === 0) delete appState.pendingDeletes;
|
|
1036
1073
|
}
|
|
1037
1074
|
removeEmptyStackStates(appState);
|
|
1038
1075
|
delete appState.idempotentToken;
|
|
@@ -1135,11 +1172,12 @@ const filterStateToMatchConfig = (state, config) => {
|
|
|
1135
1172
|
};
|
|
1136
1173
|
const status = async (app, opt) => {
|
|
1137
1174
|
const appState = await opt.backend.state.get(app.urn);
|
|
1138
|
-
const
|
|
1175
|
+
const stacks = [];
|
|
1139
1176
|
const configuredUrns = /* @__PURE__ */ new Set();
|
|
1140
1177
|
for (const stack of app.stacks) for (const node of stack.nodes) configuredUrns.add(getMeta(node).urn);
|
|
1141
1178
|
for (const stack of app.stacks) {
|
|
1142
1179
|
const stackState = appState?.stacks[stack.urn];
|
|
1180
|
+
const resources = [];
|
|
1143
1181
|
for (const node of stack.nodes) {
|
|
1144
1182
|
const meta = getMeta(node);
|
|
1145
1183
|
const nodeState = stackState?.nodes[meta.urn];
|
|
@@ -1172,18 +1210,31 @@ const status = async (app, opt) => {
|
|
|
1172
1210
|
status: "stale"
|
|
1173
1211
|
});
|
|
1174
1212
|
}
|
|
1213
|
+
stacks.push({
|
|
1214
|
+
name: stack.name,
|
|
1215
|
+
urn: stack.urn,
|
|
1216
|
+
resources
|
|
1217
|
+
});
|
|
1175
1218
|
}
|
|
1176
1219
|
if (appState) {
|
|
1177
1220
|
const configuredStackUrns = new Set(app.stacks.map((s) => s.urn));
|
|
1178
|
-
for (const [stackUrn, stackState] of Object.entries(appState.stacks)) if (!configuredStackUrns.has(stackUrn))
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1221
|
+
for (const [stackUrn, stackState] of Object.entries(appState.stacks)) if (!configuredStackUrns.has(stackUrn)) {
|
|
1222
|
+
const resources = [];
|
|
1223
|
+
for (const [urn, nodeState] of Object.entries(stackState.nodes)) resources.push({
|
|
1224
|
+
urn,
|
|
1225
|
+
type: nodeState.type,
|
|
1226
|
+
provider: nodeState.provider,
|
|
1227
|
+
tag: nodeState.tag,
|
|
1228
|
+
status: "stale"
|
|
1229
|
+
});
|
|
1230
|
+
stacks.push({
|
|
1231
|
+
name: stackState.name,
|
|
1232
|
+
urn: stackUrn,
|
|
1233
|
+
resources
|
|
1234
|
+
});
|
|
1235
|
+
}
|
|
1185
1236
|
}
|
|
1186
|
-
return
|
|
1237
|
+
return stacks;
|
|
1187
1238
|
};
|
|
1188
1239
|
|
|
1189
1240
|
//#endregion
|