declastruct 1.0.0 → 1.1.1

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 (250) hide show
  1. package/dist/.test/assets/providers/demo.provider.d.ts +32 -0
  2. package/dist/.test/assets/providers/demo.provider.js +101 -0
  3. package/dist/.test/assets/providers/demo.provider.js.map +1 -0
  4. package/dist/contract/cli/apply.d.ts +9 -0
  5. package/dist/contract/cli/apply.integration.test.js +148 -0
  6. package/dist/contract/cli/apply.integration.test.js.map +1 -0
  7. package/dist/contract/cli/apply.js +90 -0
  8. package/dist/contract/cli/apply.js.map +1 -0
  9. package/dist/contract/cli/invoke.d.ts +8 -0
  10. package/dist/contract/cli/invoke.js +58 -0
  11. package/dist/contract/cli/invoke.js.map +1 -0
  12. package/dist/contract/cli/plan.d.ts +10 -0
  13. package/dist/contract/cli/plan.integration.test.js +107 -0
  14. package/dist/contract/cli/plan.integration.test.js.map +1 -0
  15. package/dist/contract/cli/plan.js +94 -0
  16. package/dist/contract/cli/plan.js.map +1 -0
  17. package/dist/contract/sdk/index.d.ts +15 -3
  18. package/dist/contract/sdk/index.js +31 -17
  19. package/dist/contract/sdk/index.js.map +1 -1
  20. package/dist/domain.objects/ContextDeclastruct.d.ts +15 -0
  21. package/dist/{domain/DeclastructContext.js → domain.objects/ContextDeclastruct.js} +1 -1
  22. package/dist/domain.objects/ContextDeclastruct.js.map +1 -0
  23. package/dist/domain.objects/ContextDeclastruct.test.js +41 -0
  24. package/dist/domain.objects/ContextDeclastruct.test.js.map +1 -0
  25. package/dist/domain.objects/DeclastructChange.d.ts +73 -0
  26. package/dist/domain.objects/DeclastructChange.js +35 -0
  27. package/dist/domain.objects/DeclastructChange.js.map +1 -0
  28. package/dist/domain.objects/DeclastructChange.test.js +59 -0
  29. package/dist/domain.objects/DeclastructChange.test.js.map +1 -0
  30. package/dist/domain.objects/DeclastructDao.d.ts +39 -0
  31. package/dist/domain.objects/DeclastructDao.js +8 -0
  32. package/dist/domain.objects/DeclastructDao.js.map +1 -0
  33. package/dist/domain.objects/DeclastructDao.test.js +42 -0
  34. package/dist/domain.objects/DeclastructDao.test.js.map +1 -0
  35. package/dist/domain.objects/DeclastructPlan.d.ts +35 -0
  36. package/dist/domain.objects/DeclastructPlan.js +11 -0
  37. package/dist/domain.objects/DeclastructPlan.js.map +1 -0
  38. package/dist/domain.objects/DeclastructPlan.test.js +31 -0
  39. package/dist/domain.objects/DeclastructPlan.test.js.map +1 -0
  40. package/dist/domain.objects/DeclastructProvider.d.ts +30 -0
  41. package/dist/domain.objects/DeclastructProvider.js +8 -0
  42. package/dist/domain.objects/DeclastructProvider.js.map +1 -0
  43. package/dist/domain.objects/DeclastructProvider.test.js +35 -0
  44. package/dist/domain.objects/DeclastructProvider.test.js.map +1 -0
  45. package/dist/domain.objects/IsoTimestamp.d.ts +6 -0
  46. package/dist/{domain/DeclaredResource.js → domain.objects/IsoTimestamp.js} +1 -1
  47. package/dist/domain.objects/IsoTimestamp.js.map +1 -0
  48. package/dist/domain.objects/IsoTimestamp.test.js +10 -0
  49. package/dist/domain.objects/IsoTimestamp.test.js.map +1 -0
  50. package/dist/domain.operations/apply/applyChange.d.ts +14 -0
  51. package/dist/domain.operations/apply/applyChange.js +64 -0
  52. package/dist/domain.operations/apply/applyChange.js.map +1 -0
  53. package/dist/domain.operations/apply/applyChange.test.d.ts +1 -0
  54. package/dist/domain.operations/apply/applyChange.test.js +247 -0
  55. package/dist/domain.operations/apply/applyChange.test.js.map +1 -0
  56. package/dist/domain.operations/apply/applyChanges.d.ts +18 -0
  57. package/dist/domain.operations/apply/applyChanges.integration.test.d.ts +1 -0
  58. package/dist/domain.operations/apply/applyChanges.integration.test.js +291 -0
  59. package/dist/domain.operations/apply/applyChanges.integration.test.js.map +1 -0
  60. package/dist/domain.operations/apply/applyChanges.js +53 -0
  61. package/dist/domain.operations/apply/applyChanges.js.map +1 -0
  62. package/dist/domain.operations/plan/computeChange.d.ts +11 -0
  63. package/dist/domain.operations/plan/computeChange.js +78 -0
  64. package/dist/domain.operations/plan/computeChange.js.map +1 -0
  65. package/dist/domain.operations/plan/computeChange.test.d.ts +1 -0
  66. package/dist/domain.operations/plan/computeChange.test.js +67 -0
  67. package/dist/domain.operations/plan/computeChange.test.js.map +1 -0
  68. package/dist/domain.operations/plan/extractResourcesFromPlan.d.ts +8 -0
  69. package/dist/domain.operations/plan/extractResourcesFromPlan.js +17 -0
  70. package/dist/domain.operations/plan/extractResourcesFromPlan.js.map +1 -0
  71. package/dist/domain.operations/plan/getDaoByResource.d.ts +12 -0
  72. package/dist/domain.operations/plan/getDaoByResource.js +41 -0
  73. package/dist/domain.operations/plan/getDaoByResource.js.map +1 -0
  74. package/dist/domain.operations/plan/getDaoByResource.test.d.ts +1 -0
  75. package/dist/domain.operations/plan/getDaoByResource.test.js +99 -0
  76. package/dist/domain.operations/plan/getDaoByResource.test.js.map +1 -0
  77. package/dist/domain.operations/plan/hashChanges.d.ts +7 -0
  78. package/dist/domain.operations/plan/hashChanges.js +18 -0
  79. package/dist/domain.operations/plan/hashChanges.js.map +1 -0
  80. package/dist/domain.operations/plan/planChanges.d.ts +15 -0
  81. package/dist/domain.operations/plan/planChanges.integration.test.d.ts +1 -0
  82. package/dist/domain.operations/plan/planChanges.integration.test.js +197 -0
  83. package/dist/domain.operations/plan/planChanges.integration.test.js.map +1 -0
  84. package/dist/domain.operations/plan/planChanges.js +50 -0
  85. package/dist/domain.operations/plan/planChanges.js.map +1 -0
  86. package/dist/domain.operations/plan/validate.d.ts +10 -0
  87. package/dist/domain.operations/plan/validate.js +21 -0
  88. package/dist/domain.operations/plan/validate.js.map +1 -0
  89. package/dist/infra/asIsoTimestamp.d.ts +6 -0
  90. package/dist/infra/asIsoTimestamp.js +12 -0
  91. package/dist/infra/asIsoTimestamp.js.map +1 -0
  92. package/package.json +8 -15
  93. package/readme.md +225 -29
  94. package/dist/__test_assets__/getExampleContext.d.ts +0 -33
  95. package/dist/__test_assets__/getExampleContext.js +0 -87
  96. package/dist/__test_assets__/getExampleContext.js.map +0 -1
  97. package/dist/contract/commands/command.apply.d.ts +0 -6
  98. package/dist/contract/commands/command.apply.js +0 -20
  99. package/dist/contract/commands/command.apply.js.map +0 -1
  100. package/dist/contract/commands/command.plan.d.ts +0 -6
  101. package/dist/contract/commands/command.plan.js +0 -20
  102. package/dist/contract/commands/command.plan.js.map +0 -1
  103. package/dist/contract/commands/utils/resolveCommandInputs.d.ts +0 -17
  104. package/dist/contract/commands/utils/resolveCommandInputs.js +0 -23
  105. package/dist/contract/commands/utils/resolveCommandInputs.js.map +0 -1
  106. package/dist/contract/sdk/refs.d.ts +0 -2
  107. package/dist/contract/sdk/refs.js +0 -19
  108. package/dist/contract/sdk/refs.js.map +0 -1
  109. package/dist/contract/sdk/sync/apply.d.ts +0 -22
  110. package/dist/contract/sdk/sync/apply.js +0 -29
  111. package/dist/contract/sdk/sync/apply.js.map +0 -1
  112. package/dist/contract/sdk/sync/plan.d.ts +0 -22
  113. package/dist/contract/sdk/sync/plan.js +0 -30
  114. package/dist/contract/sdk/sync/plan.js.map +0 -1
  115. package/dist/domain/DeclaredResource.d.ts +0 -2
  116. package/dist/domain/DeclaredResource.js.map +0 -1
  117. package/dist/domain/DeclaredResourceReference.d.ts +0 -66
  118. package/dist/domain/DeclaredResourceReference.js +0 -42
  119. package/dist/domain/DeclaredResourceReference.js.map +0 -1
  120. package/dist/domain/DeclastructChangeProposal.d.ts +0 -61
  121. package/dist/domain/DeclastructChangeProposal.js +0 -37
  122. package/dist/domain/DeclastructChangeProposal.js.map +0 -1
  123. package/dist/domain/DeclastructContext.d.ts +0 -24
  124. package/dist/domain/DeclastructContext.js.map +0 -1
  125. package/dist/domain/DeclastructProvider.d.ts +0 -58
  126. package/dist/domain/DeclastructProvider.js +0 -3
  127. package/dist/domain/DeclastructProvider.js.map +0 -1
  128. package/dist/domain/DeclastructProviderContext.d.ts +0 -30
  129. package/dist/domain/DeclastructProviderContext.js +0 -3
  130. package/dist/domain/DeclastructProviderContext.js.map +0 -1
  131. package/dist/domain/DeclastructProviderResourceRemoteStateInterface.d.ts +0 -156
  132. package/dist/domain/DeclastructProviderResourceRemoteStateInterface.js +0 -3
  133. package/dist/domain/DeclastructProviderResourceRemoteStateInterface.js.map +0 -1
  134. package/dist/logic/actions/execute/canUpdateResource.d.ts +0 -5
  135. package/dist/logic/actions/execute/canUpdateResource.js +0 -12
  136. package/dist/logic/actions/execute/canUpdateResource.js.map +0 -1
  137. package/dist/logic/actions/execute/executeProposal.d.ts +0 -5
  138. package/dist/logic/actions/execute/executeProposal.js +0 -52
  139. package/dist/logic/actions/execute/executeProposal.js.map +0 -1
  140. package/dist/logic/actions/propose/getColoredActionToken.d.ts +0 -4
  141. package/dist/logic/actions/propose/getColoredActionToken.js +0 -22
  142. package/dist/logic/actions/propose/getColoredActionToken.js.map +0 -1
  143. package/dist/logic/actions/propose/getColoredProposalTitle.d.ts +0 -4
  144. package/dist/logic/actions/propose/getColoredProposalTitle.js +0 -34
  145. package/dist/logic/actions/propose/getColoredProposalTitle.js.map +0 -1
  146. package/dist/logic/actions/propose/proposeChangeForResource.d.ts +0 -7
  147. package/dist/logic/actions/propose/proposeChangeForResource.js +0 -65
  148. package/dist/logic/actions/propose/proposeChangeForResource.js.map +0 -1
  149. package/dist/logic/actions/propose/proposeChangeForResource.test.js +0 -48
  150. package/dist/logic/actions/propose/proposeChangeForResource.test.js.map +0 -1
  151. package/dist/logic/commands/command.apply.d.ts +0 -8
  152. package/dist/logic/commands/command.apply.js +0 -77
  153. package/dist/logic/commands/command.apply.js.map +0 -1
  154. package/dist/logic/commands/command.plan.d.ts +0 -13
  155. package/dist/logic/commands/command.plan.js +0 -155
  156. package/dist/logic/commands/command.plan.js.map +0 -1
  157. package/dist/logic/commands/execute.d.ts +0 -15
  158. package/dist/logic/commands/execute.js +0 -63
  159. package/dist/logic/commands/execute.js.map +0 -1
  160. package/dist/logic/tools/compare/castReferenceToGrokableString.d.ts +0 -16
  161. package/dist/logic/tools/compare/castReferenceToGrokableString.js +0 -66
  162. package/dist/logic/tools/compare/castReferenceToGrokableString.js.map +0 -1
  163. package/dist/logic/tools/compare/castReferenceToGrokableString.test.js +0 -111
  164. package/dist/logic/tools/compare/castReferenceToGrokableString.test.js.map +0 -1
  165. package/dist/logic/tools/compare/detectDifferenceBetweenDesiredAndRemoteStateOfResource.d.ts +0 -11
  166. package/dist/logic/tools/compare/detectDifferenceBetweenDesiredAndRemoteStateOfResource.js +0 -61
  167. package/dist/logic/tools/compare/detectDifferenceBetweenDesiredAndRemoteStateOfResource.js.map +0 -1
  168. package/dist/logic/tools/compare/detectDifferenceBetweenDesiredAndRemoteStateOfResource.test.js +0 -31
  169. package/dist/logic/tools/compare/detectDifferenceBetweenDesiredAndRemoteStateOfResource.test.js.map +0 -1
  170. package/dist/logic/tools/compare/resolveReferenceToCommonComparableForm.d.ts +0 -21
  171. package/dist/logic/tools/compare/resolveReferenceToCommonComparableForm.js +0 -53
  172. package/dist/logic/tools/compare/resolveReferenceToCommonComparableForm.js.map +0 -1
  173. package/dist/logic/tools/compare/resolveReferenceToCommonComparableForm.test.js +0 -31
  174. package/dist/logic/tools/compare/resolveReferenceToCommonComparableForm.test.js.map +0 -1
  175. package/dist/logic/tools/compare/resolveReferencesToCommonComparableForm.d.ts +0 -10
  176. package/dist/logic/tools/compare/resolveReferencesToCommonComparableForm.js +0 -41
  177. package/dist/logic/tools/compare/resolveReferencesToCommonComparableForm.js.map +0 -1
  178. package/dist/logic/tools/compare/resolveReferencesToCommonComparableForm.test.js +0 -174
  179. package/dist/logic/tools/compare/resolveReferencesToCommonComparableForm.test.js.map +0 -1
  180. package/dist/logic/tools/context/createDeclastructContext.d.ts +0 -10
  181. package/dist/logic/tools/context/createDeclastructContext.js +0 -12
  182. package/dist/logic/tools/context/createDeclastructContext.js.map +0 -1
  183. package/dist/logic/tools/context/destroyDeclastructContext.d.ts +0 -4
  184. package/dist/logic/tools/context/destroyDeclastructContext.js +0 -10
  185. package/dist/logic/tools/context/destroyDeclastructContext.js.map +0 -1
  186. package/dist/logic/tools/provider/castProviderContextToGlobalContext.d.ts +0 -4
  187. package/dist/logic/tools/provider/castProviderContextToGlobalContext.js +0 -10
  188. package/dist/logic/tools/provider/castProviderContextToGlobalContext.js.map +0 -1
  189. package/dist/logic/tools/provider/getProviderContextFromGlobalContextForResourceClass.d.ts +0 -13
  190. package/dist/logic/tools/provider/getProviderContextFromGlobalContextForResourceClass.js +0 -29
  191. package/dist/logic/tools/provider/getProviderContextFromGlobalContextForResourceClass.js.map +0 -1
  192. package/dist/logic/tools/provider/getProviderResourceRemoteStateInterfaceExecutionDependenciesForResource.d.ts +0 -13
  193. package/dist/logic/tools/provider/getProviderResourceRemoteStateInterfaceExecutionDependenciesForResource.js +0 -24
  194. package/dist/logic/tools/provider/getProviderResourceRemoteStateInterfaceExecutionDependenciesForResource.js.map +0 -1
  195. package/dist/logic/tools/provider/getProviderResourceRemoteStateInterfaceFromContextForResourceClass.d.ts +0 -10
  196. package/dist/logic/tools/provider/getProviderResourceRemoteStateInterfaceFromContextForResourceClass.js +0 -21
  197. package/dist/logic/tools/provider/getProviderResourceRemoteStateInterfaceFromContextForResourceClass.js.map +0 -1
  198. package/dist/logic/tools/reference/buildPrimaryKeyTo.d.ts +0 -5
  199. package/dist/logic/tools/reference/buildPrimaryKeyTo.js +0 -40
  200. package/dist/logic/tools/reference/buildPrimaryKeyTo.js.map +0 -1
  201. package/dist/logic/tools/reference/buildReferenceTo.d.ts +0 -28
  202. package/dist/logic/tools/reference/buildReferenceTo.js +0 -92
  203. package/dist/logic/tools/reference/buildReferenceTo.js.map +0 -1
  204. package/dist/logic/tools/reference/buildReferenceTo.test.js +0 -119
  205. package/dist/logic/tools/reference/buildReferenceTo.test.js.map +0 -1
  206. package/dist/logic/tools/reference/buildUniqueKeyTo.d.ts +0 -5
  207. package/dist/logic/tools/reference/buildUniqueKeyTo.js +0 -40
  208. package/dist/logic/tools/reference/buildUniqueKeyTo.js.map +0 -1
  209. package/dist/logic/tools/reference/defineReferenceClassOf.d.ts +0 -5
  210. package/dist/logic/tools/reference/defineReferenceClassOf.js +0 -25
  211. package/dist/logic/tools/reference/defineReferenceClassOf.js.map +0 -1
  212. package/dist/logic/tools/reference/defineReferenceKeyConstituentsOf.d.ts +0 -13
  213. package/dist/logic/tools/reference/defineReferenceKeyConstituentsOf.js +0 -36
  214. package/dist/logic/tools/reference/defineReferenceKeyConstituentsOf.js.map +0 -1
  215. package/dist/logic/tools/reference/getByReference.d.ts +0 -15
  216. package/dist/logic/tools/reference/getByReference.js +0 -55
  217. package/dist/logic/tools/reference/getByReference.js.map +0 -1
  218. package/dist/logic/tools/reference/getByReference.test.js +0 -92
  219. package/dist/logic/tools/reference/getByReference.test.js.map +0 -1
  220. package/dist/logic/tools/reference/getByReferencedPrimaryKey.d.ts +0 -6
  221. package/dist/logic/tools/reference/getByReferencedPrimaryKey.js +0 -17
  222. package/dist/logic/tools/reference/getByReferencedPrimaryKey.js.map +0 -1
  223. package/dist/logic/tools/reference/getByReferencedUniqueKey.d.ts +0 -7
  224. package/dist/logic/tools/reference/getByReferencedUniqueKey.js +0 -42
  225. package/dist/logic/tools/reference/getByReferencedUniqueKey.js.map +0 -1
  226. package/dist/logic/tools/reference/getPrimaryKeyByReference.d.ts +0 -15
  227. package/dist/logic/tools/reference/getPrimaryKeyByReference.js +0 -36
  228. package/dist/logic/tools/reference/getPrimaryKeyByReference.js.map +0 -1
  229. package/dist/logic/tools/reference/getReferenceTo.d.ts +0 -18
  230. package/dist/logic/tools/reference/getReferenceTo.js +0 -55
  231. package/dist/logic/tools/reference/getReferenceTo.js.map +0 -1
  232. package/dist/logic/tools/reference/getReferenceTo.test.js +0 -95
  233. package/dist/logic/tools/reference/getReferenceTo.test.js.map +0 -1
  234. package/dist/logic/tools/reference/getUniqueKeyByReference.d.ts +0 -15
  235. package/dist/logic/tools/reference/getUniqueKeyByReference.js +0 -36
  236. package/dist/logic/tools/reference/getUniqueKeyByReference.js.map +0 -1
  237. package/dist/logic/tools/reference/isPrimaryKeyReference.d.ts +0 -6
  238. package/dist/logic/tools/reference/isPrimaryKeyReference.js +0 -7
  239. package/dist/logic/tools/reference/isPrimaryKeyReference.js.map +0 -1
  240. package/dist/logic/tools/reference/isUniqueKeyReference.d.ts +0 -6
  241. package/dist/logic/tools/reference/isUniqueKeyReference.js +0 -7
  242. package/dist/logic/tools/reference/isUniqueKeyReference.js.map +0 -1
  243. /package/dist/{logic/actions/propose/proposeChangeForResource.test.d.ts → contract/cli/apply.integration.test.d.ts} +0 -0
  244. /package/dist/{logic/tools/compare/castReferenceToGrokableString.test.d.ts → contract/cli/plan.integration.test.d.ts} +0 -0
  245. /package/dist/{logic/tools/compare/detectDifferenceBetweenDesiredAndRemoteStateOfResource.test.d.ts → domain.objects/ContextDeclastruct.test.d.ts} +0 -0
  246. /package/dist/{logic/tools/compare/resolveReferenceToCommonComparableForm.test.d.ts → domain.objects/DeclastructChange.test.d.ts} +0 -0
  247. /package/dist/{logic/tools/compare/resolveReferencesToCommonComparableForm.test.d.ts → domain.objects/DeclastructDao.test.d.ts} +0 -0
  248. /package/dist/{logic/tools/reference/buildReferenceTo.test.d.ts → domain.objects/DeclastructPlan.test.d.ts} +0 -0
  249. /package/dist/{logic/tools/reference/getByReference.test.d.ts → domain.objects/DeclastructProvider.test.d.ts} +0 -0
  250. /package/dist/{logic/tools/reference/getReferenceTo.test.d.ts → domain.objects/IsoTimestamp.test.d.ts} +0 -0
@@ -0,0 +1,291 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const bottleneck_1 = __importDefault(require("bottleneck"));
7
+ const fs_1 = require("fs");
8
+ const promises_1 = require("fs/promises");
9
+ const path_1 = require("path");
10
+ const demo_provider_1 = require("../../.test/assets/providers/demo.provider");
11
+ const DeclastructChange_1 = require("../../domain.objects/DeclastructChange");
12
+ const planChanges_1 = require("../plan/planChanges");
13
+ const applyChanges_1 = require("./applyChanges");
14
+ describe('applyChanges', () => {
15
+ const wishFilePath = (0, path_1.resolve)(process.cwd(), 'src/.test/assets/wish.fixture.ts');
16
+ beforeAll(async () => {
17
+ // initialize provider (creates temp directory)
18
+ await demo_provider_1.demoProvider.hooks.beforeAll();
19
+ });
20
+ const createContext = () => ({
21
+ bottleneck: new bottleneck_1.default({ maxConcurrent: 1 }),
22
+ log: {
23
+ info: jest.fn(),
24
+ error: jest.fn(),
25
+ warn: jest.fn(),
26
+ debug: jest.fn(),
27
+ },
28
+ });
29
+ it('should apply CREATE changes and verify files created on disk', async () => {
30
+ // define desired resources with automatic unique IDs
31
+ const resources = [
32
+ (0, demo_provider_1.genSampleDemoResource)({ name: 'First Test' }),
33
+ (0, demo_provider_1.genSampleDemoResource)({ name: 'Second Test' }),
34
+ ];
35
+ // plan changes
36
+ const plan = await (0, planChanges_1.planChanges)({
37
+ resources,
38
+ providers: [demo_provider_1.demoProvider],
39
+ wishFilePath,
40
+ }, createContext());
41
+ // verify plan has CREATE actions
42
+ expect(plan.changes.every((c) => c.action === DeclastructChange_1.DeclastructChangeAction.CREATE)).toBe(true);
43
+ // apply changes
44
+ const result = await (0, applyChanges_1.applyChanges)({
45
+ plan,
46
+ resources,
47
+ providers: [demo_provider_1.demoProvider],
48
+ }, createContext());
49
+ // verify changes were applied
50
+ expect(result.appliedChanges.length).toBe(2);
51
+ result.appliedChanges.forEach((change) => {
52
+ expect(change.action).toBe(DeclastructChange_1.DeclastructChangeAction.CREATE);
53
+ });
54
+ // verify files exist on disk
55
+ const file1Path = (0, path_1.resolve)(process.cwd(), `.test/demo/provider/.temp/${resources[0].exid}.json`);
56
+ const file2Path = (0, path_1.resolve)(process.cwd(), `.test/demo/provider/.temp/${resources[1].exid}.json`);
57
+ expect((0, fs_1.existsSync)(file1Path)).toBe(true);
58
+ expect((0, fs_1.existsSync)(file2Path)).toBe(true);
59
+ // verify file contents
60
+ const file1Json = await (0, promises_1.readFile)(file1Path, 'utf-8');
61
+ const file1Data = JSON.parse(file1Json);
62
+ expect(file1Data.exid).toBe(resources[0].exid);
63
+ expect(file1Data.name).toBe('First Test');
64
+ const file2Json = await (0, promises_1.readFile)(file2Path, 'utf-8');
65
+ const file2Data = JSON.parse(file2Json);
66
+ expect(file2Data.exid).toBe(resources[1].exid);
67
+ expect(file2Data.name).toBe('Second Test');
68
+ });
69
+ it('should apply UPDATE changes and verify files modified on disk', async () => {
70
+ // create initial resource
71
+ const initialResource = (0, demo_provider_1.genSampleDemoResource)({ name: 'Old Name' });
72
+ // create initial remote state
73
+ const dao = demo_provider_1.demoProvider.daos.DemoResource;
74
+ await dao.set.finsert(initialResource, {});
75
+ // define desired resource with updated name (same exid)
76
+ const resources = [initialResource.clone({ name: 'New Name' })];
77
+ // plan changes
78
+ const plan = await (0, planChanges_1.planChanges)({
79
+ resources,
80
+ providers: [demo_provider_1.demoProvider],
81
+ wishFilePath,
82
+ }, createContext());
83
+ // verify plan has UPDATE action
84
+ expect(plan.changes.length).toBe(1);
85
+ expect(plan.changes[0].action).toBe(DeclastructChange_1.DeclastructChangeAction.UPDATE);
86
+ // apply changes
87
+ const result = await (0, applyChanges_1.applyChanges)({
88
+ plan,
89
+ resources,
90
+ providers: [demo_provider_1.demoProvider],
91
+ }, createContext());
92
+ // verify update was applied
93
+ expect(result.appliedChanges.length).toBe(1);
94
+ expect(result.appliedChanges[0].action).toBe(DeclastructChange_1.DeclastructChangeAction.UPDATE);
95
+ // verify file was updated on disk
96
+ const filePath = (0, path_1.resolve)(process.cwd(), `.test/demo/provider/.temp/${initialResource.exid}.json`);
97
+ const fileJson = await (0, promises_1.readFile)(filePath, 'utf-8');
98
+ const fileData = JSON.parse(fileJson);
99
+ expect(fileData.name).toBe('New Name');
100
+ });
101
+ it('should skip KEEP changes without making modifications', async () => {
102
+ // create resource
103
+ const resource = (0, demo_provider_1.genSampleDemoResource)({ name: 'Unchanged' });
104
+ // create remote state
105
+ const dao = demo_provider_1.demoProvider.daos.DemoResource;
106
+ await dao.set.finsert(resource, {});
107
+ // define same resource (no changes)
108
+ const resources = [resource];
109
+ // plan changes
110
+ const plan = await (0, planChanges_1.planChanges)({
111
+ resources,
112
+ providers: [demo_provider_1.demoProvider],
113
+ wishFilePath,
114
+ }, createContext());
115
+ // verify plan has KEEP action
116
+ expect(plan.changes.length).toBe(1);
117
+ expect(plan.changes[0].action).toBe(DeclastructChange_1.DeclastructChangeAction.KEEP);
118
+ // apply changes
119
+ const context = createContext();
120
+ const result = await (0, applyChanges_1.applyChanges)({
121
+ plan,
122
+ resources,
123
+ providers: [demo_provider_1.demoProvider],
124
+ }, context);
125
+ // verify KEEP was not included in applied changes
126
+ expect(result.appliedChanges.length).toBe(0);
127
+ // verify log was emitted for KEEP
128
+ expect(context.log.info).toHaveBeenCalledWith(expect.stringContaining('[KEEP]'), {});
129
+ // verify file still exists with same content
130
+ const filePath = (0, path_1.resolve)(process.cwd(), `.test/demo/provider/.temp/${resource.exid}.json`);
131
+ const fileJson = await (0, promises_1.readFile)(filePath, 'utf-8');
132
+ const fileData = JSON.parse(fileJson);
133
+ expect(fileData.name).toBe('Unchanged');
134
+ });
135
+ it('should emit real-time logs as changes are applied', async () => {
136
+ // define resources
137
+ const resources = [
138
+ (0, demo_provider_1.genSampleDemoResource)({ name: 'First Test' }),
139
+ (0, demo_provider_1.genSampleDemoResource)({ name: 'Second Test' }),
140
+ ];
141
+ // plan changes
142
+ const plan = await (0, planChanges_1.planChanges)({
143
+ resources,
144
+ providers: [demo_provider_1.demoProvider],
145
+ wishFilePath,
146
+ }, createContext());
147
+ // apply with spy on log
148
+ const context = createContext();
149
+ await (0, applyChanges_1.applyChanges)({
150
+ plan,
151
+ resources,
152
+ providers: [demo_provider_1.demoProvider],
153
+ }, context);
154
+ // verify logs were emitted (logs include the full slug with hash)
155
+ expect(context.log.info).toHaveBeenCalledWith(expect.stringContaining(`[CREATE] DemoResource.`), {});
156
+ expect(context.log.info).toHaveBeenCalled();
157
+ });
158
+ it('should handle mixed CREATE, UPDATE, and KEEP actions in single apply', async () => {
159
+ // create initial resources for remote state
160
+ const resource1 = (0, demo_provider_1.genSampleDemoResource)({ name: 'Unchanged' });
161
+ const resource2 = (0, demo_provider_1.genSampleDemoResource)({ name: 'Old Name' });
162
+ // create remote state for some resources
163
+ const dao = demo_provider_1.demoProvider.daos.DemoResource;
164
+ await dao.set.finsert(resource1, {});
165
+ await dao.set.finsert(resource2, {});
166
+ // define desired resources
167
+ const resources = [
168
+ resource1, // KEEP (unchanged)
169
+ resource2.clone({ name: 'New Name' }), // UPDATE
170
+ (0, demo_provider_1.genSampleDemoResource)({ name: 'Brand New' }), // CREATE
171
+ ];
172
+ // plan changes
173
+ const plan = await (0, planChanges_1.planChanges)({
174
+ resources,
175
+ providers: [demo_provider_1.demoProvider],
176
+ wishFilePath,
177
+ }, createContext());
178
+ // verify mixed actions in plan
179
+ expect(plan.changes.length).toBe(3);
180
+ // apply changes
181
+ const result = await (0, applyChanges_1.applyChanges)({
182
+ plan,
183
+ resources,
184
+ providers: [demo_provider_1.demoProvider],
185
+ }, createContext());
186
+ // verify only CREATE and UPDATE were applied (not KEEP)
187
+ expect(result.appliedChanges.length).toBe(2);
188
+ const appliedActions = result.appliedChanges.map((c) => c.action);
189
+ expect(appliedActions).toContain(DeclastructChange_1.DeclastructChangeAction.UPDATE);
190
+ expect(appliedActions).toContain(DeclastructChange_1.DeclastructChangeAction.CREATE);
191
+ // verify all files exist with correct content
192
+ const file1Path = (0, path_1.resolve)(process.cwd(), `.test/demo/provider/.temp/${resources[0].exid}.json`);
193
+ const file2Path = (0, path_1.resolve)(process.cwd(), `.test/demo/provider/.temp/${resources[1].exid}.json`);
194
+ const file3Path = (0, path_1.resolve)(process.cwd(), `.test/demo/provider/.temp/${resources[2].exid}.json`);
195
+ expect((0, fs_1.existsSync)(file1Path)).toBe(true);
196
+ expect((0, fs_1.existsSync)(file2Path)).toBe(true);
197
+ expect((0, fs_1.existsSync)(file3Path)).toBe(true);
198
+ const file2Json = await (0, promises_1.readFile)(file2Path, 'utf-8');
199
+ const file2Data = JSON.parse(file2Json);
200
+ expect(file2Data.name).toBe('New Name');
201
+ });
202
+ it('should detect and reject stale plans', async () => {
203
+ // define initial resource
204
+ const initialResources = [(0, demo_provider_1.genSampleDemoResource)({ name: 'Original Name' })];
205
+ // plan changes
206
+ const plan = await (0, planChanges_1.planChanges)({
207
+ resources: initialResources,
208
+ providers: [demo_provider_1.demoProvider],
209
+ wishFilePath,
210
+ }, createContext());
211
+ // apply the plan (creates the resource)
212
+ await (0, applyChanges_1.applyChanges)({
213
+ plan,
214
+ resources: initialResources,
215
+ providers: [demo_provider_1.demoProvider],
216
+ }, createContext());
217
+ // externally modify the resource
218
+ const dao = demo_provider_1.demoProvider.daos.DemoResource;
219
+ await dao.set.upsert(initialResources[0].clone({ name: 'Externally Modified' }), {});
220
+ // try to reapply the stale plan
221
+ await expect((0, applyChanges_1.applyChanges)({
222
+ plan, // stale plan still shows "Original Name"
223
+ resources: initialResources,
224
+ providers: [demo_provider_1.demoProvider],
225
+ }, createContext())).rejects.toThrow();
226
+ });
227
+ it('should be idempotent - reapplying same plan is safe', async () => {
228
+ // define resource
229
+ const resources = [(0, demo_provider_1.genSampleDemoResource)({ name: 'Test Resource' })];
230
+ // plan changes
231
+ const plan = await (0, planChanges_1.planChanges)({
232
+ resources,
233
+ providers: [demo_provider_1.demoProvider],
234
+ wishFilePath,
235
+ }, createContext());
236
+ // apply first time
237
+ const result1 = await (0, applyChanges_1.applyChanges)({
238
+ plan,
239
+ resources,
240
+ providers: [demo_provider_1.demoProvider],
241
+ }, createContext());
242
+ expect(result1.appliedChanges.length).toBe(1);
243
+ expect(result1.appliedChanges[0].action).toBe(DeclastructChange_1.DeclastructChangeAction.CREATE);
244
+ // replan with same resources
245
+ const plan2 = await (0, planChanges_1.planChanges)({
246
+ resources,
247
+ providers: [demo_provider_1.demoProvider],
248
+ wishFilePath,
249
+ }, createContext());
250
+ // apply second time
251
+ const result2 = await (0, applyChanges_1.applyChanges)({
252
+ plan: plan2,
253
+ resources,
254
+ providers: [demo_provider_1.demoProvider],
255
+ }, createContext());
256
+ // verify second apply was KEEP (no changes)
257
+ expect(result2.appliedChanges.length).toBe(0);
258
+ expect(plan2.changes[0].action).toBe(DeclastructChange_1.DeclastructChangeAction.KEEP);
259
+ // verify file exists with correct content
260
+ const filePath = (0, path_1.resolve)(process.cwd(), `.test/demo/provider/.temp/${resources[0].exid}.json`);
261
+ const fileJson = await (0, promises_1.readFile)(filePath, 'utf-8');
262
+ const fileData = JSON.parse(fileJson);
263
+ expect(fileData.name).toBe('Test Resource');
264
+ });
265
+ it('should validate plan before applying to ensure it is still valid', async () => {
266
+ // define resource
267
+ const resources = [(0, demo_provider_1.genSampleDemoResource)({ name: 'Test Resource' })];
268
+ // plan changes
269
+ const originalPlan = await (0, planChanges_1.planChanges)({
270
+ resources,
271
+ providers: [demo_provider_1.demoProvider],
272
+ wishFilePath,
273
+ }, createContext());
274
+ // apply the plan (creates the resource)
275
+ await (0, applyChanges_1.applyChanges)({
276
+ plan: originalPlan,
277
+ resources,
278
+ providers: [demo_provider_1.demoProvider],
279
+ }, createContext());
280
+ // externally modify the remote resource to make original plan stale
281
+ const dao = demo_provider_1.demoProvider.daos.DemoResource;
282
+ await dao.set.upsert(resources[0].clone({ name: 'Externally Modified' }), {});
283
+ // try to apply the stale plan again
284
+ await expect((0, applyChanges_1.applyChanges)({
285
+ plan: originalPlan, // stale - remote state changed
286
+ resources,
287
+ providers: [demo_provider_1.demoProvider],
288
+ }, createContext())).rejects.toThrow('plan is stale');
289
+ });
290
+ });
291
+ //# sourceMappingURL=applyChanges.integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applyChanges.integration.test.js","sourceRoot":"","sources":["../../../src/domain.operations/apply/applyChanges.integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyChanges = void 0;
4
+ const domain_objects_1 = require("domain-objects");
5
+ const helpful_errors_1 = require("helpful-errors");
6
+ const DeclastructChange_1 = require("../../domain.objects/DeclastructChange");
7
+ const planChanges_1 = require("../plan/planChanges");
8
+ const validate_1 = require("../plan/validate");
9
+ const applyChange_1 = require("./applyChange");
10
+ /**
11
+ * .what = applies a validated plan to achieve desired state
12
+ * .why = executes infrastructure changes in a controlled, observable manner
13
+ * .note = idempotent - reapplying same plan is safe (guards check if already applied)
14
+ */
15
+ const applyChanges = async (input, context) => {
16
+ // replan to ensure plan is still valid
17
+ const currentPlan = await (0, planChanges_1.planChanges)({
18
+ resources: input.resources,
19
+ providers: input.providers,
20
+ wishFilePath: input.plan.wish.uri,
21
+ }, context);
22
+ // validate plan matches current state
23
+ (0, validate_1.assertPlanStillValid)({
24
+ originalPlan: input.plan,
25
+ currentPlan,
26
+ });
27
+ // apply each change with real-time logging
28
+ const appliedChanges = [];
29
+ for (const change of input.plan.changes) {
30
+ // log KEEP actions and skip
31
+ if (change.action === DeclastructChange_1.DeclastructChangeAction.KEEP) {
32
+ context.log.info(`↓ [KEEP] ${change.forResource.slug}`, {});
33
+ continue;
34
+ }
35
+ // find the desired resource
36
+ const resourceFound = input.resources.find((candidate) => candidate.constructor.name === change.forResource.class &&
37
+ (0, domain_objects_1.getUniqueIdentifierSlug)(candidate) === change.forResource.slug) ??
38
+ helpful_errors_1.UnexpectedCodePathError.throw('could not find resource specified in plan. was it removed and plan is no longer valid?', { change });
39
+ // apply the change
40
+ const applied = await (0, applyChange_1.applyChange)({
41
+ change,
42
+ resource: resourceFound,
43
+ providers: input.providers,
44
+ context,
45
+ });
46
+ // log success immediately
47
+ context.log.info(`✔ [${applied.action}] ${applied.forResource.slug}`, {});
48
+ appliedChanges.push(applied);
49
+ }
50
+ return { appliedChanges };
51
+ };
52
+ exports.applyChanges = applyChanges;
53
+ //# sourceMappingURL=applyChanges.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applyChanges.js","sourceRoot":"","sources":["../../../src/domain.operations/apply/applyChanges.ts"],"names":[],"mappings":";;;AAAA,mDAAuE;AACvE,mDAAyD;AAIzD,8EAGgD;AAGhD,qDAAkD;AAClD,+CAAwD;AACxD,+CAA4C;AAE5C;;;;GAIG;AACI,MAAM,YAAY,GAAG,KAAK,EAC/B,KAIC,EACD,OAA6C,EACK,EAAE;IACpD,uCAAuC;IACvC,MAAM,WAAW,GAAG,MAAM,IAAA,yBAAW,EACnC;QACE,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;KAClC,EACD,OAAO,CACR,CAAC;IAEF,sCAAsC;IACtC,IAAA,+BAAoB,EAAC;QACnB,YAAY,EAAE,KAAK,CAAC,IAAI;QACxB,WAAW;KACZ,CAAC,CAAC;IAEH,2CAA2C;IAC3C,MAAM,cAAc,GAAwB,EAAE,CAAC;IAE/C,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACxC,4BAA4B;QAC5B,IAAI,MAAM,CAAC,MAAM,KAAK,2CAAuB,CAAC,IAAI,EAAE,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YAC5D,SAAS;QACX,CAAC;QAED,4BAA4B;QAC5B,MAAM,aAAa,GACjB,KAAK,CAAC,SAAS,CAAC,IAAI,CAClB,CAAC,SAAS,EAAE,EAAE,CACZ,SAAS,CAAC,WAAW,CAAC,IAAI,KAAK,MAAM,CAAC,WAAW,CAAC,KAAK;YACvD,IAAA,wCAAuB,EAAC,SAAS,CAAC,KAAK,MAAM,CAAC,WAAW,CAAC,IAAI,CACjE;YACD,wCAAuB,CAAC,KAAK,CAC3B,wFAAwF,EACxF,EAAE,MAAM,EAAE,CACX,CAAC;QAEJ,mBAAmB;QACnB,MAAM,OAAO,GAAG,MAAM,IAAA,yBAAW,EAAC;YAChC,MAAM;YACN,QAAQ,EAAE,aAAa;YACvB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,OAAO;SACR,CAAC,CAAC;QAEH,0BAA0B;QAC1B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAE1E,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,EAAE,cAAc,EAAE,CAAC;AAC5B,CAAC,CAAC;AA7DW,QAAA,YAAY,gBA6DvB"}
@@ -0,0 +1,11 @@
1
+ import { DomainEntity } from 'domain-objects';
2
+ import { DeclastructChange } from '../../domain.objects/DeclastructChange';
3
+ /**
4
+ * .what = computes a single change by comparing desired vs remote state
5
+ * .why = determines the action needed to achieve desired state for one resource
6
+ * .note = uses IIFE to compute action immutably
7
+ */
8
+ export declare const computeChange: ({ desired, remote, }: {
9
+ desired: DomainEntity<any> | null;
10
+ remote: DomainEntity<any> | null;
11
+ }) => DeclastructChange;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeChange = void 0;
4
+ const domain_objects_1 = require("domain-objects");
5
+ const jest_diff_1 = require("jest-diff");
6
+ const DeclastructChange_1 = require("../../domain.objects/DeclastructChange");
7
+ /**
8
+ * .what = checks if two resources are equivalent
9
+ * .why = determines whether a resource needs to be updated
10
+ * .note = uses JSON serialization for deep equality check
11
+ */
12
+ const resourcesAreEquivalent = (remote, desired) => {
13
+ // serialize both to JSON for deep comparison
14
+ const remoteJson = JSON.stringify(remote);
15
+ const desiredJson = JSON.stringify(desired);
16
+ return remoteJson === desiredJson;
17
+ };
18
+ /**
19
+ * .what = computes human-readable diff between two resources
20
+ * .why = helps users understand what will change
21
+ * .note = returns null if resources are identical; for CREATE uses empty object to show all attributes
22
+ */
23
+ const computeDiff = ({ from, into, }) => {
24
+ // no diff if both are null
25
+ if (from === null && into === null)
26
+ return null;
27
+ // use empty object for CREATE to show all attributes in diff
28
+ const fromValue = from === null ? {} : from;
29
+ const intoValue = into === null ? {} : into;
30
+ // compute diff using jest-diff
31
+ const difference = (0, jest_diff_1.diff)(fromValue, intoValue, {
32
+ aAnnotation: 'Remote',
33
+ bAnnotation: 'Desired',
34
+ });
35
+ return difference;
36
+ };
37
+ /**
38
+ * .what = computes a single change by comparing desired vs remote state
39
+ * .why = determines the action needed to achieve desired state for one resource
40
+ * .note = uses IIFE to compute action immutably
41
+ */
42
+ const computeChange = ({ desired, remote, }) => {
43
+ // determine action based on state comparison
44
+ const action = (() => {
45
+ // resource doesn't exist remotely
46
+ if (!remote)
47
+ return DeclastructChange_1.DeclastructChangeAction.CREATE;
48
+ // resource exists but should be deleted
49
+ if (!desired)
50
+ return DeclastructChange_1.DeclastructChangeAction.DESTROY;
51
+ // no changes needed
52
+ if (resourcesAreEquivalent(remote, desired))
53
+ return DeclastructChange_1.DeclastructChangeAction.KEEP;
54
+ // resource exists and needs updating
55
+ return DeclastructChange_1.DeclastructChangeAction.UPDATE;
56
+ })();
57
+ // compute displayable difference
58
+ const difference = action === DeclastructChange_1.DeclastructChangeAction.KEEP
59
+ ? null
60
+ : computeDiff({ from: remote, into: desired });
61
+ // get resource info for change record
62
+ const resourceForChange = desired || remote;
63
+ // return change
64
+ return new DeclastructChange_1.DeclastructChange({
65
+ forResource: {
66
+ class: resourceForChange.constructor.name,
67
+ slug: (0, domain_objects_1.getUniqueIdentifierSlug)(resourceForChange),
68
+ },
69
+ action,
70
+ state: {
71
+ desired,
72
+ remote,
73
+ difference,
74
+ },
75
+ });
76
+ };
77
+ exports.computeChange = computeChange;
78
+ //# sourceMappingURL=computeChange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computeChange.js","sourceRoot":"","sources":["../../../src/domain.operations/plan/computeChange.ts"],"names":[],"mappings":";;;AAAA,mDAAuE;AACvE,yCAAiC;AAEjC,8EAGgD;AAEhD;;;;GAIG;AACH,MAAM,sBAAsB,GAAG,CAC7B,MAAyB,EACzB,OAA0B,EACjB,EAAE;IACX,6CAA6C;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAE5C,OAAO,UAAU,KAAK,WAAW,CAAC;AACpC,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,WAAW,GAAG,CAAC,EACnB,IAAI,EACJ,IAAI,GAIL,EAAiB,EAAE;IAClB,2BAA2B;IAC3B,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEhD,6DAA6D;IAC7D,MAAM,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5C,MAAM,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAE5C,+BAA+B;IAC/B,MAAM,UAAU,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,SAAS,EAAE;QAC5C,WAAW,EAAE,QAAQ;QACrB,WAAW,EAAE,SAAS;KACvB,CAAC,CAAC;IAEH,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AAEF;;;;GAIG;AACI,MAAM,aAAa,GAAG,CAAC,EAC5B,OAAO,EACP,MAAM,GAIP,EAAqB,EAAE;IACtB,6CAA6C;IAC7C,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE;QACnB,kCAAkC;QAClC,IAAI,CAAC,MAAM;YAAE,OAAO,2CAAuB,CAAC,MAAM,CAAC;QAEnD,wCAAwC;QACxC,IAAI,CAAC,OAAO;YAAE,OAAO,2CAAuB,CAAC,OAAO,CAAC;QAErD,oBAAoB;QACpB,IAAI,sBAAsB,CAAC,MAAM,EAAE,OAAO,CAAC;YACzC,OAAO,2CAAuB,CAAC,IAAI,CAAC;QAEtC,qCAAqC;QACrC,OAAO,2CAAuB,CAAC,MAAM,CAAC;IACxC,CAAC,CAAC,EAAE,CAAC;IAEL,iCAAiC;IACjC,MAAM,UAAU,GACd,MAAM,KAAK,2CAAuB,CAAC,IAAI;QACrC,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAEnD,sCAAsC;IACtC,MAAM,iBAAiB,GAAG,OAAO,IAAI,MAAO,CAAC;IAE7C,gBAAgB;IAChB,OAAO,IAAI,qCAAiB,CAAC;QAC3B,WAAW,EAAE;YACX,KAAK,EAAE,iBAAiB,CAAC,WAAW,CAAC,IAAI;YACzC,IAAI,EAAE,IAAA,wCAAuB,EAAC,iBAAiB,CAAC;SACjD;QACD,MAAM;QACN,KAAK,EAAE;YACL,OAAO;YACP,MAAM;YACN,UAAU;SACX;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AA7CW,QAAA,aAAa,iBA6CxB"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const domain_objects_1 = require("domain-objects");
4
+ const DeclastructChange_1 = require("../../domain.objects/DeclastructChange");
5
+ const computeChange_1 = require("./computeChange");
6
+ describe('computeChange', () => {
7
+ class DemoResource extends domain_objects_1.DomainEntity {
8
+ }
9
+ DemoResource.unique = ['id'];
10
+ it('should return CREATE when remote is null', () => {
11
+ const desired = new DemoResource({ id: 'new-1', name: 'New Resource' });
12
+ const change = (0, computeChange_1.computeChange)({
13
+ desired,
14
+ remote: null,
15
+ });
16
+ expect(change.action).toBe(DeclastructChange_1.DeclastructChangeAction.CREATE);
17
+ expect(change.forResource.class).toBe('DemoResource');
18
+ expect(change.forResource.slug).toBe((0, domain_objects_1.getUniqueIdentifierSlug)(desired));
19
+ expect(change.state.desired).toBe(desired);
20
+ expect(change.state.remote).toBeNull();
21
+ expect(change.state.difference).toBeTruthy();
22
+ });
23
+ it('should return DESTROY when desired is null', () => {
24
+ const remote = new DemoResource({ id: 'old-1', name: 'Old Resource' });
25
+ const change = (0, computeChange_1.computeChange)({
26
+ desired: null,
27
+ remote,
28
+ });
29
+ expect(change.action).toBe(DeclastructChange_1.DeclastructChangeAction.DESTROY);
30
+ expect(change.forResource.class).toBe('DemoResource');
31
+ expect(change.forResource.slug).toBe((0, domain_objects_1.getUniqueIdentifierSlug)(remote));
32
+ expect(change.state.desired).toBeNull();
33
+ expect(change.state.remote).toBe(remote);
34
+ expect(change.state.difference).toBeTruthy();
35
+ });
36
+ it('should return KEEP when resources are equivalent', () => {
37
+ const desired = new DemoResource({ id: 'same-1', name: 'Same Resource' });
38
+ const remote = new DemoResource({ id: 'same-1', name: 'Same Resource' });
39
+ const change = (0, computeChange_1.computeChange)({
40
+ desired,
41
+ remote,
42
+ });
43
+ expect(change.action).toBe(DeclastructChange_1.DeclastructChangeAction.KEEP);
44
+ expect(change.forResource.class).toBe('DemoResource');
45
+ expect(change.forResource.slug).toBe((0, domain_objects_1.getUniqueIdentifierSlug)(desired));
46
+ expect(change.state.desired).toBe(desired);
47
+ expect(change.state.remote).toBe(remote);
48
+ expect(change.state.difference).toBeNull();
49
+ });
50
+ it('should return UPDATE when resources differ', () => {
51
+ const desired = new DemoResource({ id: 'update-1', name: 'New Name' });
52
+ const remote = new DemoResource({ id: 'update-1', name: 'Old Name' });
53
+ const change = (0, computeChange_1.computeChange)({
54
+ desired,
55
+ remote,
56
+ });
57
+ expect(change.action).toBe(DeclastructChange_1.DeclastructChangeAction.UPDATE);
58
+ expect(change.forResource.class).toBe('DemoResource');
59
+ expect(change.forResource.slug).toBe((0, domain_objects_1.getUniqueIdentifierSlug)(desired));
60
+ expect(change.state.desired).toBe(desired);
61
+ expect(change.state.remote).toBe(remote);
62
+ expect(change.state.difference).toBeTruthy();
63
+ expect(change.state.difference).toContain('Old Name');
64
+ expect(change.state.difference).toContain('New Name');
65
+ });
66
+ });
67
+ //# sourceMappingURL=computeChange.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computeChange.test.js","sourceRoot":"","sources":["../../../src/domain.operations/plan/computeChange.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { DomainEntity } from 'domain-objects';
2
+ import { DeclastructPlan } from '../../domain.objects/DeclastructPlan';
3
+ /**
4
+ * .what = extracts resources from a plan's changes
5
+ * .why = needed for replanning during applyChanges
6
+ * .note = returns desired state for each change, filtering out DESTROY-only changes
7
+ */
8
+ export declare const extractResourcesFromPlan: (plan: DeclastructPlan) => DomainEntity<any>[];
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractResourcesFromPlan = void 0;
4
+ /**
5
+ * .what = extracts resources from a plan's changes
6
+ * .why = needed for replanning during applyChanges
7
+ * .note = returns desired state for each change, filtering out DESTROY-only changes
8
+ */
9
+ const extractResourcesFromPlan = (plan) => {
10
+ // extract desired resources from changes
11
+ const resources = plan.changes
12
+ .map((change) => change.state.desired)
13
+ .filter((resource) => resource !== null);
14
+ return resources;
15
+ };
16
+ exports.extractResourcesFromPlan = extractResourcesFromPlan;
17
+ //# sourceMappingURL=extractResourcesFromPlan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractResourcesFromPlan.js","sourceRoot":"","sources":["../../../src/domain.operations/plan/extractResourcesFromPlan.ts"],"names":[],"mappings":";;;AAIA;;;;GAIG;AACI,MAAM,wBAAwB,GAAG,CACtC,IAAqB,EACA,EAAE;IACvB,yCAAyC;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO;SAC3B,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;SACrC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,IAAI,CAAwB,CAAC;IAElE,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AATW,QAAA,wBAAwB,4BASnC"}
@@ -0,0 +1,12 @@
1
+ import { DomainEntity } from 'domain-objects';
2
+ import { DeclastructDao } from '../../domain.objects/DeclastructDao';
3
+ import { DeclastructProvider } from '../../domain.objects/DeclastructProvider';
4
+ /**
5
+ * .what = gets the DAO for a given resource from available providers
6
+ * .why = enables automatic routing of operations to the correct provider
7
+ * .note = fails fast if multiple providers support same resource or if no provider is found
8
+ */
9
+ export declare const getDaoByResource: ({ resource, providers, }: {
10
+ resource: DomainEntity<any>;
11
+ providers: DeclastructProvider<any, any>[];
12
+ }) => DeclastructDao<DomainEntity<any>, any, any>;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDaoByResource = void 0;
4
+ const helpful_errors_1 = require("helpful-errors");
5
+ /**
6
+ * .what = gets the DAO for a given resource from available providers
7
+ * .why = enables automatic routing of operations to the correct provider
8
+ * .note = fails fast if multiple providers support same resource or if no provider is found
9
+ */
10
+ const getDaoByResource = ({ resource, providers, }) => {
11
+ // get resource class name
12
+ const resourceClassName = resource.constructor.name;
13
+ // find all DAOs applicable to this resource
14
+ const daosApplicable = providers
15
+ .map((provider) => ({
16
+ from: provider.name,
17
+ dao: provider.daos[resourceClassName],
18
+ }))
19
+ .filter((match) => match.dao);
20
+ // reject if multiple providers support same resource
21
+ if (daosApplicable.length > 1) {
22
+ throw new helpful_errors_1.UnexpectedCodePathError('multiple providers support same resource', {
23
+ resource: resourceClassName,
24
+ providers: daosApplicable.map((m) => m.from),
25
+ });
26
+ }
27
+ // reject if no DAO found
28
+ const [matchedDao] = daosApplicable;
29
+ if (!matchedDao) {
30
+ throw new helpful_errors_1.UnexpectedCodePathError('no DAO found for resource', {
31
+ resourceClassName,
32
+ availableProviders: providers.map((p) => ({
33
+ name: p.name,
34
+ supportedResources: Object.keys(p.daos),
35
+ })),
36
+ });
37
+ }
38
+ return matchedDao.dao;
39
+ };
40
+ exports.getDaoByResource = getDaoByResource;
41
+ //# sourceMappingURL=getDaoByResource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getDaoByResource.js","sourceRoot":"","sources":["../../../src/domain.operations/plan/getDaoByResource.ts"],"names":[],"mappings":";;;AACA,mDAAyD;AAKzD;;;;GAIG;AACI,MAAM,gBAAgB,GAAG,CAAC,EAC/B,QAAQ,EACR,SAAS,GAIV,EAA+C,EAAE;IAChD,0BAA0B;IAC1B,MAAM,iBAAiB,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC;IAEpD,4CAA4C;IAC5C,MAAM,cAAc,GAAG,SAAS;SAC7B,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAClB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,GAAG,EAAE,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC;KACtC,CAAC,CAAC;SACF,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEhC,qDAAqD;IACrD,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,wCAAuB,CAC/B,0CAA0C,EAC1C;YACE,QAAQ,EAAE,iBAAiB;YAC3B,SAAS,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAC7C,CACF,CAAC;IACJ,CAAC;IAED,yBAAyB;IACzB,MAAM,CAAC,UAAU,CAAC,GAAG,cAAc,CAAC;IACpC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,wCAAuB,CAAC,2BAA2B,EAAE;YAC7D,iBAAiB;YACjB,kBAAkB,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACxC,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,kBAAkB,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;aACxC,CAAC,CAAC;SACJ,CAAC,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC,GAAG,CAAC;AACxB,CAAC,CAAC;AA1CW,QAAA,gBAAgB,oBA0C3B"}