declastruct 1.5.2 → 1.7.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.
@@ -33,6 +33,7 @@ const fs_1 = require("fs");
33
33
  const promises_1 = require("fs/promises");
34
34
  const helpful_errors_1 = require("helpful-errors");
35
35
  const path_1 = require("path");
36
+ const rhachet_artifact_git_1 = require("rhachet-artifact-git");
36
37
  const DeclastructPlan_1 = require("../../domain.objects/DeclastructPlan");
37
38
  const applyChanges_1 = require("../../domain.operations/apply/applyChanges");
38
39
  const log = console;
@@ -76,12 +77,18 @@ const executeApplyCommand = async (input) => {
76
77
  // validate wish file exists
77
78
  if (!(0, fs_1.existsSync)(resolvedWishPath))
78
79
  throw new helpful_errors_1.BadRequestError(`Wish file not found: ${resolvedWishPath}`);
80
+ // get git root for relative path display
81
+ const gitRoot = await (0, rhachet_artifact_git_1.getGitRepoRoot)({ from: process.cwd() });
82
+ const relativePlanPath = resolvedPlanPath
83
+ ? (0, path_1.relative)(gitRoot, resolvedPlanPath)
84
+ : null;
85
+ const relativeWishPath = (0, path_1.relative)(gitRoot, resolvedWishPath);
79
86
  // log header
80
87
  log.info('');
81
88
  log.info('🌊 declastruct apply');
82
- if (resolvedPlanPath)
83
- log.info(` plan: ${resolvedPlanPath}`);
84
- log.info(` wish: ${resolvedWishPath}`);
89
+ if (relativePlanPath)
90
+ log.info(` plan: ${relativePlanPath}`);
91
+ log.info(` wish: ${relativeWishPath}`);
85
92
  log.info('');
86
93
  // import wish file
87
94
  const wish = await Promise.resolve(`${resolvedWishPath}`).then(s => __importStar(require(s)));
@@ -1 +1 @@
1
- {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/contract/cli/apply.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../../src/contract/cli/apply.ts"],"names":[],"mappings":"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"}
@@ -33,6 +33,7 @@ const fs_1 = require("fs");
33
33
  const promises_1 = require("fs/promises");
34
34
  const helpful_errors_1 = require("helpful-errors");
35
35
  const path_1 = require("path");
36
+ const rhachet_artifact_git_1 = require("rhachet-artifact-git");
36
37
  const planChanges_1 = require("../../domain.operations/plan/planChanges");
37
38
  const log = console;
38
39
  /**
@@ -44,14 +45,18 @@ const executePlanCommand = async ({ wishFilePath, planFilePath, }) => {
44
45
  // resolve paths
45
46
  const resolvedWishPath = (0, path_1.resolve)(process.cwd(), wishFilePath);
46
47
  const resolvedPlanPath = (0, path_1.resolve)(process.cwd(), planFilePath);
48
+ // get git root for relative path display
49
+ const gitRoot = await (0, rhachet_artifact_git_1.getGitRepoRoot)({ from: process.cwd() });
50
+ const relativeWishPath = (0, path_1.relative)(gitRoot, resolvedWishPath);
51
+ const relativePlanPath = (0, path_1.relative)(gitRoot, resolvedPlanPath);
47
52
  // validate wish file exists
48
53
  if (!(0, fs_1.existsSync)(resolvedWishPath)) {
49
54
  throw new helpful_errors_1.BadRequestError(`Wish file not found: ${resolvedWishPath}`);
50
55
  }
51
56
  log.info('');
52
57
  log.info('🌊 declastruct plan');
53
- log.info(` wish: ${resolvedWishPath}`);
54
- log.info(` plan: ${resolvedPlanPath}`);
58
+ log.info(` wish: ${relativeWishPath}`);
59
+ log.info(` plan: ${relativePlanPath}`);
55
60
  log.info('');
56
61
  // import wish file
57
62
  const wish = await Promise.resolve(`${resolvedWishPath}`).then(s => __importStar(require(s)));
@@ -91,7 +96,7 @@ const executePlanCommand = async ({ wishFilePath, planFilePath, }) => {
91
96
  // log summary
92
97
  log.info('');
93
98
  log.info(`🌊 planned for ${plan.changes.length} resources`);
94
- log.info(` into ${resolvedPlanPath}`);
99
+ log.info(` into ${relativePlanPath}`);
95
100
  log.info('');
96
101
  };
97
102
  exports.executePlanCommand = executePlanCommand;
@@ -1 +1 @@
1
- {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/contract/cli/plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/contract/cli/plan.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,9 @@ export { DeclastructChange, DeclastructChangeAction, } from '../../domain.object
4
4
  export { DeclastructDao } from '../../domain.objects/DeclastructDao';
5
5
  export { DeclastructPlan } from '../../domain.objects/DeclastructPlan';
6
6
  export { DeclastructProvider } from '../../domain.objects/DeclastructProvider';
7
+ export type { DeclastructDaoInput, DeclastructDaoWithRef, DeclastructDaoWoutRef, } from '../../domain.objects/genDeclastructDao';
8
+ export { genDeclastructDao } from '../../domain.objects/genDeclastructDao';
7
9
  export type { IsoTimestamp } from '../../domain.objects/IsoTimestamp';
10
+ export { del, isMarkedForDeletion } from '../../domain.operations/del/del';
8
11
  export { getRefByPrimary } from '../../domain.operations/ref/getRefByPrimary';
9
12
  export { getRefByUnique } from '../../domain.operations/ref/getRefByUnique';
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // domain objects
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.getRefByUnique = exports.getRefByPrimary = exports.DeclastructProvider = exports.DeclastructPlan = exports.DeclastructDao = exports.DeclastructChangeAction = exports.DeclastructChange = void 0;
4
+ exports.getRefByUnique = exports.getRefByPrimary = exports.isMarkedForDeletion = exports.del = exports.genDeclastructDao = exports.DeclastructProvider = exports.DeclastructPlan = exports.DeclastructDao = exports.DeclastructChangeAction = exports.DeclastructChange = void 0;
5
5
  var DeclastructChange_1 = require("../../domain.objects/DeclastructChange");
6
6
  Object.defineProperty(exports, "DeclastructChange", { enumerable: true, get: function () { return DeclastructChange_1.DeclastructChange; } });
7
7
  Object.defineProperty(exports, "DeclastructChangeAction", { enumerable: true, get: function () { return DeclastructChange_1.DeclastructChangeAction; } });
@@ -11,7 +11,13 @@ var DeclastructPlan_1 = require("../../domain.objects/DeclastructPlan");
11
11
  Object.defineProperty(exports, "DeclastructPlan", { enumerable: true, get: function () { return DeclastructPlan_1.DeclastructPlan; } });
12
12
  var DeclastructProvider_1 = require("../../domain.objects/DeclastructProvider");
13
13
  Object.defineProperty(exports, "DeclastructProvider", { enumerable: true, get: function () { return DeclastructProvider_1.DeclastructProvider; } });
14
+ // factories
15
+ var genDeclastructDao_1 = require("../../domain.objects/genDeclastructDao");
16
+ Object.defineProperty(exports, "genDeclastructDao", { enumerable: true, get: function () { return genDeclastructDao_1.genDeclastructDao; } });
14
17
  // domain operations
18
+ var del_1 = require("../../domain.operations/del/del");
19
+ Object.defineProperty(exports, "del", { enumerable: true, get: function () { return del_1.del; } });
20
+ Object.defineProperty(exports, "isMarkedForDeletion", { enumerable: true, get: function () { return del_1.isMarkedForDeletion; } });
15
21
  var getRefByPrimary_1 = require("../../domain.operations/ref/getRefByPrimary");
16
22
  Object.defineProperty(exports, "getRefByPrimary", { enumerable: true, get: function () { return getRefByPrimary_1.getRefByPrimary; } });
17
23
  var getRefByUnique_1 = require("../../domain.operations/ref/getRefByUnique");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/contract/sdk/index.ts"],"names":[],"mappings":";AAAA,iBAAiB;;;AAIjB,4EAGgD;AAF9C,sHAAA,iBAAiB,OAAA;AACjB,4HAAA,uBAAuB,OAAA;AAEzB,sEAAqE;AAA5D,gHAAA,cAAc,OAAA;AACvB,wEAAuE;AAA9D,kHAAA,eAAe,OAAA;AACxB,gFAA+E;AAAtE,0HAAA,mBAAmB,OAAA;AAG5B,oBAAoB;AACpB,+EAA8E;AAArE,kHAAA,eAAe,OAAA;AACxB,6EAA4E;AAAnE,gHAAA,cAAc,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/contract/sdk/index.ts"],"names":[],"mappings":";AAAA,iBAAiB;;;AAIjB,4EAGgD;AAF9C,sHAAA,iBAAiB,OAAA;AACjB,4HAAA,uBAAuB,OAAA;AAEzB,sEAAqE;AAA5D,gHAAA,cAAc,OAAA;AACvB,wEAAuE;AAA9D,kHAAA,eAAe,OAAA;AACxB,gFAA+E;AAAtE,0HAAA,mBAAmB,OAAA;AAM5B,YAAY;AACZ,4EAA2E;AAAlE,sHAAA,iBAAiB,OAAA;AAE1B,oBAAoB;AACpB,uDAA2E;AAAlE,0FAAA,GAAG,OAAA;AAAE,0GAAA,mBAAmB,OAAA;AACjC,+EAA8E;AAArE,kHAAA,eAAe,OAAA;AACxB,6EAA4E;AAAnE,gHAAA,cAAc,OAAA"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * .what = symbol used to mark resources for declarative deletion
3
+ * .why = enables del() wrapper to mark resources without polluting their interface
4
+ */
5
+ export declare const DECLASTRUCT_DELETE: unique symbol;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DECLASTRUCT_DELETE = void 0;
4
+ /**
5
+ * .what = symbol used to mark resources for declarative deletion
6
+ * .why = enables del() wrapper to mark resources without polluting their interface
7
+ */
8
+ exports.DECLASTRUCT_DELETE = Symbol.for('declastruct.delete');
9
+ //# sourceMappingURL=symbols.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbols.js","sourceRoot":"","sources":["../../src/domain/symbols.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACU,QAAA,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC"}
@@ -34,9 +34,9 @@ export interface DeclastructDao<TResourceClass extends Refable<any, any, any>, T
34
34
  * .what = fetch by primary keys
35
35
  * .why = enables efficient lookups when primary key is known
36
36
  *
37
- * .note = set to null if resource lacks primary keys (forces explicit decision)
37
+ * .note = undefined if resource lacks primary keys; would be null, but that breaks bivariance
38
38
  */
39
- byPrimary: null | ((input: RefByPrimary<TResourceClass>, context: TContext) => Promise<InstanceType<TResourceClass> | null>);
39
+ byPrimary?(input: RefByPrimary<TResourceClass>, context: TContext): Promise<InstanceType<TResourceClass> | null>;
40
40
  /**
41
41
  * .what = fetch by any supported reference type
42
42
  * .why = enables flexible lookups when ref type is not known at compile time
@@ -54,16 +54,16 @@ export interface DeclastructDao<TResourceClass extends Refable<any, any, any>, T
54
54
  * .what = resolve any ref to RefByPrimary
55
55
  * .why = enables getting primary key from any ref type
56
56
  *
57
- * .note = set to null if resource lacks primary keys
57
+ * .note = undefined if resource lacks primary keys; would be null, but that breaks bivariance
58
58
  */
59
- byPrimary: null | ((input: Ref<TResourceClass>, context: TContext) => Promise<RefByPrimary<TResourceClass>>);
59
+ byPrimary?(input: Ref<TResourceClass>, context: TContext): Promise<RefByPrimary<TResourceClass> | null>;
60
60
  /**
61
61
  * .what = resolve any ref to RefByUnique
62
62
  * .why = enables getting unique key from any ref type
63
63
  *
64
- * .note = set to null if resource lacks primary keys
64
+ * .note = undefined if resource lacks primary keys; would be null, but that breaks bivariance
65
65
  */
66
- byUnique: null | ((input: Ref<TResourceClass>, context: TContext) => Promise<RefByUnique<TResourceClass>>);
66
+ byUnique?(input: Ref<TResourceClass>, context: TContext): Promise<RefByUnique<TResourceClass> | null>;
67
67
  };
68
68
  };
69
69
  /**
@@ -80,16 +80,16 @@ export interface DeclastructDao<TResourceClass extends Refable<any, any, any>, T
80
80
  * .what = create or update resource
81
81
  * .why = idempotent upsert - creates if not found, updates if found
82
82
  *
83
- * .note = set to null if resource does not support updates
83
+ * .note = undefined if resource does not support updates; would be null, but that breaks bivariance
84
84
  */
85
- upsert: null | ((input: InstanceType<TResourceClass>, context: TContext) => Promise<HasMetadata<InstanceType<TResourceClass>>>);
85
+ upsert?(input: InstanceType<TResourceClass>, context: TContext): Promise<HasMetadata<InstanceType<TResourceClass>>>;
86
86
  /**
87
87
  * .what = delete resource
88
88
  * .why = removes resource from remote state
89
89
  *
90
- * .note = set to null if resource does not support deletion
90
+ * .note = undefined if resource does not support deletion; would be null, but that breaks bivariance
91
91
  */
92
- delete: null | ((input: Ref<TResourceClass>, context: TContext) => Promise<void>);
92
+ delete?(input: Ref<TResourceClass>, context: TContext): Promise<void>;
93
93
  };
94
94
  }
95
95
  export declare class DeclastructDao<TResourceClass extends Refable<any, any, any>, TContext> extends DomainLiteral<DeclastructDao<TResourceClass, TContext>> implements DeclastructDao<TResourceClass, TContext> {
@@ -1 +1 @@
1
- {"version":3,"file":"DeclastructDao.js","sourceRoot":"","sources":["../../src/domain.objects/DeclastructDao.ts"],"names":[],"mappings":";;;AAAA,mDAMwB;AA0IxB,MAAa,cAIX,SAAQ,8BAAuD;CACT;AALxD,wCAKwD"}
1
+ {"version":3,"file":"DeclastructDao.js","sourceRoot":"","sources":["../../src/domain.objects/DeclastructDao.ts"],"names":[],"mappings":";;;AAAA,mDAMwB;AAgIxB,MAAa,cAIX,SAAQ,8BAAuD;CACT;AALxD,wCAKwD"}
@@ -0,0 +1,79 @@
1
+ import { type Ref, type Refable, type RefByPrimary, type RefByUnique } from 'domain-objects';
2
+ import type { DeclastructDao } from './DeclastructDao';
3
+ /**
4
+ * .what = input type for genDeclastructDao without get.ref and get.one.byRef (auto-wired by factory)
5
+ * .why = derives from DeclastructDao to stay in sync, omits auto-wired methods
6
+ * .note = uses `| null` syntax to force explicit decision on nullable methods
7
+ */
8
+ export type DeclastructDaoInput<TResourceClass extends Refable<any, any, any>, TContext> = Omit<DeclastructDao<TResourceClass, TContext>, 'get' | 'set'> & {
9
+ get: {
10
+ one: Omit<DeclastructDao<TResourceClass, TContext>['get']['one'], 'byRef' | 'byPrimary'> & {
11
+ byPrimary: ((input: RefByPrimary<TResourceClass>, context: TContext) => Promise<InstanceType<TResourceClass> | null>) | null;
12
+ };
13
+ };
14
+ set: Omit<DeclastructDao<TResourceClass, TContext>['set'], 'upsert' | 'delete'> & {
15
+ upsert: ((input: InstanceType<TResourceClass>, context: TContext) => Promise<InstanceType<TResourceClass>>) | null;
16
+ delete: ((input: Ref<TResourceClass>, context: TContext) => Promise<void>) | null;
17
+ };
18
+ };
19
+ /**
20
+ * .what = input type for daos with byPrimary defined
21
+ * .why = enables overload to distinguish daos with primary key support
22
+ */
23
+ export type DeclastructDaoInputWithPrimary<TResourceClass extends Refable<any, any, any>, TContext> = Omit<DeclastructDaoInput<TResourceClass, TContext>, 'get'> & {
24
+ get: {
25
+ one: Omit<DeclastructDao<TResourceClass, TContext>['get']['one'], 'byPrimary' | 'byRef'> & {
26
+ byPrimary: NonNullable<DeclastructDao<TResourceClass, TContext>['get']['one']['byPrimary']>;
27
+ };
28
+ };
29
+ };
30
+ /**
31
+ * .what = input type for daos without byPrimary
32
+ * .why = enables overload to distinguish daos without primary key support
33
+ */
34
+ export type DeclastructDaoInputWoutPrimary<TResourceClass extends Refable<any, any, any>, TContext> = Omit<DeclastructDaoInput<TResourceClass, TContext>, 'get'> & {
35
+ get: {
36
+ one: Omit<DeclastructDao<TResourceClass, TContext>['get']['one'], 'byPrimary' | 'byRef'> & {
37
+ byPrimary: null;
38
+ };
39
+ };
40
+ };
41
+ /**
42
+ * .what = output type for daos with ref methods defined
43
+ * .why = enables type-safe access to ref resolution methods
44
+ * .note = uses method syntax for bivariance (enables assignment to DeclastructDao<any>)
45
+ */
46
+ export type DeclastructDaoWithRef<TResourceClass extends Refable<any, any, any>, TContext> = Omit<DeclastructDao<TResourceClass, TContext>, 'get'> & {
47
+ get: {
48
+ one: DeclastructDao<TResourceClass, TContext>['get']['one'];
49
+ ref: {
50
+ byPrimary(input: Ref<TResourceClass>, context: TContext): Promise<RefByPrimary<TResourceClass> | null>;
51
+ byUnique(input: Ref<TResourceClass>, context: TContext): Promise<RefByUnique<TResourceClass> | null>;
52
+ };
53
+ };
54
+ };
55
+ /**
56
+ * .what = output type for daos without ref methods
57
+ * .why = ref methods are undefined when byPrimary is not supported
58
+ */
59
+ export type DeclastructDaoWoutRef<TResourceClass extends Refable<any, any, any>, TContext> = Omit<DeclastructDao<TResourceClass, TContext>, 'get'> & {
60
+ get: {
61
+ one: DeclastructDao<TResourceClass, TContext>['get']['one'];
62
+ ref: {
63
+ byPrimary: undefined;
64
+ byUnique: undefined;
65
+ };
66
+ };
67
+ };
68
+ /**
69
+ * .what = factory to create DeclastructDao with auto-wired ref methods
70
+ * .why = enforces that ref methods are defined iff byPrimary is defined
71
+ * .note = TContext must be explicitly provided as a generic parameter to avoid hazardous Record<string, any> inference
72
+ *
73
+ * @overload input with byPrimary defined → output with ref methods defined
74
+ */
75
+ export declare function genDeclastructDao<TResourceClass extends Refable<any, any, any>, TContext extends Record<string, any> = never>(input: DeclastructDaoInputWithPrimary<TResourceClass, TContext>): DeclastructDaoWithRef<TResourceClass, TContext>;
76
+ /**
77
+ * @overload input without byPrimary → output with ref methods null
78
+ */
79
+ export declare function genDeclastructDao<TResourceClass extends Refable<any, any, any>, TContext extends Record<string, any> = never>(input: DeclastructDaoInputWoutPrimary<TResourceClass, TContext>): DeclastructDaoWoutRef<TResourceClass, TContext>;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.genDeclastructDao = void 0;
4
+ const domain_objects_1 = require("domain-objects");
5
+ const helpful_errors_1 = require("helpful-errors");
6
+ const getRefByPrimary_1 = require("../domain.operations/ref/getRefByPrimary");
7
+ const getRefByUnique_1 = require("../domain.operations/ref/getRefByUnique");
8
+ /**
9
+ * .impl = creates dao with byRef and ref methods auto-wired based on byPrimary presence
10
+ */
11
+ function genDeclastructDao(input) {
12
+ const hasPrimary = input.get.one.byPrimary !== null;
13
+ // build byRef from byUnique + byPrimary
14
+ const byRef = async (ref, context) => {
15
+ // check primary key first (only if resource declares .primary)
16
+ if (hasPrimary && (0, domain_objects_1.isRefByPrimary)({ of: input.dobj })(ref))
17
+ return input.get.one.byPrimary(ref, context);
18
+ // check unique key
19
+ if ((0, domain_objects_1.isRefByUnique)({ of: input.dobj })(ref))
20
+ return input.get.one.byUnique(ref, context);
21
+ throw new helpful_errors_1.BadRequestError('get.one.byRef called with neither a RefByUnique nor RefByPrimary', { ref });
22
+ };
23
+ // convert null → undefined for optional methods
24
+ const upsert = input.set.upsert ?? undefined;
25
+ const del = input.set.delete ?? undefined;
26
+ if (hasPrimary) {
27
+ // auto-wire ref methods using the helper functions
28
+ // convert null → undefined for byPrimary (input requires null, output uses undefined)
29
+ const byPrimary = input.get.one.byPrimary ?? undefined;
30
+ const dao = {
31
+ ...input,
32
+ get: {
33
+ one: {
34
+ byUnique: input.get.one.byUnique,
35
+ byPrimary,
36
+ byRef,
37
+ },
38
+ ref: {
39
+ byPrimary: (ref, context) => (0, getRefByPrimary_1.getRefByPrimary)({ ref }, { dao, ...context }),
40
+ byUnique: (ref, context) => (0, getRefByUnique_1.getRefByUnique)({ ref }, { dao, ...context }),
41
+ },
42
+ },
43
+ set: {
44
+ finsert: input.set.finsert,
45
+ upsert,
46
+ delete: del,
47
+ },
48
+ };
49
+ return dao;
50
+ }
51
+ // no primary key support - ref methods are undefined
52
+ return {
53
+ ...input,
54
+ get: {
55
+ one: {
56
+ byUnique: input.get.one.byUnique,
57
+ byPrimary: undefined,
58
+ byRef,
59
+ },
60
+ ref: {
61
+ byPrimary: undefined,
62
+ byUnique: undefined,
63
+ },
64
+ },
65
+ set: {
66
+ finsert: input.set.finsert,
67
+ upsert,
68
+ delete: del,
69
+ },
70
+ };
71
+ }
72
+ exports.genDeclastructDao = genDeclastructDao;
73
+ //# sourceMappingURL=genDeclastructDao.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"genDeclastructDao.js","sourceRoot":"","sources":["../../src/domain.objects/genDeclastructDao.ts"],"names":[],"mappings":";;;AAAA,mDAOwB;AACxB,mDAAiD;AAEjD,8EAA2E;AAC3E,4EAAyE;AAqJzE;;GAEG;AACH,SAAgB,iBAAiB,CAI/B,KAAoD;IAEpD,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,KAAK,IAAI,CAAC;IAEpD,wCAAwC;IACxC,MAAM,KAAK,GAAG,KAAK,EACjB,GAAwB,EACxB,OAAiB,EAC6B,EAAE;QAChD,+DAA+D;QAC/D,IAAI,UAAU,IAAI,IAAA,+BAAc,EAAC,EAAE,EAAE,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC;YACvD,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,SAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAEhD,mBAAmB;QACnB,IAAI,IAAA,8BAAa,EAAC,EAAE,EAAE,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC;YACxC,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAE9C,MAAM,IAAI,gCAAe,CACvB,kEAAkE,EAClE,EAAE,GAAG,EAAE,CACR,CAAC;IACJ,CAAC,CAAC;IAEF,gDAAgD;IAChD,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,IAAI,SAAS,CAAC;IAC7C,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,IAAI,SAAS,CAAC;IAE1C,IAAI,UAAU,EAAE,CAAC;QACf,mDAAmD;QACnD,sFAAsF;QACtF,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,IAAI,SAAS,CAAC;QACvD,MAAM,GAAG,GAA6C;YACpD,GAAG,KAAK;YACR,GAAG,EAAE;gBACH,GAAG,EAAE;oBACH,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ;oBAChC,SAAS;oBACT,KAAK;iBACN;gBACD,GAAG,EAAE;oBACH,SAAS,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CAC1B,IAAA,iCAAe,EAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;oBAC/C,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CACzB,IAAA,+BAAc,EAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;iBAC/C;aACF;YACD,GAAG,EAAE;gBACH,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO;gBAC1B,MAAM;gBACN,MAAM,EAAE,GAAG;aACZ;SACF,CAAC;QACF,OAAO,GAAG,CAAC;IACb,CAAC;IAED,qDAAqD;IACrD,OAAO;QACL,GAAG,KAAK;QACR,GAAG,EAAE;YACH,GAAG,EAAE;gBACH,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ;gBAChC,SAAS,EAAE,SAAS;gBACpB,KAAK;aACN;YACD,GAAG,EAAE;gBACH,SAAS,EAAE,SAAS;gBACpB,QAAQ,EAAE,SAAS;aACpB;SACF;QACD,GAAG,EAAE;YACH,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO;YAC1B,MAAM;YACN,MAAM,EAAE,GAAG;SACZ;KACF,CAAC;AACJ,CAAC;AA/ED,8CA+EC"}
@@ -0,0 +1,27 @@
1
+ import { DECLASTRUCT_DELETE } from '../../domain/symbols';
2
+ import type { DeclaredResource } from '../../domain.objects/DeclaredResource';
3
+ /**
4
+ * .what = marks a resource for deletion via declarative instruction
5
+ * .why = enables users to express deletion intent
6
+ *
7
+ * .how = attaches a symbol-keyed property to the resource object
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const getResources = async () => {
12
+ * const tokens = await getAllIamAuthTokens(...);
13
+ * return tokens.map(token => del(token)); // mark all for deletion
14
+ * }
15
+ * ```
16
+ */
17
+ export declare const del: <T extends DeclaredResource>(resource: T) => T & {
18
+ [DECLASTRUCT_DELETE]: true;
19
+ };
20
+ /**
21
+ * .what = checks if a resource is marked for deletion
22
+ * .why = enables planChanges to detect deletion intent
23
+ * .note = type guard narrows to the marked type for downstream type safety
24
+ */
25
+ export declare const isMarkedForDeletion: <T extends DeclaredResource>(resource: T) => resource is T & {
26
+ [DECLASTRUCT_DELETE]: true;
27
+ };
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isMarkedForDeletion = exports.del = void 0;
4
+ const symbols_1 = require("../../domain/symbols");
5
+ /**
6
+ * .what = marks a resource for deletion via declarative instruction
7
+ * .why = enables users to express deletion intent
8
+ *
9
+ * .how = attaches a symbol-keyed property to the resource object
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * const getResources = async () => {
14
+ * const tokens = await getAllIamAuthTokens(...);
15
+ * return tokens.map(token => del(token)); // mark all for deletion
16
+ * }
17
+ * ```
18
+ */
19
+ const del = (resource) => {
20
+ return Object.assign(resource, { [symbols_1.DECLASTRUCT_DELETE]: true });
21
+ };
22
+ exports.del = del;
23
+ /**
24
+ * .what = checks if a resource is marked for deletion
25
+ * .why = enables planChanges to detect deletion intent
26
+ * .note = type guard narrows to the marked type for downstream type safety
27
+ */
28
+ const isMarkedForDeletion = (resource) => {
29
+ // biome-ignore lint/suspicious/noExplicitAny: symbol access requires any cast
30
+ return resource[symbols_1.DECLASTRUCT_DELETE] === true;
31
+ };
32
+ exports.isMarkedForDeletion = isMarkedForDeletion;
33
+ //# sourceMappingURL=del.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"del.js","sourceRoot":"","sources":["../../../src/domain.operations/del/del.ts"],"names":[],"mappings":";;;AAAA,kDAA0D;AAG1D;;;;;;;;;;;;;GAaG;AACI,MAAM,GAAG,GAAG,CACjB,QAAW,EACyB,EAAE;IACtC,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,4BAAkB,CAAC,EAAE,IAAa,EAAE,CAAC,CAAC;AAC1E,CAAC,CAAC;AAJW,QAAA,GAAG,OAId;AAEF;;;;GAIG;AACI,MAAM,mBAAmB,GAAG,CACjC,QAAW,EACqC,EAAE;IAClD,8EAA8E;IAC9E,OAAQ,QAAgB,CAAC,4BAAkB,CAAC,KAAK,IAAI,CAAC;AACxD,CAAC,CAAC;AALW,QAAA,mBAAmB,uBAK9B"}
@@ -4,6 +4,7 @@ exports.planChanges = void 0;
4
4
  const domain_objects_1 = require("domain-objects");
5
5
  const DeclastructChange_1 = require("../../domain.objects/DeclastructChange");
6
6
  const DeclastructPlan_1 = require("../../domain.objects/DeclastructPlan");
7
+ const del_1 = require("../../domain.operations/del/del");
7
8
  const asIsoTimestamp_1 = require("../../infra/asIsoTimestamp");
8
9
  const colorizeAction_1 = require("../../infra/colorizeAction");
9
10
  const withSpinner_1 = require("../../infra/withSpinner");
@@ -42,9 +43,11 @@ const planChanges = async (input, context) => {
42
43
  // log done (replaces spinner)
43
44
  const durationSec = (durationMs / 1000).toFixed(2);
44
45
  context.log.info(` ├─ ✔ done in ${durationSec}s`);
46
+ // determine desired state - null if marked for deletion
47
+ const desiredState = (0, del_1.isMarkedForDeletion)(resource) ? null : resource;
45
48
  // compute change
46
49
  const computed = (0, computeChange_1.computeChange)({
47
- desired: resource,
50
+ desired: desiredState,
48
51
  remote: remoteState,
49
52
  });
50
53
  // log decision
@@ -1 +1 @@
1
- {"version":3,"file":"planChanges.js","sourceRoot":"","sources":["../../../src/domain.operations/plan/planChanges.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"planChanges.js","sourceRoot":"","sources":["../../../src/domain.operations/plan/planChanges.ts"],"names":[],"mappings":"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"}
@@ -9,4 +9,4 @@ export declare const getRefByPrimary: <TResourceClass extends Refable<any, any,
9
9
  ref: Ref<TResourceClass>;
10
10
  }, context: {
11
11
  dao: DeclastructDao<TResourceClass, TContext>;
12
- } & TContext) => Promise<RefByPrimary<TResourceClass>>;
12
+ } & TContext) => Promise<RefByPrimary<TResourceClass> | null>;
@@ -16,11 +16,9 @@ const getRefByPrimary = async (input, context) => {
16
16
  if ((0, domain_objects_1.isRefByUnique)({ of: context.dao.dobj })(input.ref)) {
17
17
  // fetch the resource by unique key
18
18
  const resource = await context.dao.get.one.byUnique(input.ref, context);
19
- // throw if resource not found
19
+ // return null if resource not found (resource may not exist yet)
20
20
  if (!resource)
21
- throw new helpful_errors_1.BadRequestError('resource not found by unique ref', {
22
- ref: input.ref,
23
- });
21
+ return null;
24
22
  // extract primary key from the resource
25
23
  return (0, domain_objects_1.refByPrimary)(resource);
26
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"getRefByPrimary.js","sourceRoot":"","sources":["../../../src/domain.operations/ref/getRefByPrimary.ts"],"names":[],"mappings":";;;AAAA,mDAOwB;AACxB,mDAA0E;AAI1E;;;;GAIG;AACI,MAAM,eAAe,GAAG,KAAK,EAIlC,KAEC,EACD,OAEY,EAC2B,EAAE;IACzC,wDAAwD;IACxD,IAAI,IAAA,+BAAc,EAAC,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC;IAE1E,yDAAyD;IACzD,IAAI,IAAA,8BAAa,EAAC,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACvD,mCAAmC;QACnC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAExE,8BAA8B;QAC9B,IAAI,CAAC,QAAQ;YACX,MAAM,IAAI,gCAAe,CAAC,kCAAkC,EAAE;gBAC5D,GAAG,EAAE,KAAK,CAAC,GAAG;aACf,CAAC,CAAC;QAEL,wCAAwC;QACxC,OAAO,IAAA,6BAAY,EAAiB,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED,iCAAiC;IACjC,MAAM,IAAI,wCAAuB,CAAC,kBAAkB,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;AAC5E,CAAC,CAAC;AA/BW,QAAA,eAAe,mBA+B1B"}
1
+ {"version":3,"file":"getRefByPrimary.js","sourceRoot":"","sources":["../../../src/domain.operations/ref/getRefByPrimary.ts"],"names":[],"mappings":";;;AAAA,mDAOwB;AACxB,mDAAyD;AAIzD;;;;GAIG;AACI,MAAM,eAAe,GAAG,KAAK,EAIlC,KAEC,EACD,OAEY,EACkC,EAAE;IAChD,wDAAwD;IACxD,IAAI,IAAA,+BAAc,EAAC,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC;IAE1E,yDAAyD;IACzD,IAAI,IAAA,8BAAa,EAAC,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACvD,mCAAmC;QACnC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAExE,iEAAiE;QACjE,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE3B,wCAAwC;QACxC,OAAO,IAAA,6BAAY,EAAiB,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED,iCAAiC;IACjC,MAAM,IAAI,wCAAuB,CAAC,kBAAkB,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;AAC5E,CAAC,CAAC;AA5BW,QAAA,eAAe,mBA4B1B"}
@@ -9,4 +9,4 @@ export declare const getRefByUnique: <TResourceClass extends Refable<any, any, a
9
9
  ref: Ref<TResourceClass>;
10
10
  }, context: {
11
11
  dao: DeclastructDao<TResourceClass, TContext>;
12
- } & TContext) => Promise<RefByUnique<TResourceClass>>;
12
+ } & TContext) => Promise<RefByUnique<TResourceClass> | null>;
@@ -19,11 +19,9 @@ const getRefByUnique = async (input, context) => {
19
19
  throw new helpful_errors_1.UnexpectedCodePathError('dao does not support byPrimary lookup', { ref: input.ref });
20
20
  // fetch the resource by primary key
21
21
  const resource = await context.dao.get.one.byPrimary(input.ref, context);
22
- // throw if resource not found
22
+ // return null if resource not found (resource may not exist yet)
23
23
  if (!resource)
24
- throw new helpful_errors_1.BadRequestError('resource not found by primary ref', {
25
- ref: input.ref,
26
- });
24
+ return null;
27
25
  // extract unique key from the resource
28
26
  return (0, domain_objects_1.refByUnique)(resource);
29
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"getRefByUnique.js","sourceRoot":"","sources":["../../../src/domain.operations/ref/getRefByUnique.ts"],"names":[],"mappings":";;;AAAA,mDAOwB;AACxB,mDAA0E;AAI1E;;;;GAIG;AACI,MAAM,cAAc,GAAG,KAAK,EAIjC,KAEC,EACD,OAEY,EAC0B,EAAE;IACxC,uDAAuD;IACvD,IAAI,IAAA,8BAAa,EAAC,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC;IAEzE,yDAAyD;IACzD,IAAI,IAAA,+BAAc,EAAC,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACxD,gCAAgC;QAChC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS;YAChC,MAAM,IAAI,wCAAuB,CAC/B,uCAAuC,EACvC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CACnB,CAAC;QAEJ,oCAAoC;QACpC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAEzE,8BAA8B;QAC9B,IAAI,CAAC,QAAQ;YACX,MAAM,IAAI,gCAAe,CAAC,mCAAmC,EAAE;gBAC7D,GAAG,EAAE,KAAK,CAAC,GAAG;aACf,CAAC,CAAC;QAEL,uCAAuC;QACvC,OAAO,IAAA,4BAAW,EAAiB,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,iCAAiC;IACjC,MAAM,IAAI,wCAAuB,CAAC,kBAAkB,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;AAC5E,CAAC,CAAC;AAtCW,QAAA,cAAc,kBAsCzB"}
1
+ {"version":3,"file":"getRefByUnique.js","sourceRoot":"","sources":["../../../src/domain.operations/ref/getRefByUnique.ts"],"names":[],"mappings":";;;AAAA,mDAOwB;AACxB,mDAAyD;AAIzD;;;;GAIG;AACI,MAAM,cAAc,GAAG,KAAK,EAIjC,KAEC,EACD,OAEY,EACiC,EAAE;IAC/C,uDAAuD;IACvD,IAAI,IAAA,8BAAa,EAAC,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC;IAEzE,yDAAyD;IACzD,IAAI,IAAA,+BAAc,EAAC,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACxD,gCAAgC;QAChC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS;YAChC,MAAM,IAAI,wCAAuB,CAC/B,uCAAuC,EACvC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CACnB,CAAC;QAEJ,oCAAoC;QACpC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAEzE,iEAAiE;QACjE,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE3B,uCAAuC;QACvC,OAAO,IAAA,4BAAW,EAAiB,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,iCAAiC;IACjC,MAAM,IAAI,wCAAuB,CAAC,kBAAkB,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;AAC5E,CAAC,CAAC;AAnCW,QAAA,cAAc,kBAmCzB"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "declastruct",
3
3
  "author": "ehmpathy",
4
4
  "description": "Add declarative control to any resource constructs. Declare, plan, and apply within an observable pit-of-success.",
5
- "version": "1.5.2",
5
+ "version": "1.7.0",
6
6
  "repository": "ehmpathy/declastruct",
7
7
  "homepage": "https://github.com/ehmpathy/declastruct",
8
8
  "keywords": [
@@ -28,9 +28,10 @@
28
28
  "scripts": {
29
29
  "build:ts": "tsc -p ./tsconfig.build.json",
30
30
  "commit:with-cli": "npx cz",
31
- "fix:format:biome": "biome check --write src",
31
+ "fix:format:biome": "biome check --write",
32
32
  "fix:format": "npm run fix:format:biome",
33
- "fix:lint": "biome check --write src",
33
+ "fix:lint": "biome check --write",
34
+ "fix": "npm run fix:format && npm run fix:lint",
34
35
  "build:clean": "rm dist/ -rf",
35
36
  "build:compile": "tsc -p ./tsconfig.build.json",
36
37
  "build": "npm run build:clean && npm run build:compile",
@@ -38,9 +39,9 @@
38
39
  "test:types": "tsc -p ./tsconfig.json --noEmit",
39
40
  "test:format": "npm run test:format:biome",
40
41
  "test:lint:deps": "npx depcheck -c ./.depcheckrc.yml",
41
- "test:format:biome": "biome format src",
42
- "test:lint:biome": "biome check src --diagnostic-level=error",
43
- "test:lint:biome:all": "biome check src",
42
+ "test:format:biome": "biome format",
43
+ "test:lint:biome": "biome check --diagnostic-level=error",
44
+ "test:lint:biome:all": "biome check",
44
45
  "test:lint": "npm run test:lint:biome && npm run test:lint:deps",
45
46
  "test:unit": "jest -c ./jest.unit.config.ts --forceExit --verbose --passWithNoTests $([ -z $THOROUGH ] && echo '--changedSince=main')",
46
47
  "test:integration": "jest -c ./jest.integration.config.ts --forceExit --verbose --passWithNoTests $([ -z $THOROUGH ] && echo '--changedSince=main')",
@@ -52,7 +53,7 @@
52
53
  "preversion": "npm run prepush",
53
54
  "postversion": "git push origin HEAD --tags --no-verify",
54
55
  "prepare:husky": "npx husky install && chmod ug+x .husky/*",
55
- "prepare": "[ -d .git ] && npm run prepare:husky || exit 0"
56
+ "prepare": "[ -e .git ] && npm run prepare:husky || exit 0"
56
57
  },
57
58
  "dependencies": {
58
59
  "bottleneck": "2.19.5",
@@ -60,6 +61,7 @@
60
61
  "commander": "14.0.2",
61
62
  "helpful-errors": "1.5.3",
62
63
  "jest-diff": "30.0.2",
64
+ "rhachet-artifact-git": "1.1.3",
63
65
  "simple-log-methods": "0.6.2",
64
66
  "tsx": "4.20.6",
65
67
  "type-fns": "1.21.0",
@@ -80,9 +82,9 @@
80
82
  "@types/node": "22.15.29",
81
83
  "cz-conventional-changelog": "3.3.0",
82
84
  "declapract": "^0.13.0",
83
- "declapract-typescript-ehmpathy": "^0.43.7",
84
- "declastruct": "^1.5.1",
85
- "declastruct-github": "^1.0.7",
85
+ "declapract-typescript-ehmpathy": "0.43.16",
86
+ "declastruct": "1.5.1",
87
+ "declastruct-github": "1.0.7",
86
88
  "depcheck": "1.4.3",
87
89
  "esbuild-register": "3.6.0",
88
90
  "husky": "8.0.3",
package/readme.md CHANGED
@@ -270,3 +270,145 @@ each `DeclastructChange` includes:
270
270
  ## inspiration
271
271
 
272
272
  inspired by Terraform's declarative approach, but designed to eliminate state file overhead, work with any resource construct, be reusable across both prod codepaths and cicd control, and leverage TypeScript's type system for safer declarative instructions.
273
+
274
+
275
+ # plugin
276
+
277
+ build your own provider to control any resource construct via declastruct.
278
+
279
+ ## 1. declare your resource
280
+
281
+ define your resource as a [`domain-object`](https://github.com/ehmpathy/domain-objects) with key attributes:
282
+
283
+ ```ts
284
+ import { DomainEntity } from 'domain-objects';
285
+
286
+ interface DeclaredStripeCustomer {
287
+ id?: string;
288
+ email: string;
289
+ name: string;
290
+ status?: string;
291
+ }
292
+ class DeclaredStripeCustomer
293
+ extends DomainEntity<DeclaredStripeCustomer>
294
+ implements DeclaredStripeCustomer
295
+ {
296
+ // primary key: the surrogate key identifier for this resource
297
+ public static primary = ['id'] as const;
298
+
299
+ // unique key: the natural key identifier for this resource (i.e., the non-primary unique key)
300
+ public static unique = ['email'] as const;
301
+
302
+ // metadata keys: readonly persistance-specific fields - excluded from change detection
303
+ // if unspecified, the defaults of 'id', 'uuid', 'createdAt', 'updatedAt', 'effectiveAt' will be assumed
304
+ public static metadata = ['id'] as const;
305
+
306
+ // readonly keys: readonly domain-intrinsic fields - excluded from change detection
307
+ // note: all metadata is implicitly readonly, so you only need to specify non-metadata readonly keys here
308
+ public static readonly = ['status'] as const;
309
+ }
310
+ ```
311
+
312
+ key attributes to consider:
313
+ - **primary key** (`static primary`): surrogate identifier for efficient lookups after creation
314
+ - **unique key** (`static unique`): natural key that uniquely identifies the resource, used for idempotent operations
315
+ - **metadata keys** (`static metadata`): readonly persistence-layer fields that describe *how* the object is stored (e.g., `uuid`, `createdAt`). note, metadata is a specific subset of readonly
316
+ - **readonly keys** (`static readonly`): readonly domain-layer fields that describe *what* the object is (e.g., `status`). note, you only need to declare the readonly attributes that are not already flagged as metadata here
317
+
318
+ ## 2. generate your dao
319
+
320
+ use `genDeclastructDao` to create a type-safe DAO with auto-wired ref resolution:
321
+
322
+ ```ts
323
+ import { genDeclastructDao } from 'declastruct';
324
+ import Stripe from 'stripe';
325
+
326
+ // define the context type for your provider
327
+ interface StripeContext {
328
+ stripe: Stripe;
329
+ }
330
+
331
+ const daoStripeCustomer = genDeclastructDao<
332
+ typeof DeclaredStripeCustomer,
333
+ StripeContext
334
+ >({
335
+ dobj: DeclaredStripeCustomer,
336
+ get: {
337
+ one: {
338
+ byUnique: async ({ email }, context) => {
339
+ // lookup by natural key (email)
340
+ const customer = await context.stripe.customers.list({ email });
341
+ return customer.data[0] ? toResource(customer.data[0]) : null;
342
+ },
343
+ byPrimary: async ({ id }, context) => {
344
+ // lookup by stripe-assigned id
345
+ const customer = await context.stripe.customers.retrieve(id);
346
+ return customer ? toResource(customer) : null;
347
+ },
348
+ },
349
+ },
350
+ set: {
351
+ finsert: async (resource, context) => {
352
+ // find-or-insert: idempotent create
353
+ const foundBefore = await daoStripeCustomer.get.one.byUnique(
354
+ { email: resource.email },
355
+ context,
356
+ );
357
+ if (foundBefore) return foundBefore;
358
+
359
+ const created = await context.stripe.customers.create({
360
+ email: resource.email,
361
+ name: resource.name,
362
+ });
363
+ return toResource(created);
364
+ },
365
+ upsert: async (resource, context) => {
366
+ // update-or-insert: idempotent update
367
+ const foundBefore = await daoStripeCustomer.get.one.byUnique(
368
+ { email: resource.email },
369
+ context,
370
+ );
371
+ if (foundBefore) {
372
+ const updated = await context.stripe.customers.update(foundBefore.id, {
373
+ name: resource.name,
374
+ });
375
+ return toResource(updated);
376
+ }
377
+ return daoStripeCustomer.set.finsert(resource, context);
378
+ },
379
+ delete: async (ref, context) => {
380
+ const foundBefore = await daoStripeCustomer.get.one.byRef(ref, context);
381
+ if (foundBefore) await context.stripe.customers.del(foundBefore.id);
382
+ },
383
+ },
384
+ });
385
+ ```
386
+
387
+ the factory automatically:
388
+ - **builds get.one.byRef**: `get.one.byRef` is built for you, based on `get.one.byUnique` and `get.one.byPrimary`
389
+ - **builds get.ref.byPrimary,.byUnique**: if `byPrimary` is defined, `get.ref.byPrimary` and `get.ref.byUnique` are built for you, based on `get.one.byUnique` and `get.one.byPrimary`
390
+ - **enforces type safety**: if `byPrimary` is null, `get.ref.*` are typed as null (prevents accidental calls)
391
+
392
+ ## 3. create your provider
393
+
394
+ bundle your DAOs into a provider:
395
+
396
+ ```ts
397
+ import { DeclastructProvider } from 'declastruct';
398
+
399
+ export const stripeProvider = new DeclastructProvider({
400
+ name: 'stripe',
401
+ daos: {
402
+ DeclaredStripeCustomer: daoStripeCustomer,
403
+ },
404
+ context: {
405
+ stripe, // stripe client instance
406
+ },
407
+ hooks: {
408
+ beforeAll: async () => { /* setup */ },
409
+ afterAll: async () => { /* cleanup */ },
410
+ },
411
+ });
412
+ ```
413
+
414
+ now users can declare stripe customers and use `plan` + `apply` to control them declaratively.