@backstage/cli 0.28.0-next.1 → 0.28.0

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 (157) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/config/jest.js +9 -1
  3. package/config/jestCacheResultProcessor.cjs +23 -0
  4. package/config/jestSwcTransform.js +4 -1
  5. package/dist/commands/build/buildBackend.cjs.js +65 -0
  6. package/dist/commands/build/buildFrontend.cjs.js +57 -0
  7. package/dist/commands/build/command.cjs.js +75 -0
  8. package/dist/commands/build/index.cjs.js +8 -0
  9. package/dist/commands/buildWorkspace.cjs.js +24 -0
  10. package/dist/commands/clean/clean.cjs.js +19 -0
  11. package/dist/{cjs/docs-BGyA6jwW.cjs.js → commands/config/docs.cjs.js} +4 -12
  12. package/dist/{cjs/print-Dd6aChXU.cjs.js → commands/config/print.cjs.js} +4 -12
  13. package/dist/{cjs/schema-D93FRhBL.cjs.js → commands/config/schema.cjs.js} +4 -12
  14. package/dist/commands/config/validate.cjs.js +19 -0
  15. package/dist/{cjs/index-j193pV_Y.cjs.js → commands/create-github-app/GithubCreateAppServer.cjs.js} +2 -110
  16. package/dist/commands/create-github-app/index.cjs.js +117 -0
  17. package/dist/commands/index.cjs.js +231 -0
  18. package/dist/{cjs/info-DuAv1Tsx.cjs.js → commands/info.cjs.js} +13 -17
  19. package/dist/{cjs/lint-BwiDJkjE.cjs.js → commands/lint.cjs.js} +10 -10
  20. package/dist/commands/migrate/packageExports.cjs.js +17 -0
  21. package/dist/{cjs/packageLintConfigs-DeUGBP17.cjs.js → commands/migrate/packageLintConfigs.cjs.js} +2 -10
  22. package/dist/{cjs/packageRole-Iuv9NRii.cjs.js → commands/migrate/packageRole.cjs.js} +5 -8
  23. package/dist/{cjs/packageScripts-DX6dilK6.cjs.js → commands/migrate/packageScripts.cjs.js} +1 -1
  24. package/dist/{cjs/reactRouterDeps-CR-hjviw.cjs.js → commands/migrate/reactRouterDeps.cjs.js} +1 -1
  25. package/dist/commands/new/new.cjs.js +101 -0
  26. package/dist/commands/pack.cjs.js +29 -0
  27. package/dist/commands/repo/build.cjs.js +113 -0
  28. package/dist/{cjs/clean-a6Q4k9Vm.cjs.js → commands/repo/clean.cjs.js} +5 -10
  29. package/dist/{cjs/fix-COitqgqm.cjs.js → commands/repo/fix.cjs.js} +8 -13
  30. package/dist/commands/repo/lint.cjs.js +205 -0
  31. package/dist/{cjs/list-deprecations-CtUaQgaP.cjs.js → commands/repo/list-deprecations.cjs.js} +7 -12
  32. package/dist/commands/repo/optionsParser.cjs.js +37 -0
  33. package/dist/commands/repo/test.cjs.js +277 -0
  34. package/dist/commands/start/command.cjs.js +48 -0
  35. package/dist/commands/start/index.cjs.js +8 -0
  36. package/dist/commands/start/startBackend.cjs.js +112 -0
  37. package/dist/commands/start/startFrontend.cjs.js +47 -0
  38. package/dist/{cjs/test-COxIko8N.cjs.js → commands/test.cjs.js} +6 -12
  39. package/dist/{cjs/bump-BHEh5ytx.cjs.js → commands/versions/bump.cjs.js} +21 -190
  40. package/dist/commands/versions/migrate.cjs.js +112 -0
  41. package/dist/index.cjs.js +29 -7
  42. package/dist/lib/builder/config.cjs.js +199 -0
  43. package/dist/lib/builder/packager.cjs.js +131 -0
  44. package/dist/lib/builder/plugins.cjs.js +71 -0
  45. package/dist/lib/builder/types.cjs.js +11 -0
  46. package/dist/lib/bundler/LinkedPackageResolvePlugin.cjs.js +47 -0
  47. package/dist/lib/bundler/backend.cjs.js +36 -0
  48. package/dist/{cjs/buildBackend-CkhZWCz1.cjs.js → lib/bundler/bundle.cjs.js} +31 -117
  49. package/dist/lib/bundler/config.cjs.js +491 -0
  50. package/dist/lib/bundler/hasReactDomClient.cjs.js +17 -0
  51. package/dist/lib/bundler/moduleFederation.cjs.js +28 -0
  52. package/dist/lib/bundler/optimization.cjs.js +67 -0
  53. package/dist/lib/bundler/packageDetection.cjs.js +117 -0
  54. package/dist/lib/bundler/paths.cjs.js +60 -0
  55. package/dist/lib/bundler/server.cjs.js +286 -0
  56. package/dist/lib/bundler/transforms.cjs.js +172 -0
  57. package/dist/lib/codeowners/codeowners.cjs.js +92 -0
  58. package/dist/{cjs/config-DBpmZirN.cjs.js → lib/config.cjs.js} +6 -6
  59. package/dist/{cjs/entryPoints-coip0t-x.cjs.js → lib/entryPoints.cjs.js} +1 -1
  60. package/dist/lib/errors.cjs.js +45 -0
  61. package/dist/lib/experimental/IpcServer.cjs.js +60 -0
  62. package/dist/lib/experimental/ServerDataStore.cjs.js +36 -0
  63. package/dist/lib/experimental/startBackendExperimental.cjs.js +128 -0
  64. package/dist/lib/new/FactoryRegistry.cjs.js +96 -0
  65. package/dist/lib/new/factories/backendModule.cjs.js +82 -0
  66. package/dist/lib/new/factories/backendPlugin.cjs.js +78 -0
  67. package/dist/lib/new/factories/common/prompts.cjs.js +57 -0
  68. package/dist/lib/new/factories/common/tasks.cjs.js +66 -0
  69. package/dist/lib/new/factories/common/util.cjs.js +16 -0
  70. package/dist/lib/new/factories/frontendPlugin.cjs.js +107 -0
  71. package/dist/lib/new/factories/index.cjs.js +24 -0
  72. package/dist/lib/new/factories/nodeLibraryPackage.cjs.js +57 -0
  73. package/dist/lib/new/factories/pluginCommon.cjs.js +58 -0
  74. package/dist/lib/new/factories/pluginNode.cjs.js +58 -0
  75. package/dist/lib/new/factories/pluginWeb.cjs.js +58 -0
  76. package/dist/lib/new/factories/scaffolderModule.cjs.js +90 -0
  77. package/dist/lib/new/factories/webLibraryPackage.cjs.js +57 -0
  78. package/dist/lib/new/types.cjs.js +8 -0
  79. package/dist/lib/packager/createDistWorkspace.cjs.js +219 -0
  80. package/dist/{cjs/productionPack-BxoMbBkH.cjs.js → lib/packager/productionPack.cjs.js} +8 -96
  81. package/dist/{cjs/parallel-BszNaKyc.cjs.js → lib/parallel.cjs.js} +2 -1
  82. package/dist/lib/paths.cjs.js +8 -0
  83. package/dist/{cjs/publishing-DQtsKTbc.cjs.js → lib/publishing.cjs.js} +1 -1
  84. package/dist/{cjs/role-BjiBExhi.cjs.js → lib/role.cjs.js} +3 -3
  85. package/dist/{cjs/run-CpZGNJQr.cjs.js → lib/run.cjs.js} +6 -5
  86. package/dist/{cjs/svgrTemplate-BTjBQ3by.cjs.js → lib/svgrTemplate.cjs.js} +1 -1
  87. package/dist/lib/tasks.cjs.js +188 -0
  88. package/dist/lib/typeDistProject.cjs.js +94 -0
  89. package/dist/lib/urls.cjs.js +13 -0
  90. package/dist/lib/version.cjs.js +94 -0
  91. package/dist/{cjs/yarn-6FNAgNBK.cjs.js → lib/versioning/Lockfile.cjs.js} +1 -31
  92. package/dist/lib/versioning/packages.cjs.js +75 -0
  93. package/dist/lib/yarn.cjs.js +34 -0
  94. package/dist/packages/backend-defaults/package.json.cjs.js +6 -0
  95. package/dist/packages/backend-plugin-api/package.json.cjs.js +6 -0
  96. package/dist/packages/backend-test-utils/package.json.cjs.js +6 -0
  97. package/dist/packages/catalog-client/package.json.cjs.js +6 -0
  98. package/dist/packages/cli/package.json.cjs.js +171 -0
  99. package/dist/packages/config/package.json.cjs.js +6 -0
  100. package/dist/packages/core-app-api/package.json.cjs.js +6 -0
  101. package/dist/packages/core-components/package.json.cjs.js +6 -0
  102. package/dist/packages/core-plugin-api/package.json.cjs.js +6 -0
  103. package/dist/packages/dev-utils/package.json.cjs.js +6 -0
  104. package/dist/packages/errors/package.json.cjs.js +6 -0
  105. package/dist/packages/test-utils/package.json.cjs.js +6 -0
  106. package/dist/packages/theme/package.json.cjs.js +6 -0
  107. package/dist/plugins/auth-backend/package.json.cjs.js +6 -0
  108. package/dist/plugins/auth-backend-module-guest-provider/package.json.cjs.js +6 -0
  109. package/dist/plugins/catalog-node/package.json.cjs.js +6 -0
  110. package/dist/plugins/scaffolder-node/package.json.cjs.js +6 -0
  111. package/dist/plugins/scaffolder-node-test-utils/package.json.cjs.js +6 -0
  112. package/package.json +55 -25
  113. package/templates/default-backend-plugin/README.md.hbs +22 -8
  114. package/templates/default-backend-plugin/dev/index.ts.hbs +60 -0
  115. package/templates/default-backend-plugin/package.json.hbs +5 -5
  116. package/templates/default-backend-plugin/src/index.ts.hbs +0 -1
  117. package/templates/default-backend-plugin/src/plugin.test.ts.hbs +85 -0
  118. package/templates/default-backend-plugin/src/plugin.ts.hbs +16 -14
  119. package/templates/default-backend-plugin/src/router.test.ts +67 -0
  120. package/templates/default-backend-plugin/src/router.ts +51 -0
  121. package/templates/default-backend-plugin/src/services/TodoListService/createTodoListService.ts +100 -0
  122. package/templates/default-backend-plugin/src/services/TodoListService/index.ts +1 -0
  123. package/templates/default-backend-plugin/src/services/TodoListService/types.ts +27 -0
  124. package/templates/scaffolder-module/package.json.hbs +3 -1
  125. package/templates/scaffolder-module/src/actions/example.test.ts +24 -0
  126. package/templates/scaffolder-module/src/actions/{example/example.ts → example.ts} +7 -3
  127. package/templates/scaffolder-module/src/index.ts.hbs +1 -1
  128. package/templates/scaffolder-module/src/{actions/example/module.ts → module.ts} +3 -3
  129. package/dist/cjs/build-CQdcGuBr.cjs.js +0 -194
  130. package/dist/cjs/buildWorkspace-CZPp9oRm.cjs.js +0 -53
  131. package/dist/cjs/clean-W6nxsHeK.cjs.js +0 -22
  132. package/dist/cjs/createDistWorkspace-DdHPGSMS.cjs.js +0 -576
  133. package/dist/cjs/index-BXv4Xa2e.cjs.js +0 -625
  134. package/dist/cjs/index-CGuAP7nv.cjs.js +0 -131
  135. package/dist/cjs/index-b1ouG3q6.cjs.js +0 -518
  136. package/dist/cjs/lint-Dsiocf9K.cjs.js +0 -91
  137. package/dist/cjs/moduleFederation-DmStnvEg.cjs.js +0 -910
  138. package/dist/cjs/new-CEnFhTT-.cjs.js +0 -1043
  139. package/dist/cjs/pack-XLRcGJqH.cjs.js +0 -34
  140. package/dist/cjs/packageExports-BJBwdvUH.cjs.js +0 -27
  141. package/dist/cjs/test-JcLI2pPM.cjs.js +0 -126
  142. package/dist/cjs/validate-CELljsEX.cjs.js +0 -28
  143. package/templates/default-backend-plugin/dev/index.ts +0 -9
  144. package/templates/default-backend-plugin/src/service/router.test.ts +0 -30
  145. package/templates/default-backend-plugin/src/service/router.ts +0 -28
  146. package/templates/scaffolder-module/src/actions/example/example.test.ts +0 -32
  147. package/templates/scaffolder-module/src/actions/example/index.ts +0 -7
  148. package/templates/scaffolder-module/src/actions/index.ts +0 -1
  149. /package/templates/default-backend-module/{.eslintrc.js → .eslintrc.js.hbs} +0 -0
  150. /package/templates/default-backend-plugin/{.eslintrc.js → .eslintrc.js.hbs} +0 -0
  151. /package/templates/default-common-plugin-package/{.eslintrc.js → .eslintrc.js.hbs} +0 -0
  152. /package/templates/default-node-plugin-package/{.eslintrc.js → .eslintrc.js.hbs} +0 -0
  153. /package/templates/default-plugin/{.eslintrc.js → .eslintrc.js.hbs} +0 -0
  154. /package/templates/default-react-plugin-package/{.eslintrc.js → .eslintrc.js.hbs} +0 -0
  155. /package/templates/node-library-package/{.eslintrc.js → .eslintrc.js.hbs} +0 -0
  156. /package/templates/scaffolder-module/{.eslintrc.js → .eslintrc.js.hbs} +0 -0
  157. /package/templates/web-library-package/{.eslintrc.js → .eslintrc.js.hbs} +0 -0
@@ -0,0 +1,92 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs-extra');
4
+ var path = require('path');
5
+ var paths = require('../paths.cjs.js');
6
+
7
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
8
+
9
+ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
10
+ var path__default = /*#__PURE__*/_interopDefaultCompat(path);
11
+
12
+ const TEAM_ID_RE = /^@[-\w]+\/[-\w]+$/;
13
+ const USER_ID_RE = /^@[-\w]+$/;
14
+ const EMAIL_RE = /^[^@]+@[-.\w]+\.[-\w]+$/i;
15
+ const DEFAULT_OWNER = "@backstage/maintainers";
16
+ async function getCodeownersFilePath(rootDir) {
17
+ const possiblePaths = [
18
+ path__default.default.join(rootDir, ".github", "CODEOWNERS"),
19
+ path__default.default.join(rootDir, ".gitlab", "CODEOWNERS"),
20
+ path__default.default.join(rootDir, "docs", "CODEOWNERS"),
21
+ path__default.default.join(rootDir, "CODEOWNERS")
22
+ ];
23
+ for (const p of possiblePaths) {
24
+ if (await fs__default.default.pathExists(p)) {
25
+ return p;
26
+ }
27
+ }
28
+ return void 0;
29
+ }
30
+ function isValidSingleOwnerId(id) {
31
+ if (!id || typeof id !== "string") {
32
+ return false;
33
+ }
34
+ return TEAM_ID_RE.test(id) || USER_ID_RE.test(id) || EMAIL_RE.test(id);
35
+ }
36
+ function parseOwnerIds(spaceSeparatedOwnerIds) {
37
+ if (!spaceSeparatedOwnerIds || typeof spaceSeparatedOwnerIds !== "string") {
38
+ return void 0;
39
+ }
40
+ const ids = spaceSeparatedOwnerIds.split(" ").filter(Boolean);
41
+ if (!ids.every(isValidSingleOwnerId)) {
42
+ return void 0;
43
+ }
44
+ return ids;
45
+ }
46
+ async function addCodeownersEntry(ownedPath, ownerStr, codeownersFilePath) {
47
+ const ownerIds = parseOwnerIds(ownerStr);
48
+ if (!ownerIds || ownerIds.length === 0) {
49
+ return false;
50
+ }
51
+ let filePath = codeownersFilePath;
52
+ if (!filePath) {
53
+ filePath = await getCodeownersFilePath(paths.paths.targetRoot);
54
+ if (!filePath) {
55
+ return false;
56
+ }
57
+ }
58
+ const allLines = (await fs__default.default.readFile(filePath, "utf8")).split("\n");
59
+ const commentLines = [];
60
+ for (const line of allLines) {
61
+ if (line[0] !== "#") {
62
+ break;
63
+ }
64
+ commentLines.push(line);
65
+ }
66
+ const oldDeclarationEntries = allLines.filter((line) => line[0] !== "#").map((line) => line.split(/\s+/).filter(Boolean)).filter((tokens) => tokens.length >= 2).map((tokens) => ({
67
+ ownedPath: tokens[0],
68
+ ownerIds: tokens.slice(1)
69
+ }));
70
+ const newDeclarationEntries = oldDeclarationEntries.filter((entry) => entry.ownedPath !== "*").concat([{ ownedPath, ownerIds }]).sort((l1, l2) => l1.ownedPath.localeCompare(l2.ownedPath));
71
+ newDeclarationEntries.unshift({
72
+ ownedPath: "*",
73
+ ownerIds: [DEFAULT_OWNER]
74
+ });
75
+ const longestOwnedPath = newDeclarationEntries.reduce(
76
+ (length, entry) => Math.max(length, entry.ownedPath.length),
77
+ 0
78
+ );
79
+ const newDeclarationLines = newDeclarationEntries.map((entry) => {
80
+ const entryPath = entry.ownedPath + " ".repeat(longestOwnedPath - entry.ownedPath.length);
81
+ return [entryPath, ...entry.ownerIds].join(" ");
82
+ });
83
+ const newLines = [...commentLines, "", ...newDeclarationLines, ""];
84
+ await fs__default.default.writeFile(filePath, newLines.join("\n"), "utf8");
85
+ return true;
86
+ }
87
+
88
+ exports.addCodeownersEntry = addCodeownersEntry;
89
+ exports.getCodeownersFilePath = getCodeownersFilePath;
90
+ exports.isValidSingleOwnerId = isValidSingleOwnerId;
91
+ exports.parseOwnerIds = parseOwnerIds;
92
+ //# sourceMappingURL=codeowners.cjs.js.map
@@ -2,12 +2,12 @@
2
2
 
3
3
  var configLoader = require('@backstage/config-loader');
4
4
  var config = require('@backstage/config');
5
- var index = require('./index-b1ouG3q6.cjs.js');
5
+ var paths = require('./paths.cjs.js');
6
6
  var getPackages = require('@manypkg/get-packages');
7
7
  var cliNode = require('@backstage/cli-node');
8
8
 
9
9
  async function loadCliConfig(options) {
10
- const { packages } = await getPackages.getPackages(index.paths.targetDir);
10
+ const { packages } = await getPackages.getPackages(paths.paths.targetDir);
11
11
  let localPackageNames;
12
12
  if (options.fromPackage) {
13
13
  if (packages.length) {
@@ -29,15 +29,15 @@ async function loadCliConfig(options) {
29
29
  const schema = await configLoader.loadConfigSchema({
30
30
  dependencies: localPackageNames,
31
31
  // Include the package.json in the project root if it exists
32
- packagePaths: [index.paths.resolveTargetRoot("package.json")],
32
+ packagePaths: [paths.paths.resolveTargetRoot("package.json")],
33
33
  noUndeclaredProperties: options.strict
34
34
  });
35
35
  const source = configLoader.ConfigSources.default({
36
36
  allowMissingDefaultConfig: true,
37
37
  substitutionFunc: options.mockEnv ? async (name) => process.env[name] || "x" : void 0,
38
38
  watch: Boolean(options.watch),
39
- rootDir: index.paths.targetRoot,
40
- argv: options.args.flatMap((t) => ["--config", index.paths.resolveTarget(t)])
39
+ rootDir: paths.paths.targetRoot,
40
+ argv: options.args.flatMap((t) => ["--config", paths.paths.resolveTarget(t)])
41
41
  });
42
42
  const appConfigs = await new Promise((resolve, reject) => {
43
43
  async function loadConfigReaderLoop() {
@@ -105,4 +105,4 @@ async function loadCliConfig(options) {
105
105
  }
106
106
 
107
107
  exports.loadCliConfig = loadCliConfig;
108
- //# sourceMappingURL=config-DBpmZirN.cjs.js.map
108
+ //# sourceMappingURL=config.cjs.js.map
@@ -44,4 +44,4 @@ function readEntryPoints(pkg) {
44
44
  }
45
45
 
46
46
  exports.readEntryPoints = readEntryPoints;
47
- //# sourceMappingURL=entryPoints-coip0t-x.cjs.js.map
47
+ //# sourceMappingURL=entryPoints.cjs.js.map
@@ -0,0 +1,45 @@
1
+ 'use strict';
2
+
3
+ var chalk = require('chalk');
4
+
5
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
6
+
7
+ var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
8
+
9
+ class CustomError extends Error {
10
+ get name() {
11
+ return this.constructor.name;
12
+ }
13
+ }
14
+ class ExitCodeError extends CustomError {
15
+ code;
16
+ constructor(code, command) {
17
+ super(
18
+ command ? `Command '${command}' exited with code ${code}` : `Child exited with code ${code}`
19
+ );
20
+ this.code = code;
21
+ }
22
+ }
23
+ function exitWithError(error) {
24
+ if (error instanceof ExitCodeError) {
25
+ process.stderr.write(`
26
+ ${chalk__default.default.red(error.message)}
27
+
28
+ `);
29
+ process.exit(error.code);
30
+ } else {
31
+ process.stderr.write(`
32
+ ${chalk__default.default.red(`${error}`)}
33
+
34
+ `);
35
+ process.exit(1);
36
+ }
37
+ }
38
+ class NotFoundError extends CustomError {
39
+ }
40
+
41
+ exports.CustomError = CustomError;
42
+ exports.ExitCodeError = ExitCodeError;
43
+ exports.NotFoundError = NotFoundError;
44
+ exports.exitWithError = exitWithError;
45
+ //# sourceMappingURL=errors.cjs.js.map
@@ -0,0 +1,60 @@
1
+ 'use strict';
2
+
3
+ var errors = require('@backstage/errors');
4
+
5
+ const requestType = "@backstage/cli/channel/request";
6
+ const responseType = "@backstage/cli/channel/response";
7
+ class IpcServer {
8
+ #generation = 1;
9
+ #methods = /* @__PURE__ */ new Map();
10
+ addChild(child) {
11
+ const generation = this.#generation++;
12
+ const sendMessage = child.send?.bind(child);
13
+ if (!sendMessage) {
14
+ return;
15
+ }
16
+ const messageListener = (request) => {
17
+ if (request.type !== requestType) {
18
+ return;
19
+ }
20
+ const handler = this.#methods.get(request.method);
21
+ if (!handler) {
22
+ sendMessage({
23
+ type: responseType,
24
+ id: request.id,
25
+ error: {
26
+ name: "NotFoundError",
27
+ message: `No handler registered for method ${request.method}`
28
+ }
29
+ });
30
+ return;
31
+ }
32
+ Promise.resolve().then(() => handler(request.body, { generation })).then(
33
+ (response) => sendMessage({
34
+ type: responseType,
35
+ id: request.id,
36
+ body: response
37
+ })
38
+ ).catch(
39
+ (error) => sendMessage({
40
+ type: responseType,
41
+ id: request.id,
42
+ error: errors.serializeError(error)
43
+ })
44
+ );
45
+ };
46
+ child.addListener("message", messageListener);
47
+ child.addListener("exit", () => {
48
+ child.removeListener("message", messageListener);
49
+ });
50
+ }
51
+ registerMethod(method, handler) {
52
+ if (this.#methods.has(method)) {
53
+ throw new Error(`A handler is already registered for method ${method}`);
54
+ }
55
+ this.#methods.set(method, handler);
56
+ }
57
+ }
58
+
59
+ exports.IpcServer = IpcServer;
60
+ //# sourceMappingURL=IpcServer.cjs.js.map
@@ -0,0 +1,36 @@
1
+ 'use strict';
2
+
3
+ class ServerDataStore {
4
+ static bind(server) {
5
+ const store = /* @__PURE__ */ new Map();
6
+ server.registerMethod(
7
+ "DevDataStore.save",
8
+ async (request, { generation }) => {
9
+ const { key, data } = request;
10
+ if (!key) {
11
+ throw new Error("Key is required in DevDataStore.save");
12
+ }
13
+ const item = store.get(key);
14
+ if (!item) {
15
+ store.set(key, { generation, data });
16
+ return { saved: true };
17
+ }
18
+ if (item.generation > generation) {
19
+ return { saved: false };
20
+ }
21
+ store.set(key, { generation, data });
22
+ return { saved: true };
23
+ }
24
+ );
25
+ server.registerMethod(
26
+ "DevDataStore.load",
27
+ async (request) => {
28
+ const item = store.get(request.key);
29
+ return { loaded: Boolean(item), data: item?.data };
30
+ }
31
+ );
32
+ }
33
+ }
34
+
35
+ exports.ServerDataStore = ServerDataStore;
36
+ //# sourceMappingURL=ServerDataStore.cjs.js.map
@@ -0,0 +1,128 @@
1
+ 'use strict';
2
+
3
+ var chokidar = require('chokidar');
4
+ var ctrlcWindows = require('ctrlc-windows');
5
+ var IpcServer = require('./IpcServer.cjs.js');
6
+ var ServerDataStore = require('./ServerDataStore.cjs.js');
7
+ var debounce = require('lodash/debounce');
8
+ var url = require('url');
9
+ var path = require('path');
10
+ var paths = require('../paths.cjs.js');
11
+ var spawn = require('cross-spawn');
12
+
13
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
14
+
15
+ var debounce__default = /*#__PURE__*/_interopDefaultCompat(debounce);
16
+ var spawn__default = /*#__PURE__*/_interopDefaultCompat(spawn);
17
+
18
+ const loaderArgs = [
19
+ "--enable-source-maps",
20
+ "--require",
21
+ require.resolve("@backstage/cli/config/nodeTransform.cjs")
22
+ // TODO: Support modules, although there's currently no way to load them since import() is transpiled tp require()
23
+ ];
24
+ async function startBackendExperimental(options) {
25
+ const envEnv = process.env;
26
+ if (!envEnv.NODE_ENV) {
27
+ envEnv.NODE_ENV = "development";
28
+ }
29
+ const server = new IpcServer.IpcServer();
30
+ ServerDataStore.ServerDataStore.bind(server);
31
+ let exiting = false;
32
+ let firstStart = true;
33
+ let child;
34
+ let watcher = void 0;
35
+ let shutdownPromise = void 0;
36
+ const watchedPaths = /* @__PURE__ */ new Set();
37
+ const restart = debounce__default.default(async () => {
38
+ if (firstStart) {
39
+ firstStart = false;
40
+ } else {
41
+ console.log();
42
+ console.log("Change detected, restarting the development server...");
43
+ console.log();
44
+ }
45
+ if (shutdownPromise) {
46
+ return;
47
+ }
48
+ if (child && !child.killed && child.exitCode === null) {
49
+ shutdownPromise = new Promise((resolve) => child.once("exit", resolve));
50
+ if (process.platform === "win32" && child.pid) {
51
+ ctrlcWindows.ctrlc(child.pid);
52
+ } else {
53
+ child.kill();
54
+ }
55
+ await shutdownPromise;
56
+ shutdownPromise = void 0;
57
+ }
58
+ if (exiting) {
59
+ return;
60
+ }
61
+ const optionArgs = new Array();
62
+ if (options.inspectEnabled) {
63
+ const inspect = typeof options.inspectEnabled === "string" ? `--inspect=${options.inspectEnabled}` : "--inspect";
64
+ optionArgs.push(inspect);
65
+ } else if (options.inspectBrkEnabled) {
66
+ const inspect = typeof options.inspectBrkEnabled === "string" ? `--inspect-brk=${options.inspectBrkEnabled}` : "--inspect-brk";
67
+ optionArgs.push(inspect);
68
+ }
69
+ if (options.require) {
70
+ optionArgs.push(`--require=${options.require}`);
71
+ }
72
+ const userArgs = process.argv.slice(["node", "backstage-cli", "package", "start"].length).filter((arg) => !optionArgs.includes(arg));
73
+ child = spawn__default.default(
74
+ process.execPath,
75
+ [...loaderArgs, ...optionArgs, options.entry, ...userArgs],
76
+ {
77
+ stdio: ["ignore", "inherit", "inherit", "ipc"],
78
+ env: {
79
+ ...process.env,
80
+ BACKSTAGE_CLI_CHANNEL: "1",
81
+ ESBK_TSCONFIG_PATH: paths.paths.resolveTargetRoot("tsconfig.json")
82
+ },
83
+ serialization: "advanced"
84
+ }
85
+ );
86
+ server.addChild(child);
87
+ child.on("message", (data) => {
88
+ if (!watcher) {
89
+ return;
90
+ }
91
+ if (typeof data === "object" && data?.type === "watch") {
92
+ let path$1 = data.path;
93
+ if (path$1.startsWith("file:")) {
94
+ path$1 = url.fileURLToPath(path$1);
95
+ }
96
+ if (path.isAbsolute(path$1) && !watchedPaths.has(path$1)) {
97
+ watchedPaths.add(path$1);
98
+ watcher.add(path$1);
99
+ }
100
+ }
101
+ });
102
+ }, 100);
103
+ restart();
104
+ watcher = chokidar.watch(["./package.json"], {
105
+ cwd: process.cwd(),
106
+ ignoreInitial: true,
107
+ ignorePermissionErrors: true
108
+ }).on("all", restart);
109
+ process.stdin.on("data", restart);
110
+ const exitPromise = new Promise((resolveExitPromise) => {
111
+ async function handleSignal(signal) {
112
+ exiting = true;
113
+ if (child && child.exitCode === null) {
114
+ await new Promise((resolve) => {
115
+ child.on("close", resolve);
116
+ child.kill(signal);
117
+ });
118
+ }
119
+ resolveExitPromise();
120
+ }
121
+ process.once("SIGINT", handleSignal);
122
+ process.once("SIGTERM", handleSignal);
123
+ });
124
+ return () => exitPromise;
125
+ }
126
+
127
+ exports.startBackendExperimental = startBackendExperimental;
128
+ //# sourceMappingURL=startBackendExperimental.cjs.js.map
@@ -0,0 +1,96 @@
1
+ 'use strict';
2
+
3
+ var chalk = require('chalk');
4
+ var inquirer = require('inquirer');
5
+ var index = require('./factories/index.cjs.js');
6
+ var partition = require('lodash/partition');
7
+
8
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
9
+
10
+ var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
11
+ var inquirer__default = /*#__PURE__*/_interopDefaultCompat(inquirer);
12
+ var partition__default = /*#__PURE__*/_interopDefaultCompat(partition);
13
+
14
+ function applyPromptMessageTransforms(prompt, transforms) {
15
+ return {
16
+ ...prompt,
17
+ message: prompt.message && (async (answers) => {
18
+ if (typeof prompt.message === "function") {
19
+ return transforms.message(await prompt.message(answers));
20
+ }
21
+ return transforms.message(await prompt.message);
22
+ }),
23
+ validate: prompt.validate && (async (...args) => {
24
+ const result = await prompt.validate(...args);
25
+ if (typeof result === "string") {
26
+ return transforms.error(result);
27
+ }
28
+ return result;
29
+ })
30
+ };
31
+ }
32
+ class FactoryRegistry {
33
+ static factoryMap = new Map(
34
+ Object.values(index).map((factory) => [factory.name, factory])
35
+ );
36
+ static async interactiveSelect(preselected) {
37
+ let selected = preselected;
38
+ if (!selected) {
39
+ const answers = await inquirer__default.default.prompt([
40
+ {
41
+ type: "list",
42
+ name: "name",
43
+ message: "What do you want to create?",
44
+ choices: Array.from(this.factoryMap.values()).map((factory2) => ({
45
+ name: `${factory2.name} - ${factory2.description}`,
46
+ value: factory2.name
47
+ }))
48
+ }
49
+ ]);
50
+ selected = answers.name;
51
+ }
52
+ const factory = this.factoryMap.get(selected);
53
+ if (!factory) {
54
+ throw new Error(`Unknown selection '${selected}'`);
55
+ }
56
+ return factory;
57
+ }
58
+ static async populateOptions(factory, provided) {
59
+ let currentOptions = provided;
60
+ if (factory.optionsDiscovery) {
61
+ const discoveredOptions = await factory.optionsDiscovery();
62
+ currentOptions = {
63
+ ...currentOptions,
64
+ ...discoveredOptions
65
+ };
66
+ }
67
+ if (factory.optionsPrompts) {
68
+ const [hasAnswers, needsAnswers] = partition__default.default(
69
+ factory.optionsPrompts,
70
+ (option) => option.name in currentOptions
71
+ );
72
+ for (const option of hasAnswers) {
73
+ const value = provided[option.name];
74
+ if (option.validate) {
75
+ const result = option.validate(value);
76
+ if (result !== true) {
77
+ throw new Error(`Invalid option '${option.name}'. ${result}`);
78
+ }
79
+ }
80
+ }
81
+ currentOptions = await inquirer__default.default.prompt(
82
+ needsAnswers.map(
83
+ (option) => applyPromptMessageTransforms(option, {
84
+ message: chalk__default.default.blue,
85
+ error: chalk__default.default.red
86
+ })
87
+ ),
88
+ currentOptions
89
+ );
90
+ }
91
+ return currentOptions;
92
+ }
93
+ }
94
+
95
+ exports.FactoryRegistry = FactoryRegistry;
96
+ //# sourceMappingURL=FactoryRegistry.cjs.js.map
@@ -0,0 +1,82 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs-extra');
4
+ var chalk = require('chalk');
5
+ var camelCase = require('lodash/camelCase');
6
+ var paths = require('../../paths.cjs.js');
7
+ var codeowners = require('../../codeowners/codeowners.cjs.js');
8
+ var types = require('../types.cjs.js');
9
+ var tasks = require('../../tasks.cjs.js');
10
+ var prompts = require('./common/prompts.cjs.js');
11
+ var tasks$1 = require('./common/tasks.cjs.js');
12
+ var util = require('./common/util.cjs.js');
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 chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
18
+ var camelCase__default = /*#__PURE__*/_interopDefaultCompat(camelCase);
19
+
20
+ const backendModule = types.createFactory({
21
+ name: "backend-module",
22
+ description: "A new backend module that extends an existing backend plugin with additional features",
23
+ optionsDiscovery: async () => ({
24
+ codeOwnersPath: await codeowners.getCodeownersFilePath(paths.paths.targetRoot)
25
+ }),
26
+ optionsPrompts: [prompts.pluginIdPrompt(), prompts.moduleIdIdPrompt(), prompts.ownerPrompt()],
27
+ async create(options, ctx) {
28
+ const { id: pluginId, moduleId } = options;
29
+ const dirName = `${pluginId}-backend-module-${moduleId}`;
30
+ const name = util.resolvePackageName({
31
+ baseName: dirName,
32
+ scope: ctx.scope,
33
+ plugin: true
34
+ });
35
+ tasks.Task.log();
36
+ tasks.Task.log(`Creating backend module ${chalk__default.default.cyan(name)}`);
37
+ const targetDir = ctx.isMonoRepo ? paths.paths.resolveTargetRoot("plugins", dirName) : paths.paths.resolveTargetRoot(`backstage-plugin-${dirName}`);
38
+ const moduleCamelCase = camelCase__default.default(moduleId);
39
+ const modulePascalCase = moduleCamelCase[0].toUpperCase() + moduleCamelCase.slice(1);
40
+ const moduleVar = `${camelCase__default.default(pluginId)}Module${modulePascalCase}`;
41
+ await tasks$1.executePluginPackageTemplate(ctx, {
42
+ targetDir,
43
+ templateName: "default-backend-module",
44
+ values: {
45
+ pluginId,
46
+ moduleId,
47
+ name,
48
+ moduleVar,
49
+ packageVersion: ctx.defaultVersion,
50
+ privatePackage: ctx.private,
51
+ npmRegistry: ctx.npmRegistry,
52
+ license: ctx.license
53
+ }
54
+ });
55
+ if (await fs__default.default.pathExists(paths.paths.resolveTargetRoot("packages/backend"))) {
56
+ await tasks.Task.forItem("backend", "adding dependency", async () => {
57
+ await tasks.addPackageDependency(
58
+ paths.paths.resolveTargetRoot("packages/backend/package.json"),
59
+ {
60
+ dependencies: {
61
+ [name]: `^${ctx.defaultVersion}`
62
+ }
63
+ }
64
+ );
65
+ });
66
+ }
67
+ await tasks.addToBackend(name, {
68
+ type: "module"
69
+ });
70
+ if (options.owner) {
71
+ await codeowners.addCodeownersEntry(`/plugins/${dirName}`, options.owner);
72
+ }
73
+ await tasks.Task.forCommand("yarn install", { cwd: targetDir, optional: true });
74
+ await tasks.Task.forCommand("yarn lint --fix", {
75
+ cwd: targetDir,
76
+ optional: true
77
+ });
78
+ }
79
+ });
80
+
81
+ exports.backendModule = backendModule;
82
+ //# sourceMappingURL=backendModule.cjs.js.map
@@ -0,0 +1,78 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs-extra');
4
+ var chalk = require('chalk');
5
+ var camelCase = require('lodash/camelCase');
6
+ var paths = require('../../paths.cjs.js');
7
+ var codeowners = require('../../codeowners/codeowners.cjs.js');
8
+ var types = require('../types.cjs.js');
9
+ var tasks = require('../../tasks.cjs.js');
10
+ var prompts = require('./common/prompts.cjs.js');
11
+ var tasks$1 = require('./common/tasks.cjs.js');
12
+ var util = require('./common/util.cjs.js');
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 chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
18
+ var camelCase__default = /*#__PURE__*/_interopDefaultCompat(camelCase);
19
+
20
+ const backendPlugin = types.createFactory({
21
+ name: "backend-plugin",
22
+ description: "A new backend plugin",
23
+ optionsDiscovery: async () => ({
24
+ codeOwnersPath: await codeowners.getCodeownersFilePath(paths.paths.targetRoot)
25
+ }),
26
+ optionsPrompts: [prompts.pluginIdPrompt(), prompts.ownerPrompt()],
27
+ async create(options, ctx) {
28
+ const { id } = options;
29
+ const pluginId = `${id}-backend`;
30
+ const name = util.resolvePackageName({
31
+ baseName: pluginId,
32
+ scope: ctx.scope,
33
+ plugin: true
34
+ });
35
+ tasks.Task.log();
36
+ tasks.Task.log(`Creating backend plugin ${chalk__default.default.cyan(name)}`);
37
+ const targetDir = ctx.isMonoRepo ? paths.paths.resolveTargetRoot("plugins", pluginId) : paths.paths.resolveTargetRoot(`backstage-plugin-${pluginId}`);
38
+ await tasks$1.executePluginPackageTemplate(ctx, {
39
+ targetDir,
40
+ templateName: "default-backend-plugin",
41
+ values: {
42
+ id,
43
+ name,
44
+ pluginVar: `${camelCase__default.default(id)}Plugin`,
45
+ pluginVersion: ctx.defaultVersion,
46
+ privatePackage: ctx.private,
47
+ npmRegistry: ctx.npmRegistry,
48
+ license: ctx.license
49
+ }
50
+ });
51
+ if (await fs__default.default.pathExists(paths.paths.resolveTargetRoot("packages/backend"))) {
52
+ await tasks.Task.forItem("backend", "adding dependency", async () => {
53
+ await tasks.addPackageDependency(
54
+ paths.paths.resolveTargetRoot("packages/backend/package.json"),
55
+ {
56
+ dependencies: {
57
+ [name]: `^${ctx.defaultVersion}`
58
+ }
59
+ }
60
+ );
61
+ });
62
+ }
63
+ await tasks.addToBackend(name, {
64
+ type: "plugin"
65
+ });
66
+ if (options.owner) {
67
+ await codeowners.addCodeownersEntry(`/plugins/${id}`, options.owner);
68
+ }
69
+ await tasks.Task.forCommand("yarn install", { cwd: targetDir, optional: true });
70
+ await tasks.Task.forCommand("yarn lint --fix", {
71
+ cwd: targetDir,
72
+ optional: true
73
+ });
74
+ }
75
+ });
76
+
77
+ exports.backendPlugin = backendPlugin;
78
+ //# sourceMappingURL=backendPlugin.cjs.js.map