@backstage/cli 0.30.0-next.2 → 0.30.0-next.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 (135) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/commands/index.cjs.js +3 -0
  3. package/dist/commands/new/new.cjs.js +39 -80
  4. package/dist/lib/new/createNewPackage.cjs.js +32 -0
  5. package/dist/lib/new/defaultTemplates.cjs.js +16 -0
  6. package/dist/lib/new/execution/PortableTemplater.cjs.js +91 -0
  7. package/dist/lib/new/execution/executePortableTemplate.cjs.js +54 -0
  8. package/dist/lib/new/execution/installNewPackage.cjs.js +127 -0
  9. package/dist/lib/new/execution/writeTemplateContents.cjs.js +111 -0
  10. package/dist/lib/new/preparation/collectPortableTemplateInput.cjs.js +157 -0
  11. package/dist/lib/new/preparation/loadPortableTemplate.cjs.js +82 -0
  12. package/dist/lib/new/preparation/loadPortableTemplateConfig.cjs.js +121 -0
  13. package/dist/lib/new/preparation/resolvePackageParams.cjs.js +40 -0
  14. package/dist/lib/new/preparation/selectTemplateInteractively.cjs.js +38 -0
  15. package/dist/lib/new/types.cjs.js +15 -4
  16. package/dist/lib/tasks.cjs.js +0 -111
  17. package/dist/packages/backend-defaults/package.json.cjs.js +1 -1
  18. package/dist/packages/backend-plugin-api/package.json.cjs.js +1 -1
  19. package/dist/packages/backend-test-utils/package.json.cjs.js +1 -1
  20. package/dist/packages/cli/package.json.cjs.js +3 -2
  21. package/dist/packages/dev-utils/package.json.cjs.js +1 -1
  22. package/dist/plugins/auth-backend/package.json.cjs.js +1 -1
  23. package/dist/plugins/auth-backend-module-guest-provider/package.json.cjs.js +1 -1
  24. package/dist/plugins/catalog-node/package.json.cjs.js +1 -1
  25. package/dist/plugins/scaffolder-node/package.json.cjs.js +1 -1
  26. package/dist/plugins/scaffolder-node-test-utils/package.json.cjs.js +1 -1
  27. package/package.json +11 -10
  28. package/templates/{default-backend-plugin → backend-plugin}/README.md.hbs +4 -4
  29. package/templates/{default-backend-plugin → backend-plugin}/dev/index.ts.hbs +5 -5
  30. package/templates/{default-backend-plugin → backend-plugin}/package.json.hbs +1 -9
  31. package/templates/backend-plugin/portable-template.yaml +5 -0
  32. package/templates/{default-backend-plugin → backend-plugin}/src/plugin.test.ts.hbs +5 -5
  33. package/templates/{default-backend-plugin → backend-plugin}/src/plugin.ts.hbs +1 -1
  34. package/templates/{default-backend-module → backend-plugin-module}/README.md.hbs +1 -1
  35. package/templates/{default-backend-module → backend-plugin-module}/package.json.hbs +1 -9
  36. package/templates/backend-plugin-module/portable-template.yaml +5 -0
  37. package/templates/{default-plugin → frontend-plugin}/README.md.hbs +3 -3
  38. package/templates/{default-plugin → frontend-plugin}/dev/index.tsx.hbs +1 -1
  39. package/templates/{default-plugin → frontend-plugin}/package.json.hbs +1 -9
  40. package/templates/frontend-plugin/portable-template.yaml +6 -0
  41. package/templates/{default-plugin → frontend-plugin}/src/components/ExampleComponent/ExampleComponent.test.tsx.hbs +1 -1
  42. package/templates/{default-plugin → frontend-plugin}/src/components/ExampleComponent/ExampleComponent.tsx.hbs +1 -1
  43. package/templates/{default-plugin → frontend-plugin}/src/plugin.test.ts.hbs +1 -1
  44. package/templates/{default-plugin → frontend-plugin}/src/plugin.ts.hbs +1 -1
  45. package/templates/{default-plugin → frontend-plugin}/src/routes.ts.hbs +1 -1
  46. package/templates/{node-library-package → node-library}/README.md.hbs +2 -2
  47. package/templates/{node-library-package → node-library}/package.json.hbs +1 -9
  48. package/templates/node-library/portable-template.yaml +3 -0
  49. package/templates/plugin-common-library/README.md.hbs +5 -0
  50. package/templates/{default-common-plugin-package → plugin-common-library}/package.json.hbs +2 -10
  51. package/templates/plugin-common-library/portable-template.yaml +3 -0
  52. package/templates/{default-common-plugin-package → plugin-common-library}/src/index.ts.hbs +1 -1
  53. package/templates/plugin-node-library/README.md.hbs +5 -0
  54. package/templates/{default-node-plugin-package → plugin-node-library}/package.json.hbs +2 -10
  55. package/templates/plugin-node-library/portable-template.yaml +3 -0
  56. package/templates/{default-node-plugin-package → plugin-node-library}/src/index.ts.hbs +1 -1
  57. package/templates/plugin-web-library/README.md.hbs +5 -0
  58. package/templates/{default-react-plugin-package → plugin-web-library}/package.json.hbs +2 -10
  59. package/templates/plugin-web-library/portable-template.yaml +3 -0
  60. package/templates/{default-react-plugin-package → plugin-web-library}/src/index.ts.hbs +1 -1
  61. package/templates/scaffolder-backend-module/README.md.hbs +5 -0
  62. package/templates/{scaffolder-module → scaffolder-backend-module}/package.json.hbs +2 -10
  63. package/templates/scaffolder-backend-module/portable-template.yaml +6 -0
  64. package/templates/{scaffolder-module → scaffolder-backend-module}/src/index.ts.hbs +1 -1
  65. package/templates/{web-library-package → web-library}/README.md.hbs +2 -2
  66. package/templates/{web-library-package → web-library}/package.json.hbs +1 -9
  67. package/templates/web-library/portable-template.yaml +3 -0
  68. package/dist/lib/new/FactoryRegistry.cjs.js +0 -96
  69. package/dist/lib/new/factories/backendModule.cjs.js +0 -82
  70. package/dist/lib/new/factories/backendPlugin.cjs.js +0 -78
  71. package/dist/lib/new/factories/common/prompts.cjs.js +0 -57
  72. package/dist/lib/new/factories/common/tasks.cjs.js +0 -66
  73. package/dist/lib/new/factories/common/util.cjs.js +0 -16
  74. package/dist/lib/new/factories/frontendPlugin.cjs.js +0 -107
  75. package/dist/lib/new/factories/index.cjs.js +0 -24
  76. package/dist/lib/new/factories/nodeLibraryPackage.cjs.js +0 -57
  77. package/dist/lib/new/factories/pluginCommon.cjs.js +0 -58
  78. package/dist/lib/new/factories/pluginNode.cjs.js +0 -58
  79. package/dist/lib/new/factories/pluginWeb.cjs.js +0 -58
  80. package/dist/lib/new/factories/scaffolderModule.cjs.js +0 -90
  81. package/dist/lib/new/factories/webLibraryPackage.cjs.js +0 -57
  82. package/templates/default-backend-module/tsconfig.json +0 -9
  83. package/templates/default-backend-plugin/tsconfig.json +0 -13
  84. package/templates/default-common-plugin-package/README.md.hbs +0 -5
  85. package/templates/default-common-plugin-package/tsconfig.json +0 -9
  86. package/templates/default-node-plugin-package/README.md.hbs +0 -5
  87. package/templates/default-node-plugin-package/tsconfig.json +0 -9
  88. package/templates/default-plugin/tsconfig.json +0 -12
  89. package/templates/default-react-plugin-package/README.md.hbs +0 -5
  90. package/templates/default-react-plugin-package/tsconfig.json +0 -11
  91. package/templates/node-library-package/tsconfig.json +0 -11
  92. package/templates/scaffolder-module/README.md.hbs +0 -5
  93. package/templates/scaffolder-module/tsconfig.json +0 -9
  94. package/templates/web-library-package/tsconfig.json +0 -11
  95. /package/templates/{default-backend-plugin → backend-plugin}/.eslintrc.js.hbs +0 -0
  96. /package/templates/{default-backend-plugin → backend-plugin}/src/index.ts.hbs +0 -0
  97. /package/templates/{default-backend-plugin → backend-plugin}/src/router.test.ts +0 -0
  98. /package/templates/{default-backend-plugin → backend-plugin}/src/router.ts +0 -0
  99. /package/templates/{default-backend-plugin → backend-plugin}/src/services/TodoListService/createTodoListService.ts +0 -0
  100. /package/templates/{default-backend-plugin → backend-plugin}/src/services/TodoListService/index.ts +0 -0
  101. /package/templates/{default-backend-plugin → backend-plugin}/src/services/TodoListService/types.ts +0 -0
  102. /package/templates/{default-backend-plugin → backend-plugin}/src/setupTests.ts +0 -0
  103. /package/templates/{default-backend-module → backend-plugin-module}/.eslintrc.js.hbs +0 -0
  104. /package/templates/{default-backend-module → backend-plugin-module}/src/index.ts.hbs +0 -0
  105. /package/templates/{default-backend-module → backend-plugin-module}/src/module.ts.hbs +0 -0
  106. /package/templates/{default-common-plugin-package → frontend-plugin}/.eslintrc.js.hbs +0 -0
  107. /package/templates/{default-plugin → frontend-plugin}/src/components/ExampleComponent/index.ts +0 -0
  108. /package/templates/{default-plugin → frontend-plugin}/src/components/ExampleFetchComponent/ExampleFetchComponent.test.tsx.hbs +0 -0
  109. /package/templates/{default-plugin → frontend-plugin}/src/components/ExampleFetchComponent/ExampleFetchComponent.tsx.hbs +0 -0
  110. /package/templates/{default-plugin → frontend-plugin}/src/components/ExampleFetchComponent/index.ts +0 -0
  111. /package/templates/{default-plugin → frontend-plugin}/src/index.ts.hbs +0 -0
  112. /package/templates/{default-plugin → frontend-plugin}/src/setupTests.ts +0 -0
  113. /package/templates/{default-node-plugin-package → node-library}/.eslintrc.js.hbs +0 -0
  114. /package/templates/{node-library-package → node-library}/src/index.ts.hbs +0 -0
  115. /package/templates/{default-common-plugin-package → node-library}/src/setupTests.ts +0 -0
  116. /package/templates/{default-plugin → plugin-common-library}/.eslintrc.js.hbs +0 -0
  117. /package/templates/{default-node-plugin-package → plugin-common-library}/src/setupTests.ts +0 -0
  118. /package/templates/{default-react-plugin-package → plugin-node-library}/.eslintrc.js.hbs +0 -0
  119. /package/templates/{node-library-package → plugin-node-library}/src/setupTests.ts +0 -0
  120. /package/templates/{node-library-package → plugin-web-library}/.eslintrc.js.hbs +0 -0
  121. /package/templates/{default-react-plugin-package → plugin-web-library}/src/components/ExampleComponent/ExampleComponent.test.tsx +0 -0
  122. /package/templates/{default-react-plugin-package → plugin-web-library}/src/components/ExampleComponent/ExampleComponent.tsx +0 -0
  123. /package/templates/{default-react-plugin-package → plugin-web-library}/src/components/ExampleComponent/index.ts +0 -0
  124. /package/templates/{default-react-plugin-package → plugin-web-library}/src/components/index.ts +0 -0
  125. /package/templates/{default-react-plugin-package → plugin-web-library}/src/hooks/index.ts +0 -0
  126. /package/templates/{default-react-plugin-package → plugin-web-library}/src/hooks/useExample/index.ts +0 -0
  127. /package/templates/{default-react-plugin-package → plugin-web-library}/src/hooks/useExample/useExample.ts +0 -0
  128. /package/templates/{default-react-plugin-package → plugin-web-library}/src/setupTests.ts +0 -0
  129. /package/templates/{scaffolder-module → scaffolder-backend-module}/.eslintrc.js.hbs +0 -0
  130. /package/templates/{scaffolder-module → scaffolder-backend-module}/src/actions/example.test.ts +0 -0
  131. /package/templates/{scaffolder-module → scaffolder-backend-module}/src/actions/example.ts +0 -0
  132. /package/templates/{scaffolder-module → scaffolder-backend-module}/src/module.ts +0 -0
  133. /package/templates/{web-library-package → web-library}/.eslintrc.js.hbs +0 -0
  134. /package/templates/{web-library-package → web-library}/src/index.ts.hbs +0 -0
  135. /package/templates/{web-library-package → web-library}/src/setupTests.ts +0 -0
@@ -0,0 +1,157 @@
1
+ 'use strict';
2
+
3
+ var inquirer = require('inquirer');
4
+ var codeowners = require('../../codeowners/codeowners.cjs.js');
5
+ var paths = require('../../paths.cjs.js');
6
+ var resolvePackageParams = require('./resolvePackageParams.cjs.js');
7
+
8
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
9
+
10
+ var inquirer__default = /*#__PURE__*/_interopDefaultCompat(inquirer);
11
+
12
+ async function collectPortableTemplateInput(options) {
13
+ const { config, template, prefilledParams } = options;
14
+ const codeOwnersFilePath = await codeowners.getCodeownersFilePath(paths.paths.targetRoot);
15
+ const prompts = getPromptsForRole(template.role);
16
+ if (codeOwnersFilePath) {
17
+ prompts.push(ownerPrompt());
18
+ }
19
+ const deprecatedParams = {};
20
+ if (config.isUsingDefaultTemplates && prefilledParams.id) {
21
+ console.warn(
22
+ `DEPRECATION WARNING: The 'id' parameter is deprecated, use 'pluginId' instead`
23
+ );
24
+ deprecatedParams.pluginId = prefilledParams.id;
25
+ }
26
+ const parameters = {
27
+ ...template.values,
28
+ ...prefilledParams,
29
+ ...deprecatedParams
30
+ };
31
+ const needsAnswer = [];
32
+ const prefilledAnswers = {};
33
+ for (const prompt of prompts) {
34
+ if (prompt.name && parameters[prompt.name] !== void 0) {
35
+ prefilledAnswers[prompt.name] = parameters[prompt.name];
36
+ } else {
37
+ needsAnswer.push(prompt);
38
+ }
39
+ }
40
+ const promptAnswers = await inquirer__default.default.prompt(
41
+ needsAnswer
42
+ );
43
+ const answers = {
44
+ ...prefilledAnswers,
45
+ ...promptAnswers
46
+ };
47
+ const roleParams = {
48
+ role: template.role,
49
+ name: answers.name,
50
+ pluginId: answers.pluginId,
51
+ moduleId: answers.moduleId
52
+ };
53
+ const packageParams = resolvePackageParams.resolvePackageParams({
54
+ roleParams,
55
+ packagePrefix: config.packageNamePrefix,
56
+ pluginInfix: config.packageNamePluginInfix
57
+ });
58
+ return {
59
+ roleParams,
60
+ owner: answers.owner,
61
+ license: config.license,
62
+ version: config.version,
63
+ private: config.private,
64
+ publishRegistry: config.publishRegistry,
65
+ packageName: packageParams.packageName,
66
+ packagePath: packageParams.packagePath
67
+ };
68
+ }
69
+ function namePrompt() {
70
+ return {
71
+ type: "input",
72
+ name: "name",
73
+ message: "Enter the name of the package, without scope [required]",
74
+ validate: (value) => {
75
+ if (!value) {
76
+ return "Please enter the name of the package";
77
+ } else if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(value)) {
78
+ return "Package names must be lowercase and contain only letters, digits, and dashes.";
79
+ }
80
+ return true;
81
+ }
82
+ };
83
+ }
84
+ function pluginIdPrompt() {
85
+ return {
86
+ type: "input",
87
+ name: "pluginId",
88
+ message: "Enter the ID of the plugin [required]",
89
+ validate: (value) => {
90
+ if (!value) {
91
+ return "Please enter the ID of the plugin";
92
+ } else if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(value)) {
93
+ return "Plugin IDs must be lowercase and contain only letters, digits, and dashes.";
94
+ }
95
+ return true;
96
+ }
97
+ };
98
+ }
99
+ function moduleIdIdPrompt() {
100
+ return {
101
+ type: "input",
102
+ name: "moduleId",
103
+ message: "Enter the ID of the module [required]",
104
+ validate: (value) => {
105
+ if (!value) {
106
+ return "Please enter the ID of the module";
107
+ } else if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(value)) {
108
+ return "Module IDs must be lowercase and contain only letters, digits, and dashes.";
109
+ }
110
+ return true;
111
+ }
112
+ };
113
+ }
114
+ function getPromptsForRole(role) {
115
+ switch (role) {
116
+ case "web-library":
117
+ case "node-library":
118
+ case "common-library":
119
+ return [namePrompt()];
120
+ case "plugin-web-library":
121
+ case "plugin-node-library":
122
+ case "plugin-common-library":
123
+ case "frontend-plugin":
124
+ case "backend-plugin":
125
+ return [pluginIdPrompt()];
126
+ case "frontend-plugin-module":
127
+ case "backend-plugin-module":
128
+ return [pluginIdPrompt(), moduleIdIdPrompt()];
129
+ default:
130
+ return [];
131
+ }
132
+ }
133
+ function ownerPrompt() {
134
+ return {
135
+ type: "input",
136
+ name: "owner",
137
+ message: "Enter an owner to add to CODEOWNERS [optional]",
138
+ validate: (value) => {
139
+ if (!value) {
140
+ return true;
141
+ }
142
+ const ownerIds = codeowners.parseOwnerIds(value);
143
+ if (!ownerIds) {
144
+ return "The owner must be a space separated list of team names (e.g. @org/team-name), usernames (e.g. @username), or the email addresses (e.g. user@example.com).";
145
+ }
146
+ return true;
147
+ }
148
+ };
149
+ }
150
+
151
+ exports.collectPortableTemplateInput = collectPortableTemplateInput;
152
+ exports.getPromptsForRole = getPromptsForRole;
153
+ exports.moduleIdIdPrompt = moduleIdIdPrompt;
154
+ exports.namePrompt = namePrompt;
155
+ exports.ownerPrompt = ownerPrompt;
156
+ exports.pluginIdPrompt = pluginIdPrompt;
157
+ //# sourceMappingURL=collectPortableTemplateInput.cjs.js.map
@@ -0,0 +1,82 @@
1
+ 'use strict';
2
+
3
+ var z = require('zod');
4
+ var fs = require('fs-extra');
5
+ var recursiveReaddir = require('recursive-readdir');
6
+ var path = require('path');
7
+ var node_path = require('node:path');
8
+ var yaml = require('yaml');
9
+ var paths = require('../../paths.cjs.js');
10
+ var types = require('../types.cjs.js');
11
+ var errors = require('@backstage/errors');
12
+ var zodValidationError = require('zod-validation-error');
13
+
14
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
15
+
16
+ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
17
+ var recursiveReaddir__default = /*#__PURE__*/_interopDefaultCompat(recursiveReaddir);
18
+
19
+ const templateDefinitionSchema = z.z.object({
20
+ name: z.z.string(),
21
+ role: z.z.enum(types.TEMPLATE_ROLES),
22
+ description: z.z.string().optional(),
23
+ values: z.z.record(z.z.string()).optional()
24
+ }).strict();
25
+ async function loadPortableTemplate(pointer) {
26
+ if (pointer.target.match(/https?:\/\//)) {
27
+ throw new Error("Remote templates are not supported yet");
28
+ }
29
+ const templateContent = await fs__default.default.readFile(paths.paths.resolveTargetRoot(pointer.target), "utf-8").catch((error) => {
30
+ throw new errors.ForwardedError(
31
+ `Failed to load template definition from '${pointer.target}'`,
32
+ error
33
+ );
34
+ });
35
+ const rawTemplate = yaml.parse(templateContent);
36
+ const parsed = templateDefinitionSchema.safeParse(rawTemplate);
37
+ if (!parsed.success) {
38
+ throw new errors.ForwardedError(
39
+ `Invalid template definition at '${pointer.target}'`,
40
+ zodValidationError.fromZodError(parsed.error)
41
+ );
42
+ }
43
+ const { role, values = {} } = parsed.data;
44
+ const templatePath = path.resolve(node_path.dirname(pointer.target));
45
+ const filePaths = await recursiveReaddir__default.default(templatePath).catch((error) => {
46
+ throw new errors.ForwardedError(
47
+ `Failed to load template contents from '${templatePath}'`,
48
+ error
49
+ );
50
+ });
51
+ const loadedFiles = new Array();
52
+ for (const filePath of filePaths) {
53
+ const path$1 = path.relative(templatePath, filePath);
54
+ if (filePath === pointer.target) {
55
+ continue;
56
+ }
57
+ const content = await fs__default.default.readFile(filePath, "utf-8").catch((error) => {
58
+ throw new errors.ForwardedError(
59
+ `Failed to load file contents from '${path$1}'`,
60
+ error
61
+ );
62
+ });
63
+ if (path$1.endsWith(".hbs")) {
64
+ loadedFiles.push({
65
+ path: path$1.slice(0, -4),
66
+ content,
67
+ syntax: "handlebars"
68
+ });
69
+ } else {
70
+ loadedFiles.push({ path: path$1, content });
71
+ }
72
+ }
73
+ return {
74
+ name: pointer.name,
75
+ role,
76
+ files: loadedFiles,
77
+ values
78
+ };
79
+ }
80
+
81
+ exports.loadPortableTemplate = loadPortableTemplate;
82
+ //# sourceMappingURL=loadPortableTemplate.cjs.js.map
@@ -0,0 +1,121 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs-extra');
4
+ var node_path = require('node:path');
5
+ var paths = require('../../paths.cjs.js');
6
+ var defaultTemplates = require('../defaultTemplates.cjs.js');
7
+ var types = require('../types.cjs.js');
8
+ var yaml = require('yaml');
9
+ var z = require('zod');
10
+ var zodValidationError = require('zod-validation-error');
11
+ var errors = require('@backstage/errors');
12
+
13
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
14
+
15
+ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
16
+
17
+ const defaults = {
18
+ license: "Apache-2.0",
19
+ version: "0.1.0",
20
+ private: true,
21
+ publishRegistry: void 0,
22
+ packageNamePrefix: "@internal/",
23
+ packageNamePluginInfix: "plugin-"
24
+ };
25
+ const newConfigSchema = z.z.object({
26
+ templates: z.z.array(z.z.string()).optional(),
27
+ globals: z.z.object({
28
+ license: z.z.string().optional(),
29
+ version: z.z.string().optional(),
30
+ private: z.z.boolean().optional(),
31
+ publishRegistry: z.z.string().optional(),
32
+ namePrefix: z.z.string().optional(),
33
+ namePluginInfix: z.z.string().optional()
34
+ }).optional()
35
+ }).strict();
36
+ const pkgJsonWithNewConfigSchema = z.z.object({
37
+ backstage: z.z.object({
38
+ cli: z.z.object({
39
+ new: newConfigSchema.optional()
40
+ }).optional()
41
+ }).optional()
42
+ });
43
+ async function loadPortableTemplateConfig(options = {}) {
44
+ const { overrides = {} } = options;
45
+ const pkgPath = options.packagePath ?? paths.paths.resolveTargetRoot("package.json");
46
+ const pkgJson = await fs__default.default.readJson(pkgPath);
47
+ const parsed = pkgJsonWithNewConfigSchema.safeParse(pkgJson);
48
+ if (!parsed.success) {
49
+ throw new errors.ForwardedError(
50
+ `Failed to load templating configuration from '${pkgPath}'`,
51
+ zodValidationError.fromZodError(parsed.error)
52
+ );
53
+ }
54
+ const config = parsed.data.backstage?.cli?.new;
55
+ const basePath = node_path.dirname(pkgPath);
56
+ const templatePointerEntries = await Promise.all(
57
+ (config?.templates ?? defaultTemplates.defaultTemplates).map(async (rawPointer) => {
58
+ try {
59
+ const templatePath = resolveLocalTemplatePath(rawPointer, basePath);
60
+ const pointer = await peekLocalTemplateDefinition(templatePath);
61
+ return { pointer, rawPointer };
62
+ } catch (error) {
63
+ throw new errors.ForwardedError(
64
+ `Failed to load template definition '${rawPointer}'`,
65
+ error
66
+ );
67
+ }
68
+ })
69
+ );
70
+ const templateNameConflicts = /* @__PURE__ */ new Map();
71
+ for (const { pointer, rawPointer } of templatePointerEntries) {
72
+ const conflict = templateNameConflicts.get(pointer.name);
73
+ if (conflict) {
74
+ throw new Error(
75
+ `Invalid template configuration, received conflicting template name '${pointer.name}' from '${conflict}' and '${rawPointer}'`
76
+ );
77
+ }
78
+ templateNameConflicts.set(pointer.name, rawPointer);
79
+ }
80
+ return {
81
+ isUsingDefaultTemplates: !config?.templates,
82
+ templatePointers: templatePointerEntries.map(({ pointer }) => pointer),
83
+ license: overrides.license ?? config?.globals?.license ?? defaults.license,
84
+ version: overrides.version ?? config?.globals?.version ?? defaults.version,
85
+ private: overrides.private ?? config?.globals?.private ?? defaults.private,
86
+ publishRegistry: overrides.publishRegistry ?? config?.globals?.publishRegistry ?? defaults.publishRegistry,
87
+ packageNamePrefix: overrides.packageNamePrefix ?? config?.globals?.namePrefix ?? defaults.packageNamePrefix,
88
+ packageNamePluginInfix: overrides.packageNamePluginInfix ?? config?.globals?.namePluginInfix ?? defaults.packageNamePluginInfix
89
+ };
90
+ }
91
+ function resolveLocalTemplatePath(pointer, basePath) {
92
+ if (node_path.isAbsolute(pointer)) {
93
+ throw new Error(`Template target may not be an absolute path`);
94
+ }
95
+ if (pointer.startsWith(".")) {
96
+ return node_path.resolve(basePath, pointer, types.TEMPLATE_FILE_NAME);
97
+ }
98
+ return require.resolve(`${pointer}/${types.TEMPLATE_FILE_NAME}`, {
99
+ paths: [basePath]
100
+ });
101
+ }
102
+ const partialTemplateDefinitionSchema = z.z.object({
103
+ name: z.z.string(),
104
+ description: z.z.string().optional()
105
+ });
106
+ async function peekLocalTemplateDefinition(target) {
107
+ const content = await fs__default.default.readFile(target, "utf8");
108
+ const rawTemplate = yaml.parse(content);
109
+ const parsed = partialTemplateDefinitionSchema.safeParse(rawTemplate);
110
+ if (!parsed.success) {
111
+ throw zodValidationError.fromZodError(parsed.error);
112
+ }
113
+ return {
114
+ name: parsed.data.name,
115
+ description: parsed.data.description,
116
+ target
117
+ };
118
+ }
119
+
120
+ exports.loadPortableTemplateConfig = loadPortableTemplateConfig;
121
+ //# sourceMappingURL=loadPortableTemplateConfig.cjs.js.map
@@ -0,0 +1,40 @@
1
+ 'use strict';
2
+
3
+ var path = require('path');
4
+
5
+ function resolvePackageParams(options) {
6
+ const baseName = getBaseNameForRole(options.roleParams);
7
+ const isPlugin = options.roleParams.role.includes("plugin");
8
+ const pluginInfix = isPlugin ? options.pluginInfix : "";
9
+ return {
10
+ packageName: `${options.packagePrefix}${pluginInfix}${baseName}`,
11
+ packagePath: path.join(isPlugin ? "plugins" : "packages", baseName)
12
+ };
13
+ }
14
+ function getBaseNameForRole(roleParams) {
15
+ switch (roleParams.role) {
16
+ case "web-library":
17
+ case "node-library":
18
+ case "common-library":
19
+ return roleParams.name;
20
+ case "plugin-web-library":
21
+ return `${roleParams.pluginId}-react`;
22
+ case "plugin-node-library":
23
+ return `${roleParams.pluginId}-node`;
24
+ case "plugin-common-library":
25
+ return `${roleParams.pluginId}-common`;
26
+ case "frontend-plugin":
27
+ return `${roleParams.pluginId}`;
28
+ case "frontend-plugin-module":
29
+ return `${roleParams.pluginId}-module-${roleParams.moduleId}`;
30
+ case "backend-plugin":
31
+ return `${roleParams.pluginId}-backend`;
32
+ case "backend-plugin-module":
33
+ return `${roleParams.pluginId}-backend-module-${roleParams.moduleId}`;
34
+ default:
35
+ throw new Error(`Unknown role ${roleParams.role}`);
36
+ }
37
+ }
38
+
39
+ exports.resolvePackageParams = resolvePackageParams;
40
+ //# sourceMappingURL=resolvePackageParams.cjs.js.map
@@ -0,0 +1,38 @@
1
+ 'use strict';
2
+
3
+ var inquirer = require('inquirer');
4
+
5
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
6
+
7
+ var inquirer__default = /*#__PURE__*/_interopDefaultCompat(inquirer);
8
+
9
+ async function selectTemplateInteractively(config, preselectedTemplateName) {
10
+ let selectedName = preselectedTemplateName;
11
+ if (config.isUsingDefaultTemplates && selectedName === "plugin") {
12
+ console.warn(
13
+ `DEPRECATION WARNING: The 'plugin' template is deprecated, use 'frontend-plugin' instead`
14
+ );
15
+ selectedName = "frontend-plugin";
16
+ }
17
+ if (!selectedName) {
18
+ const answers = await inquirer__default.default.prompt([
19
+ {
20
+ type: "list",
21
+ name: "name",
22
+ message: "What do you want to create?",
23
+ choices: config.templatePointers.map(
24
+ (t) => t.description ? { name: `${t.name} - ${t.description}`, value: t.name } : t.name
25
+ )
26
+ }
27
+ ]);
28
+ selectedName = answers.name;
29
+ }
30
+ const template = config.templatePointers.find((t) => t.name === selectedName);
31
+ if (!template) {
32
+ throw new Error(`Template '${selectedName}' not found`);
33
+ }
34
+ return template;
35
+ }
36
+
37
+ exports.selectTemplateInteractively = selectTemplateInteractively;
38
+ //# sourceMappingURL=selectTemplateInteractively.cjs.js.map
@@ -1,8 +1,19 @@
1
1
  'use strict';
2
2
 
3
- function createFactory(config) {
4
- return config;
5
- }
3
+ const TEMPLATE_FILE_NAME = "portable-template.yaml";
4
+ const TEMPLATE_ROLES = [
5
+ "web-library",
6
+ "node-library",
7
+ "common-library",
8
+ "plugin-web-library",
9
+ "plugin-node-library",
10
+ "plugin-common-library",
11
+ "frontend-plugin",
12
+ "frontend-plugin-module",
13
+ "backend-plugin",
14
+ "backend-plugin-module"
15
+ ];
6
16
 
7
- exports.createFactory = createFactory;
17
+ exports.TEMPLATE_FILE_NAME = TEMPLATE_FILE_NAME;
18
+ exports.TEMPLATE_ROLES = TEMPLATE_ROLES;
8
19
  //# sourceMappingURL=types.cjs.js.map
@@ -1,23 +1,15 @@
1
1
  'use strict';
2
2
 
3
3
  var chalk = require('chalk');
4
- var fs = require('fs-extra');
5
- var handlebars = require('handlebars');
6
4
  var ora = require('ora');
7
5
  var util = require('util');
8
- var path = require('path');
9
- var recursive = require('recursive-readdir');
10
6
  var child_process = require('child_process');
11
7
  var errors = require('@backstage/errors');
12
- var paths = require('./paths.cjs.js');
13
8
 
14
9
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
15
10
 
16
11
  var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
17
- var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
18
- var handlebars__default = /*#__PURE__*/_interopDefaultCompat(handlebars);
19
12
  var ora__default = /*#__PURE__*/_interopDefaultCompat(ora);
20
- var recursive__default = /*#__PURE__*/_interopDefaultCompat(recursive);
21
13
 
22
14
  const exec = util.promisify(child_process.exec);
23
15
  const TASK_NAME_MAX_LENGTH = 14;
@@ -80,109 +72,6 @@ ${chalk__default.default.red(message)}
80
72
  }
81
73
  }
82
74
  }
83
- async function templatingTask(templateDir, destinationDir, context, versionProvider, isMonoRepo) {
84
- const files = await recursive__default.default(templateDir).catch((error) => {
85
- throw new Error(`Failed to read template directory: ${error.message}`);
86
- });
87
- for (const file of files) {
88
- const destinationFile = file.replace(templateDir, destinationDir);
89
- await fs__default.default.ensureDir(path.dirname(destinationFile));
90
- if (file.endsWith(".hbs")) {
91
- await Task.forItem("templating", path.basename(file), async () => {
92
- const destination = destinationFile.replace(/\.hbs$/, "");
93
- const template = await fs__default.default.readFile(file);
94
- const compiled = handlebars__default.default.compile(template.toString(), {
95
- strict: true
96
- });
97
- const contents = compiled(
98
- { name: path.basename(destination), ...context },
99
- {
100
- helpers: {
101
- versionQuery(name, versionHint) {
102
- return versionProvider(
103
- name,
104
- typeof versionHint === "string" ? versionHint : void 0
105
- );
106
- }
107
- }
108
- }
109
- );
110
- await fs__default.default.writeFile(destination, contents).catch((error) => {
111
- throw new Error(
112
- `Failed to create file: ${destination}: ${error.message}`
113
- );
114
- });
115
- });
116
- } else {
117
- if (isMonoRepo && file.match("tsconfig.json")) {
118
- continue;
119
- }
120
- await Task.forItem("copying", path.basename(file), async () => {
121
- await fs__default.default.copyFile(file, destinationFile).catch((error) => {
122
- const destination = destinationFile;
123
- throw new Error(
124
- `Failed to copy file to ${destination} : ${error.message}`
125
- );
126
- });
127
- });
128
- }
129
- }
130
- }
131
- async function addPackageDependency(path, options) {
132
- try {
133
- const pkgJson = await fs__default.default.readJson(path);
134
- const normalize = (obj) => {
135
- if (Object.keys(obj).length === 0) {
136
- return void 0;
137
- }
138
- return Object.fromEntries(
139
- Object.keys(obj).sort().map((key) => [key, obj[key]])
140
- );
141
- };
142
- pkgJson.dependencies = normalize({
143
- ...pkgJson.dependencies,
144
- ...options.dependencies
145
- });
146
- pkgJson.devDependencies = normalize({
147
- ...pkgJson.devDependencies,
148
- ...options.devDependencies
149
- });
150
- pkgJson.peerDependencies = normalize({
151
- ...pkgJson.peerDependencies,
152
- ...options.peerDependencies
153
- });
154
- await fs__default.default.writeJson(path, pkgJson, { spaces: 2 });
155
- } catch (error) {
156
- throw new Error(`Failed to add package dependencies, ${error}`);
157
- }
158
- }
159
- async function addToBackend(name, options) {
160
- if (await fs__default.default.pathExists(paths.paths.resolveTargetRoot("packages/backend"))) {
161
- await Task.forItem("backend", `adding ${options.type}`, async () => {
162
- const backendFilePath = paths.paths.resolveTargetRoot(
163
- "packages/backend/src/index.ts"
164
- );
165
- if (!await fs__default.default.pathExists(backendFilePath)) {
166
- return;
167
- }
168
- const content = await fs__default.default.readFile(backendFilePath, "utf8");
169
- const lines = content.split("\n");
170
- const backendAddLine = `backend.add(import('${name}'));`;
171
- const backendStartIndex = lines.findIndex(
172
- (line) => line.match(/backend.start/)
173
- );
174
- if (backendStartIndex !== -1) {
175
- const [indentation] = lines[backendStartIndex].match(/^\s*/);
176
- lines.splice(backendStartIndex, 0, `${indentation}${backendAddLine}`);
177
- const newContent = lines.join("\n");
178
- await fs__default.default.writeFile(backendFilePath, newContent, "utf8");
179
- }
180
- });
181
- }
182
- }
183
75
 
184
76
  exports.Task = Task;
185
- exports.addPackageDependency = addPackageDependency;
186
- exports.addToBackend = addToBackend;
187
- exports.templatingTask = templatingTask;
188
77
  //# sourceMappingURL=tasks.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.8.0-next.2";
3
+ var version = "0.8.0-next.3";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "1.2.0-next.1";
3
+ var version = "1.2.0-next.2";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "1.3.0-next.2";
3
+ var version = "1.3.0-next.3";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.30.0-next.2";
3
+ var version = "0.30.0-next.3";
4
4
  var dependencies = {
5
5
  "@backstage/catalog-model": "workspace:^",
6
6
  "@backstage/cli-common": "workspace:^",
@@ -114,7 +114,8 @@ var dependencies = {
114
114
  yargs: "^16.2.0",
115
115
  "yml-loader": "^2.1.0",
116
116
  yn: "^4.0.0",
117
- zod: "^3.22.4"
117
+ zod: "^3.22.4",
118
+ "zod-validation-error": "^3.4.0"
118
119
  };
119
120
  var devDependencies = {
120
121
  "@backstage/backend-plugin-api": "workspace:^",
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "1.1.7-next.2";
3
+ var version = "1.1.7-next.3";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.24.3-next.2";
3
+ var version = "0.24.3-next.3";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.2.5-next.1";
3
+ var version = "0.2.5-next.2";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "1.16.0-next.2";
3
+ var version = "1.16.0-next.3";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map