@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
|
@@ -0,0 +1,373 @@
|
|
|
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: Add `TriggerEvent.RESEND_INVITE` wiring to the country config
|
|
28
|
+
* (email schemas, templates, `/triggers/user/resend-invite` route,
|
|
29
|
+
* SMS keys, CSV copy, HTML template).
|
|
30
|
+
*
|
|
31
|
+
* Idempotent: safe to run multiple times; skips edits when markers are
|
|
32
|
+
* already present.
|
|
33
|
+
*/
|
|
34
|
+
const fs_1 = require("fs");
|
|
35
|
+
const path_1 = __importDefault(require("path"));
|
|
36
|
+
const ts_morph_1 = require("ts-morph");
|
|
37
|
+
const TS_MORPH_PROJECT_OPTIONS = {
|
|
38
|
+
skipAddingFilesFromTsConfig: true,
|
|
39
|
+
manipulationSettings: {
|
|
40
|
+
indentationText: ts_morph_1.IndentationText.TwoSpaces
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const EMAIL_TEMPLATES_INDEX = 'src/api/notification/email-templates/index.ts';
|
|
44
|
+
const NOTIFICATION_HANDLER = 'src/api/notification/handler.ts';
|
|
45
|
+
const USER_NOTIFICATION_ROUTES = 'src/config/routes/userNotificationRoutes.ts';
|
|
46
|
+
const SMS_SERVICE = 'src/api/notification/sms-service.ts';
|
|
47
|
+
const NOTIFICATION_CSV = 'src/translations/notification.csv';
|
|
48
|
+
const RESEND_INVITE_HTML = 'src/api/notification/email-templates/other/resend-invite.html';
|
|
49
|
+
const RESEND_INVITE_HTML_CONTENT = `<!doctype html>
|
|
50
|
+
<html>
|
|
51
|
+
<head>
|
|
52
|
+
<link
|
|
53
|
+
href="https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;700&display=swap"
|
|
54
|
+
rel="stylesheet"
|
|
55
|
+
/>
|
|
56
|
+
<style type="text/css">
|
|
57
|
+
body {
|
|
58
|
+
font-family: 'Noto Sans', sans-serif;
|
|
59
|
+
color: #222;
|
|
60
|
+
padding: 16px 24px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
h1 {
|
|
64
|
+
font-size: 21px;
|
|
65
|
+
margin-top: 32px;
|
|
66
|
+
margin-bottom: 36px;
|
|
67
|
+
font-weight: 700;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
p {
|
|
71
|
+
font-weight: 400;
|
|
72
|
+
font-size: 16px;
|
|
73
|
+
line-height: 1.8;
|
|
74
|
+
margin-bottom: 24px;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
i {
|
|
78
|
+
color: #666;
|
|
79
|
+
font-weight: 400;
|
|
80
|
+
font-size: 16px;
|
|
81
|
+
}
|
|
82
|
+
</style>
|
|
83
|
+
</head>
|
|
84
|
+
|
|
85
|
+
<body>
|
|
86
|
+
<img
|
|
87
|
+
src="{{countryLogo}}"
|
|
88
|
+
alt="country_logo"
|
|
89
|
+
style="max-height: 88px; max-width: 100%"
|
|
90
|
+
/>
|
|
91
|
+
<h1>Your {{applicationName}} account invitation</h1>
|
|
92
|
+
<p>Hello {{firstname}},</p>
|
|
93
|
+
<p>Your account invitation has been resent. Please use the following credentials to access your account:</p>
|
|
94
|
+
<p>
|
|
95
|
+
Username: <strong>{{username}}</strong><br />
|
|
96
|
+
Password: <strong>{{temporaryPassword}}</strong>
|
|
97
|
+
</p>
|
|
98
|
+
<p>
|
|
99
|
+
Please click the link below to complete your account setup and start using
|
|
100
|
+
{{applicationName}}.
|
|
101
|
+
</p>
|
|
102
|
+
|
|
103
|
+
<div style="margin-top: 32px; margin-bottom: 32px">
|
|
104
|
+
<a href="{{loginURL}}">Complete setup</a>
|
|
105
|
+
</div>
|
|
106
|
+
<br />
|
|
107
|
+
<p>
|
|
108
|
+
Best regards, <br />
|
|
109
|
+
{{applicationName}} Team
|
|
110
|
+
</p>
|
|
111
|
+
</body>
|
|
112
|
+
</html>
|
|
113
|
+
`;
|
|
114
|
+
const CSV_ROW = "resendInviteNotification,The SMS message that is sent when a user invitation is resent,Your OpenCRVS account invitation was resent. Please login with your username: {{username}} and temporary password: {{temporaryPassword}},Votre invitation de compte OpenCRVS a été renvoyée. Veuillez vous connecter avec votre nom d'utilisateur : {{username}} et votre mot de passe temporaire : {{temporaryPassword}}.\n";
|
|
115
|
+
function getObjectLiteralFromConst(declaration) {
|
|
116
|
+
if (!declaration) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const initializer = declaration.getInitializer();
|
|
120
|
+
if (!initializer) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (ts_morph_1.Node.isObjectLiteralExpression(initializer)) {
|
|
124
|
+
return initializer;
|
|
125
|
+
}
|
|
126
|
+
/* `{...} as const` */
|
|
127
|
+
if (ts_morph_1.Node.isAsExpression(initializer)) {
|
|
128
|
+
const expression = initializer.getExpression();
|
|
129
|
+
if (ts_morph_1.Node.isObjectLiteralExpression(expression)) {
|
|
130
|
+
return expression;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/* `{...} satisfies Record<...>` */
|
|
134
|
+
if (ts_morph_1.Node.isSatisfiesExpression(initializer)) {
|
|
135
|
+
const expression = initializer.getExpression();
|
|
136
|
+
if (ts_morph_1.Node.isObjectLiteralExpression(expression)) {
|
|
137
|
+
return expression;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function patchEmailTemplatesIndex() {
|
|
142
|
+
const full = path_1.default.join(process.cwd(), EMAIL_TEMPLATES_INDEX);
|
|
143
|
+
if (!(0, fs_1.existsSync)(full)) {
|
|
144
|
+
// eslint-disable-next-line no-console
|
|
145
|
+
console.log(` '${EMAIL_TEMPLATES_INDEX}' missing — skipping.`);
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
const project = new ts_morph_1.Project(TS_MORPH_PROJECT_OPTIONS);
|
|
149
|
+
const sourceFile = project.addSourceFileAtPath(full);
|
|
150
|
+
let changed = false;
|
|
151
|
+
const triggerVariableObject = getObjectLiteralFromConst(sourceFile.getVariableDeclaration('TriggerVariable'));
|
|
152
|
+
if (triggerVariableObject) {
|
|
153
|
+
const hasResendInviteVariable = triggerVariableObject
|
|
154
|
+
.getProperties()
|
|
155
|
+
.some((prop) => prop.getText().includes('[TriggerEvent.RESEND_INVITE]'));
|
|
156
|
+
if (!hasResendInviteVariable) {
|
|
157
|
+
const properties = triggerVariableObject.getProperties();
|
|
158
|
+
const lastProperty = properties[properties.length - 1];
|
|
159
|
+
if (lastProperty) {
|
|
160
|
+
sourceFile.insertText(lastProperty.getEnd(), `,
|
|
161
|
+
[TriggerEvent.RESEND_INVITE]: z.object({
|
|
162
|
+
firstname: z.string(),
|
|
163
|
+
username: z.string(),
|
|
164
|
+
temporaryPassword: z.string(),
|
|
165
|
+
completeSetupUrl: z.string(),
|
|
166
|
+
loginURL: z.string()
|
|
167
|
+
})`);
|
|
168
|
+
changed = true;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const templatesObject = getObjectLiteralFromConst(sourceFile.getVariableDeclaration('templates'));
|
|
173
|
+
if (templatesObject) {
|
|
174
|
+
const hasResendInviteTemplate = templatesObject
|
|
175
|
+
.getProperties()
|
|
176
|
+
.some((prop) => prop
|
|
177
|
+
.getText()
|
|
178
|
+
.includes("readOtherTemplate<TriggerVariable['resend-invite']>"));
|
|
179
|
+
if (!hasResendInviteTemplate) {
|
|
180
|
+
const userCreatedProp = templatesObject
|
|
181
|
+
.getProperties()
|
|
182
|
+
.find((prop) => prop.getText().includes('[TriggerEvent.USER_CREATED]'));
|
|
183
|
+
const anchor = userCreatedProp !== null && userCreatedProp !== void 0 ? userCreatedProp : templatesObject.getProperties()[templatesObject.getProperties().length - 1];
|
|
184
|
+
if (anchor) {
|
|
185
|
+
sourceFile.insertText(anchor.getEnd(), `,
|
|
186
|
+
[TriggerEvent.RESEND_INVITE]: {
|
|
187
|
+
type: 'resend-invite',
|
|
188
|
+
subject: 'Your OpenCRVS account invitation',
|
|
189
|
+
template:
|
|
190
|
+
readOtherTemplate<TriggerVariable['resend-invite']>('resend-invite')
|
|
191
|
+
}`);
|
|
192
|
+
changed = true;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (changed) {
|
|
197
|
+
sourceFile.saveSync();
|
|
198
|
+
}
|
|
199
|
+
return changed;
|
|
200
|
+
}
|
|
201
|
+
function patchNotificationHandler() {
|
|
202
|
+
const full = path_1.default.join(process.cwd(), NOTIFICATION_HANDLER);
|
|
203
|
+
if (!(0, fs_1.existsSync)(full)) {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
const project = new ts_morph_1.Project(TS_MORPH_PROJECT_OPTIONS);
|
|
207
|
+
const sourceFile = project.addSourceFileAtPath(full);
|
|
208
|
+
const convertFn = sourceFile.getFunction('convertPayloadToVariable');
|
|
209
|
+
if (!convertFn) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
const switchStmt = convertFn.getFirstDescendantByKind(ts_morph_1.SyntaxKind.SwitchStatement);
|
|
213
|
+
if (!switchStmt) {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
const clauses = switchStmt.getCaseBlock().getClauses();
|
|
217
|
+
const hasResendInvite = clauses.some((clause) => ts_morph_1.Node.isCaseClause(clause) &&
|
|
218
|
+
clause.getExpression().getText() === 'TriggerEvent.RESEND_INVITE');
|
|
219
|
+
if (hasResendInvite) {
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
const userCreatedClauseIndex = clauses.findIndex((clause) => ts_morph_1.Node.isCaseClause(clause) &&
|
|
223
|
+
clause.getExpression().getText() === 'TriggerEvent.USER_CREATED');
|
|
224
|
+
if (userCreatedClauseIndex < 0) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
const userCreatedClause = clauses[userCreatedClauseIndex];
|
|
228
|
+
sourceFile.insertText(userCreatedClause.getEnd(), `
|
|
229
|
+
|
|
230
|
+
case TriggerEvent.RESEND_INVITE:
|
|
231
|
+
return {
|
|
232
|
+
firstname,
|
|
233
|
+
username: payload.username,
|
|
234
|
+
temporaryPassword: payload.temporaryPassword,
|
|
235
|
+
completeSetupUrl: LOGIN_URL,
|
|
236
|
+
loginURL: LOGIN_URL
|
|
237
|
+
}`);
|
|
238
|
+
sourceFile.saveSync();
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
function getReturnedArrayLiteral(functionFilePath, fnName) {
|
|
242
|
+
const project = new ts_morph_1.Project(TS_MORPH_PROJECT_OPTIONS);
|
|
243
|
+
const sourceFile = project.addSourceFileAtPath(functionFilePath);
|
|
244
|
+
const fn = sourceFile.getFunction(fnName);
|
|
245
|
+
const returnStmt = fn === null || fn === void 0 ? void 0 : fn.getFirstDescendantByKind(ts_morph_1.SyntaxKind.ReturnStatement);
|
|
246
|
+
const expr = returnStmt === null || returnStmt === void 0 ? void 0 : returnStmt.getExpression();
|
|
247
|
+
if (!expr || !ts_morph_1.Node.isArrayLiteralExpression(expr)) {
|
|
248
|
+
return { sourceFile, arrayLiteral: undefined };
|
|
249
|
+
}
|
|
250
|
+
return { sourceFile, arrayLiteral: expr };
|
|
251
|
+
}
|
|
252
|
+
function patchUserNotificationRoutes() {
|
|
253
|
+
var _a;
|
|
254
|
+
const full = path_1.default.join(process.cwd(), USER_NOTIFICATION_ROUTES);
|
|
255
|
+
if (!(0, fs_1.existsSync)(full)) {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
const { sourceFile, arrayLiteral } = getReturnedArrayLiteral(full, 'getUserNotificationRoutes');
|
|
259
|
+
if (!arrayLiteral) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
const elements = arrayLiteral.getElements();
|
|
263
|
+
const routeExists = elements.some((element) => element.getText().includes(`path: '/triggers/user/resend-invite'`));
|
|
264
|
+
if (routeExists) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
const anchor = (_a = elements.find((element) => element.getText().includes(`path: '/triggers/user/user-created'`))) !== null && _a !== void 0 ? _a : elements[elements.length - 1];
|
|
268
|
+
if (!anchor) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
sourceFile.insertText(anchor.getEnd(), `,
|
|
272
|
+
{
|
|
273
|
+
method: 'POST',
|
|
274
|
+
path: '/triggers/user/resend-invite',
|
|
275
|
+
handler: makeNotificationHandler('resend-invite'),
|
|
276
|
+
options: {
|
|
277
|
+
auth: false,
|
|
278
|
+
tags: ['api'],
|
|
279
|
+
description: 'Handles notification for resent user invite'
|
|
280
|
+
}
|
|
281
|
+
}`);
|
|
282
|
+
sourceFile.saveSync();
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
285
|
+
function patchSmsService() {
|
|
286
|
+
const full = path_1.default.join(process.cwd(), SMS_SERVICE);
|
|
287
|
+
if (!(0, fs_1.existsSync)(full)) {
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
const project = new ts_morph_1.Project(TS_MORPH_PROJECT_OPTIONS);
|
|
291
|
+
const sourceFile = project.addSourceFileAtPath(full);
|
|
292
|
+
let changed = false;
|
|
293
|
+
const otherTemplatesObject = getObjectLiteralFromConst(sourceFile.getVariableDeclaration('otherTemplates'));
|
|
294
|
+
if (otherTemplatesObject) {
|
|
295
|
+
const hasResendTemplate = otherTemplatesObject
|
|
296
|
+
.getProperties()
|
|
297
|
+
.some((prop) => prop.getText().includes('resendInviteNotification'));
|
|
298
|
+
if (!hasResendTemplate) {
|
|
299
|
+
const userCredentialsIndex = otherTemplatesObject
|
|
300
|
+
.getProperties()
|
|
301
|
+
.findIndex((prop) => prop.getText().includes('userCredentialsNotification'));
|
|
302
|
+
otherTemplatesObject.insertPropertyAssignment(userCredentialsIndex >= 0
|
|
303
|
+
? userCredentialsIndex + 1
|
|
304
|
+
: otherTemplatesObject.getProperties().length, {
|
|
305
|
+
name: 'resendInviteNotification',
|
|
306
|
+
initializer: `'resendInviteNotification'`
|
|
307
|
+
});
|
|
308
|
+
changed = true;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const triggerToSmsTemplateObject = getObjectLiteralFromConst(sourceFile.getVariableDeclaration('TriggerToSMSTemplate'));
|
|
312
|
+
if (triggerToSmsTemplateObject) {
|
|
313
|
+
const hasResendInviteMap = triggerToSmsTemplateObject
|
|
314
|
+
.getProperties()
|
|
315
|
+
.some((prop) => prop.getText().includes(`['resend-invite']`));
|
|
316
|
+
if (!hasResendInviteMap) {
|
|
317
|
+
const userCreatedIndex = triggerToSmsTemplateObject
|
|
318
|
+
.getProperties()
|
|
319
|
+
.findIndex((prop) => prop.getText().includes(`['user-created']`));
|
|
320
|
+
triggerToSmsTemplateObject.insertPropertyAssignment(userCreatedIndex >= 0
|
|
321
|
+
? userCreatedIndex + 1
|
|
322
|
+
: triggerToSmsTemplateObject.getProperties().length, {
|
|
323
|
+
name: `['resend-invite']`,
|
|
324
|
+
initializer: `'resendInviteNotification'`
|
|
325
|
+
});
|
|
326
|
+
changed = true;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
if (changed) {
|
|
330
|
+
sourceFile.saveSync();
|
|
331
|
+
}
|
|
332
|
+
return changed;
|
|
333
|
+
}
|
|
334
|
+
function main() {
|
|
335
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
336
|
+
// eslint-disable-next-line no-console
|
|
337
|
+
console.log('Adding RESEND_INVITE notification wiring…');
|
|
338
|
+
const touched = [];
|
|
339
|
+
if (patchEmailTemplatesIndex())
|
|
340
|
+
touched.push(EMAIL_TEMPLATES_INDEX);
|
|
341
|
+
if (patchNotificationHandler())
|
|
342
|
+
touched.push(NOTIFICATION_HANDLER);
|
|
343
|
+
if (patchUserNotificationRoutes())
|
|
344
|
+
touched.push(USER_NOTIFICATION_ROUTES);
|
|
345
|
+
if (patchSmsService())
|
|
346
|
+
touched.push(SMS_SERVICE);
|
|
347
|
+
/* csv */
|
|
348
|
+
const csvPath = path_1.default.join(process.cwd(), NOTIFICATION_CSV);
|
|
349
|
+
if ((0, fs_1.existsSync)(csvPath)) {
|
|
350
|
+
let t = (0, fs_1.readFileSync)(csvPath, 'utf8');
|
|
351
|
+
if (!/^resendInviteNotification,/m.test(t)) {
|
|
352
|
+
if (!t.endsWith('\n'))
|
|
353
|
+
t += '\n';
|
|
354
|
+
(0, fs_1.writeFileSync)(csvPath, t + CSV_ROW);
|
|
355
|
+
touched.push(NOTIFICATION_CSV);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
/* html */
|
|
359
|
+
const htmlPath = path_1.default.join(process.cwd(), RESEND_INVITE_HTML);
|
|
360
|
+
(0, fs_1.mkdirSync)(path_1.default.dirname(htmlPath), { recursive: true });
|
|
361
|
+
if (!(0, fs_1.existsSync)(htmlPath)) {
|
|
362
|
+
(0, fs_1.writeFileSync)(htmlPath, RESEND_INVITE_HTML_CONTENT);
|
|
363
|
+
touched.push(RESEND_INVITE_HTML);
|
|
364
|
+
}
|
|
365
|
+
if (touched.length === 0) {
|
|
366
|
+
// eslint-disable-next-line no-console
|
|
367
|
+
console.log(' Nothing to update (already present or anchors not found).');
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
// eslint-disable-next-line no-console
|
|
371
|
+
console.log(` Updated:\n${touched.map((f) => ` - ${f}`).join('\n')}`);
|
|
372
|
+
});
|
|
373
|
+
}
|
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
export declare const UPSTREAM_URL = "https://github.com/opencrvs/opencrvs-countryconfig.git";
|
|
2
|
+
export declare const UPSTREAM_BRANCH = "develop";
|
|
3
|
+
/**
|
|
4
|
+
* Runs a git command in the country config working directory.
|
|
5
|
+
*
|
|
6
|
+
* By default stderr is inherited so the user sees progress output from
|
|
7
|
+
* long-running commands (e.g. `git fetch`). Pass `silent: true` to suppress
|
|
8
|
+
* both stdout and stderr when you only care about the exit code.
|
|
9
|
+
*/
|
|
10
|
+
export declare function runGit(args: string[], { silent }?: {
|
|
11
|
+
silent?: boolean;
|
|
12
|
+
}): string;
|
|
13
|
+
/**
|
|
14
|
+
* Runs a git command and returns true on success, false on failure.
|
|
15
|
+
* Stderr/stdout are suppressed — use only when the exit code is the only
|
|
16
|
+
* signal you care about.
|
|
17
|
+
*/
|
|
18
|
+
export declare function tryGit(args: string[]): boolean;
|
|
19
|
+
export declare function assertIsGitRepo(): void;
|
|
1
20
|
declare function main(): Promise<void>;
|
|
2
21
|
export { main };
|
|
3
22
|
//# sourceMappingURL=checkout-upstream-files.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkout-upstream-files.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/checkout-upstream-files.ts"],"names":[],"mappings":"
|
|
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"}
|
|
@@ -19,6 +19,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
19
19
|
});
|
|
20
20
|
};
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.UPSTREAM_BRANCH = exports.UPSTREAM_URL = void 0;
|
|
23
|
+
exports.runGit = runGit;
|
|
24
|
+
exports.tryGit = tryGit;
|
|
25
|
+
exports.assertIsGitRepo = assertIsGitRepo;
|
|
22
26
|
exports.main = main;
|
|
23
27
|
/**
|
|
24
28
|
* Codemod: Replace selected files with their upstream v2.0 versions from
|
|
@@ -54,16 +58,16 @@ exports.main = main;
|
|
|
54
58
|
* - Requires the country config working directory to be a git repo.
|
|
55
59
|
*/
|
|
56
60
|
const child_process_1 = require("child_process");
|
|
57
|
-
|
|
58
|
-
const UPSTREAM_URL = 'https://github.com/opencrvs/opencrvs-countryconfig.git';
|
|
61
|
+
exports.UPSTREAM_URL = 'https://github.com/opencrvs/opencrvs-countryconfig.git';
|
|
59
62
|
// @TODO: This needs to be changed to 'release-v2.0.0' once the branch is created
|
|
60
|
-
|
|
63
|
+
exports.UPSTREAM_BRANCH = 'develop';
|
|
61
64
|
// Remote name used only for the duration of this codemod. Prefixed to avoid
|
|
62
65
|
// clashing with remotes the user may have (origin, upstream, etc.).
|
|
63
66
|
const TEMP_REMOTE = 'opencrvs-upgrade-v19-v20-codemod';
|
|
64
67
|
const FILES_TO_CHECKOUT = [
|
|
65
|
-
'
|
|
66
|
-
'
|
|
68
|
+
'src/analytics/analytics.ts',
|
|
69
|
+
'Dockerfile',
|
|
70
|
+
'Dockerfile.assets'
|
|
67
71
|
];
|
|
68
72
|
// ─── Git helpers ─────────────────────────────────────────────────────────────
|
|
69
73
|
/**
|
|
@@ -75,7 +79,7 @@ const FILES_TO_CHECKOUT = [
|
|
|
75
79
|
*/
|
|
76
80
|
function runGit(args, { silent = false } = {}) {
|
|
77
81
|
return (0, child_process_1.execFileSync)('git', args, {
|
|
78
|
-
cwd:
|
|
82
|
+
cwd: process.cwd(),
|
|
79
83
|
encoding: 'utf8',
|
|
80
84
|
stdio: silent ? ['ignore', 'pipe', 'pipe'] : ['ignore', 'pipe', 'inherit']
|
|
81
85
|
});
|
|
@@ -96,22 +100,22 @@ function tryGit(args) {
|
|
|
96
100
|
}
|
|
97
101
|
function assertIsGitRepo() {
|
|
98
102
|
if (!tryGit(['rev-parse', '--is-inside-work-tree'])) {
|
|
99
|
-
throw new Error(
|
|
103
|
+
throw new Error(`${process.cwd()} is not a git repository. Initialise git (or run the upgrade inside a git checkout) before re-running.`);
|
|
100
104
|
}
|
|
101
105
|
}
|
|
102
106
|
// ─── Entry point ─────────────────────────────────────────────────────────────
|
|
103
107
|
function main() {
|
|
104
108
|
return __awaiter(this, void 0, void 0, function* () {
|
|
105
|
-
console.log(`Checking out ${FILES_TO_CHECKOUT.length} file(s) from ${UPSTREAM_URL}@${UPSTREAM_BRANCH}...\n`);
|
|
109
|
+
console.log(`Checking out ${FILES_TO_CHECKOUT.length} file(s) from ${exports.UPSTREAM_URL}@${exports.UPSTREAM_BRANCH}...\n`);
|
|
106
110
|
assertIsGitRepo();
|
|
107
111
|
// Best-effort cleanup of a stale temp remote from a previous aborted run.
|
|
108
112
|
tryGit(['remote', 'remove', TEMP_REMOTE]);
|
|
109
113
|
try {
|
|
110
|
-
console.log(` Adding temporary remote '${TEMP_REMOTE}' → ${UPSTREAM_URL}`);
|
|
111
|
-
runGit(['remote', 'add', TEMP_REMOTE, UPSTREAM_URL], { silent: true });
|
|
112
|
-
console.log(` Fetching ${TEMP_REMOTE}/${UPSTREAM_BRANCH} (depth 1)...`);
|
|
113
|
-
runGit(['fetch', '--depth=1', TEMP_REMOTE, UPSTREAM_BRANCH]);
|
|
114
|
-
const ref = `${TEMP_REMOTE}/${UPSTREAM_BRANCH}`;
|
|
114
|
+
console.log(` Adding temporary remote '${TEMP_REMOTE}' → ${exports.UPSTREAM_URL}`);
|
|
115
|
+
runGit(['remote', 'add', TEMP_REMOTE, exports.UPSTREAM_URL], { silent: true });
|
|
116
|
+
console.log(` Fetching ${TEMP_REMOTE}/${exports.UPSTREAM_BRANCH} (depth 1)...`);
|
|
117
|
+
runGit(['fetch', '--depth=1', TEMP_REMOTE, exports.UPSTREAM_BRANCH]);
|
|
118
|
+
const ref = `${TEMP_REMOTE}/${exports.UPSTREAM_BRANCH}`;
|
|
115
119
|
const missing = [];
|
|
116
120
|
let checkedOut = 0;
|
|
117
121
|
for (const file of FILES_TO_CHECKOUT) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert-config-files-to-ts.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/convert-config-files-to-ts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"convert-config-files-to-ts.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/convert-config-files-to-ts.ts"],"names":[],"mappings":"AAuuBA,wBAAsB,IAAI,kBAyPzB"}
|
|
@@ -87,7 +87,6 @@ exports.main = main;
|
|
|
87
87
|
const fs = __importStar(require("fs"));
|
|
88
88
|
const ts_morph_1 = require("ts-morph");
|
|
89
89
|
const path_1 = __importDefault(require("path"));
|
|
90
|
-
const _1 = require(".");
|
|
91
90
|
// ─── Schema-valid keys per config type ───────────────────────────────────────
|
|
92
91
|
const CLIENT_VALID_KEYS = new Set([
|
|
93
92
|
'COUNTRY',
|
|
@@ -634,8 +633,8 @@ function ensureJoinImport(sf) {
|
|
|
634
633
|
function main() {
|
|
635
634
|
return __awaiter(this, void 0, void 0, function* () {
|
|
636
635
|
var _a;
|
|
637
|
-
const srcDir = path_1.default.join(
|
|
638
|
-
const relCwd = (fp) => path_1.default.relative(
|
|
636
|
+
const srcDir = path_1.default.join(process.cwd(), 'src');
|
|
637
|
+
const relCwd = (fp) => path_1.default.relative(process.cwd(), fp);
|
|
639
638
|
// ── Phase 1: Convert JS config files to TypeScript ────────────────────────
|
|
640
639
|
console.log('Phase 1: Converting JS config files to TypeScript...\n');
|
|
641
640
|
let convertedCount = 0;
|
|
@@ -741,7 +740,7 @@ function main() {
|
|
|
741
740
|
if (/\bjoin\s*\(/.test(adjustedValue)) {
|
|
742
741
|
ensureJoinImport(sf);
|
|
743
742
|
}
|
|
744
|
-
console.log(` Inlined applicationConfig.${accessPath.join('.')} → ${adjustedValue} in ${path_1.default.relative(
|
|
743
|
+
console.log(` Inlined applicationConfig.${accessPath.join('.')} → ${adjustedValue} in ${path_1.default.relative(process.cwd(), sf.getFilePath())}`);
|
|
745
744
|
filesToSaveAfterInlining.add(sf);
|
|
746
745
|
madeReplacement = true;
|
|
747
746
|
break; // restart — tree has changed
|
|
@@ -752,7 +751,7 @@ function main() {
|
|
|
752
751
|
// Persist files that received inline replacements
|
|
753
752
|
for (const sf of Array.from(filesToSaveAfterInlining)) {
|
|
754
753
|
yield sf.save();
|
|
755
|
-
console.log(` Saved (inlined): ${path_1.default.relative(
|
|
754
|
+
console.log(` Saved (inlined): ${path_1.default.relative(process.cwd(), sf.getFilePath())}`);
|
|
756
755
|
}
|
|
757
756
|
// Remove in reverse order to avoid index shifting
|
|
758
757
|
for (const prop of [...propsToRemove].reverse()) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert-paragraph-to-heading.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/convert-paragraph-to-heading.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"convert-paragraph-to-heading.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/convert-paragraph-to-heading.ts"],"names":[],"mappings":"AAsJA,iBAAe,IAAI,kBA6ClB;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
|
|
@@ -42,7 +42,6 @@ exports.main = main;
|
|
|
42
42
|
*/
|
|
43
43
|
const ts_morph_1 = require("ts-morph");
|
|
44
44
|
const path_1 = __importDefault(require("path"));
|
|
45
|
-
const _1 = require(".");
|
|
46
45
|
const FIELD_TYPE_ENUM_NAME = 'FieldType';
|
|
47
46
|
const PARAGRAPH_MEMBER_NAME = 'PARAGRAPH';
|
|
48
47
|
const HEADING_MEMBER_NAME = 'HEADING';
|
|
@@ -112,18 +111,18 @@ function processFile(filePath, project) {
|
|
|
112
111
|
const result = transformParagraphField(obj);
|
|
113
112
|
if (result === 'converted-to-heading') {
|
|
114
113
|
changedCount++;
|
|
115
|
-
console.log(` [${path_1.default.relative(
|
|
114
|
+
console.log(` [${path_1.default.relative(process.cwd(), filePath)}] Converted PARAGRAPH with heading fontVariant to HEADING`);
|
|
116
115
|
}
|
|
117
116
|
else if (result === 'removed-font-variant') {
|
|
118
117
|
changedCount++;
|
|
119
|
-
console.log(` [${path_1.default.relative(
|
|
118
|
+
console.log(` [${path_1.default.relative(process.cwd(), filePath)}] Removed non-heading fontVariant from PARAGRAPH`);
|
|
120
119
|
}
|
|
121
120
|
}
|
|
122
121
|
return changedCount;
|
|
123
122
|
}
|
|
124
123
|
function main() {
|
|
125
124
|
return __awaiter(this, void 0, void 0, function* () {
|
|
126
|
-
const srcDir = path_1.default.join(
|
|
125
|
+
const srcDir = path_1.default.join(process.cwd(), 'src');
|
|
127
126
|
console.log(`Scanning for FieldType.PARAGRAPH fields in: ${srcDir}\n`);
|
|
128
127
|
const project = new ts_morph_1.Project({
|
|
129
128
|
tsConfigFilePath: path_1.default.resolve(srcDir, '../tsconfig.json'),
|
|
@@ -152,7 +151,7 @@ function main() {
|
|
|
152
151
|
for (const filePath of modifiedFiles) {
|
|
153
152
|
const sourceFile = project.getSourceFileOrThrow(filePath);
|
|
154
153
|
yield sourceFile.save();
|
|
155
|
-
console.log(` Saved: ${path_1.default.relative(
|
|
154
|
+
console.log(` Saved: ${path_1.default.relative(process.cwd(), filePath)}`);
|
|
156
155
|
}
|
|
157
156
|
console.log(`\nDone. Processed ${totalChanged} FieldType.PARAGRAPH field(s).`);
|
|
158
157
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-events-index.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/create-events-index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create-events-index.d.ts","sourceRoot":"","sources":["../../../src/migrations/v2.0/create-events-index.ts"],"names":[],"mappings":"AAmTA,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAmEnC;AAED,OAAO,EAAE,IAAI,EAAE,CAAA"}
|
|
@@ -63,7 +63,6 @@ exports.main = main;
|
|
|
63
63
|
const ts_morph_1 = require("ts-morph");
|
|
64
64
|
const fs_1 = __importDefault(require("fs"));
|
|
65
65
|
const path_1 = __importDefault(require("path"));
|
|
66
|
-
const _1 = require(".");
|
|
67
66
|
const DEFINE_CONFIG_NAME = 'defineConfig';
|
|
68
67
|
const HANDLER_FUNCTION_NAMES = new Set([
|
|
69
68
|
'getCustomEventsHandler',
|
|
@@ -274,7 +273,7 @@ function modifyHandler(sourceFile, exportNames) {
|
|
|
274
273
|
// ─── Entry point ─────────────────────────────────────────────────────────────
|
|
275
274
|
function main() {
|
|
276
275
|
return __awaiter(this, void 0, void 0, function* () {
|
|
277
|
-
const cwd =
|
|
276
|
+
const cwd = process.cwd();
|
|
278
277
|
const srcDir = path_1.default.join(cwd, 'src');
|
|
279
278
|
console.log(`Scanning for defineConfig event exports in: ${srcDir}\n`);
|
|
280
279
|
const project = new ts_morph_1.Project({
|
|
@@ -0,0 +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"}
|