@opencrvs/toolkit 2.0.0-rc.fc7f7fc → 2.0.0-rc.fef9d21
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/cli.js +1383 -142
- package/dist/commons/api/router.d.ts +42 -63
- package/dist/migrations/v2.0/add-birth-certificate-issuance-flag.d.ts.map +1 -1
- package/dist/migrations/v2.0/add-birth-certificate-issuance-flag.js +3 -4
- package/dist/migrations/v2.0/add-resend-invite-notification.d.ts +3 -0
- package/dist/migrations/v2.0/add-resend-invite-notification.d.ts.map +1 -0
- package/dist/migrations/v2.0/add-resend-invite-notification.js +373 -0
- package/dist/migrations/v2.0/checkout-upstream-files.d.ts +19 -0
- package/dist/migrations/v2.0/checkout-upstream-files.d.ts.map +1 -1
- package/dist/migrations/v2.0/checkout-upstream-files.js +17 -13
- package/dist/migrations/v2.0/convert-config-files-to-ts.d.ts.map +1 -1
- package/dist/migrations/v2.0/convert-config-files-to-ts.js +4 -5
- package/dist/migrations/v2.0/convert-paragraph-to-heading.d.ts.map +1 -1
- package/dist/migrations/v2.0/convert-paragraph-to-heading.js +4 -5
- package/dist/migrations/v2.0/create-events-index.d.ts.map +1 -1
- package/dist/migrations/v2.0/create-events-index.js +1 -2
- package/dist/migrations/v2.0/delete-infrastructure-directory.d.ts +3 -0
- package/dist/migrations/v2.0/delete-infrastructure-directory.d.ts.map +1 -0
- package/dist/migrations/v2.0/delete-infrastructure-directory.js +77 -0
- package/dist/migrations/v2.0/index.d.ts +8 -4
- package/dist/migrations/v2.0/index.d.ts.map +1 -1
- package/dist/migrations/v2.0/index.js +1351 -139
- package/dist/migrations/v2.0/make-built-in-validate-actions-custom.d.ts.map +1 -1
- package/dist/migrations/v2.0/make-built-in-validate-actions-custom.js +5 -6
- package/dist/migrations/v2.0/merge-infrastructure-directory.d.ts +3 -0
- package/dist/migrations/v2.0/merge-infrastructure-directory.d.ts.map +1 -0
- package/dist/migrations/v2.0/merge-infrastructure-directory.js +221 -0
- package/dist/migrations/v2.0/migrate-application-config-url.d.ts +3 -0
- package/dist/migrations/v2.0/migrate-application-config-url.d.ts.map +1 -0
- package/dist/migrations/v2.0/migrate-application-config-url.js +342 -0
- package/dist/migrations/v2.0/migrate-scopes.d.ts.map +1 -1
- package/dist/migrations/v2.0/migrate-scopes.js +6 -7
- package/dist/migrations/v2.0/migrate-validated-workqueue-status-to-flag.d.ts.map +1 -1
- package/dist/migrations/v2.0/migrate-validated-workqueue-status-to-flag.js +3 -4
- package/dist/migrations/v2.0/migrate-workqueue-configs.d.ts.map +1 -1
- package/dist/migrations/v2.0/migrate-workqueue-configs.js +3 -4
- package/dist/migrations/v2.0/remove-delete-actions.d.ts.map +1 -1
- package/dist/migrations/v2.0/remove-delete-actions.js +3 -4
- package/dist/migrations/v2.0/remove-demo-scope.d.ts.map +1 -1
- package/dist/migrations/v2.0/remove-demo-scope.js +2 -3
- package/dist/migrations/v2.0/remove-deprecated-imports.d.ts.map +1 -1
- package/dist/migrations/v2.0/remove-deprecated-imports.js +3 -4
- package/dist/migrations/v2.0/remove-fhir-url-helpers.d.ts +3 -0
- package/dist/migrations/v2.0/remove-fhir-url-helpers.d.ts.map +1 -0
- package/dist/migrations/v2.0/remove-fhir-url-helpers.js +163 -0
- package/dist/migrations/v2.0/remove-hearth-migrations.d.ts.map +1 -1
- package/dist/migrations/v2.0/remove-hearth-migrations.js +1 -2
- package/dist/migrations/v2.0/remove-old-statistics-service.d.ts +3 -0
- package/dist/migrations/v2.0/remove-old-statistics-service.d.ts.map +1 -0
- package/dist/migrations/v2.0/remove-old-statistics-service.js +356 -0
- package/dist/migrations/v2.0/remove-pending-certification-flag.d.ts.map +1 -1
- package/dist/migrations/v2.0/remove-pending-certification-flag.js +3 -4
- package/dist/migrations/v2.0/remove-review-from-register-action.d.ts.map +1 -1
- package/dist/migrations/v2.0/remove-review-from-register-action.js +3 -4
- package/dist/migrations/v2.0/remove-unused-environment-variables.d.ts +3 -0
- package/dist/migrations/v2.0/remove-unused-environment-variables.d.ts.map +1 -0
- package/dist/migrations/v2.0/remove-unused-environment-variables.js +186 -0
- package/dist/migrations/v2.0/rename-api-paths.d.ts.map +1 -1
- package/dist/migrations/v2.0/rename-api-paths.js +3 -4
- package/dist/migrations/v2.0/rename-location-parent-id.d.ts.map +1 -1
- package/dist/migrations/v2.0/rename-location-parent-id.js +3 -4
- package/dist/migrations/v2.0/simplify-analytics-precalculations.d.ts.map +1 -1
- package/dist/migrations/v2.0/simplify-analytics-precalculations.js +1 -2
- package/dist/migrations/v2.0/update-package-json.d.ts +3 -0
- package/dist/migrations/v2.0/update-package-json.d.ts.map +1 -0
- package/dist/migrations/v2.0/update-package-json.js +105 -0
- package/opencrvs-toolkit-2.0.0-rc.fef9d21.tgz +0 -0
- package/package.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/opencrvs-toolkit-2.0.0-rc.fc7f7fc.tgz +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"make-built-in-validate-actions-custom.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/make-built-in-validate-actions-custom.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"make-built-in-validate-actions-custom.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/make-built-in-validate-actions-custom.ts"],"names":[],"mappings":"AA2WA,iBAAe,IAAI,kBAiDlB;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
|
|
@@ -45,7 +45,6 @@ exports.main = main;
|
|
|
45
45
|
*/
|
|
46
46
|
const ts_morph_1 = require("ts-morph");
|
|
47
47
|
const path_1 = __importDefault(require("path"));
|
|
48
|
-
const _1 = require(".");
|
|
49
48
|
const TOOLKIT_EVENTS_MODULE = '@opencrvs/toolkit/events';
|
|
50
49
|
const REQUIRED_SYMBOLS = [
|
|
51
50
|
'ConditionalType',
|
|
@@ -263,7 +262,7 @@ function processFile(filePath, project) {
|
|
|
263
262
|
// Resolve the root event type for use in the auditHistoryLabel id
|
|
264
263
|
const eventType = resolveEventType(configArg);
|
|
265
264
|
if (!eventType) {
|
|
266
|
-
console.warn(` [${path_1.default.relative(
|
|
265
|
+
console.warn(` [${path_1.default.relative(process.cwd(), configArg.getSourceFile().getFilePath())}] Could not resolve root 'type' from defineConfig — skipping auditHistoryLabel id generation`);
|
|
267
266
|
}
|
|
268
267
|
// Iterate over every element in the `actions` array
|
|
269
268
|
let fileNeedsImports = false;
|
|
@@ -276,7 +275,7 @@ function processFile(filePath, project) {
|
|
|
276
275
|
transformedCount++;
|
|
277
276
|
fileNeedsImports = true;
|
|
278
277
|
configHadValidateAction = true;
|
|
279
|
-
console.log(` [${path_1.default.relative(
|
|
278
|
+
console.log(` [${path_1.default.relative(process.cwd(), filePath)}] Transformed VALIDATE action to CUSTOM with customActionType: '${VALIDATE_DECLARATION_VALUE}'`);
|
|
280
279
|
}
|
|
281
280
|
}
|
|
282
281
|
// Add top-level flags array to the config object if a VALIDATE action was found
|
|
@@ -296,7 +295,7 @@ function processFile(filePath, project) {
|
|
|
296
295
|
}
|
|
297
296
|
]`
|
|
298
297
|
});
|
|
299
|
-
console.log(` [${path_1.default.relative(
|
|
298
|
+
console.log(` [${path_1.default.relative(process.cwd(), filePath)}] Added top-level 'flags' array to defineConfig`);
|
|
300
299
|
}
|
|
301
300
|
if (fileNeedsImports) {
|
|
302
301
|
ensureImports(sourceFile);
|
|
@@ -306,7 +305,7 @@ function processFile(filePath, project) {
|
|
|
306
305
|
}
|
|
307
306
|
function main() {
|
|
308
307
|
return __awaiter(this, void 0, void 0, function* () {
|
|
309
|
-
const srcDir = path_1.default.join(
|
|
308
|
+
const srcDir = path_1.default.join(process.cwd(), 'src');
|
|
310
309
|
console.log(`Scanning for defineConfig calls in: ${srcDir}\n`);
|
|
311
310
|
const project = new ts_morph_1.Project({
|
|
312
311
|
tsConfigFilePath: path_1.default.resolve(srcDir, '../tsconfig.json'),
|
|
@@ -337,7 +336,7 @@ function main() {
|
|
|
337
336
|
for (const filePath of modifiedFiles) {
|
|
338
337
|
const sourceFile = project.getSourceFileOrThrow(filePath);
|
|
339
338
|
yield sourceFile.save();
|
|
340
|
-
console.log(` Saved: ${path_1.default.relative(
|
|
339
|
+
console.log(` Saved: ${path_1.default.relative(process.cwd(), filePath)}`);
|
|
341
340
|
}
|
|
342
341
|
console.log(`\nDone. Transformed ${totalTransformed} VALIDATE action(s) to CUSTOM with customActionType: '${VALIDATE_DECLARATION_VALUE}'.`);
|
|
343
342
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-infrastructure-directory.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/merge-infrastructure-directory.ts"],"names":[],"mappings":"AAsHA,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAkInC;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
|
|
@@ -0,0 +1,221 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.main = main;
|
|
23
|
+
/**
|
|
24
|
+
* Codemod: Merge upstream changes into the local `infrastructure/` directory
|
|
25
|
+
* from opencrvs/opencrvs-countryconfig.
|
|
26
|
+
*
|
|
27
|
+
* Usage:
|
|
28
|
+
* ts-node -r tsconfig-paths/register src/migrations/v2.0/merge-infrastructure-directory.ts
|
|
29
|
+
*
|
|
30
|
+
* What it does:
|
|
31
|
+
* 1. Registers a temporary git remote that points at the canonical
|
|
32
|
+
* opencrvs-countryconfig repository and fetches both:
|
|
33
|
+
* - the upstream "theirs" branch (v2.0) → `UPSTREAM_BRANCH`
|
|
34
|
+
* - the synthetic merge-base branch (latest 1.9 release line)
|
|
35
|
+
* → `BASE_BRANCH`
|
|
36
|
+
* 2. For every file under `infrastructure/` on upstream "theirs", performs
|
|
37
|
+
* a file-scoped 3-way merge:
|
|
38
|
+
* - new file on upstream → checked out and staged
|
|
39
|
+
* - existing file → 3-way merged in place via `git merge-file`,
|
|
40
|
+
* using the BASE_BRANCH version of the file
|
|
41
|
+
* as the ancestor (or an empty file if the
|
|
42
|
+
* base doesn't have it)
|
|
43
|
+
* Files local to the country config that don't exist on upstream are
|
|
44
|
+
* left untouched.
|
|
45
|
+
* 3. Cleanly merged files are staged. Files with conflicts are left in the
|
|
46
|
+
* working tree with standard <<<<<<< / ======= / >>>>>>> markers and
|
|
47
|
+
* MUST be resolved manually by the developer.
|
|
48
|
+
* 4. Removes the temporary remote in all cases (success, failure, or
|
|
49
|
+
* unexpected error) via a `finally` block.
|
|
50
|
+
*
|
|
51
|
+
* Why a content-based synthetic merge-base instead of `git merge-base`:
|
|
52
|
+
* - Country config repos rarely share git history with
|
|
53
|
+
* opencrvs-countryconfig (squashed forks, template-cloned repos, etc.),
|
|
54
|
+
* so `git merge-base HEAD upstream/develop` typically returns nothing.
|
|
55
|
+
* - With no merge-base, a 3-way merge degenerates to a 2-way diff against
|
|
56
|
+
* an empty file — every line that differs becomes a conflict.
|
|
57
|
+
* - `release-v1.9` is the latest 1.9.x release line on upstream and is a
|
|
58
|
+
* near-perfect representation of "what `infrastructure/` looked like
|
|
59
|
+
* before v2.0", regardless of whether the fork's git history reaches it.
|
|
60
|
+
* - For files the country config never modified relative to that baseline,
|
|
61
|
+
* `git merge-file` resolves cleanly to upstream's v2.0 version. Conflicts
|
|
62
|
+
* are produced only where local edits genuinely overlap with v1.9 → v2.0
|
|
63
|
+
* upstream edits — which is what the developer needs to review anyway.
|
|
64
|
+
*
|
|
65
|
+
* Why per-file merge instead of a real `git merge`:
|
|
66
|
+
* - Limits the blast radius to `infrastructure/` only — no other paths
|
|
67
|
+
* are touched.
|
|
68
|
+
* - Doesn't put the repository into an in-progress merge state
|
|
69
|
+
* (no MERGE_HEAD), so subsequent codemods/commands behave normally.
|
|
70
|
+
* - Works regardless of whether the local repo shares history with
|
|
71
|
+
* opencrvs-countryconfig.
|
|
72
|
+
*
|
|
73
|
+
* Caveats:
|
|
74
|
+
* - Local edits to merged files may be overwritten where they overlap
|
|
75
|
+
* with upstream changes. Run on a clean working tree.
|
|
76
|
+
* - Requires git to be installed and network access to github.com.
|
|
77
|
+
* - Requires the country config working directory to be a git repo.
|
|
78
|
+
* - Binary files in `infrastructure/` are not merged textually; if both
|
|
79
|
+
* sides changed a binary file, the result will be invalid and a warning
|
|
80
|
+
* is printed.
|
|
81
|
+
* - Forks that are on a much older 1.9.x and never merged later 1.9 patches
|
|
82
|
+
* may see a few extra conflicts on files where 1.9.x → release-v1.9
|
|
83
|
+
* patches and v1.9 → v2.0 changes textually overlap.
|
|
84
|
+
*/
|
|
85
|
+
const child_process_1 = require("child_process");
|
|
86
|
+
const fs_1 = require("fs");
|
|
87
|
+
const os_1 = require("os");
|
|
88
|
+
const path_1 = require("path");
|
|
89
|
+
const checkout_upstream_files_1 = require("./checkout-upstream-files");
|
|
90
|
+
// Distinct from the remote used by `checkout-upstream-files` so that a stale
|
|
91
|
+
// remote left behind by an aborted run of one codemod doesn't trip up the
|
|
92
|
+
// other.
|
|
93
|
+
const TEMP_REMOTE = 'opencrvs-upgrade-v19-v20-codemod-merge-infra';
|
|
94
|
+
const INFRASTRUCTURE_DIR = 'infrastructure';
|
|
95
|
+
// Synthetic merge-base: the tip of upstream's latest 1.9.x release line.
|
|
96
|
+
// We use this branch's content as the "common ancestor" for every file,
|
|
97
|
+
// since most country forks don't share git history with upstream.
|
|
98
|
+
const BASE_BRANCH = 'release-v1.9';
|
|
99
|
+
/**
|
|
100
|
+
* Reads `git show <ref>:<path>` as a Uint8Array (binary-safe).
|
|
101
|
+
* Returns `null` if the path doesn't exist at that ref.
|
|
102
|
+
*/
|
|
103
|
+
function gitShowBytes(ref, path) {
|
|
104
|
+
try {
|
|
105
|
+
const buf = (0, child_process_1.execFileSync)('git', ['show', `${ref}:${path}`], {
|
|
106
|
+
cwd: process.cwd(),
|
|
107
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
108
|
+
});
|
|
109
|
+
// Return a plain Uint8Array view to satisfy strict typings of `fs`
|
|
110
|
+
// (which want `ArrayBufferView`, not Node's `Buffer` subtype).
|
|
111
|
+
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
112
|
+
}
|
|
113
|
+
catch (_a) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// ─── Entry point ─────────────────────────────────────────────────────────────
|
|
118
|
+
function main() {
|
|
119
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
120
|
+
console.log(`Merging '${INFRASTRUCTURE_DIR}/' from ${checkout_upstream_files_1.UPSTREAM_URL}@${checkout_upstream_files_1.UPSTREAM_BRANCH} (base: ${BASE_BRANCH})...\n`);
|
|
121
|
+
(0, checkout_upstream_files_1.assertIsGitRepo)();
|
|
122
|
+
// Best-effort cleanup of a stale temp remote from a previous aborted run.
|
|
123
|
+
(0, checkout_upstream_files_1.tryGit)(['remote', 'remove', TEMP_REMOTE]);
|
|
124
|
+
try {
|
|
125
|
+
console.log(` Adding temporary remote '${TEMP_REMOTE}' → ${checkout_upstream_files_1.UPSTREAM_URL}`);
|
|
126
|
+
(0, checkout_upstream_files_1.runGit)(['remote', 'add', TEMP_REMOTE, checkout_upstream_files_1.UPSTREAM_URL], { silent: true });
|
|
127
|
+
// Fetch both branches at depth=1 — we only need their tip contents,
|
|
128
|
+
// not their history (the merge is content-based, not history-based).
|
|
129
|
+
console.log(` Fetching ${TEMP_REMOTE}/{${checkout_upstream_files_1.UPSTREAM_BRANCH},${BASE_BRANCH}} (depth 1)...`);
|
|
130
|
+
(0, checkout_upstream_files_1.runGit)(['fetch', '--depth=1', TEMP_REMOTE, checkout_upstream_files_1.UPSTREAM_BRANCH, BASE_BRANCH]);
|
|
131
|
+
const ref = `${TEMP_REMOTE}/${checkout_upstream_files_1.UPSTREAM_BRANCH}`;
|
|
132
|
+
const baseRef = `${TEMP_REMOTE}/${BASE_BRANCH}`;
|
|
133
|
+
// -z gives NUL-separated paths so filenames with spaces or newlines
|
|
134
|
+
// survive the round-trip.
|
|
135
|
+
const upstreamFiles = (0, checkout_upstream_files_1.runGit)([
|
|
136
|
+
'ls-tree',
|
|
137
|
+
'-r',
|
|
138
|
+
'--name-only',
|
|
139
|
+
'-z',
|
|
140
|
+
ref,
|
|
141
|
+
'--',
|
|
142
|
+
`${INFRASTRUCTURE_DIR}/`
|
|
143
|
+
], { silent: true })
|
|
144
|
+
.split('\0')
|
|
145
|
+
.filter(Boolean);
|
|
146
|
+
if (upstreamFiles.length === 0) {
|
|
147
|
+
console.log(` No files found under '${INFRASTRUCTURE_DIR}/' on ${ref}. Nothing to merge.`);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const tmpDir = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'opencrvs-merge-infra-'));
|
|
151
|
+
const baseTmp = (0, path_1.join)(tmpDir, 'base');
|
|
152
|
+
const theirsTmp = (0, path_1.join)(tmpDir, 'theirs');
|
|
153
|
+
let added = 0;
|
|
154
|
+
let merged = 0;
|
|
155
|
+
const conflictedFiles = [];
|
|
156
|
+
for (const file of upstreamFiles) {
|
|
157
|
+
const fullPath = (0, path_1.join)(process.cwd(), file);
|
|
158
|
+
if (!(0, fs_1.existsSync)(fullPath)) {
|
|
159
|
+
// New upstream file — `git checkout` handles binary correctly and
|
|
160
|
+
// stages the result, matching the UX of `checkout-upstream-files`.
|
|
161
|
+
if ((0, checkout_upstream_files_1.tryGit)(['checkout', ref, '--', file])) {
|
|
162
|
+
console.log(` + ${file} (new from upstream)`);
|
|
163
|
+
added++;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
console.warn(` [warn] failed to add new file ${file}`);
|
|
167
|
+
}
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const theirContents = gitShowBytes(ref, file);
|
|
171
|
+
if (theirContents === null) {
|
|
172
|
+
// Shouldn't happen — `ls-tree` just told us the file is there.
|
|
173
|
+
console.warn(` [warn] could not read ${file} from ${ref} — skipping.`);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
(0, fs_1.writeFileSync)(theirsTmp, theirContents);
|
|
177
|
+
// Pull the base version from upstream's latest 1.9 release line. If
|
|
178
|
+
// the file didn't exist there yet (added in v2.0), fall back to an
|
|
179
|
+
// empty base — `git merge-file` will then treat any local content as
|
|
180
|
+
// a local addition.
|
|
181
|
+
const baseContents = gitShowBytes(baseRef, file);
|
|
182
|
+
(0, fs_1.writeFileSync)(baseTmp, baseContents !== null && baseContents !== void 0 ? baseContents : new Uint8Array(0));
|
|
183
|
+
// `git merge-file` does an in-place 3-way merge. Exit codes:
|
|
184
|
+
// 0 → clean merge
|
|
185
|
+
// 1..N → that many conflicts; markers written into the file
|
|
186
|
+
// <0/127 → error (e.g. binary file rejected)
|
|
187
|
+
try {
|
|
188
|
+
(0, child_process_1.execFileSync)('git', ['merge-file', fullPath, baseTmp, theirsTmp], {
|
|
189
|
+
cwd: process.cwd(),
|
|
190
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
191
|
+
});
|
|
192
|
+
(0, checkout_upstream_files_1.runGit)(['add', '--', file], { silent: true });
|
|
193
|
+
merged++;
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
const status = err.status;
|
|
197
|
+
if (typeof status === 'number' && status > 0) {
|
|
198
|
+
conflictedFiles.push(file);
|
|
199
|
+
console.warn(` ! ${file} (${status} conflict${status > 1 ? 's' : ''})`);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
conflictedFiles.push(file);
|
|
203
|
+
console.warn(` [warn] merge failed for ${file} (likely binary or unreadable) — left untouched.`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
console.log(`\n Done. ${added} added, ${merged} merged cleanly, ${conflictedFiles.length} with conflicts.`);
|
|
208
|
+
if (conflictedFiles.length > 0) {
|
|
209
|
+
console.warn(`\n NOTE: ${conflictedFiles.length} file(s) under '${INFRASTRUCTURE_DIR}/' have merge conflicts that you must resolve manually.\n` +
|
|
210
|
+
` Look for the standard conflict markers (<<<<<<<, =======, >>>>>>>) in:\n` +
|
|
211
|
+
conflictedFiles.map((f) => ` - ${f}`).join('\n') +
|
|
212
|
+
`\n After resolving, stage the fixes with: git add ${INFRASTRUCTURE_DIR}/`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
finally {
|
|
216
|
+
if ((0, checkout_upstream_files_1.tryGit)(['remote', 'remove', TEMP_REMOTE])) {
|
|
217
|
+
console.log(` Removed temporary remote '${TEMP_REMOTE}'.`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate-application-config-url.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/migrate-application-config-url.ts"],"names":[],"mappings":"AAwUA,iBAAe,IAAI,kBAqElB;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
|
|
@@ -0,0 +1,342 @@
|
|
|
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: Replace usages of the legacy `APPLICATION_CONFIG_URL` env-derived
|
|
28
|
+
* constant with direct usage of the v2.0 `applicationConfig` object.
|
|
29
|
+
*
|
|
30
|
+
* Background:
|
|
31
|
+
* In v1.9 country configs read application configuration over HTTP from
|
|
32
|
+
* the config service via `APPLICATION_CONFIG_URL`. In v2.0 the config is
|
|
33
|
+
* defined statically in `src/api/application/application-config.ts` (as
|
|
34
|
+
* `applicationConfig`) and consumed by import.
|
|
35
|
+
*
|
|
36
|
+
* What it does (per source file under `src/`):
|
|
37
|
+
* 1. If the file imports `APPLICATION_CONFIG_URL` (from any module), the
|
|
38
|
+
* named import is removed; if that leaves the import declaration empty,
|
|
39
|
+
* the whole declaration is removed.
|
|
40
|
+
* 2. An import of `applicationConfig` from
|
|
41
|
+
* `@countryconfig/api/application/application-config` is added
|
|
42
|
+
* (idempotent — re-uses an existing import declaration if one exists).
|
|
43
|
+
* 3. Block-bodied functions whose body references *both*
|
|
44
|
+
* `APPLICATION_CONFIG_URL` *and* a `fetch(...)` call are recognised
|
|
45
|
+
* as "config-fetcher" functions. Their entire body is replaced with
|
|
46
|
+
* `return applicationConfig` — eliminating the URL construction,
|
|
47
|
+
* `fetch`, JSON parsing, and unwrapping of `.config`. Callers
|
|
48
|
+
* (`await getApplicationConfig()` etc.) keep working because async
|
|
49
|
+
* functions still wrap the return value in a `Promise`.
|
|
50
|
+
* 4. Any remaining bare identifier references to `APPLICATION_CONFIG_URL`
|
|
51
|
+
* are renamed to `applicationConfig`. Property names (e.g.
|
|
52
|
+
* `obj.APPLICATION_CONFIG_URL` or `{ APPLICATION_CONFIG_URL: x }`)
|
|
53
|
+
* are left alone.
|
|
54
|
+
*
|
|
55
|
+
* Caveats:
|
|
56
|
+
* - Wholesale body replacement of config-fetcher functions destroys any
|
|
57
|
+
* custom logic the country had inlined there (error handling, derived
|
|
58
|
+
* fields, etc.). Each rewrite is logged so the developer can review
|
|
59
|
+
* the diff and re-apply customisations on top of `applicationConfig`.
|
|
60
|
+
* - The shape of v2.0 `applicationConfig` is not identical to the v1.9
|
|
61
|
+
* `IApplicationConfigResponse.config` — callers that destructured
|
|
62
|
+
* v1.9-only fields will produce TypeScript errors and need manual
|
|
63
|
+
* review.
|
|
64
|
+
* - Files that have a local declaration named `applicationConfig` are
|
|
65
|
+
* skipped to avoid a name collision; a warning is logged so the
|
|
66
|
+
* developer can resolve it manually.
|
|
67
|
+
* - Files that reference `APPLICATION_CONFIG_URL` *without* importing it
|
|
68
|
+
* (e.g. as a local variable) are skipped — we only rewrite imported
|
|
69
|
+
* usages.
|
|
70
|
+
* - Concise-body arrow functions (`() => fetch(...)`) are not
|
|
71
|
+
* body-rewritten — only their identifier is renamed in step 4. If a
|
|
72
|
+
* country happens to inline the fetch in concise form, the result
|
|
73
|
+
* will need manual cleanup.
|
|
74
|
+
*/
|
|
75
|
+
const path_1 = __importDefault(require("path"));
|
|
76
|
+
const ts_morph_1 = require("ts-morph");
|
|
77
|
+
const TARGET_IDENTIFIER = 'APPLICATION_CONFIG_URL';
|
|
78
|
+
const REPLACEMENT_IDENTIFIER = 'applicationConfig';
|
|
79
|
+
const REPLACEMENT_MODULE = '@countryconfig/api/application/application-config';
|
|
80
|
+
/**
|
|
81
|
+
* Function-like syntax kinds whose `body` we know how to replace via
|
|
82
|
+
* `setBodyText` (i.e. block-bodied callables).
|
|
83
|
+
*/
|
|
84
|
+
const FUNCTION_LIKE_KINDS = [
|
|
85
|
+
ts_morph_1.SyntaxKind.FunctionDeclaration,
|
|
86
|
+
ts_morph_1.SyntaxKind.FunctionExpression,
|
|
87
|
+
ts_morph_1.SyntaxKind.ArrowFunction,
|
|
88
|
+
ts_morph_1.SyntaxKind.MethodDeclaration
|
|
89
|
+
];
|
|
90
|
+
/**
|
|
91
|
+
* Returns the name of the function-like node for logging purposes.
|
|
92
|
+
* Falls back to `<anonymous>` when nothing useful can be derived.
|
|
93
|
+
*/
|
|
94
|
+
function describeFunction(node) {
|
|
95
|
+
var _a, _b, _c;
|
|
96
|
+
if (ts_morph_1.Node.isFunctionDeclaration(node) || ts_morph_1.Node.isMethodDeclaration(node)) {
|
|
97
|
+
return (_a = node.getName()) !== null && _a !== void 0 ? _a : '<anonymous>';
|
|
98
|
+
}
|
|
99
|
+
// FunctionExpression / ArrowFunction: try to pick up the assignment target.
|
|
100
|
+
const parent = node.getParent();
|
|
101
|
+
if (parent && ts_morph_1.Node.isVariableDeclaration(parent)) {
|
|
102
|
+
return parent.getName();
|
|
103
|
+
}
|
|
104
|
+
if (parent && ts_morph_1.Node.isPropertyAssignment(parent)) {
|
|
105
|
+
return parent.getName();
|
|
106
|
+
}
|
|
107
|
+
if (ts_morph_1.Node.isFunctionExpression(node) &&
|
|
108
|
+
node.getNameNode() !== undefined) {
|
|
109
|
+
return (_c = (_b = node.getNameNode()) === null || _b === void 0 ? void 0 : _b.getText()) !== null && _c !== void 0 ? _c : '<anonymous>';
|
|
110
|
+
}
|
|
111
|
+
return '<anonymous>';
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* True when the node has a block body that we can safely replace via
|
|
115
|
+
* `setBodyText` (excludes concise-body arrow functions like `() => 1`).
|
|
116
|
+
*/
|
|
117
|
+
function hasBlockBody(node) {
|
|
118
|
+
if (ts_morph_1.Node.isFunctionDeclaration(node) ||
|
|
119
|
+
ts_morph_1.Node.isFunctionExpression(node) ||
|
|
120
|
+
ts_morph_1.Node.isMethodDeclaration(node)) {
|
|
121
|
+
return node.getBody() !== undefined;
|
|
122
|
+
}
|
|
123
|
+
if (ts_morph_1.Node.isArrowFunction(node)) {
|
|
124
|
+
return node.getBody().getKind() === ts_morph_1.SyntaxKind.Block;
|
|
125
|
+
}
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* True when the node's body references `APPLICATION_CONFIG_URL` AND
|
|
130
|
+
* contains at least one `fetch(...)` call — the "config-fetcher" signature.
|
|
131
|
+
*/
|
|
132
|
+
function isConfigFetcher(node) {
|
|
133
|
+
let referencesTarget = false;
|
|
134
|
+
let callsFetch = false;
|
|
135
|
+
for (const id of node.getDescendantsOfKind(ts_morph_1.SyntaxKind.Identifier)) {
|
|
136
|
+
const text = id.getText();
|
|
137
|
+
if (!referencesTarget && text === TARGET_IDENTIFIER)
|
|
138
|
+
referencesTarget = true;
|
|
139
|
+
if (!callsFetch && text === 'fetch') {
|
|
140
|
+
// Only count `fetch(` calls, not bare references like
|
|
141
|
+
// `const f = fetch` (rare, but pedantic).
|
|
142
|
+
const parent = id.getParent();
|
|
143
|
+
if (ts_morph_1.Node.isCallExpression(parent) &&
|
|
144
|
+
parent.getExpression() === id) {
|
|
145
|
+
callsFetch = true;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (referencesTarget && callsFetch)
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
function processFile(sourceFile) {
|
|
154
|
+
const importsWithTarget = sourceFile
|
|
155
|
+
.getImportDeclarations()
|
|
156
|
+
.filter((decl) => decl.getNamedImports().some((ni) => ni.getName() === TARGET_IDENTIFIER));
|
|
157
|
+
if (importsWithTarget.length === 0) {
|
|
158
|
+
return { changed: false, rewrittenFunctions: [], renamedReferences: 0 };
|
|
159
|
+
}
|
|
160
|
+
// Bail out if a same-named local would collide with the new identifier.
|
|
161
|
+
// Imported `applicationConfig` doesn't count as a local declaration.
|
|
162
|
+
const collidingLocals = sourceFile
|
|
163
|
+
.getDescendantsOfKind(ts_morph_1.SyntaxKind.Identifier)
|
|
164
|
+
.filter((id) => id.getText() === REPLACEMENT_IDENTIFIER)
|
|
165
|
+
.filter((id) => {
|
|
166
|
+
const parent = id.getParent();
|
|
167
|
+
const kind = parent.getKind();
|
|
168
|
+
return (kind === ts_morph_1.SyntaxKind.VariableDeclaration ||
|
|
169
|
+
kind === ts_morph_1.SyntaxKind.FunctionDeclaration ||
|
|
170
|
+
kind === ts_morph_1.SyntaxKind.ClassDeclaration ||
|
|
171
|
+
kind === ts_morph_1.SyntaxKind.Parameter);
|
|
172
|
+
});
|
|
173
|
+
if (collidingLocals.length > 0) {
|
|
174
|
+
return {
|
|
175
|
+
changed: false,
|
|
176
|
+
rewrittenFunctions: [],
|
|
177
|
+
renamedReferences: 0,
|
|
178
|
+
skippedReason: `local declaration named '${REPLACEMENT_IDENTIFIER}' would collide`
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
// ─── 1. Rewrite "config-fetcher" function bodies ───────────────────────
|
|
182
|
+
// We only replace block-bodied functions that reference both
|
|
183
|
+
// APPLICATION_CONFIG_URL and `fetch(...)`. The bodies are replaced with
|
|
184
|
+
// `return applicationConfig`, which works for both sync and async
|
|
185
|
+
// functions (the latter automatically wraps the value in a Promise).
|
|
186
|
+
const candidateFunctions = FUNCTION_LIKE_KINDS.flatMap((kind) => sourceFile.getDescendantsOfKind(kind));
|
|
187
|
+
// Outermost-first: when functions are nested, rewriting the outer one
|
|
188
|
+
// also discards the inner one, so we shouldn't try to rewrite the inner
|
|
189
|
+
// afterwards. Sorting by start position handles this; we additionally
|
|
190
|
+
// filter out any candidate whose ancestor we already rewrote.
|
|
191
|
+
candidateFunctions.sort((a, b) => a.getStart() - b.getStart());
|
|
192
|
+
const rewrittenFunctions = [];
|
|
193
|
+
const rewrittenSet = new Set();
|
|
194
|
+
for (const fn of candidateFunctions) {
|
|
195
|
+
if (!hasBlockBody(fn))
|
|
196
|
+
continue;
|
|
197
|
+
if (!isConfigFetcher(fn))
|
|
198
|
+
continue;
|
|
199
|
+
// Skip if any ancestor was already rewritten (its descendants are now
|
|
200
|
+
// detached from the source file).
|
|
201
|
+
let inRewrittenAncestor = false;
|
|
202
|
+
let cursor = fn.getParent();
|
|
203
|
+
while (cursor) {
|
|
204
|
+
if (rewrittenSet.has(cursor)) {
|
|
205
|
+
inRewrittenAncestor = true;
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
cursor = cursor.getParent();
|
|
209
|
+
}
|
|
210
|
+
if (inRewrittenAncestor)
|
|
211
|
+
continue;
|
|
212
|
+
const start = fn.getStart();
|
|
213
|
+
const line = sourceFile.getLineAndColumnAtPos(start).line;
|
|
214
|
+
const name = describeFunction(fn);
|
|
215
|
+
if (ts_morph_1.Node.isFunctionDeclaration(fn) ||
|
|
216
|
+
ts_morph_1.Node.isFunctionExpression(fn) ||
|
|
217
|
+
ts_morph_1.Node.isMethodDeclaration(fn) ||
|
|
218
|
+
ts_morph_1.Node.isArrowFunction(fn)) {
|
|
219
|
+
fn.setBodyText(`return ${REPLACEMENT_IDENTIFIER}`);
|
|
220
|
+
}
|
|
221
|
+
rewrittenFunctions.push({ name, line });
|
|
222
|
+
rewrittenSet.add(fn);
|
|
223
|
+
}
|
|
224
|
+
// ─── 2. Remove the `APPLICATION_CONFIG_URL` import ─────────────────────
|
|
225
|
+
for (const decl of importsWithTarget) {
|
|
226
|
+
const targetNamed = decl
|
|
227
|
+
.getNamedImports()
|
|
228
|
+
.find((ni) => ni.getName() === TARGET_IDENTIFIER);
|
|
229
|
+
targetNamed === null || targetNamed === void 0 ? void 0 : targetNamed.remove();
|
|
230
|
+
const isNowEmpty = decl.getNamedImports().length === 0 &&
|
|
231
|
+
!decl.getDefaultImport() &&
|
|
232
|
+
!decl.getNamespaceImport();
|
|
233
|
+
if (isNowEmpty)
|
|
234
|
+
decl.remove();
|
|
235
|
+
}
|
|
236
|
+
// ─── 3. Add the new `applicationConfig` import ─────────────────────────
|
|
237
|
+
const existing = sourceFile.getImportDeclaration((decl) => decl.getModuleSpecifierValue() === REPLACEMENT_MODULE);
|
|
238
|
+
if (existing) {
|
|
239
|
+
const alreadyImported = existing
|
|
240
|
+
.getNamedImports()
|
|
241
|
+
.some((ni) => ni.getName() === REPLACEMENT_IDENTIFIER);
|
|
242
|
+
if (!alreadyImported)
|
|
243
|
+
existing.addNamedImport(REPLACEMENT_IDENTIFIER);
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
sourceFile.addImportDeclaration({
|
|
247
|
+
moduleSpecifier: REPLACEMENT_MODULE,
|
|
248
|
+
namedImports: [REPLACEMENT_IDENTIFIER]
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
// ─── 4. Rename remaining identifier references ─────────────────────────
|
|
252
|
+
// Anything still named APPLICATION_CONFIG_URL after the function-body
|
|
253
|
+
// rewrites and import cleanup is a stray reference; rename it. Iterate
|
|
254
|
+
// from highest position to lowest so `replaceWithText` doesn't shift
|
|
255
|
+
// offsets for nodes we haven't visited yet.
|
|
256
|
+
const renameTargets = sourceFile
|
|
257
|
+
.getDescendantsOfKind(ts_morph_1.SyntaxKind.Identifier)
|
|
258
|
+
.filter((id) => id.getText() === TARGET_IDENTIFIER)
|
|
259
|
+
.filter((id) => !id.getFirstAncestorByKind(ts_morph_1.SyntaxKind.ImportDeclaration))
|
|
260
|
+
.filter((id) => {
|
|
261
|
+
const parent = id.getParent();
|
|
262
|
+
const parentKind = parent.getKind();
|
|
263
|
+
if (parentKind === ts_morph_1.SyntaxKind.PropertyAccessExpression) {
|
|
264
|
+
const pae = parent.asKind(ts_morph_1.SyntaxKind.PropertyAccessExpression);
|
|
265
|
+
// Right-hand side of `x.APPLICATION_CONFIG_URL` — leave alone.
|
|
266
|
+
if (pae.getNameNode() === id)
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
if (parentKind === ts_morph_1.SyntaxKind.PropertyAssignment) {
|
|
270
|
+
const pa = parent.asKind(ts_morph_1.SyntaxKind.PropertyAssignment);
|
|
271
|
+
// `{ APPLICATION_CONFIG_URL: ... }` — leave the key alone.
|
|
272
|
+
if (pa.getNameNode() === id)
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
if (parentKind === ts_morph_1.SyntaxKind.ShorthandPropertyAssignment) {
|
|
276
|
+
// `{ APPLICATION_CONFIG_URL }` shorthand — both binding name AND
|
|
277
|
+
// referenced symbol. Leave alone here; if the user wants to rename
|
|
278
|
+
// the referenced value they should expand it manually first.
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
return true;
|
|
282
|
+
})
|
|
283
|
+
.sort((a, b) => b.getPos() - a.getPos());
|
|
284
|
+
for (const id of renameTargets) {
|
|
285
|
+
id.replaceWithText(REPLACEMENT_IDENTIFIER);
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
changed: true,
|
|
289
|
+
rewrittenFunctions,
|
|
290
|
+
renamedReferences: renameTargets.length
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
function main() {
|
|
294
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
295
|
+
const project = new ts_morph_1.Project({
|
|
296
|
+
tsConfigFilePath: path_1.default.resolve(process.cwd(), 'tsconfig.json'),
|
|
297
|
+
skipAddingFilesFromTsConfig: false
|
|
298
|
+
});
|
|
299
|
+
const sourceFiles = project.getSourceFiles().filter((sf) => {
|
|
300
|
+
const fp = sf.getFilePath();
|
|
301
|
+
return fp.includes('/src/') && !fp.includes('/node_modules/');
|
|
302
|
+
});
|
|
303
|
+
console.log(`Migrating '${TARGET_IDENTIFIER}' → '${REPLACEMENT_IDENTIFIER}' across ${sourceFiles.length} source file(s)...\n`);
|
|
304
|
+
let changedFiles = 0;
|
|
305
|
+
let totalRewrittenFunctions = 0;
|
|
306
|
+
let totalRenamedReferences = 0;
|
|
307
|
+
const skipped = [];
|
|
308
|
+
for (const sourceFile of sourceFiles) {
|
|
309
|
+
const filePath = sourceFile.getFilePath();
|
|
310
|
+
const rel = path_1.default.relative(process.cwd(), filePath);
|
|
311
|
+
const result = processFile(sourceFile);
|
|
312
|
+
if (result.skippedReason) {
|
|
313
|
+
skipped.push(`${rel} (${result.skippedReason})`);
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
if (!result.changed)
|
|
317
|
+
continue;
|
|
318
|
+
yield sourceFile.save();
|
|
319
|
+
changedFiles++;
|
|
320
|
+
totalRewrittenFunctions += result.rewrittenFunctions.length;
|
|
321
|
+
totalRenamedReferences += result.renamedReferences;
|
|
322
|
+
for (const fn of result.rewrittenFunctions) {
|
|
323
|
+
console.log(` [${rel}:${fn.line}] Rewrote '${fn.name}' body → 'return ${REPLACEMENT_IDENTIFIER}' (config fetch eliminated)`);
|
|
324
|
+
}
|
|
325
|
+
if (result.renamedReferences > 0) {
|
|
326
|
+
console.log(` [${rel}] Renamed ${result.renamedReferences} stray reference(s) ${TARGET_IDENTIFIER} → ${REPLACEMENT_IDENTIFIER}`);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
if (skipped.length > 0) {
|
|
330
|
+
console.warn(`\n ${skipped.length} file(s) skipped:\n` +
|
|
331
|
+
skipped.map((s) => ` - ${s}`).join('\n'));
|
|
332
|
+
}
|
|
333
|
+
if (changedFiles === 0) {
|
|
334
|
+
console.log(`\nNo files reference '${TARGET_IDENTIFIER}'. Nothing to do.`);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
console.log(`\nDone. Updated ${changedFiles} file(s): ${totalRewrittenFunctions} fetch function(s) rewritten, ${totalRenamedReferences} bare reference(s) renamed.`);
|
|
338
|
+
if (totalRewrittenFunctions > 0) {
|
|
339
|
+
console.log(`NOTE: rewriting fetch functions discards any custom logic that lived inside them. Review the diff and re-apply any country-specific adjustments on top of '${REPLACEMENT_IDENTIFIER}'.`);
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate-scopes.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/migrate-scopes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"migrate-scopes.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/migrate-scopes.ts"],"names":[],"mappings":"AAyVA,iBAAe,IAAI,kBAmDlB;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
|