@opencrvs/toolkit 2.0.0-rc.fef9d21 → 2.0.0-rc.ff99998

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 (59) hide show
  1. package/create-countryconfig/index.js +103 -0
  2. package/create-countryconfig/package.json +21 -0
  3. package/dist/application-config/index.js +305 -129
  4. package/dist/cli.js +548 -178
  5. package/dist/commons/api/router.d.ts +3379 -239
  6. package/dist/commons/application-config/index.d.ts +17 -4
  7. package/dist/commons/conditionals/conditionals.d.ts +360 -10
  8. package/dist/commons/conditionals/validate.d.ts +52 -2
  9. package/dist/commons/events/ActionDocument.d.ts +6 -0
  10. package/dist/commons/events/ActionInput.d.ts +114 -0
  11. package/dist/commons/events/AdvancedSearchConfig.d.ts +342 -0
  12. package/dist/commons/events/Draft.d.ts +4 -2
  13. package/dist/commons/events/EventDocument.d.ts +3 -0
  14. package/dist/commons/events/EventIndex.d.ts +0 -3
  15. package/dist/commons/events/EventMetadata.d.ts +0 -7
  16. package/dist/commons/events/FieldConfig.d.ts +387 -50
  17. package/dist/commons/events/FieldValue.d.ts +6 -0
  18. package/dist/commons/events/WorkqueueConfig.d.ts +150 -150
  19. package/dist/commons/events/field.d.ts +53 -1
  20. package/dist/commons/events/index.d.ts +2 -0
  21. package/dist/commons/events/locations.d.ts +38 -1
  22. package/dist/commons/events/mocks.test.utils.d.ts +19 -0
  23. package/dist/commons/events/scopes.d.ts +24 -1
  24. package/dist/commons/events/state/flags.d.ts +16 -0
  25. package/dist/commons/events/state/index.d.ts +0 -4
  26. package/dist/commons/events/state/utils.d.ts +12 -289
  27. package/dist/commons/events/utils.d.ts +13 -2
  28. package/dist/conditionals/index.js +92 -9
  29. package/dist/events/index.js +1084 -261
  30. package/dist/migrations/v2.0/add-birth-certificate-issuance-flag.d.ts.map +1 -1
  31. package/dist/migrations/v2.0/add-birth-certificate-issuance-flag.js +60 -35
  32. package/dist/migrations/v2.0/checkout-upstream-files.d.ts +1 -1
  33. package/dist/migrations/v2.0/checkout-upstream-files.d.ts.map +1 -1
  34. package/dist/migrations/v2.0/checkout-upstream-files.js +1 -2
  35. package/dist/migrations/v2.0/delete-infrastructure-directory.d.ts +9 -1
  36. package/dist/migrations/v2.0/delete-infrastructure-directory.d.ts.map +1 -1
  37. package/dist/migrations/v2.0/delete-infrastructure-directory.js +66 -20
  38. package/dist/migrations/v2.0/fix-accept-requested-registration-function-type.d.ts +3 -0
  39. package/dist/migrations/v2.0/fix-accept-requested-registration-function-type.d.ts.map +1 -0
  40. package/dist/migrations/v2.0/fix-accept-requested-registration-function-type.js +110 -0
  41. package/dist/migrations/v2.0/index.d.ts +5 -3
  42. package/dist/migrations/v2.0/index.d.ts.map +1 -1
  43. package/dist/migrations/v2.0/index.js +546 -176
  44. package/dist/migrations/v2.0/make-built-in-validate-actions-custom.d.ts.map +1 -1
  45. package/dist/migrations/v2.0/make-built-in-validate-actions-custom.js +90 -1
  46. package/dist/migrations/v2.0/merge-infrastructure-directory.d.ts +11 -1
  47. package/dist/migrations/v2.0/merge-infrastructure-directory.d.ts.map +1 -1
  48. package/dist/migrations/v2.0/merge-infrastructure-directory.js +17 -16
  49. package/dist/migrations/v2.0/migrate-scopes.d.ts.map +1 -1
  50. package/dist/migrations/v2.0/migrate-scopes.js +54 -30
  51. package/dist/migrations/v2.0/migrate-workqueue-configs.d.ts.map +1 -1
  52. package/dist/migrations/v2.0/migrate-workqueue-configs.js +140 -59
  53. package/dist/notification/index.js +841 -160
  54. package/dist/scopes/index.d.ts +91 -16
  55. package/dist/scopes/index.js +55 -12
  56. package/opencrvs-toolkit-2.0.0-rc.ff99998.tgz +0 -0
  57. package/package.json +6 -2
  58. package/tsconfig.tsbuildinfo +1 -1
  59. package/opencrvs-toolkit-2.0.0-rc.fef9d21.tgz +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"add-birth-certificate-issuance-flag.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/add-birth-certificate-issuance-flag.ts"],"names":[],"mappings":"AA2aA,iBAAe,IAAI,kBAiDlB;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
1
+ {"version":3,"file":"add-birth-certificate-issuance-flag.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/add-birth-certificate-issuance-flag.ts"],"names":[],"mappings":"AAycA,iBAAe,IAAI,kBAiDlB;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
@@ -24,15 +24,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
25
  exports.main = main;
26
26
  /**
27
- * Codemod: Add `pending-first-certificate-issuance` flag to birth event configs and workqueues.
27
+ * Codemod: Add `pending-first-certificate-issuance` flag to event configs and workqueues.
28
28
  *
29
29
  * Usage:
30
30
  * ts-node -r tsconfig-paths/register src/migrations/v2.0/add-birth-certificate-issuance-flag.ts
31
31
  *
32
32
  * What it does:
33
- * defineConfig (birth type only):
33
+ * defineConfig (every event type — birth, death, marriage, custom, etc.):
34
34
  * - Ensures the top-level `flags` array contains the `pending-first-certificate-issuance`
35
- * flag definition
35
+ * flag definition. The flag's i18n `label.id` is event-specific, e.g.
36
+ * `event.birth.flag.pending-first-certificate-issuance`,
37
+ * `event.death.flag.pending-first-certificate-issuance`.
36
38
  * - Ensures every `REGISTER` action has
37
39
  * `flags: [{ id: 'pending-first-certificate-issuance', operation: 'add' }]`
38
40
  * - Ensures every `PRINT_CERTIFICATE` action has
@@ -55,20 +57,27 @@ const ACTION_PROPERTY_NAME = 'action';
55
57
  const FLAGS_PROPERTY_NAME = 'flags';
56
58
  const QUERY_PROPERTY_NAME = 'query';
57
59
  const TYPE_PROPERTY_NAME = 'type';
60
+ const ID_PROPERTY_NAME = 'id';
58
61
  const CLAUSES_PROPERTY_NAME = 'clauses';
59
62
  const ANY_OF_PROPERTY_NAME = 'anyOf';
60
63
  const FLAG_ID = 'pending-first-certificate-issuance';
61
64
  const REGISTER_TYPE = 'REGISTER';
62
65
  const PRINT_CERTIFICATE_TYPE = 'PRINT_CERTIFICATE';
63
- const FLAG_DEFINITION_INITIALIZER = `{
66
+ /**
67
+ * Builds the flag-definition object literal for a given event type so the i18n
68
+ * `label.id` is namespaced per event (e.g. `event.death.flag.…`).
69
+ */
70
+ function flagDefinitionInitializer(eventType) {
71
+ return `{
64
72
  id: '${FLAG_ID}',
65
73
  label: {
66
- id: 'event.birth.flag.${FLAG_ID}',
74
+ id: 'event.${eventType}.flag.${FLAG_ID}',
67
75
  defaultMessage: 'Pending first certificate issuance',
68
76
  description: 'Flag label for first certificate issuance'
69
77
  },
70
78
  requiresAction: true
71
79
  }`;
80
+ }
72
81
  // ─── Generic helpers ──────────────────────────────────────────────────────────
73
82
  /**
74
83
  * Returns true if the object's `type` property matches the given type name.
@@ -90,23 +99,36 @@ function isActionOfType(obj, typeName) {
90
99
  return false;
91
100
  }
92
101
  /**
93
- * Returns true when the `defineConfig` root config object describes a birth event.
94
- * Handles both `'birth'` string literal and `EventType.BIRTH` enum access.
102
+ * Extracts the event type from a `defineConfig` root config object, using the
103
+ * (lower-cased) value of either the `type` or `id` property. Property name has
104
+ * shifted across core/country-config versions, so both are tried.
105
+ *
106
+ * Handles all known shapes:
107
+ * - `type: 'birth'` / `id: 'birth'`
108
+ * - `type: EventType.BIRTH` / `id: Event.Birth`
109
+ *
110
+ * For `PropertyAccessExpression` (enum access), the *member name* is returned
111
+ * lower-cased — this works for the conventional `EventType.BIRTH = 'birth'` and
112
+ * `Event.Birth = 'birth'` mappings used in core and country configs.
113
+ *
114
+ * Returns null when no event type can be determined.
95
115
  */
96
- function isBirthConfig(configArg) {
97
- const typeProperty = configArg.getProperty(TYPE_PROPERTY_NAME);
98
- if (!typeProperty || !ts_morph_1.Node.isPropertyAssignment(typeProperty))
99
- return false;
100
- const initializer = typeProperty.getInitializer();
101
- if (!initializer)
102
- return false;
103
- if (ts_morph_1.Node.isStringLiteral(initializer)) {
104
- return initializer.getLiteralValue().toLowerCase() === 'birth';
105
- }
106
- if (ts_morph_1.Node.isPropertyAccessExpression(initializer)) {
107
- return initializer.getName().toLowerCase() === 'birth';
116
+ function getEventType(configArg) {
117
+ for (const propName of [TYPE_PROPERTY_NAME, ID_PROPERTY_NAME]) {
118
+ const prop = configArg.getProperty(propName);
119
+ if (!prop || !ts_morph_1.Node.isPropertyAssignment(prop))
120
+ continue;
121
+ const initializer = prop.getInitializer();
122
+ if (!initializer)
123
+ continue;
124
+ if (ts_morph_1.Node.isStringLiteral(initializer)) {
125
+ return initializer.getLiteralValue().toLowerCase();
126
+ }
127
+ if (ts_morph_1.Node.isPropertyAccessExpression(initializer)) {
128
+ return initializer.getName().toLowerCase();
129
+ }
108
130
  }
109
- return false;
131
+ return null;
110
132
  }
111
133
  /**
112
134
  * Returns true if an array literal contains an object literal with `id: <id>`.
@@ -129,17 +151,19 @@ function hasElementWithId(array, id) {
129
151
  }
130
152
  // ─── defineConfig helpers ─────────────────────────────────────────────────────
131
153
  /**
132
- * Ensures the top-level `flags` array in a birth `defineConfig` contains the
133
- * `pending-first-certificate-issuance` flag definition.
154
+ * Ensures the top-level `flags` array in a `defineConfig` contains the
155
+ * `pending-first-certificate-issuance` flag definition. The flag's i18n
156
+ * `label.id` is namespaced per event type (e.g. `event.death.flag.…`).
134
157
  */
135
- function ensureTopLevelFlagDefinition(configArg) {
158
+ function ensureTopLevelFlagDefinition(configArg, eventType) {
159
+ const initializer = flagDefinitionInitializer(eventType);
136
160
  const flagsProp = configArg.getProperty(FLAGS_PROPERTY_NAME);
137
161
  if (flagsProp && ts_morph_1.Node.isPropertyAssignment(flagsProp)) {
138
162
  const flagsInit = flagsProp.getInitializer();
139
163
  if (flagsInit && ts_morph_1.Node.isArrayLiteralExpression(flagsInit)) {
140
164
  if (hasElementWithId(flagsInit, FLAG_ID))
141
165
  return false;
142
- flagsInit.addElement(FLAG_DEFINITION_INITIALIZER);
166
+ flagsInit.addElement(initializer);
143
167
  return true;
144
168
  }
145
169
  return false;
@@ -147,7 +171,7 @@ function ensureTopLevelFlagDefinition(configArg) {
147
171
  // No `flags` property at all — create it
148
172
  configArg.addPropertyAssignment({
149
173
  name: FLAGS_PROPERTY_NAME,
150
- initializer: `[\n ${FLAG_DEFINITION_INITIALIZER}\n]`
174
+ initializer: `[\n ${initializer}\n]`
151
175
  });
152
176
  return true;
153
177
  }
@@ -174,15 +198,15 @@ function ensureActionOperationFlag(action, operation) {
174
198
  return true;
175
199
  }
176
200
  /**
177
- * Processes a birth defineConfig object: ensures top-level flag definition,
201
+ * Processes a `defineConfig` object: ensures top-level flag definition,
178
202
  * REGISTER action flags, and PRINT_CERTIFICATE action flags.
179
203
  * Returns the number of changes made.
180
204
  */
181
- function processBirthConfig(configArg, relPath) {
205
+ function processConfig(configArg, eventType, relPath) {
182
206
  let changes = 0;
183
- if (ensureTopLevelFlagDefinition(configArg)) {
207
+ if (ensureTopLevelFlagDefinition(configArg, eventType)) {
184
208
  changes++;
185
- console.log(` [${relPath}] Added '${FLAG_ID}' to top-level flags`);
209
+ console.log(` [${relPath}] (${eventType}) Added '${FLAG_ID}' to top-level flags`);
186
210
  }
187
211
  const actionsProp = configArg.getProperty(ACTIONS_PROPERTY_NAME);
188
212
  if (!actionsProp || !ts_morph_1.Node.isPropertyAssignment(actionsProp))
@@ -197,13 +221,13 @@ function processBirthConfig(configArg, relPath) {
197
221
  if (isActionOfType(element, REGISTER_TYPE)) {
198
222
  if (ensureActionOperationFlag(element, 'add')) {
199
223
  changes++;
200
- console.log(` [${relPath}] Added '${FLAG_ID}' add-flag to REGISTER action`);
224
+ console.log(` [${relPath}] (${eventType}) Added '${FLAG_ID}' add-flag to REGISTER action`);
201
225
  }
202
226
  }
203
227
  if (isActionOfType(element, PRINT_CERTIFICATE_TYPE)) {
204
228
  if (ensureActionOperationFlag(element, 'remove')) {
205
229
  changes++;
206
- console.log(` [${relPath}] Added '${FLAG_ID}' remove-flag to PRINT_CERTIFICATE action`);
230
+ console.log(` [${relPath}] (${eventType}) Added '${FLAG_ID}' remove-flag to PRINT_CERTIFICATE action`);
207
231
  }
208
232
  }
209
233
  }
@@ -332,9 +356,10 @@ function processFile(filePath, project) {
332
356
  const configArg = args[0];
333
357
  if (!ts_morph_1.Node.isObjectLiteralExpression(configArg))
334
358
  continue;
335
- if (!isBirthConfig(configArg))
359
+ const eventType = getEventType(configArg);
360
+ if (!eventType)
336
361
  continue;
337
- totalChanges += processBirthConfig(configArg, relPath);
362
+ totalChanges += processConfig(configArg, eventType, relPath);
338
363
  }
339
364
  // ── defineWorkqueues ──────────────────────────────────────────────────────
340
365
  if (calleeName === DEFINE_WORKQUEUES_NAME) {
@@ -369,7 +394,7 @@ function processFile(filePath, project) {
369
394
  function main() {
370
395
  return __awaiter(this, void 0, void 0, function* () {
371
396
  const srcDir = path_1.default.join(process.cwd(), 'src');
372
- console.log(`Scanning for birth defineConfig and PRINT_CERTIFICATE workqueues in: ${srcDir}\n`);
397
+ console.log(`Scanning for defineConfig and PRINT_CERTIFICATE workqueues in: ${srcDir}\n`);
373
398
  const project = new ts_morph_1.Project({
374
399
  tsConfigFilePath: path_1.default.resolve(srcDir, '../tsconfig.json'),
375
400
  skipAddingFilesFromTsConfig: false
@@ -390,7 +415,7 @@ function main() {
390
415
  }
391
416
  }
392
417
  if (modifiedFiles.length === 0) {
393
- console.log('No birth configs or PRINT_CERTIFICATE workqueues found. Nothing to do.');
418
+ console.log('No event configs or PRINT_CERTIFICATE workqueues found. Nothing to do.');
394
419
  return;
395
420
  }
396
421
  console.log(`\nSaving ${modifiedFiles.length} modified file(s)...`);
@@ -1,5 +1,5 @@
1
1
  export declare const UPSTREAM_URL = "https://github.com/opencrvs/opencrvs-countryconfig.git";
2
- export declare const UPSTREAM_BRANCH = "develop";
2
+ export declare const UPSTREAM_BRANCH = "release-v2.0.0";
3
3
  /**
4
4
  * Runs a git command in the country config working directory.
5
5
  *
@@ -1 +1 @@
1
- {"version":3,"file":"checkout-upstream-files.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/checkout-upstream-files.ts"],"names":[],"mappings":"AA8CA,eAAO,MAAM,YAAY,2DACiC,CAAA;AAG1D,eAAO,MAAM,eAAe,YAAY,CAAA;AAcxC;;;;;;GAMG;AACH,wBAAgB,MAAM,CACpB,IAAI,EAAE,MAAM,EAAE,EACd,EAAE,MAAc,EAAE,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAC5C,MAAM,CAMR;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAO9C;AAED,wBAAgB,eAAe,IAAI,IAAI,CAMtC;AAID,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAuDnC;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
1
+ {"version":3,"file":"checkout-upstream-files.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/checkout-upstream-files.ts"],"names":[],"mappings":"AA8CA,eAAO,MAAM,YAAY,2DACiC,CAAA;AAE1D,eAAO,MAAM,eAAe,mBAAmB,CAAA;AAc/C;;;;;;GAMG;AACH,wBAAgB,MAAM,CACpB,IAAI,EAAE,MAAM,EAAE,EACd,EAAE,MAAc,EAAE,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAC5C,MAAM,CAMR;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAO9C;AAED,wBAAgB,eAAe,IAAI,IAAI,CAMtC;AAID,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAuDnC;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
@@ -59,8 +59,7 @@ exports.main = main;
59
59
  */
60
60
  const child_process_1 = require("child_process");
61
61
  exports.UPSTREAM_URL = 'https://github.com/opencrvs/opencrvs-countryconfig.git';
62
- // @TODO: This needs to be changed to 'release-v2.0.0' once the branch is created
63
- exports.UPSTREAM_BRANCH = 'develop';
62
+ exports.UPSTREAM_BRANCH = 'release-v2.0.0';
64
63
  // Remote name used only for the duration of this codemod. Prefixed to avoid
65
64
  // clashing with remotes the user may have (origin, upstream, etc.).
66
65
  const TEMP_REMOTE = 'opencrvs-upgrade-v19-v20-codemod';
@@ -1,3 +1,11 @@
1
- declare function main(): Promise<void>;
1
+ interface DeleteInfrastructureOptions {
2
+ /**
3
+ * Top-level entries directly under `infrastructure/` to preserve. Names
4
+ * match against the basename of each entry (file or directory). When
5
+ * empty (the default), the whole `infrastructure/` directory is deleted.
6
+ */
7
+ keep?: string[];
8
+ }
9
+ declare function main({ keep }?: DeleteInfrastructureOptions): Promise<void>;
2
10
  export { main };
3
11
  //# sourceMappingURL=delete-infrastructure-directory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"delete-infrastructure-directory.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/delete-infrastructure-directory.ts"],"names":[],"mappings":"AA4CA,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAgCnC;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
1
+ {"version":3,"file":"delete-infrastructure-directory.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/delete-infrastructure-directory.ts"],"names":[],"mappings":"AAoDA,UAAU,2BAA2B;IACnC;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,iBAAe,IAAI,CAAC,EAClB,IAAS,EACV,GAAE,2BAAgC,GAAG,OAAO,CAAC,IAAI,CAAC,CA4FlD;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
@@ -27,20 +27,28 @@ exports.main = main;
27
27
  * via Docker Swarm. In that case the `infrastructure/` directory shipped
28
28
  * with opencrvs-countryconfig is no longer needed and can be removed.
29
29
  *
30
+ * Some non-Swarm deployments still need a small subset of
31
+ * `infrastructure/` (e.g. `postgres/` and `metabase/`). Pass `keep` to
32
+ * preserve those top-level subdirectories — everything else under
33
+ * `infrastructure/` is deleted, and the kept subdirectories can then be
34
+ * refreshed from upstream by `merge-infrastructure-directory.ts` with the
35
+ * matching `subdirs` option.
36
+ *
30
37
  * Usage:
31
38
  * ts-node -r tsconfig-paths/register src/migrations/v2.0/delete-infrastructure-directory.ts
32
39
  *
33
40
  * What it does:
34
41
  * 1. Stages deletion of all tracked files under `infrastructure/` via
35
- * `git rm -rf --ignore-unmatch -- infrastructure/`. This both removes
36
- * the files from the working tree and records the deletion in the
42
+ * `git rm -rf --ignore-unmatch -- <path>`. This both removes the
43
+ * files from the working tree and records the deletion in the
37
44
  * index, so it shows up in the upgrade commit alongside the other
38
- * codemod changes.
45
+ * codemod changes. When `keep` is provided, deletion is scoped to
46
+ * the top-level entries that are NOT in `keep`.
39
47
  * 2. Cleans up any untracked files / empty directory that `git rm` left
40
- * behind, so the path is fully gone from the working tree.
48
+ * behind, so the deleted paths are fully gone from the working tree.
41
49
  *
42
50
  * Caveats:
43
- * - Destructive: any local edits to `infrastructure/` are lost. Run on a
51
+ * - Destructive: any local edits to deleted paths are lost. Run on a
44
52
  * clean working tree (or after committing your local changes).
45
53
  * - If `infrastructure/` doesn't exist, this codemod is a no-op.
46
54
  * - Requires git to be installed and the country config working directory
@@ -51,27 +59,65 @@ const path_1 = require("path");
51
59
  const checkout_upstream_files_1 = require("./checkout-upstream-files");
52
60
  const INFRASTRUCTURE_DIR = 'infrastructure';
53
61
  function main() {
54
- return __awaiter(this, void 0, void 0, function* () {
62
+ return __awaiter(this, arguments, void 0, function* ({ keep = [] } = {}) {
55
63
  const fullPath = (0, path_1.join)(process.cwd(), INFRASTRUCTURE_DIR);
56
64
  if (!(0, fs_1.existsSync)(fullPath)) {
57
65
  console.log(`'${INFRASTRUCTURE_DIR}/' not found in ${process.cwd()} — nothing to delete.`);
58
66
  return;
59
67
  }
60
- console.log(`Deleting '${INFRASTRUCTURE_DIR}/'...\n`);
61
68
  (0, checkout_upstream_files_1.assertIsGitRepo)();
62
- // `git rm -rf --ignore-unmatch` removes tracked files (working tree + index)
63
- // and is a no-op for paths with no tracked entries, so it's safe to run
64
- // even when `infrastructure/` exists only as untracked files.
65
- (0, checkout_upstream_files_1.runGit)(['rm', '-rf', '--ignore-unmatch', '--', `${INFRASTRUCTURE_DIR}/`], {
66
- silent: true
67
- });
68
- console.log(` Staged deletion of tracked files under '${INFRASTRUCTURE_DIR}/'.`);
69
- // `git rm` leaves untracked files (and any now-empty directory) on disk;
70
- // remove whatever's left so the path is fully gone.
71
- if ((0, fs_1.existsSync)(fullPath)) {
72
- (0, fs_1.rmSync)(fullPath, { recursive: true, force: true });
73
- console.log(` Removed remaining untracked files under '${INFRASTRUCTURE_DIR}/'.`);
69
+ // ─── Whole-directory delete (legacy behavior) ────────────────────────
70
+ if (keep.length === 0) {
71
+ console.log(`Deleting '${INFRASTRUCTURE_DIR}/'...\n`);
72
+ // `git rm -rf --ignore-unmatch` removes tracked files (working tree +
73
+ // index) and is a no-op for paths with no tracked entries, so it's
74
+ // safe to run even when `infrastructure/` exists only as untracked
75
+ // files.
76
+ (0, checkout_upstream_files_1.runGit)(['rm', '-rf', '--ignore-unmatch', '--', `${INFRASTRUCTURE_DIR}/`], {
77
+ silent: true
78
+ });
79
+ console.log(` Staged deletion of tracked files under '${INFRASTRUCTURE_DIR}/'.`);
80
+ // `git rm` leaves untracked files (and any now-empty directory) on
81
+ // disk; remove whatever's left so the path is fully gone.
82
+ if ((0, fs_1.existsSync)(fullPath)) {
83
+ (0, fs_1.rmSync)(fullPath, { recursive: true, force: true });
84
+ console.log(` Removed remaining untracked files under '${INFRASTRUCTURE_DIR}/'.`);
85
+ }
86
+ console.log(`\n Done. Review the staged deletion with: git diff --cached -- '${INFRASTRUCTURE_DIR}/'`);
87
+ return;
88
+ }
89
+ // ─── Selective delete: keep listed top-level entries ─────────────────
90
+ const keepSet = new Set(keep);
91
+ console.log(`Deleting contents of '${INFRASTRUCTURE_DIR}/' except: ${[...keepSet]
92
+ .map((name) => `'${name}'`)
93
+ .join(', ')}\n`);
94
+ const topLevelEntries = (0, fs_1.readdirSync)(fullPath, { withFileTypes: true });
95
+ let deleted = 0;
96
+ for (const entry of topLevelEntries) {
97
+ if (keepSet.has(entry.name)) {
98
+ console.log(` Keeping '${INFRASTRUCTURE_DIR}/${entry.name}'.`);
99
+ continue;
100
+ }
101
+ // Append a trailing slash for directories so git treats it as a tree
102
+ // pathspec (matches the recursive behavior of `git rm -rf`).
103
+ const relPath = `${INFRASTRUCTURE_DIR}/${entry.name}${entry.isDirectory() ? '/' : ''}`;
104
+ (0, checkout_upstream_files_1.runGit)(['rm', '-rf', '--ignore-unmatch', '--', relPath], { silent: true });
105
+ const fullEntryPath = (0, path_1.join)(fullPath, entry.name);
106
+ if ((0, fs_1.existsSync)(fullEntryPath)) {
107
+ (0, fs_1.rmSync)(fullEntryPath, { recursive: true, force: true });
108
+ }
109
+ console.log(` Deleted '${relPath}'.`);
110
+ deleted++;
111
+ }
112
+ // Note any requested keeps that weren't actually present, so the dev
113
+ // notices typos / missing directories.
114
+ const presentNames = new Set(topLevelEntries.map((e) => e.name));
115
+ const missingKeeps = [...keepSet].filter((name) => !presentNames.has(name));
116
+ if (missingKeeps.length > 0) {
117
+ console.warn(` [warn] Requested to keep ${missingKeeps
118
+ .map((n) => `'${n}'`)
119
+ .join(', ')} but they don't exist under '${INFRASTRUCTURE_DIR}/'.`);
74
120
  }
75
- console.log(`\n Done. Review the staged deletion with: git diff --cached -- '${INFRASTRUCTURE_DIR}/'`);
121
+ console.log(`\n Done. Deleted ${deleted} top-level entr${deleted === 1 ? 'y' : 'ies'}. Review the staged deletions with: git diff --cached -- '${INFRASTRUCTURE_DIR}/'`);
76
122
  });
77
123
  }
@@ -0,0 +1,3 @@
1
+ declare function main(): Promise<void>;
2
+ export { main };
3
+ //# sourceMappingURL=fix-accept-requested-registration-function-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix-accept-requested-registration-function-type.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/fix-accept-requested-registration-function-type.ts"],"names":[],"mappings":"AAuFA,iBAAe,IAAI,kBA6ClB;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ /*
3
+ * This Source Code Form is subject to the terms of the Mozilla Public
4
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
6
+ *
7
+ * OpenCRVS is also distributed under the terms of the Civil Registration
8
+ * & Healthcare Disclaimer located at http://opencrvs.org/license.
9
+ *
10
+ * Copyright (C) The OpenCRVS Authors located at https://github.com/opencrvs/opencrvs-core/blob/master/AUTHORS.
11
+ */
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __importDefault = (this && this.__importDefault) || function (mod) {
22
+ return (mod && mod.__esModule) ? mod : { "default": mod };
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.main = main;
26
+ /**
27
+ * Codemod: In `acceptRequestedRegistration`, update the `action` parameter type from:
28
+ * action: ActionInput
29
+ * to:
30
+ * action: Extract<ActionInput, { type?: 'REGISTER' }>
31
+ *
32
+ * What it does:
33
+ * - Scans all TypeScript files under `src/`
34
+ * - Finds `acceptRequestedRegistration` (function declaration or const assignment)
35
+ * - Rewrites only the `action` parameter when its type is exactly `ActionInput`
36
+ * - Saves modified files in-place
37
+ */
38
+ /* eslint-disable no-console */
39
+ const ts_morph_1 = require("ts-morph");
40
+ const path_1 = __importDefault(require("path"));
41
+ const TARGET_FUNCTION_NAME = 'acceptRequestedRegistration';
42
+ const ACTION_PARAMETER_NAME = 'action';
43
+ const OLD_TYPE = 'ActionInput';
44
+ const NEW_TYPE = "Extract<ActionInput, { type?: 'REGISTER' }>";
45
+ function isAcceptRequestedRegistrationParameter(parameter) {
46
+ const functionDeclaration = parameter.getFirstAncestorByKind(ts_morph_1.SyntaxKind.FunctionDeclaration);
47
+ if ((functionDeclaration === null || functionDeclaration === void 0 ? void 0 : functionDeclaration.getName()) === TARGET_FUNCTION_NAME) {
48
+ return true;
49
+ }
50
+ const arrowFunction = parameter.getFirstAncestorByKind(ts_morph_1.SyntaxKind.ArrowFunction);
51
+ const variableDeclaration = arrowFunction === null || arrowFunction === void 0 ? void 0 : arrowFunction.getFirstAncestorByKind(ts_morph_1.SyntaxKind.VariableDeclaration);
52
+ return (variableDeclaration === null || variableDeclaration === void 0 ? void 0 : variableDeclaration.getName()) === TARGET_FUNCTION_NAME;
53
+ }
54
+ function processFile(filePath, project) {
55
+ const sourceFile = project.getSourceFile(filePath);
56
+ if (!sourceFile)
57
+ return 0;
58
+ let updatedCount = 0;
59
+ for (const parameter of sourceFile.getDescendantsOfKind(ts_morph_1.SyntaxKind.Parameter)) {
60
+ if (parameter.getName() !== ACTION_PARAMETER_NAME) {
61
+ continue;
62
+ }
63
+ if (!isAcceptRequestedRegistrationParameter(parameter)) {
64
+ continue;
65
+ }
66
+ const typeNode = parameter.getTypeNode();
67
+ if (!typeNode || typeNode.getText() !== OLD_TYPE) {
68
+ continue;
69
+ }
70
+ parameter.setType(NEW_TYPE);
71
+ updatedCount++;
72
+ console.log(` [${path_1.default.relative(process.cwd(), filePath)}] Updated '${ACTION_PARAMETER_NAME}' in ${TARGET_FUNCTION_NAME} to ${NEW_TYPE}`);
73
+ }
74
+ return updatedCount;
75
+ }
76
+ function main() {
77
+ return __awaiter(this, void 0, void 0, function* () {
78
+ const srcDir = path_1.default.join(process.cwd(), 'src');
79
+ console.log(`Scanning for ${TARGET_FUNCTION_NAME} in: ${srcDir}\n`);
80
+ const project = new ts_morph_1.Project({
81
+ tsConfigFilePath: path_1.default.resolve(srcDir, '../tsconfig.json'),
82
+ skipAddingFilesFromTsConfig: false
83
+ });
84
+ const sourceFiles = project.getSourceFiles().filter((sf) => {
85
+ const filePath = sf.getFilePath();
86
+ return filePath.includes('/src/') && !filePath.includes('/node_modules/');
87
+ });
88
+ let totalUpdated = 0;
89
+ const modifiedFiles = [];
90
+ for (const sourceFile of sourceFiles) {
91
+ const filePath = sourceFile.getFilePath();
92
+ const updated = processFile(filePath, project);
93
+ if (updated > 0) {
94
+ totalUpdated += updated;
95
+ modifiedFiles.push(filePath);
96
+ }
97
+ }
98
+ if (modifiedFiles.length === 0) {
99
+ console.log(`No '${ACTION_PARAMETER_NAME}: ${OLD_TYPE}' parameter in ${TARGET_FUNCTION_NAME} found. Nothing to do.`);
100
+ return;
101
+ }
102
+ console.log(`\nSaving ${modifiedFiles.length} modified file(s)...`);
103
+ for (const filePath of modifiedFiles) {
104
+ const sourceFile = project.getSourceFileOrThrow(filePath);
105
+ yield sourceFile.save();
106
+ console.log(` Saved: ${path_1.default.relative(process.cwd(), filePath)}`);
107
+ }
108
+ console.log(`\nDone. Updated ${totalUpdated} parameter type annotation(s) in ${TARGET_FUNCTION_NAME}.`);
109
+ });
110
+ }
@@ -3,9 +3,11 @@
3
3
  * directory.
4
4
  *
5
5
  * @param dockerSwarm - When true, the local `infrastructure/` directory is
6
- * merged with upstream changes (Docker Swarm deployments still need it).
7
- * When false (the default), `infrastructure/` is deleted entirely, since
8
- * non-Swarm deployments no longer ship it.
6
+ * merged with upstream changes in its entirety (Docker Swarm deployments
7
+ * still need it all). When false (the default), everything under
8
+ * `infrastructure/` is deleted EXCEPT the subdirectories listed in
9
+ * `NON_SWARM_INFRA_SUBDIRS`, and those preserved subdirectories are then
10
+ * merged with upstream.
9
11
  */
10
12
  export declare function runUpgrade(dockerSwarm: boolean): Promise<void>;
11
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/index.ts"],"names":[],"mappings":"AAqCA;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAAC,WAAW,EAAE,OAAO,iBA+BpD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/index.ts"],"names":[],"mappings":"AA8CA;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,CAAC,WAAW,EAAE,OAAO,iBAiCpD"}