@webiny/cli 5.17.4 → 5.18.0-beta.3

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 (49) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/commands/upgrade/index.js +52 -11
  3. package/context.js +1 -2
  4. package/package.json +4 -15
  5. package/utils/getProjectApplication.js +25 -2
  6. package/utils/log.js +2 -2
  7. package/commands/upgrade/upgrades/5.10.0/index.js +0 -123
  8. package/commands/upgrade/upgrades/5.10.0/upgradeApiFileManager.js +0 -111
  9. package/commands/upgrade/upgrades/5.10.0/upgradeApolloCachePlugins.js +0 -114
  10. package/commands/upgrade/upgrades/5.10.0/upgradeDeliveryPath.js +0 -19
  11. package/commands/upgrade/upgrades/5.10.0/upgradeLambdaConfig.js +0 -30
  12. package/commands/upgrade/upgrades/5.11.0/index.js +0 -109
  13. package/commands/upgrade/upgrades/5.11.0/upgradeApiI18n.js +0 -59
  14. package/commands/upgrade/upgrades/5.11.0/upgradeObjectField.js +0 -59
  15. package/commands/upgrade/upgrades/5.11.0/upgradeWebsite.js +0 -21
  16. package/commands/upgrade/upgrades/5.12.0/index.js +0 -106
  17. package/commands/upgrade/upgrades/5.12.0/upgradeApiSecurity.js +0 -53
  18. package/commands/upgrade/upgrades/5.12.0/upgradeElasticsearch.js +0 -111
  19. package/commands/upgrade/upgrades/5.13.0/addDotWebinyToGitIgnore.js +0 -25
  20. package/commands/upgrade/upgrades/5.13.0/addNewScaffolds.js +0 -75
  21. package/commands/upgrade/upgrades/5.13.0/createTypesTsFiles.js +0 -101
  22. package/commands/upgrade/upgrades/5.13.0/files/types/graphql.ts +0 -34
  23. package/commands/upgrade/upgrades/5.13.0/files/types/headlessCMS.ts +0 -28
  24. package/commands/upgrade/upgrades/5.13.0/index.js +0 -49
  25. package/commands/upgrade/upgrades/5.15.0/index.js +0 -97
  26. package/commands/upgrade/upgrades/5.15.0/upgradeApiPageBuilder.js +0 -121
  27. package/commands/upgrade/upgrades/5.16.0/index.js +0 -207
  28. package/commands/upgrade/upgrades/5.17.0/apiPrerenderingService.js +0 -182
  29. package/commands/upgrade/upgrades/5.17.0/index.js +0 -93
  30. package/commands/upgrade/upgrades/5.17.0/security.js +0 -611
  31. package/commands/upgrade/upgrades/5.5.0/index.js +0 -426
  32. package/commands/upgrade/upgrades/5.5.0/templates/api/default.webiny.config.js +0 -8
  33. package/commands/upgrade/upgrades/5.5.0/templates/api/fileManagerTransform.webiny.config.js +0 -9
  34. package/commands/upgrade/upgrades/5.5.0/templates/api/prerenderingService.webiny.config.js +0 -30
  35. package/commands/upgrade/upgrades/5.5.0/templates/customPackages/webiny.config.js +0 -8
  36. package/commands/upgrade/upgrades/5.5.0/templates/webinyApplication/api/webiny.application.js +0 -9
  37. package/commands/upgrade/upgrades/5.5.0/templates/webinyApplication/apps/admin/webiny.application.js +0 -15
  38. package/commands/upgrade/upgrades/5.5.0/templates/webinyApplication/apps/site/webiny.application.js +0 -16
  39. package/commands/upgrade/upgrades/5.5.0/templates/webinyApplication/apps/website/webiny.application.js +0 -16
  40. package/commands/upgrade/upgrades/5.8.0/index.js +0 -137
  41. package/commands/upgrade/upgrades/5.9.0/index.js +0 -144
  42. package/commands/upgrade/upgrades/5.9.0/upgradeScaffolding/babelrc.js +0 -1
  43. package/commands/upgrade/upgrades/5.9.0/upgradeScaffolding/jestConfig.js +0 -40
  44. package/commands/upgrade/upgrades/5.9.0/upgradeScaffolding.js +0 -337
  45. package/commands/upgrade/upgrades/5.9.0/upgradeSecurity.js +0 -280
  46. package/commands/upgrade/upgrades/5.9.0/upgradeTelemetry.js +0 -30
  47. package/commands/upgrade/upgrades/fileUtils.js +0 -152
  48. package/commands/upgrade/upgrades/upgrade.js +0 -1
  49. package/commands/upgrade/upgrades/utils.js +0 -792
@@ -1,792 +0,0 @@
1
- const tsMorph = require("ts-morph");
2
- const path = require("path");
3
- const fs = require("fs");
4
- const prettier = require("prettier");
5
- const loadJson = require("load-json-file");
6
- const writeJson = require("write-json-file");
7
- const semverCoerce = require("semver/functions/coerce");
8
- const execa = require("execa");
9
- /**
10
- *
11
- * @param pkg {string}
12
- * @param version {string}
13
- *
14
- * @return {boolean}
15
- */
16
- const validateVersion = (pkg, version) => {
17
- if (version === "latest") {
18
- return true;
19
- }
20
- const coerced = semverCoerce(version);
21
- return !!coerced;
22
- };
23
- /**
24
- * @deprecated
25
- */
26
- const insertImport = (source, name, pkg) => {
27
- throw new Error("Should not be used anymore.");
28
- const statements = source.getStatements();
29
- let importAlreadyExists = false;
30
- const lastImportStatement = statements.reduce((indexAt, statement, index) => {
31
- if (statement.getKind() !== tsMorph.SyntaxKind.ImportDeclaration) {
32
- return indexAt;
33
- }
34
- const compilerNode = statement.compilerNode || {};
35
- const moduleSpecifier = compilerNode.moduleSpecifier || {};
36
- const importedPackageName = moduleSpecifier.text;
37
- if (importedPackageName === pkg) {
38
- importAlreadyExists = true;
39
- }
40
- return index > indexAt ? index : indexAt;
41
- }, -1);
42
- if (importAlreadyExists) {
43
- throw new Error(`Package "${pkg}" is already imported.`);
44
- } else if (lastImportStatement === -1) {
45
- throw new Error(
46
- `Could not find last import statement so we can insert new import "${name}"`
47
- );
48
- }
49
-
50
- console.log(`Inserting import to position ${lastImportStatement + 1}`);
51
- source.insertStatements(lastImportStatement + 1, `import ${name} from "${pkg}";`);
52
- };
53
- /**
54
- *
55
- * @param context {CliContext}
56
- * @param targetPath {string}
57
- * @param packages {object}
58
- */
59
- const addPackagesToDependencies = (context, targetPath, packages) => {
60
- addPackagesToDeps("dependencies", context, targetPath, packages);
61
- };
62
- /**
63
- * @param context {CliContext}
64
- * @param targetPath {string}
65
- * @param packages {object}
66
- */
67
- const addPackagesToDevDependencies = (context, targetPath, packages) => {
68
- addPackagesToDeps("devDependencies", context, targetPath, packages);
69
- };
70
- /**
71
- * @param context {CliContext}
72
- * @param targetPath {string}
73
- * @param packages {object}
74
- */
75
- const addPackagesToPeerDependencies = (context, targetPath, packages) => {
76
- addPackagesToDeps("peerDependencies", context, targetPath, packages);
77
- };
78
- /**
79
- *
80
- * @param type {string}
81
- * @param context {CliContext}
82
- * @param targetPath {string}
83
- * @param packages {object}
84
- */
85
- const allowedPackageDependencyTypes = ["dependencies", "devDependencies", "peerDependencies"];
86
- const addPackagesToDeps = (type, context, targetPath, packages) => {
87
- if (!allowedPackageDependencyTypes.includes(type)) {
88
- context.error(`Package dependency type "${type}" is not valid.`);
89
- return;
90
- }
91
- const file = `${targetPath}/package.json`;
92
- if (!fs.existsSync(file)) {
93
- context.error(`There is no package.json file at path "${file}".`);
94
- return;
95
- }
96
- const json = loadJson.sync(file);
97
- if (!json) {
98
- context.error(`There is no package.json file "${file}"`);
99
- return;
100
- }
101
- const dependencies = json[type] || {};
102
- for (const pkg in packages) {
103
- if (!packages.hasOwnProperty(pkg)) {
104
- continue;
105
- }
106
- const version = packages[pkg];
107
-
108
- if (version === null) {
109
- // Remove package from deps
110
- delete dependencies[pkg];
111
- continue;
112
- }
113
- if (!validateVersion(pkg, version)) {
114
- context.error(`Package "${pkg}" version is not a valid semver version: "${version}".`);
115
- continue;
116
- }
117
- dependencies[pkg] = version;
118
- }
119
- json[type] = dependencies;
120
-
121
- writeJson.sync(file, json);
122
- };
123
- /**
124
- * @param files {string[]}
125
- * @return {tsMorph.Project}
126
- */
127
- const createMorphProject = files => {
128
- const project = new tsMorph.Project();
129
- for (const file of files) {
130
- project.addSourceFileAtPath(file);
131
- }
132
- return project;
133
- };
134
-
135
- const prettierFormat = async (files, context) => {
136
- try {
137
- context.info("Running prettier...");
138
- for (const file of files) {
139
- const filePath = path.join(process.cwd(), file);
140
- const options = await prettier.resolveConfig(filePath);
141
- const fileContentRaw = fs.readFileSync(filePath).toString("utf8");
142
- const fileContentFormatted = prettier.format(fileContentRaw, {
143
- ...options,
144
- filepath: filePath
145
- });
146
- fs.writeFileSync(filePath, fileContentFormatted);
147
- }
148
-
149
- context.info("Finished formatting files.");
150
- } catch (ex) {
151
- console.log(context.error.hl("Prettier failed."));
152
- context.error(ex.message);
153
- if (ex.stdout) {
154
- console.log(ex.stdout);
155
- }
156
- }
157
- };
158
-
159
- /**
160
- * Run to install new packages in the project.
161
- */
162
- const yarnInstall = async ({ context }) => {
163
- const { info, error } = context;
164
- try {
165
- info("Installing new packages...");
166
- await execa("yarn", { cwd: process.cwd() });
167
- info("Finished installing new packages.");
168
- } catch (ex) {
169
- error("Installation of new packages failed.");
170
- console.log(error(ex.message));
171
- if (ex.stdout) {
172
- console.log(ex.stdout);
173
- }
174
- }
175
- };
176
-
177
- /**
178
- * Run to up the versions of all packages.
179
- *
180
- *
181
- */
182
- const yarnUp = async ({ context, targetVersion }) => {
183
- const { info, error } = context;
184
- try {
185
- info(`Updating all package versions to ${targetVersion}...`);
186
- await execa(`yarn`, [`up`, `@webiny/*@${targetVersion}`], { cwd: process.cwd() });
187
- await execa("yarn", { cwd: process.cwd() });
188
- info("Finished update packages.");
189
- } catch (ex) {
190
- error("Updating of the packages failed.");
191
- console.log(ex);
192
- console.log(error(ex.message));
193
- if (ex.stdout) {
194
- console.log(ex.stdout);
195
- }
196
- }
197
- };
198
-
199
- /**
200
- *
201
- * @param plugins {tsMorph.Node}
202
- * @param afterElement {String|undefined}
203
- * @returns {null|number}
204
- *
205
- * @deprecated
206
- */
207
- const findElementIndex = (plugins, afterElement) => {
208
- if (!afterElement) {
209
- return null;
210
- }
211
- const index = plugins
212
- .getInitializer()
213
- .getElements()
214
- .findIndex(node => {
215
- return Node.isCallExpression(node) && node.getExpression().getText() === afterElement;
216
- });
217
- if (index >= 0) {
218
- return index;
219
- }
220
- return null;
221
- };
222
- /**
223
- *
224
- * @param context {CliContext}
225
- * @param source {tsMorph.SourceFile}
226
- * @param imports {{elementName: String, importPath: String, afterElement: String | undefined, isImportCallable: boolean, addToPlugins: boolean}[]}
227
- * @param file {String}
228
- *
229
- *
230
- * @deprecated
231
- */
232
- const addImportsToSource = ({ context, source, imports, file }) => {
233
- const { info, warning, error } = context;
234
- let pluginsElement;
235
- const getPluginsElement = () => {
236
- if (pluginsElement) {
237
- return pluginsElement;
238
- }
239
- /**
240
- * We need the plugins property in the createHandler argument.
241
- * @type {tsMorph.Node}
242
- */
243
- pluginsElement = source.getFirstDescendant(
244
- node => tsMorph.Node.isPropertyAssignment(node) && node.getName() === "plugins"
245
- );
246
- if (!pluginsElement) {
247
- error(
248
- `Cannot find "plugins" property of the "createHandler" argument object in ${info.hl(
249
- file
250
- )}.`
251
- );
252
- }
253
- return pluginsElement;
254
- };
255
-
256
- for (const value of imports) {
257
- const {
258
- elementName,
259
- importPath,
260
- afterElement,
261
- afterImport,
262
- isImportCallable = true,
263
- addToPlugins = true
264
- } = value;
265
-
266
- const importDefinition = source.getImportDeclaration(importPath);
267
- /**
268
- * If there is required import already, do not proceed.
269
- * We do not check if imported plugins are actually sent into the handler because we dont know what user might have done.
270
- */
271
- if (importDefinition) {
272
- info(`Import ${info.hl(importPath)} already exists in ${info.hl(file)}.`);
273
- continue;
274
- }
275
- let addedImport = false;
276
- /**
277
- * If we need to import after already defined import.
278
- */
279
- if (afterImport) {
280
- const afterImportDeclaration = source.getImportDeclaration(afterImport);
281
- if (afterImportDeclaration) {
282
- source.insertImportDeclaration(afterImportDeclaration.getChildIndex() + 1, {
283
- defaultImport: elementName,
284
- moduleSpecifier: importPath
285
- });
286
- addedImport = true;
287
- } else {
288
- warning(
289
- `Import ${warning.hl(afterImport)} does not exist in ${warning.hl(
290
- file
291
- )}. Adding new import after the last one.`
292
- );
293
- }
294
- }
295
- /**
296
- * If no import was added, add it at the end.
297
- */
298
- if (addedImport === false) {
299
- /**
300
- * We add the import and after that we add the imported name to the plugins array in the createHandler.
301
- */
302
- source.addImportDeclaration({
303
- defaultImport: elementName,
304
- moduleSpecifier: importPath
305
- });
306
- }
307
- if (addToPlugins === false) {
308
- continue;
309
- }
310
-
311
- const importedElementName = `${elementName}${isImportCallable === false ? "" : "()"}`;
312
-
313
- const plugins = getPluginsElement();
314
- if (!plugins) {
315
- error(`Could not add ${error.hl(importedElementName)} to the plugins.`);
316
- continue;
317
- }
318
- /**
319
- * If after is specified, add the imported value after the one given in the args..
320
- */
321
- if (afterElement) {
322
- const afterIndex = findElementIndex(plugins, afterElement);
323
- if (afterIndex === null) {
324
- warning(
325
- `Could not find ${warning.hl(
326
- after
327
- )} of the createHandler.plugins array in ${warning.hl(file)}.`
328
- );
329
- } else {
330
- plugins.getInitializer().insertElement(afterIndex + 1, importedElementName);
331
- continue;
332
- }
333
- }
334
- /**
335
- * Add imported plugin at the end of the array as no other options are viable.
336
- */
337
- plugins.getInitializer().addElement(importedElementName);
338
- }
339
- };
340
-
341
- /**
342
- * @param packageJsonPath {String}
343
- * @param pathsToAdd {String[]}
344
- */
345
- const addWorkspaceToRootPackageJson = async (packageJsonPath, pathsToAdd) => {
346
- const rootPackageJson = await loadJson(packageJsonPath);
347
-
348
- pathsToAdd.forEach(pathToAdd => {
349
- // Ensure forward slashes are used.
350
- pathToAdd = pathToAdd.replace(/\\/g, "/");
351
- // Add it to workspaces packages if not already
352
- if (!rootPackageJson.workspaces.packages.includes(pathToAdd)) {
353
- rootPackageJson.workspaces.packages.push(pathToAdd);
354
- }
355
- });
356
-
357
- await writeJson(packageJsonPath, rootPackageJson);
358
- };
359
-
360
- /**
361
- * @param packageJsonPath {String}
362
- * @param pathsToRemove {String[]}
363
- */
364
- const removeWorkspaceToRootPackageJson = async (packageJsonPath, pathsToRemove) => {
365
- const rootPackageJson = await loadJson(packageJsonPath);
366
-
367
- pathsToRemove.forEach(pathToRemove => {
368
- // Remove it from workspaces packages if present
369
- const index = rootPackageJson.workspaces.packages.indexOf(pathToRemove);
370
- if (index !== -1) {
371
- rootPackageJson.workspaces.packages.splice(index, 1);
372
- }
373
- });
374
-
375
- await writeJson(packageJsonPath, rootPackageJson);
376
- };
377
-
378
- /**
379
- *
380
- * @param name {string | string[] | Record<string, string>}
381
- * @return {{name: string, alias: string | undefined}[]|undefined}
382
- */
383
- const createNamedImports = name => {
384
- if (typeof name === "string") {
385
- return undefined;
386
- } else if (Array.isArray(name) === true) {
387
- return name.map(n => ({
388
- name: n
389
- }));
390
- }
391
- return Object.keys(name).map(key => {
392
- return {
393
- name: key,
394
- alias: name[key]
395
- };
396
- });
397
- };
398
- /**
399
- * It is possible to send:
400
- * - string - will produce default import
401
- * - string[] - will produce named imports
402
- * - Record<string, string> - will produce named imports with aliases
403
- *
404
- * @param source {tsMorph.SourceFile}
405
- * @param name {string|string[]|Record<string, string>}
406
- * @param moduleSpecifier {string}
407
- * @param after {string|null}
408
- */
409
- const insertImportToSourceFile = ({ source, name, moduleSpecifier, after = null }) => {
410
- const namedImports = createNamedImports(name);
411
- const defaultImport = namedImports === undefined ? name : undefined;
412
-
413
- const declaration = source.getImportDeclaration(moduleSpecifier);
414
-
415
- if (declaration) {
416
- if (defaultImport) {
417
- declaration.setDefaultImport(defaultImport);
418
- return;
419
- }
420
- /**
421
- * We check the existing imports so we dont add the same one.
422
- */
423
- const existingNamedImports = declaration.getNamedImports().map(ni => {
424
- return ni.getText();
425
- });
426
- declaration.addNamedImports(
427
- namedImports.filter(ni => {
428
- return existingNamedImports.includes(ni.name) === false;
429
- })
430
- );
431
- return;
432
- }
433
- /**
434
- * If we want to add this import after some other import...
435
- */
436
- if (after) {
437
- const afterDeclaration = source.getImportDeclaration(after);
438
- /**
439
- * If there is no target import, we will just add it at the end.
440
- */
441
- if (afterDeclaration) {
442
- source.insertImportDeclaration(afterDeclaration.getChildIndex() + 1, {
443
- defaultImport,
444
- namedImports,
445
- moduleSpecifier
446
- });
447
- return;
448
- }
449
- }
450
-
451
- source.addImportDeclaration({
452
- defaultImport,
453
- namedImports,
454
- moduleSpecifier
455
- });
456
- };
457
- /**
458
- *
459
- * @param source {tsMorph.SourceFile}
460
- * @param handler {tsMorph.Node}
461
- * @return {{handlerDeclaration: VariableDeclaration, createHandlerExpression: tsMorph.Node, plugins: tsMorph.Node, arrayExpression: tsMorph.Node}}
462
- */
463
- const getCreateHandlerExpressions = (source, handler) => {
464
- /**
465
- * First, we need to find handler declaration to check if it actually is ok.
466
- */
467
- const handlerDeclaration = source.getVariableDeclaration(handler);
468
- if (!handlerDeclaration) {
469
- console.log(`Missing handler expression "${handler}".`);
470
- return {
471
- handlerDeclaration: null,
472
- createHandlerExpression: null,
473
- plugins: null,
474
- arrayExpression: null
475
- };
476
- }
477
- /**
478
- * Then we need the handler expression "createHandler" to check if it has plugins defined.
479
- *
480
- * @type {Node}
481
- */
482
- const createHandlerExpression = handlerDeclaration.getFirstDescendant(
483
- node =>
484
- tsMorph.Node.isCallExpression(node) &&
485
- node.getExpression().getText() === "createHandler"
486
- );
487
- if (!createHandlerExpression) {
488
- console.log(`Missing "createHandler" expression in the handler declaration "${handler}".`);
489
- return {
490
- handlerDeclaration,
491
- createHandlerExpression: null,
492
- plugins: null,
493
- arrayExpression: null
494
- };
495
- }
496
- /**
497
- * And third check step is to determine if we need to upgrade the "createHandler".
498
- */
499
- const plugins = createHandlerExpression.getFirstDescendant(
500
- node => tsMorph.Node.isPropertyAssignment(node) && node.getName() === "plugins"
501
- );
502
- if (!plugins) {
503
- return {
504
- handlerDeclaration,
505
- createHandlerExpression,
506
- plugins,
507
- arrayExpression: null
508
- };
509
- }
510
- const arrayExpression = plugins.getFirstDescendant(node =>
511
- tsMorph.Node.isArrayLiteralExpression(node)
512
- );
513
- return {
514
- handlerDeclaration,
515
- createHandlerExpression,
516
- plugins,
517
- arrayExpression
518
- };
519
- };
520
- /**
521
- *
522
- * @param source {tsMorph.SourceFile}
523
- * @param handler {string}
524
- */
525
- const upgradeCreateHandlerToPlugins = (source, handler) => {
526
- const { createHandlerExpression, plugins } = getCreateHandlerExpressions(source, "handler");
527
-
528
- if (plugins) {
529
- return;
530
- }
531
-
532
- const args = createHandlerExpression.getArguments().map(a => a.getText());
533
- if (args.length === 0) {
534
- console.log(`Missing arguments in handler expression "${handler}".`);
535
- return;
536
- }
537
- /**
538
- * We need to remove existing arguments.
539
- */
540
- args.forEach(() => createHandlerExpression.removeArgument(0));
541
- /**
542
- * And then add the new ones.
543
- */
544
- createHandlerExpression.addArgument(
545
- `{plugins: [${args.join(",")}], http: {debug: process.env.DEBUG === "true"}}`
546
- );
547
- };
548
- /**
549
- *
550
- * @param source {tsMorph.SourceFile}
551
- * @param handler {string}
552
- * @param targetPlugin {RegExp|string}
553
- */
554
- const removePluginFromCreateHandler = (source, handler, targetPlugin) => {
555
- const { plugins, arrayExpression } = getCreateHandlerExpressions(source, handler);
556
-
557
- if (!plugins) {
558
- console.log(`Missing plugins in "createHandler" expression "${handler}".`);
559
- return;
560
- }
561
- if (!arrayExpression) {
562
- console.log(`Missing array literal expression in handler "${handler}".`);
563
- return;
564
- }
565
-
566
- const elements = arrayExpression.getElements();
567
- const removeIndexes = elements
568
- .map((element, index) => {
569
- if (element.getText().match(targetPlugin) === null) {
570
- return null;
571
- }
572
- return index;
573
- })
574
- .reverse()
575
- .filter(index => {
576
- return index !== null;
577
- });
578
- for (const index of removeIndexes) {
579
- arrayExpression.removeElement(index);
580
- }
581
- };
582
- /**
583
- * @param source {tsMorph.SourceFile}
584
- * @param handler {string}
585
- * @param plugin {string}
586
- * @param arg {string|Record<string, string>}
587
- */
588
- const addPluginArgumentValueInCreateHandler = (source, handler, plugin, arg) => {
589
- const { plugins, arrayExpression } = getCreateHandlerExpressions(source, handler);
590
-
591
- if (!plugins) {
592
- console.log(`Missing plugins in "createHandler" in handler "${handler}".`);
593
- return;
594
- } else if (!arrayExpression) {
595
- console.log(`Missing array literal expression in "createHandler" in handler "${handler}".`);
596
- return;
597
- }
598
- /**
599
- * @type {tsMorph.Node}
600
- */
601
- const pluginExpression = arrayExpression.getElements().find(element => {
602
- return element.getText().match(plugin);
603
- });
604
- if (!pluginExpression) {
605
- console.log(
606
- `Could not find plugin "${plugin}" in "createHandler" in handler "${handler}".`
607
- );
608
- return;
609
- }
610
- const pluginArguments = pluginExpression.getArguments();
611
- /**
612
- * When there are no plugin arguments, we need to add the new one.
613
- */
614
- if (pluginArguments.length === 0) {
615
- /**
616
- * If arg is array, we need to add as array.
617
- */
618
- if (Array.isArray(arg)) {
619
- pluginExpression.addArgument(`[${arg.join(",")}]`);
620
- return;
621
- } else if (typeof arg === "string") {
622
- pluginExpression.addArgument(`"${arg}"`);
623
- return;
624
- }
625
- const createObjectArgument = args => {
626
- return Object.keys(args)
627
- .map(key => {
628
- const value = args[key];
629
- if (value === key || !value) {
630
- return key;
631
- }
632
- return `${key}:${args[key]}`;
633
- })
634
- .join(",");
635
- };
636
- if (typeof arg === "object" && Object.keys(arg).length > 0) {
637
- pluginExpression.addArgument(`{${createObjectArgument(arg)}}`);
638
- }
639
- return;
640
- }
641
- /**
642
- * When there are more plugin arguments, we allow only one.
643
- */
644
- if (pluginArguments.length > 1) {
645
- console.log(
646
- `We allow to upgrade only single argument plugin intializers. Error in "${handler}", plugin "${plugin}".`
647
- );
648
- return;
649
- }
650
-
651
- if (typeof arg === "string" || Array.isArray(arg) === true || typeof arg !== "object") {
652
- console.log(
653
- `When handlers "${handler}" plugin "${plugin}" argument already exists, we allow only objects to be added to it.`
654
- );
655
- return;
656
- }
657
- const [pluginArgument] = pluginArguments;
658
- /**
659
- * And that plugin argument MUST be an object.
660
- */
661
- if (tsMorph.Node.isObjectLiteralExpression(pluginArgument) === false) {
662
- console.log(
663
- `We allow only to upgrade ObjectLiteralExpressions in handler "${handler}" plugin "${plugin}".`
664
- );
665
- return;
666
- }
667
-
668
- for (const key in arg) {
669
- const prop = pluginArgument.getProperty(key);
670
- const value = arg[key];
671
- if (!prop) {
672
- pluginArgument.addPropertyAssignment({
673
- name: key,
674
- /**
675
- * If value and key are same or value is null or undefined, do not add the initializer because it is named assign
676
- */
677
- initializer: value === key || !value ? undefined : value
678
- });
679
- continue;
680
- }
681
- prop.setInitializer(value);
682
- }
683
- };
684
- /**
685
- * @param source {tsMorph.SourceFile}
686
- * @param target {string}
687
- */
688
- const removeImportFromSourceFile = (source, target) => {
689
- const importDeclaration = source.getImportDeclaration(target);
690
- if (!importDeclaration) {
691
- console.log(`No import declaration with target path "${target}".`);
692
- return;
693
- }
694
- importDeclaration.remove();
695
- };
696
- /**
697
- * @param source {tsMorph.SourceFile}
698
- */
699
- const addDynamoDbDocumentClient = source => {
700
- /**
701
- * If there is document client declaration, no need to proceed further.
702
- */
703
- const documentClient = source.getFirstDescendant(node => {
704
- return tsMorph.Node.isVariableDeclaration(node) && node.getName() === "documentClient";
705
- });
706
- if (documentClient) {
707
- return;
708
- }
709
-
710
- const importDeclarations = source.getImportDeclarations();
711
- const lastImportDeclaration = importDeclarations[importDeclarations.length - 1];
712
- const last = lastImportDeclaration.getEndLineNumber();
713
-
714
- source.insertVariableStatement(last, {
715
- declarationKind: tsMorph.VariableDeclarationKind.Const,
716
- declarations: [
717
- {
718
- name: "documentClient",
719
- initializer:
720
- "new DocumentClient({convertEmptyValues: true,region: process.env.AWS_REGION})"
721
- }
722
- ]
723
- });
724
- };
725
- /**
726
- *
727
- * @param source {tsMorph.SourceFile}
728
- * @param targets {({matcher: Function, info: string})[]}
729
- *
730
- * @return {tsMorph.ArrayLiteralExpression}
731
- */
732
- const findNodeInSource = (source, targets) => {
733
- let previous = source;
734
- for (const key in targets) {
735
- const node = previous.getFirstDescendant(node => {
736
- return targets[key].matcher(node);
737
- });
738
- if (!node) {
739
- return null;
740
- }
741
- previous = node;
742
- }
743
- return previous;
744
- };
745
- /**
746
- * @param parent {tsMorph.Node}
747
- *
748
- * @return {tsMorph.Node}
749
- */
750
- const findDefaultExport = parent => {
751
- const exp = parent.getFirstDescendant(node => {
752
- if (tsMorph.Node.isExportAssignment(node) === false) {
753
- return false;
754
- }
755
- return node.getText().startsWith("export default ");
756
- });
757
- return exp || null;
758
- };
759
- /**
760
- * @param parent {tsMorph.Node}
761
- *
762
- * @return {tsMorph.Node}
763
- */
764
- const findReturnStatement = parent => {
765
- const stmt = parent.getFirstDescendant(node => {
766
- return tsMorph.Node.isReturnStatement(node);
767
- });
768
- return stmt || null;
769
- };
770
-
771
- module.exports = {
772
- insertImport,
773
- addPackagesToDependencies,
774
- addPackagesToDevDependencies,
775
- addPackagesToPeerDependencies,
776
- createMorphProject,
777
- prettierFormat,
778
- yarnInstall,
779
- yarnUp,
780
- addImportsToSource,
781
- addWorkspaceToRootPackageJson,
782
- removeWorkspaceToRootPackageJson,
783
- insertImportToSourceFile,
784
- upgradeCreateHandlerToPlugins,
785
- removePluginFromCreateHandler,
786
- addPluginArgumentValueInCreateHandler,
787
- removeImportFromSourceFile,
788
- addDynamoDbDocumentClient,
789
- findNodeInSource,
790
- findDefaultExport,
791
- findReturnStatement
792
- };