@terraforge/core 0.0.14 → 0.0.16

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 CHANGED
@@ -145,6 +145,24 @@ declare class App extends Group {
145
145
  declare const enableDebug: () => void;
146
146
  declare const createDebugger: (group: string) => (...args: unknown[]) => void;
147
147
  //#endregion
148
+ //#region src/workspace/procedure/status.d.ts
149
+ /**
150
+ * The status of a resource comparing local config with state file.
151
+ *
152
+ * - `created`: Resource exists in state and matches current config
153
+ * - `changed`: Resource exists in state but config has changed
154
+ * - `pending`: Resource exists in config but not yet deployed (no state)
155
+ * - `stale`: Resource exists in state but was removed from config
156
+ */
157
+ type ResourceStatus = 'created' | 'changed' | 'pending' | 'stale';
158
+ type ResourceStatusInfo = {
159
+ urn: URN;
160
+ type: string;
161
+ provider: string;
162
+ tag: 'resource' | 'data';
163
+ status: ResourceStatus;
164
+ };
165
+ //#endregion
148
166
  //#region src/backend/lock.d.ts
149
167
  type LockBackend = {
150
168
  insecureReleaseLock(urn: URN): Promise<void>;
@@ -317,6 +335,10 @@ declare class WorkSpace {
317
335
  * Refresh the state of the resources & data-sources inside your app.
318
336
  */
319
337
  refresh(app: App): Promise<void>;
338
+ /**
339
+ * Get the status of all resources in the app by comparing current config with state file.
340
+ */
341
+ status(app: App): Promise<ResourceStatusInfo[]>;
320
342
  protected destroyProviders(): Promise<void>;
321
343
  }
322
344
  //#endregion
@@ -443,4 +465,4 @@ type CustomResourceProvider = Partial<{
443
465
  }>;
444
466
  declare const createCustomProvider: (providerId: string, resourceProviders: Record<string, CustomResourceProvider>) => Provider;
445
467
  //#endregion
446
- 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, 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 };
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 };
package/dist/index.mjs CHANGED
@@ -968,6 +968,7 @@ const deployApp = async (app, opt) => {
968
968
  if (!ignoreReplace && requiresReplacement(nodeState.input, input, meta$1.config?.replaceOnChanges ?? [])) if (meta$1.config?.createBeforeReplace) {
969
969
  const priorState = { ...nodeState };
970
970
  newResourceState = await createResource(node, appState.idempotentToken, input, opt);
971
+ if (newResourceState.output) meta$1.resolve(newResourceState.output);
971
972
  if (!meta$1.config?.retainOnDelete) replacementDeletes.set(meta$1.urn, priorState);
972
973
  } else {
973
974
  for (const [dependentUrn, dependentNode] of nodeByUrn.entries()) {
@@ -1008,6 +1009,7 @@ const deployApp = async (app, opt) => {
1008
1009
  }
1009
1010
  }
1010
1011
  newResourceState = await replaceResource(node, appState.idempotentToken, nodeState.input, nodeState.output, input, opt);
1012
+ if (newResourceState.output) meta$1.resolve(newResourceState.output);
1011
1013
  }
1012
1014
  else {
1013
1015
  newResourceState = await updateResource(node, appState.idempotentToken, nodeState.input, nodeState.output, input, opt);
@@ -1092,6 +1094,61 @@ const refresh = async (app, opt) => {
1092
1094
  }
1093
1095
  };
1094
1096
 
1097
+ //#endregion
1098
+ //#region src/workspace/procedure/status.ts
1099
+ const status = async (app, opt) => {
1100
+ const appState = await opt.backend.state.get(app.urn);
1101
+ const resources = [];
1102
+ const configuredUrns = /* @__PURE__ */ new Set();
1103
+ for (const stack of app.stacks) for (const node of stack.nodes) configuredUrns.add(getMeta(node).urn);
1104
+ for (const stack of app.stacks) {
1105
+ const stackState = appState?.stacks[stack.urn];
1106
+ for (const node of stack.nodes) {
1107
+ const meta = getMeta(node);
1108
+ const nodeState = stackState?.nodes[meta.urn];
1109
+ const baseInfo = {
1110
+ urn: meta.urn,
1111
+ type: meta.type,
1112
+ provider: meta.provider,
1113
+ tag: isResource(node) ? "resource" : "data"
1114
+ };
1115
+ if (!nodeState) {
1116
+ resources.push({
1117
+ ...baseInfo,
1118
+ status: "pending"
1119
+ });
1120
+ continue;
1121
+ }
1122
+ const currentInput = await resolveInputs(meta.input);
1123
+ const hasChanged = !compareState(nodeState.input, currentInput);
1124
+ resources.push({
1125
+ ...baseInfo,
1126
+ status: hasChanged ? "changed" : "created"
1127
+ });
1128
+ }
1129
+ if (stackState) {
1130
+ for (const [urn, nodeState] of Object.entries(stackState.nodes)) if (!configuredUrns.has(urn)) resources.push({
1131
+ urn,
1132
+ type: nodeState.type,
1133
+ provider: nodeState.provider,
1134
+ tag: nodeState.tag,
1135
+ status: "stale"
1136
+ });
1137
+ }
1138
+ }
1139
+ if (appState) {
1140
+ const configuredStackUrns = new Set(app.stacks.map((s) => s.urn));
1141
+ for (const [stackUrn, stackState] of Object.entries(appState.stacks)) if (!configuredStackUrns.has(stackUrn)) for (const [urn, nodeState] of Object.entries(stackState.nodes)) resources.push({
1142
+ urn,
1143
+ type: nodeState.type,
1144
+ provider: nodeState.provider,
1145
+ tag: nodeState.tag,
1146
+ status: "stale"
1147
+ });
1148
+ }
1149
+ return resources;
1150
+ };
1151
+
1095
1152
  //#endregion
1096
1153
  //#region src/workspace/workspace.ts
1097
1154
  var WorkSpace = class {
@@ -1146,6 +1203,12 @@ var WorkSpace = class {
1146
1203
  }
1147
1204
  });
1148
1205
  }
1206
+ /**
1207
+ * Get the status of all resources in the app by comparing current config with state file.
1208
+ */
1209
+ status(app) {
1210
+ return status(app, this.props);
1211
+ }
1149
1212
  async destroyProviders() {
1150
1213
  await Promise.all(this.props.providers.map((p) => {
1151
1214
  return p.destroy?.();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@terraforge/core",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",