@terraforge/terraform 0.0.25 → 0.0.27

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.
Files changed (2) hide show
  1. package/dist/index.mjs +32 -22
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -235,6 +235,24 @@ const sortStateValues = (values) => {
235
235
  return 0;
236
236
  });
237
237
  };
238
+ const tryNormalizeJsonString = (value) => {
239
+ const trimmed = value.trim();
240
+ if (!(trimmed.startsWith("{") || trimmed.startsWith("["))) return value;
241
+ try {
242
+ return stableStringify(JSON.parse(trimmed));
243
+ } catch {
244
+ return value;
245
+ }
246
+ };
247
+ const uniqueStateValues = (values) => {
248
+ const seen = /* @__PURE__ */ new Set();
249
+ return values.filter((value) => {
250
+ const key = stableStringify(value);
251
+ if (seen.has(key)) return false;
252
+ seen.add(key);
253
+ return true;
254
+ });
255
+ };
238
256
  const encodeDynamicValue = (value) => {
239
257
  return {
240
258
  msgpack: pack(value),
@@ -299,20 +317,24 @@ const shouldIncludeFieldForComparison = (schema, inputValue) => {
299
317
  };
300
318
  const normalizeStateForComparison = (schema, state, inputState) => {
301
319
  if (!shouldIncludeFieldForComparison(schema, inputState)) return;
320
+ if ((schema.optional || schema.computed) && (state === null || typeof state === "undefined") && isEmptyOutputValue(inputState)) state = inputState;
302
321
  if (state === null || typeof state === "undefined") return state;
303
322
  if (schema.type === "array") {
304
323
  if (!Array.isArray(state)) return state;
305
- const normalized = state.map((item, index) => {
324
+ const filtered = state.map((item, index) => {
306
325
  const inputItem = Array.isArray(inputState) ? inputState[index] : void 0;
307
326
  return normalizeStateForComparison(schema.item, item, inputItem);
308
- });
309
- return schema.collectionKind === "set" ? sortStateValues(normalized) : normalized;
327
+ }).filter((item) => typeof item !== "undefined");
328
+ if (schema.collectionKind === "set") return sortStateValues(uniqueStateValues(filtered.filter((item) => item !== null)));
329
+ return filtered;
310
330
  }
311
331
  if (schema.type === "record") {
312
332
  if (typeof state !== "object" || state === null) return state;
313
- return Object.fromEntries(Object.entries(state).map(([key, value]) => {
333
+ return Object.fromEntries(Object.entries(state).flatMap(([key, value]) => {
314
334
  const inputValue = inputState && typeof inputState === "object" ? inputState[key] : void 0;
315
- return [key, normalizeStateForComparison(schema.item, value, inputValue)];
335
+ const normalized = normalizeStateForComparison(schema.item, value, inputValue);
336
+ if (typeof normalized === "undefined") return [];
337
+ return [[key, normalized]];
316
338
  }));
317
339
  }
318
340
  if (schema.type === "object") {
@@ -333,6 +355,9 @@ const normalizeStateForComparison = (schema, state, inputState) => {
333
355
  return [[camelCase(key), normalized]];
334
356
  }));
335
357
  }
358
+ if (schema.type === "string") {
359
+ if (typeof state === "string") return tryNormalizeJsonString(state);
360
+ }
336
361
  return state;
337
362
  };
338
363
  const formatInputState = (schema, state, includeSchemaFields = true, path = []) => {
@@ -426,16 +451,6 @@ const formatOutputState = (schema, state, path = []) => {
426
451
 
427
452
  //#endregion
428
453
  //#region src/provider.ts
429
- const areStatesEqual = (left, right) => {
430
- const replacer = (_, value) => {
431
- if (value !== null && value instanceof Object && !Array.isArray(value)) return Object.keys(value).sort().reduce((sorted, key) => {
432
- sorted[key] = value[key];
433
- return sorted;
434
- }, {});
435
- return value;
436
- };
437
- return JSON.stringify(left, replacer) === JSON.stringify(right, replacer);
438
- };
439
454
  var TerraformProvider = class {
440
455
  configured;
441
456
  plugin;
@@ -529,14 +544,9 @@ var TerraformProvider = class {
529
544
  const schema = getResourceSchema(plugin.schema().resources, type);
530
545
  const refreshedState = await plugin.readResource(type, priorOutputState);
531
546
  if (!refreshedState) return { kind: "deleted" };
532
- const mergedState = {
533
- ...refreshedState,
534
- ...priorInputState
535
- };
536
- const { requiresReplace, plannedState } = await plugin.planResourceChange(type, refreshedState, mergedState, priorInputState);
537
- const normalizedPlannedState = normalizeStateForComparison(schema, plannedState, priorInputState);
547
+ const normalizedPriorInputState = normalizeStateForComparison(schema, priorInputState, priorInputState);
538
548
  const normalizedRefreshedState = normalizeStateForComparison(schema, refreshedState, priorInputState);
539
- if (requiresReplace.length === 0 && areStatesEqual(normalizedPlannedState, normalizedRefreshedState)) return {
549
+ if (stableStringify(normalizedPriorInputState) === stableStringify(normalizedRefreshedState)) return {
540
550
  kind: "unchanged",
541
551
  state: refreshedState
542
552
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@terraforge/terraform",
3
- "version": "0.0.25",
3
+ "version": "0.0.27",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",