declastruct 1.3.0 → 1.4.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/dist/contract/cli/apply.js +4 -3
- package/dist/contract/cli/apply.js.map +1 -1
- package/dist/contract/cli/plan.js +4 -3
- package/dist/contract/cli/plan.js.map +1 -1
- package/dist/domain.objects/ContextDeclastruct.d.ts +1 -1
- package/dist/domain.objects/DeclastructChange.d.ts +1 -1
- package/dist/domain.objects/DeclastructChange.js.map +1 -1
- package/dist/domain.objects/DeclastructDao.d.ts +2 -2
- package/dist/domain.objects/DeclastructPlan.d.ts +2 -2
- package/dist/domain.objects/DeclastructProvider.d.ts +1 -1
- package/dist/domain.operations/apply/applyChanges.d.ts +6 -6
- package/dist/domain.operations/apply/applyChanges.js +24 -14
- package/dist/domain.operations/apply/applyChanges.js.map +1 -1
- package/dist/domain.operations/plan/computeChange.js +2 -28
- package/dist/domain.operations/plan/computeChange.js.map +1 -1
- package/dist/domain.operations/plan/getDisplayableDiff.d.ts +10 -0
- package/dist/domain.operations/plan/getDisplayableDiff.js +40 -0
- package/dist/domain.operations/plan/getDisplayableDiff.js.map +1 -0
- package/dist/domain.operations/plan/planChanges.d.ts +4 -4
- package/dist/domain.operations/plan/planChanges.js +40 -23
- package/dist/domain.operations/plan/planChanges.js.map +1 -1
- package/dist/infra/asIsoTimestamp.d.ts +1 -1
- package/dist/infra/colorizeAction.d.ts +7 -0
- package/dist/infra/colorizeAction.js +31 -0
- package/dist/infra/colorizeAction.js.map +1 -0
- package/dist/infra/withSpinner.d.ts +12 -0
- package/dist/infra/withSpinner.js +90 -0
- package/dist/infra/withSpinner.js.map +1 -0
- package/license.md +21 -0
- package/package.json +20 -9
- package/readme.md +52 -32
- package/dist/.test/assets/providers/demo.provider.d.ts +0 -32
- package/dist/.test/assets/providers/demo.provider.js +0 -101
- package/dist/.test/assets/providers/demo.provider.js.map +0 -1
- package/dist/contract/cli/apply.integration.test.d.ts +0 -1
- package/dist/contract/cli/apply.integration.test.js +0 -215
- package/dist/contract/cli/apply.integration.test.js.map +0 -1
- package/dist/contract/cli/plan.integration.test.d.ts +0 -1
- package/dist/contract/cli/plan.integration.test.js +0 -142
- package/dist/contract/cli/plan.integration.test.js.map +0 -1
- package/dist/domain.objects/ContextDeclastruct.test.d.ts +0 -1
- package/dist/domain.objects/ContextDeclastruct.test.js +0 -41
- package/dist/domain.objects/ContextDeclastruct.test.js.map +0 -1
- package/dist/domain.objects/DeclastructChange.test.d.ts +0 -1
- package/dist/domain.objects/DeclastructChange.test.js +0 -59
- package/dist/domain.objects/DeclastructChange.test.js.map +0 -1
- package/dist/domain.objects/DeclastructDao.test.d.ts +0 -1
- package/dist/domain.objects/DeclastructDao.test.js +0 -78
- package/dist/domain.objects/DeclastructDao.test.js.map +0 -1
- package/dist/domain.objects/DeclastructPlan.test.d.ts +0 -1
- package/dist/domain.objects/DeclastructPlan.test.js +0 -31
- package/dist/domain.objects/DeclastructPlan.test.js.map +0 -1
- package/dist/domain.objects/DeclastructProvider.test.d.ts +0 -1
- package/dist/domain.objects/DeclastructProvider.test.js +0 -80
- package/dist/domain.objects/DeclastructProvider.test.js.map +0 -1
- package/dist/domain.objects/IsoTimestamp.test.d.ts +0 -1
- package/dist/domain.objects/IsoTimestamp.test.js +0 -10
- package/dist/domain.objects/IsoTimestamp.test.js.map +0 -1
- package/dist/domain.operations/apply/applyChange.test.d.ts +0 -1
- package/dist/domain.operations/apply/applyChange.test.js +0 -241
- package/dist/domain.operations/apply/applyChange.test.js.map +0 -1
- package/dist/domain.operations/apply/applyChanges.integration.test.d.ts +0 -1
- package/dist/domain.operations/apply/applyChanges.integration.test.js +0 -291
- package/dist/domain.operations/apply/applyChanges.integration.test.js.map +0 -1
- package/dist/domain.operations/plan/computeChange.test.d.ts +0 -1
- package/dist/domain.operations/plan/computeChange.test.js +0 -153
- package/dist/domain.operations/plan/computeChange.test.js.map +0 -1
- package/dist/domain.operations/plan/getDaoByResource.test.d.ts +0 -1
- package/dist/domain.operations/plan/getDaoByResource.test.js +0 -101
- package/dist/domain.operations/plan/getDaoByResource.test.js.map +0 -1
- package/dist/domain.operations/plan/planChanges.integration.test.d.ts +0 -1
- package/dist/domain.operations/plan/planChanges.integration.test.js +0 -200
- package/dist/domain.operations/plan/planChanges.integration.test.js.map +0 -1
|
@@ -77,6 +77,7 @@ const executeApplyCommand = async (input) => {
|
|
|
77
77
|
if (!(0, fs_1.existsSync)(resolvedWishPath))
|
|
78
78
|
throw new helpful_errors_1.BadRequestError(`Wish file not found: ${resolvedWishPath}`);
|
|
79
79
|
// log header
|
|
80
|
+
log.info('');
|
|
80
81
|
log.info('🌊 declastruct apply');
|
|
81
82
|
if (resolvedPlanPath)
|
|
82
83
|
log.info(` plan: ${resolvedPlanPath}`);
|
|
@@ -93,7 +94,7 @@ const executeApplyCommand = async (input) => {
|
|
|
93
94
|
const resources = await wish.getResources();
|
|
94
95
|
const providers = await wish.getProviders();
|
|
95
96
|
// initialize providers
|
|
96
|
-
log.info('✨ start providers...');
|
|
97
|
+
// log.info('✨ start providers...');
|
|
97
98
|
await Promise.all(providers.map((p) => p.hooks.beforeAll()));
|
|
98
99
|
// create context
|
|
99
100
|
const context = {
|
|
@@ -107,8 +108,8 @@ const executeApplyCommand = async (input) => {
|
|
|
107
108
|
providers,
|
|
108
109
|
}, context);
|
|
109
110
|
// cleanup providers
|
|
110
|
-
log.info('');
|
|
111
|
-
log.info('✨ stop providers...');
|
|
111
|
+
// log.info('');
|
|
112
|
+
// log.info('✨ stop providers...');
|
|
112
113
|
await Promise.all(providers.map((p) => p.hooks.afterAll()));
|
|
113
114
|
// log summary
|
|
114
115
|
log.info('');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/contract/cli/apply.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,4DAAoC;AACpC,2BAAgC;AAChC,0CAAuC;AACvC,mDAAiD;AACjD,+BAA+B;AAE/B,0EAAuE;AACvE,6EAA0E;AAE1E,MAAM,GAAG,GAAG,OAAO,CAAC;AAEpB;;;;;;GAMG;AACI,MAAM,mBAAmB,GAAG,KAAK,EAAE,KAGzC,EAAiB,EAAE;IAClB,oCAAoC;IACpC,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,KAAK,MAAM,CAAC;IACjD,IAAI,UAAU,EAAE,CAAC;QACf,4BAA4B;QAC5B,IAAI,CAAC,KAAK,CAAC,YAAY;YACrB,MAAM,IAAI,gCAAe,CAAC,kCAAkC,CAAC,CAAC;IAClE,CAAC;SAAM,CAAC;QACN,6CAA6C;QAC7C,IAAI,CAAC,KAAK,CAAC,YAAY;YAAE,MAAM,IAAI,gCAAe,CAAC,iBAAiB,CAAC,CAAC;IACxE,CAAC;IAED,yCAAyC;IACzC,MAAM,gBAAgB,GAAG,UAAU;QACjC,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,IAAA,cAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,YAAa,CAAC,CAAC;IAEhD,2CAA2C;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,IAAqC,EAAE;QAC9D,IAAI,CAAC,gBAAgB;YAAE,OAAO,IAAI,CAAC;QACnC,IAAI,CAAC,IAAA,eAAU,EAAC,gBAAgB,CAAC;YAC/B,MAAM,IAAI,gCAAe,CAAC,wBAAwB,gBAAgB,EAAE,CAAC,CAAC;QACxE,MAAM,QAAQ,GAAG,MAAM,IAAA,mBAAQ,EAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAC3D,OAAO,IAAI,iCAAe,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,EAAE,CAAC;IAEL,mDAAmD;IACnD,MAAM,gBAAgB,GAAG,UAAU;QACjC,CAAC,CAAC,IAAA,cAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,YAAa,CAAC;QAC7C,CAAC,CAAC,IAAK,CAAC,IAAI,CAAC,GAAG,CAAC;IAEnB,4BAA4B;IAC5B,IAAI,CAAC,IAAA,eAAU,EAAC,gBAAgB,CAAC;QAC/B,MAAM,IAAI,gCAAe,CAAC,wBAAwB,gBAAgB,EAAE,CAAC,CAAC;IAExE,aAAa;IACb,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACjC,IAAI,gBAAgB;QAAE,GAAG,CAAC,IAAI,CAAC,YAAY,gBAAgB,EAAE,CAAC,CAAC;IAC/D,GAAG,CAAC,IAAI,CAAC,YAAY,gBAAgB,EAAE,CAAC,CAAC;IACzC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEb,mBAAmB;IACnB,MAAM,IAAI,GAAG,yBAAa,gBAAgB,uCAAC,CAAC;IAE5C,mBAAmB;IACnB,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,UAAU;QACzC,MAAM,IAAI,gCAAe,CAAC,+CAA+C,CAAC,CAAC;IAC7E,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,UAAU;QACzC,MAAM,IAAI,gCAAe,CAAC,+CAA+C,CAAC,CAAC;IAE7E,8BAA8B;IAC9B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IAC5C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IAE5C,uBAAuB;IACvB,
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/contract/cli/apply.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,4DAAoC;AACpC,2BAAgC;AAChC,0CAAuC;AACvC,mDAAiD;AACjD,+BAA+B;AAE/B,0EAAuE;AACvE,6EAA0E;AAE1E,MAAM,GAAG,GAAG,OAAO,CAAC;AAEpB;;;;;;GAMG;AACI,MAAM,mBAAmB,GAAG,KAAK,EAAE,KAGzC,EAAiB,EAAE;IAClB,oCAAoC;IACpC,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,KAAK,MAAM,CAAC;IACjD,IAAI,UAAU,EAAE,CAAC;QACf,4BAA4B;QAC5B,IAAI,CAAC,KAAK,CAAC,YAAY;YACrB,MAAM,IAAI,gCAAe,CAAC,kCAAkC,CAAC,CAAC;IAClE,CAAC;SAAM,CAAC;QACN,6CAA6C;QAC7C,IAAI,CAAC,KAAK,CAAC,YAAY;YAAE,MAAM,IAAI,gCAAe,CAAC,iBAAiB,CAAC,CAAC;IACxE,CAAC;IAED,yCAAyC;IACzC,MAAM,gBAAgB,GAAG,UAAU;QACjC,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,IAAA,cAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,YAAa,CAAC,CAAC;IAEhD,2CAA2C;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,IAAqC,EAAE;QAC9D,IAAI,CAAC,gBAAgB;YAAE,OAAO,IAAI,CAAC;QACnC,IAAI,CAAC,IAAA,eAAU,EAAC,gBAAgB,CAAC;YAC/B,MAAM,IAAI,gCAAe,CAAC,wBAAwB,gBAAgB,EAAE,CAAC,CAAC;QACxE,MAAM,QAAQ,GAAG,MAAM,IAAA,mBAAQ,EAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAC3D,OAAO,IAAI,iCAAe,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,EAAE,CAAC;IAEL,mDAAmD;IACnD,MAAM,gBAAgB,GAAG,UAAU;QACjC,CAAC,CAAC,IAAA,cAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,YAAa,CAAC;QAC7C,CAAC,CAAC,IAAK,CAAC,IAAI,CAAC,GAAG,CAAC;IAEnB,4BAA4B;IAC5B,IAAI,CAAC,IAAA,eAAU,EAAC,gBAAgB,CAAC;QAC/B,MAAM,IAAI,gCAAe,CAAC,wBAAwB,gBAAgB,EAAE,CAAC,CAAC;IAExE,aAAa;IACb,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACb,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACjC,IAAI,gBAAgB;QAAE,GAAG,CAAC,IAAI,CAAC,YAAY,gBAAgB,EAAE,CAAC,CAAC;IAC/D,GAAG,CAAC,IAAI,CAAC,YAAY,gBAAgB,EAAE,CAAC,CAAC;IACzC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEb,mBAAmB;IACnB,MAAM,IAAI,GAAG,yBAAa,gBAAgB,uCAAC,CAAC;IAE5C,mBAAmB;IACnB,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,UAAU;QACzC,MAAM,IAAI,gCAAe,CAAC,+CAA+C,CAAC,CAAC;IAC7E,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,UAAU;QACzC,MAAM,IAAI,gCAAe,CAAC,+CAA+C,CAAC,CAAC;IAE7E,8BAA8B;IAC9B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IAC5C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IAE5C,uBAAuB;IACvB,oCAAoC;IACpC,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAElE,iBAAiB;IACjB,MAAM,OAAO,GAAG;QACd,UAAU,EAAE,IAAI,oBAAU,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;QAChD,GAAG;KACJ,CAAC;IAEF,oEAAoE;IACpE,MAAM,MAAM,GAAG,MAAM,IAAA,2BAAY,EAC/B;QACE,IAAI;QACJ,SAAS;QACT,SAAS;KACV,EACD,OAAO,CACR,CAAC;IAEF,oBAAoB;IACpB,gBAAgB;IAChB,mCAAmC;IACnC,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAEjE,cAAc;IACd,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACb,GAAG,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,cAAc,CAAC,MAAM,UAAU,CAAC,CAAC;IAC/D,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACf,CAAC,CAAC;AAvFW,QAAA,mBAAmB,uBAuF9B"}
|
|
@@ -48,6 +48,7 @@ const executePlanCommand = async ({ wishFilePath, planFilePath, }) => {
|
|
|
48
48
|
if (!(0, fs_1.existsSync)(resolvedWishPath)) {
|
|
49
49
|
throw new helpful_errors_1.BadRequestError(`Wish file not found: ${resolvedWishPath}`);
|
|
50
50
|
}
|
|
51
|
+
log.info('');
|
|
51
52
|
log.info('🌊 declastruct plan');
|
|
52
53
|
log.info(` wish: ${resolvedWishPath}`);
|
|
53
54
|
log.info(` plan: ${resolvedPlanPath}`);
|
|
@@ -65,7 +66,7 @@ const executePlanCommand = async ({ wishFilePath, planFilePath, }) => {
|
|
|
65
66
|
const resources = await wish.getResources();
|
|
66
67
|
const providers = await wish.getProviders();
|
|
67
68
|
// initialize providers
|
|
68
|
-
log.info('✨ start providers...');
|
|
69
|
+
// log.info('✨ start providers...');
|
|
69
70
|
await Promise.all(providers.map((p) => p.hooks.beforeAll()));
|
|
70
71
|
// create context
|
|
71
72
|
const context = {
|
|
@@ -84,8 +85,8 @@ const executePlanCommand = async ({ wishFilePath, planFilePath, }) => {
|
|
|
84
85
|
// write plan to file
|
|
85
86
|
await (0, promises_1.writeFile)(resolvedPlanPath, JSON.stringify(plan, null, 2), 'utf-8');
|
|
86
87
|
// cleanup providers
|
|
87
|
-
log.info('');
|
|
88
|
-
log.info('✨ stop providers...');
|
|
88
|
+
// log.info('');
|
|
89
|
+
// log.info('✨ stop providers...');
|
|
89
90
|
await Promise.all(providers.map((p) => p.hooks.afterAll()));
|
|
90
91
|
// log summary
|
|
91
92
|
log.info('');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/contract/cli/plan.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,4DAAoC;AACpC,2BAAgC;AAChC,0CAA+C;AAC/C,mDAAiD;AACjD,+BAAwC;AAExC,0EAAuE;AAEvE,MAAM,GAAG,GAAG,OAAO,CAAC;AAEpB;;;;GAIG;AACI,MAAM,kBAAkB,GAAG,KAAK,EAAE,EACvC,YAAY,EACZ,YAAY,GAIb,EAAiB,EAAE;IAClB,gBAAgB;IAChB,MAAM,gBAAgB,GAAG,IAAA,cAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;IAC9D,MAAM,gBAAgB,GAAG,IAAA,cAAO,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,CAAC;IAE9D,4BAA4B;IAC5B,IAAI,CAAC,IAAA,eAAU,EAAC,gBAAgB,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,gCAAe,CAAC,wBAAwB,gBAAgB,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAChC,GAAG,CAAC,IAAI,CAAC,YAAY,gBAAgB,EAAE,CAAC,CAAC;IACzC,GAAG,CAAC,IAAI,CAAC,YAAY,gBAAgB,EAAE,CAAC,CAAC;IACzC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEb,mBAAmB;IACnB,MAAM,IAAI,GAAG,yBAAa,gBAAgB,uCAAC,CAAC;IAE5C,mBAAmB;IACnB,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;QAC5C,MAAM,IAAI,gCAAe,CAAC,+CAA+C,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;QAC5C,MAAM,IAAI,gCAAe,CAAC,+CAA+C,CAAC,CAAC;IAC7E,CAAC;IAED,8BAA8B;IAC9B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IAC5C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IAE5C,uBAAuB;IACvB,
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/contract/cli/plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeclastructChange.js","sourceRoot":"","sources":["../../src/domain.objects/DeclastructChange.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"DeclastructChange.js","sourceRoot":"","sources":["../../src/domain.objects/DeclastructChange.ts"],"names":[],"mappings":";;;AAAA,mDAAkE;AAElE;;;GAGG;AACH,IAAY,uBAyBX;AAzBD,WAAY,uBAAuB;IACjC;;OAEG;IACH,wCAAa,CAAA;IAEb;;OAEG;IACH,4CAAiB,CAAA;IAEjB;;OAEG;IACH,4CAAiB,CAAA;IAEjB;;OAEG;IACH,8CAAmB,CAAA;IAEnB;;OAEG;IACH,8CAAmB,CAAA;AACrB,CAAC,EAzBW,uBAAuB,uCAAvB,uBAAuB,QAyBlC;AAsDD,MAAa,iBAGX,SAAQ,8BAA2C;CACT;AAJ5C,8CAI4C"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DomainEntity, DomainLiteral, Ref, Refable, RefByPrimary, RefByUnique } from 'domain-objects';
|
|
2
|
-
import { HasMetadata } from 'type-fns';
|
|
1
|
+
import { type DomainEntity, DomainLiteral, type Ref, type Refable, type RefByPrimary, type RefByUnique } from 'domain-objects';
|
|
2
|
+
import { type HasMetadata } from 'type-fns';
|
|
3
3
|
/**
|
|
4
4
|
* .what = standardized data access interface for any resource type
|
|
5
5
|
*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DomainEntity } from 'domain-objects';
|
|
2
|
-
import { DeclastructChange } from './DeclastructChange';
|
|
3
|
-
import { IsoTimestamp } from './IsoTimestamp';
|
|
2
|
+
import { type DeclastructChange } from './DeclastructChange';
|
|
3
|
+
import { type IsoTimestamp } from './IsoTimestamp';
|
|
4
4
|
/**
|
|
5
5
|
* .what = collection of all planned changes required to fulfill a wish
|
|
6
6
|
* .why = enables review, version control, and validation of infrastructure changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DomainLiteral } from 'domain-objects';
|
|
2
|
-
import { DeclastructDao } from './DeclastructDao';
|
|
2
|
+
import { type DeclastructDao } from './DeclastructDao';
|
|
3
3
|
export type DeclastructDaosShape<TContext> = Record<string, DeclastructDao<any, any, TContext>>;
|
|
4
4
|
/**
|
|
5
5
|
* .what = bundles all DAOs and lifecycle hooks for a specific infrastructure provider
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { DomainEntity } from 'domain-objects';
|
|
2
|
-
import { ContextLogTrail } from 'simple-log-methods';
|
|
3
|
-
import { ContextDeclastruct } from '../../domain.objects/ContextDeclastruct';
|
|
4
|
-
import { DeclastructChange } from '../../domain.objects/DeclastructChange';
|
|
5
|
-
import { DeclastructPlan } from '../../domain.objects/DeclastructPlan';
|
|
6
|
-
import { DeclastructProvider } from '../../domain.objects/DeclastructProvider';
|
|
1
|
+
import { type DomainEntity } from 'domain-objects';
|
|
2
|
+
import { type ContextLogTrail } from 'simple-log-methods';
|
|
3
|
+
import { type ContextDeclastruct } from '../../domain.objects/ContextDeclastruct';
|
|
4
|
+
import { type DeclastructChange } from '../../domain.objects/DeclastructChange';
|
|
5
|
+
import { type DeclastructPlan } from '../../domain.objects/DeclastructPlan';
|
|
6
|
+
import { type DeclastructProvider } from '../../domain.objects/DeclastructProvider';
|
|
7
7
|
/**
|
|
8
8
|
* .what = applies changes to achieve desired state
|
|
9
9
|
* .why = executes infrastructure changes in a controlled, observable manner
|
|
@@ -4,6 +4,8 @@ exports.applyChanges = void 0;
|
|
|
4
4
|
const domain_objects_1 = require("domain-objects");
|
|
5
5
|
const helpful_errors_1 = require("helpful-errors");
|
|
6
6
|
const DeclastructChange_1 = require("../../domain.objects/DeclastructChange");
|
|
7
|
+
const colorizeAction_1 = require("../../infra/colorizeAction");
|
|
8
|
+
const withSpinner_1 = require("../../infra/withSpinner");
|
|
7
9
|
const planChanges_1 = require("../plan/planChanges");
|
|
8
10
|
const validate_1 = require("../plan/validate");
|
|
9
11
|
const applyChange_1 = require("./applyChange");
|
|
@@ -21,6 +23,13 @@ const applyChanges = async (input, context) => {
|
|
|
21
23
|
providers: input.providers,
|
|
22
24
|
wishFilePath: input.plan?.wish.uri ?? 'ignorable',
|
|
23
25
|
}, context);
|
|
26
|
+
// use current plan for apply (works for both modes)
|
|
27
|
+
const planToApply = currentPlan;
|
|
28
|
+
// check if there are any actionable changes (non-KEEP)
|
|
29
|
+
const hasActionableChanges = planToApply.changes.some((change) => change.action !== DeclastructChange_1.DeclastructChangeAction.KEEP);
|
|
30
|
+
// skip apply phase if everything is in sync
|
|
31
|
+
if (!hasActionableChanges)
|
|
32
|
+
return { appliedChanges: [] };
|
|
24
33
|
// validate plan matches current state (skip if no plan provided, i.e. yolo mode)
|
|
25
34
|
if (input.plan) {
|
|
26
35
|
(0, validate_1.assertPlanStillValid)({
|
|
@@ -32,10 +41,8 @@ const applyChanges = async (input, context) => {
|
|
|
32
41
|
}
|
|
33
42
|
else {
|
|
34
43
|
context.log.info('');
|
|
35
|
-
context.log.info('🤙 yolo, plan
|
|
44
|
+
context.log.info('🤙 yolo, plan auto approved...');
|
|
36
45
|
}
|
|
37
|
-
// use current plan for apply (works for both modes)
|
|
38
|
-
const planToApply = currentPlan;
|
|
39
46
|
// log apply phase header
|
|
40
47
|
context.log.info('');
|
|
41
48
|
context.log.info('🪄 apply changes...');
|
|
@@ -45,26 +52,29 @@ const applyChanges = async (input, context) => {
|
|
|
45
52
|
for (const change of planToApply.changes) {
|
|
46
53
|
// log KEEP actions and skip
|
|
47
54
|
if (change.action === DeclastructChange_1.DeclastructChangeAction.KEEP) {
|
|
48
|
-
context.log.info(`↓
|
|
55
|
+
context.log.info(`↓ ${(0, colorizeAction_1.colorizeAction)(change.action)} ${change.forResource.slug}`);
|
|
49
56
|
continue;
|
|
50
57
|
}
|
|
51
58
|
// find the desired resource
|
|
52
59
|
const resourceFound = input.resources.find((candidate) => candidate.constructor.name === change.forResource.class &&
|
|
53
60
|
(0, domain_objects_1.getUniqueIdentifierSlug)(candidate) === change.forResource.slug) ??
|
|
54
61
|
helpful_errors_1.UnexpectedCodePathError.throw('could not find resource specified in plan. was it removed?', { change });
|
|
55
|
-
// log action
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const applied = await (0,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
// log the action line (stays fixed)
|
|
63
|
+
const actionLabel = (0, colorizeAction_1.colorizeAction)(change.action);
|
|
64
|
+
context.log.info(`○ ${actionLabel} ${change.forResource.slug}`);
|
|
65
|
+
// apply the change with spinner on line below
|
|
66
|
+
const { result: applied, durationMs } = await (0, withSpinner_1.withSpinner)({
|
|
67
|
+
message: 'inflight',
|
|
68
|
+
operation: () => (0, applyChange_1.applyChange)({
|
|
69
|
+
change,
|
|
70
|
+
resource: resourceFound,
|
|
71
|
+
providers: input.providers,
|
|
72
|
+
}),
|
|
63
73
|
});
|
|
64
|
-
const durationMs = Date.now() - startMs;
|
|
65
74
|
// log completion with duration
|
|
66
75
|
const durationSec = (durationMs / 1000).toFixed(2);
|
|
67
|
-
context.log.info(` └─ ✔ done in ${durationSec}s
|
|
76
|
+
context.log.info(` └─ ✔ done in ${durationSec}s`);
|
|
77
|
+
context.log.info('');
|
|
68
78
|
appliedChanges.push(applied);
|
|
69
79
|
}
|
|
70
80
|
return { appliedChanges };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"applyChanges.js","sourceRoot":"","sources":["../../../src/domain.operations/apply/applyChanges.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"applyChanges.js","sourceRoot":"","sources":["../../../src/domain.operations/apply/applyChanges.ts"],"names":[],"mappings":";;;AAAA,mDAA4E;AAC5E,mDAAyD;AAIzD,8EAGgD;AAGhD,+DAA4D;AAC5D,yDAAsD;AACtD,qDAAkD;AAClD,+CAAwD;AACxD,+CAA4C;AAE5C;;;;;;GAMG;AACI,MAAM,YAAY,GAAG,KAAK,EAC/B,KAIC,EACD,OAA6C,EACK,EAAE;IACpD,8BAA8B;IAC9B,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,EAAE,IAAI,CAAC,GAAG,IAAI,WAAW;KAClD,EACD,OAAO,CACR,CAAC;IAEF,oDAAoD;IACpD,MAAM,WAAW,GAAG,WAAW,CAAC;IAEhC,uDAAuD;IACvD,MAAM,oBAAoB,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,CACnD,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,2CAAuB,CAAC,IAAI,CAC3D,CAAC;IAEF,4CAA4C;IAC5C,IAAI,CAAC,oBAAoB;QAAE,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC;IAEzD,iFAAiF;IACjF,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,IAAA,+BAAoB,EAAC;YACnB,YAAY,EAAE,KAAK,CAAC,IAAI;YACxB,WAAW;SACZ,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IACrD,CAAC;IAED,yBAAyB;IACzB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAErB,2CAA2C;IAC3C,MAAM,cAAc,GAAwB,EAAE,CAAC;IAE/C,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;QACzC,4BAA4B;QAC5B,IAAI,MAAM,CAAC,MAAM,KAAK,2CAAuB,CAAC,IAAI,EAAE,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,IAAI,CACd,KAAK,IAAA,+BAAc,EAAC,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAChE,CAAC;YACF,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,4DAA4D,EAC5D,EAAE,MAAM,EAAE,CACX,CAAC;QAEJ,oCAAoC;QACpC,MAAM,WAAW,GAAG,IAAA,+BAAc,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QAEhE,8CAA8C;QAC9C,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,IAAA,yBAAW,EAAC;YACxD,OAAO,EAAE,UAAU;YACnB,SAAS,EAAE,GAAG,EAAE,CACd,IAAA,yBAAW,EAAC;gBACV,MAAM;gBACN,QAAQ,EAAE,aAAa;gBACvB,SAAS,EAAE,KAAK,CAAC,SAAS;aAC3B,CAAC;SACL,CAAC,CAAC;QAEH,+BAA+B;QAC/B,MAAM,WAAW,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,WAAW,GAAG,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAErB,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,EAAE,cAAc,EAAE,CAAC;AAC5B,CAAC,CAAC;AA/FW,QAAA,YAAY,gBA+FvB"}
|
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.computeChange = void 0;
|
|
4
4
|
const domain_objects_1 = require("domain-objects");
|
|
5
5
|
const helpful_errors_1 = require("helpful-errors");
|
|
6
|
-
const jest_diff_1 = require("jest-diff");
|
|
7
6
|
const DeclastructChange_1 = require("../../domain.objects/DeclastructChange");
|
|
7
|
+
const getDisplayableDiff_1 = require("./getDisplayableDiff");
|
|
8
8
|
/**
|
|
9
9
|
* .what = checks if two resources are equivalent
|
|
10
10
|
* .why = determines whether a resource needs to be updated
|
|
@@ -16,32 +16,6 @@ const checkAreResourcesEquivalent = (input) => {
|
|
|
16
16
|
const desiredSerialized = (0, domain_objects_1.serialize)((0, domain_objects_1.omitReadonly)(input.desired));
|
|
17
17
|
return remoteSerialized === desiredSerialized;
|
|
18
18
|
};
|
|
19
|
-
/**
|
|
20
|
-
* .what = computes human-readable diff between two resources
|
|
21
|
-
* .why = helps users understand what will change
|
|
22
|
-
* .note = returns null if resources are identical; for CREATE uses empty object to show all attributes; ignores readonly
|
|
23
|
-
*/
|
|
24
|
-
const computeDiff = ({ from, into, }) => {
|
|
25
|
-
// no diff if both are null
|
|
26
|
-
if (from === null && into === null)
|
|
27
|
-
return null;
|
|
28
|
-
// check if resources are equivalent after omitting readonly
|
|
29
|
-
if (from !== null && into !== null) {
|
|
30
|
-
const fromSerialized = (0, domain_objects_1.serialize)((0, domain_objects_1.omitReadonly)(from));
|
|
31
|
-
const intoSerialized = (0, domain_objects_1.serialize)((0, domain_objects_1.omitReadonly)(into));
|
|
32
|
-
if (fromSerialized === intoSerialized)
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
// omit readonly before diff
|
|
36
|
-
const fromWithoutReadonly = from === null ? {} : (0, domain_objects_1.omitReadonly)(from);
|
|
37
|
-
const intoWithoutReadonly = into === null ? {} : (0, domain_objects_1.omitReadonly)(into);
|
|
38
|
-
// compute diff using jest-diff
|
|
39
|
-
const difference = (0, jest_diff_1.diff)(fromWithoutReadonly, intoWithoutReadonly, {
|
|
40
|
-
aAnnotation: 'Remote',
|
|
41
|
-
bAnnotation: 'Desired',
|
|
42
|
-
});
|
|
43
|
-
return difference;
|
|
44
|
-
};
|
|
45
19
|
/**
|
|
46
20
|
* .what = computes a single change by comparing desired vs remote state
|
|
47
21
|
* .why = determines the action needed to achieve desired state for one resource
|
|
@@ -75,7 +49,7 @@ const computeChange = ({ desired, remote, }) => {
|
|
|
75
49
|
// compute displayable difference
|
|
76
50
|
const difference = action === DeclastructChange_1.DeclastructChangeAction.KEEP
|
|
77
51
|
? null
|
|
78
|
-
:
|
|
52
|
+
: (0, getDisplayableDiff_1.getDisplayableDiff)({ from: remote, into: desired });
|
|
79
53
|
// get resource info for change record
|
|
80
54
|
const resourceForChange = desired || remote;
|
|
81
55
|
// return change
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"computeChange.js","sourceRoot":"","sources":["../../../src/domain.operations/plan/computeChange.ts"],"names":[],"mappings":";;;AAAA,mDAKwB;AACxB,mDAAyD;
|
|
1
|
+
{"version":3,"file":"computeChange.js","sourceRoot":"","sources":["../../../src/domain.operations/plan/computeChange.ts"],"names":[],"mappings":";;;AAAA,mDAKwB;AACxB,mDAAyD;AAEzD,8EAGgD;AAChD,6DAA0D;AAE1D;;;;GAIG;AACH,MAAM,2BAA2B,GAAG,CAAC,KAGpC,EAAW,EAAE;IACZ,0EAA0E;IAC1E,MAAM,gBAAgB,GAAG,IAAA,0BAAS,EAAC,IAAA,6BAAY,EAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/D,MAAM,iBAAiB,GAAG,IAAA,0BAAS,EAAC,IAAA,6BAAY,EAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IAEjE,OAAO,gBAAgB,KAAK,iBAAiB,CAAC;AAChD,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,MAAM,sBAAsB,GAAG,wCAAuB,CAAC,IAAI,CACzD,GAAG,EAAE,CAAC,2BAA2B,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EACtD;YACE,OAAO,EAAE,uCAAuC;YAChD,QAAQ,EAAE;gBACR,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;gBAC1B,KAAK,EAAE;oBACL,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,IAAI;oBAClC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,IAAI;iBACjC;aACF;SACF,CACF,EAAE,CAAC;QACJ,IAAI,sBAAsB;YAAE,OAAO,2CAAuB,CAAC,IAAI,CAAC;QAEhE,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,IAAA,uCAAkB,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAE1D,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,wCAAuB,CAAC,IAAI,CAChC,GAAG,EAAE,CAAC,IAAA,wCAAuB,EAAC,iBAAiB,CAAC,EAChD;gBACE,OAAO,EAAE,mCAAmC;gBAC5C,QAAQ,EAAE;oBACR,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;oBAC1B,KAAK,EAAE;wBACL,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,IAAI;wBAClC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,IAAI;qBACjC;iBACF;aACF,CACF,EAAE;SACJ;QACD,MAAM;QACN,KAAK,EAAE;YACL,OAAO;YACP,MAAM;YACN,UAAU;SACX;KACF,CAAC,CAAC;AACL,CAAC,CAAC;AArEW,QAAA,aAAa,iBAqExB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DomainEntity } from 'domain-objects';
|
|
2
|
+
/**
|
|
3
|
+
* .what = computes human-readable diff between two resources
|
|
4
|
+
* .why = helps users understand what will change
|
|
5
|
+
* .note = returns null if resources are identical; for CREATE uses empty object to show all attributes; ignores readonly; preserves key order from into
|
|
6
|
+
*/
|
|
7
|
+
export declare const getDisplayableDiff: ({ from, into, }: {
|
|
8
|
+
from: DomainEntity<any> | null;
|
|
9
|
+
into: DomainEntity<any> | null;
|
|
10
|
+
}) => string | null;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDisplayableDiff = void 0;
|
|
4
|
+
const domain_objects_1 = require("domain-objects");
|
|
5
|
+
const jest_diff_1 = require("jest-diff");
|
|
6
|
+
/**
|
|
7
|
+
* .what = computes human-readable diff between two resources
|
|
8
|
+
* .why = helps users understand what will change
|
|
9
|
+
* .note = returns null if resources are identical; for CREATE uses empty object to show all attributes; ignores readonly; preserves key order from into
|
|
10
|
+
*/
|
|
11
|
+
const getDisplayableDiff = ({ from, into, }) => {
|
|
12
|
+
// no diff if both are null
|
|
13
|
+
if (from === null && into === null)
|
|
14
|
+
return null;
|
|
15
|
+
// check if resources are equivalent after omitting readonly
|
|
16
|
+
if (from !== null && into !== null) {
|
|
17
|
+
const fromSerialized = (0, domain_objects_1.serialize)((0, domain_objects_1.omitReadonly)(from));
|
|
18
|
+
const intoSerialized = (0, domain_objects_1.serialize)((0, domain_objects_1.omitReadonly)(into));
|
|
19
|
+
if (fromSerialized === intoSerialized)
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
// omit readonly before diff
|
|
23
|
+
const fromWithoutReadonly = from === null ? {} : (0, domain_objects_1.omitReadonly)(from);
|
|
24
|
+
const intoWithoutReadonly = into === null ? {} : (0, domain_objects_1.omitReadonly)(into);
|
|
25
|
+
// build key order from into (desired) for stable diff output
|
|
26
|
+
const keyOrder = Object.keys(intoWithoutReadonly);
|
|
27
|
+
// compute diff using jest-diff, sorting keys by into's order
|
|
28
|
+
const difference = (0, jest_diff_1.diff)(fromWithoutReadonly, intoWithoutReadonly, {
|
|
29
|
+
aAnnotation: 'Remote',
|
|
30
|
+
bAnnotation: 'Desired',
|
|
31
|
+
compareKeys: (a, b) => {
|
|
32
|
+
const aIdx = keyOrder.indexOf(a);
|
|
33
|
+
const bIdx = keyOrder.indexOf(b);
|
|
34
|
+
return (aIdx === -1 ? Infinity : aIdx) - (bIdx === -1 ? Infinity : bIdx);
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
return difference;
|
|
38
|
+
};
|
|
39
|
+
exports.getDisplayableDiff = getDisplayableDiff;
|
|
40
|
+
//# sourceMappingURL=getDisplayableDiff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getDisplayableDiff.js","sourceRoot":"","sources":["../../../src/domain.operations/plan/getDisplayableDiff.ts"],"names":[],"mappings":";;;AAAA,mDAAuE;AACvE,yCAAiC;AAEjC;;;;GAIG;AACI,MAAM,kBAAkB,GAAG,CAAC,EACjC,IAAI,EACJ,IAAI,GAIL,EAAiB,EAAE;IAClB,2BAA2B;IAC3B,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEhD,4DAA4D;IAC5D,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACnC,MAAM,cAAc,GAAG,IAAA,0BAAS,EAAC,IAAA,6BAAY,EAAC,IAAI,CAAC,CAAC,CAAC;QACrD,MAAM,cAAc,GAAG,IAAA,0BAAS,EAAC,IAAA,6BAAY,EAAC,IAAI,CAAC,CAAC,CAAC;QACrD,IAAI,cAAc,KAAK,cAAc;YAAE,OAAO,IAAI,CAAC;IACrD,CAAC;IAED,4BAA4B;IAC5B,MAAM,mBAAmB,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAA,6BAAY,EAAC,IAAI,CAAC,CAAC;IACpE,MAAM,mBAAmB,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAA,6BAAY,EAAC,IAAI,CAAC,CAAC;IAEpE,6DAA6D;IAC7D,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAElD,6DAA6D;IAC7D,MAAM,UAAU,GAAG,IAAA,gBAAI,EAAC,mBAAmB,EAAE,mBAAmB,EAAE;QAChE,WAAW,EAAE,QAAQ;QACrB,WAAW,EAAE,SAAS;QACtB,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACpB,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACjC,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3E,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AApCW,QAAA,kBAAkB,sBAoC7B"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { DomainEntity } from 'domain-objects';
|
|
2
|
-
import { ContextLogTrail } from 'simple-log-methods';
|
|
3
|
-
import { ContextDeclastruct } from '../../domain.objects/ContextDeclastruct';
|
|
1
|
+
import { type DomainEntity } from 'domain-objects';
|
|
2
|
+
import { type ContextLogTrail } from 'simple-log-methods';
|
|
3
|
+
import { type ContextDeclastruct } from '../../domain.objects/ContextDeclastruct';
|
|
4
4
|
import { DeclastructPlan } from '../../domain.objects/DeclastructPlan';
|
|
5
|
-
import { DeclastructProvider } from '../../domain.objects/DeclastructProvider';
|
|
5
|
+
import { type DeclastructProvider } from '../../domain.objects/DeclastructProvider';
|
|
6
6
|
/**
|
|
7
7
|
* .what = generates a plan of changes required to achieve desired state
|
|
8
8
|
* .why = enables users to review infrastructure changes before applying them
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.planChanges = void 0;
|
|
4
|
+
const domain_objects_1 = require("domain-objects");
|
|
4
5
|
const DeclastructChange_1 = require("../../domain.objects/DeclastructChange");
|
|
5
6
|
const DeclastructPlan_1 = require("../../domain.objects/DeclastructPlan");
|
|
6
7
|
const asIsoTimestamp_1 = require("../../infra/asIsoTimestamp");
|
|
8
|
+
const colorizeAction_1 = require("../../infra/colorizeAction");
|
|
9
|
+
const withSpinner_1 = require("../../infra/withSpinner");
|
|
7
10
|
const computeChange_1 = require("./computeChange");
|
|
8
11
|
const getDaoByResource_1 = require("./getDaoByResource");
|
|
9
12
|
const hashChanges_1 = require("./hashChanges");
|
|
@@ -14,7 +17,6 @@ const hashChanges_1 = require("./hashChanges");
|
|
|
14
17
|
*/
|
|
15
18
|
const planChanges = async (input, context) => {
|
|
16
19
|
// log plan phase header
|
|
17
|
-
context.log.info('');
|
|
18
20
|
context.log.info('🔮 plan changes...');
|
|
19
21
|
context.log.info('');
|
|
20
22
|
// extract bottleneck for planning
|
|
@@ -22,29 +24,44 @@ const planChanges = async (input, context) => {
|
|
|
22
24
|
? context.bottleneck.onPlan
|
|
23
25
|
: context.bottleneck;
|
|
24
26
|
// compute change for each resource with real-time logging
|
|
25
|
-
const changes =
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
resource
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
27
|
+
const changes = [];
|
|
28
|
+
for (const resource of input.resources) {
|
|
29
|
+
const change = await bottleneck.schedule(async () => {
|
|
30
|
+
// find DAO and provider context for this resource
|
|
31
|
+
const { dao, context: providerContext } = (0, getDaoByResource_1.getDaoByResource)({
|
|
32
|
+
resource,
|
|
33
|
+
providers: input.providers,
|
|
34
|
+
});
|
|
35
|
+
// log the resource being planned
|
|
36
|
+
context.log.info(`○ ${(0, domain_objects_1.getUniqueIdentifierSlug)(resource)}`);
|
|
37
|
+
// fetch current remote state using provider context with spinner
|
|
38
|
+
const { result: remoteState, durationMs } = await (0, withSpinner_1.withSpinner)({
|
|
39
|
+
message: 'inflight',
|
|
40
|
+
operation: () => dao.get.byUnique(resource, providerContext),
|
|
41
|
+
});
|
|
42
|
+
// log done (replaces spinner)
|
|
43
|
+
const durationSec = (durationMs / 1000).toFixed(2);
|
|
44
|
+
context.log.info(` ├─ ✔ done in ${durationSec}s`);
|
|
45
|
+
// compute change
|
|
46
|
+
const computed = (0, computeChange_1.computeChange)({
|
|
47
|
+
desired: resource,
|
|
48
|
+
remote: remoteState,
|
|
49
|
+
});
|
|
50
|
+
// log decision
|
|
51
|
+
context.log.info(` └─ decision ${(0, colorizeAction_1.colorizeAction)(computed.action)}`);
|
|
52
|
+
// and the diff too, indented to align with tree
|
|
53
|
+
if (computed.state.difference) {
|
|
54
|
+
const indentedDiff = computed.state.difference
|
|
55
|
+
.split('\n')
|
|
56
|
+
.map((line) => ` ${line}`)
|
|
57
|
+
.join('\n');
|
|
58
|
+
context.log.info(indentedDiff);
|
|
59
|
+
}
|
|
44
60
|
context.log.info('');
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
61
|
+
return computed;
|
|
62
|
+
});
|
|
63
|
+
changes.push(change);
|
|
64
|
+
}
|
|
48
65
|
// log success message if everything is in sync
|
|
49
66
|
const allInSync = changes.every((change) => change.action === DeclastructChange_1.DeclastructChangeAction.KEEP);
|
|
50
67
|
if (allInSync) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planChanges.js","sourceRoot":"","sources":["../../../src/domain.operations/plan/planChanges.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"planChanges.js","sourceRoot":"","sources":["../../../src/domain.operations/plan/planChanges.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DeclastructChangeAction } from '../domain.objects/DeclastructChange';
|
|
2
|
+
/**
|
|
3
|
+
* .what = returns a colorized action label for CLI output
|
|
4
|
+
* .why = improves visual distinction between action types
|
|
5
|
+
* .note = uses pastel colors for a softer, zen aesthetic
|
|
6
|
+
*/
|
|
7
|
+
export declare const colorizeAction: (action: DeclastructChangeAction) => string;
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
exports.colorizeAction = void 0;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const DeclastructChange_1 = require("../domain.objects/DeclastructChange");
|
|
9
|
+
/**
|
|
10
|
+
* .what = returns a colorized action label for CLI output
|
|
11
|
+
* .why = improves visual distinction between action types
|
|
12
|
+
* .note = uses pastel colors for a softer, zen aesthetic
|
|
13
|
+
*/
|
|
14
|
+
const colorizeAction = (action) => {
|
|
15
|
+
switch (action) {
|
|
16
|
+
case DeclastructChange_1.DeclastructChangeAction.KEEP:
|
|
17
|
+
return chalk_1.default.hex('#9ca3af')('[KEEP]'); // pastel gray
|
|
18
|
+
case DeclastructChange_1.DeclastructChangeAction.CREATE:
|
|
19
|
+
return chalk_1.default.hex('#86efac')('[CREATE]'); // pastel green
|
|
20
|
+
case DeclastructChange_1.DeclastructChangeAction.UPDATE:
|
|
21
|
+
return chalk_1.default.hex('#fde047')('[UPDATE]'); // pastel yellow
|
|
22
|
+
case DeclastructChange_1.DeclastructChangeAction.DESTROY:
|
|
23
|
+
return chalk_1.default.hex('#fca5a5')('[DESTROY]'); // pastel red
|
|
24
|
+
case DeclastructChange_1.DeclastructChangeAction.REPLACE:
|
|
25
|
+
return chalk_1.default.hex('#fca5a5')('[REPLACE]'); // pastel red, since it includes a destroy
|
|
26
|
+
default:
|
|
27
|
+
return `[${action}]`;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
exports.colorizeAction = colorizeAction;
|
|
31
|
+
//# sourceMappingURL=colorizeAction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorizeAction.js","sourceRoot":"","sources":["../../src/infra/colorizeAction.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAE1B,2EAA8E;AAE9E;;;;GAIG;AACI,MAAM,cAAc,GAAG,CAAC,MAA+B,EAAU,EAAE;IACxE,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,2CAAuB,CAAC,IAAI;YAC/B,OAAO,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc;QACvD,KAAK,2CAAuB,CAAC,MAAM;YACjC,OAAO,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,eAAe;QAC1D,KAAK,2CAAuB,CAAC,MAAM;YACjC,OAAO,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,gBAAgB;QAC3D,KAAK,2CAAuB,CAAC,OAAO;YAClC,OAAO,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa;QACzD,KAAK,2CAAuB,CAAC,OAAO;YAClC,OAAO,eAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,0CAA0C;QACtF;YACE,OAAO,IAAI,MAAM,GAAG,CAAC;IACzB,CAAC;AACH,CAAC,CAAC;AAfW,QAAA,cAAc,kBAezB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .what = wraps an async operation with a CLI spinner showing elapsed time
|
|
3
|
+
* .why = provides visual feedback during long-running operations
|
|
4
|
+
* .note = spinner renders on its own line below the action, cleared on completion
|
|
5
|
+
*/
|
|
6
|
+
export declare const withSpinner: <T>(input: {
|
|
7
|
+
message: string;
|
|
8
|
+
operation: () => Promise<T>;
|
|
9
|
+
}) => Promise<{
|
|
10
|
+
result: T;
|
|
11
|
+
durationMs: number;
|
|
12
|
+
}>;
|