@flarum/cli 2.0.0-beta.9 → 2.0.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 (133) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +181 -49
  3. package/bin/run +2 -1
  4. package/bin/splitsh-lite-darwin +0 -0
  5. package/bin/splitsh-lite-linux +0 -0
  6. package/boilerplate/skeleton/extension/.gitattributes +16 -14
  7. package/boilerplate/skeleton/extension/.github/workflows/backend.yml +2 -6
  8. package/boilerplate/skeleton/extension/.github/workflows/frontend.yml +4 -6
  9. package/boilerplate/skeleton/extension/LICENSE.md +1 -1
  10. package/boilerplate/skeleton/extension/README.md +1 -1
  11. package/boilerplate/skeleton/extension/composer.json +6 -4
  12. package/boilerplate/skeleton/extension/extend.php +2 -2
  13. package/boilerplate/skeleton/extension/js/admin.ts +2 -0
  14. package/boilerplate/skeleton/extension/js/forum.ts +2 -0
  15. package/boilerplate/skeleton/extension/js/package.json +5 -1
  16. package/boilerplate/skeleton/extension/js/src/admin/index.ts +5 -0
  17. package/boilerplate/skeleton/extension/js/src/common/index.ts +5 -0
  18. package/boilerplate/skeleton/extension/js/src/forum/index.ts +5 -0
  19. package/boilerplate/skeleton/extension/js/tsconfig.json +10 -2
  20. package/boilerplate/skeleton/extension/locale/en.yml +1 -1
  21. package/boilerplate/skeleton/extension/tests/phpunit.integration.xml +1 -0
  22. package/lib/base-command.d.ts +3 -1
  23. package/lib/base-command.js +44 -31
  24. package/lib/boilersmith/io.d.ts +28 -8
  25. package/lib/boilersmith/io.js +4 -2
  26. package/lib/boilersmith/paths.d.ts +2 -2
  27. package/lib/boilersmith/paths.js +7 -7
  28. package/lib/boilersmith/scaffolding/audit-step-factory.js +11 -11
  29. package/lib/boilersmith/scaffolding/infra-step-factory.js +2 -2
  30. package/lib/boilersmith/scaffolding/init-step-factory.js +5 -5
  31. package/lib/boilersmith/scaffolding/module.d.ts +28 -8
  32. package/lib/boilersmith/scaffolding/module.js +59 -17
  33. package/lib/boilersmith/scaffolding/scaffolder.d.ts +4 -1
  34. package/lib/boilersmith/scaffolding/scaffolder.js +32 -32
  35. package/lib/boilersmith/scaffolding/template-param.d.ts +1 -1
  36. package/lib/boilersmith/scaffolding/template-param.js +2 -2
  37. package/lib/boilersmith/step-manager.d.ts +0 -1
  38. package/lib/boilersmith/step-manager.js +10 -20
  39. package/lib/boilersmith/steps/stub-base.js +3 -3
  40. package/lib/boilersmith/utils/clone-and-fill.js +1 -1
  41. package/lib/boilersmith/utils/commit-async.d.ts +2 -0
  42. package/lib/boilersmith/utils/commit-async.js +15 -0
  43. package/lib/boilersmith/utils/read-tpl.js +2 -2
  44. package/lib/commands/audit/infra.d.ts +1 -1
  45. package/lib/commands/audit/infra.js +30 -8
  46. package/lib/commands/infra.d.ts +2 -2
  47. package/lib/commands/infra.js +18 -12
  48. package/lib/commands/init.d.ts +1 -1
  49. package/lib/commands/init.js +4 -2
  50. package/lib/commands/make/backend/api-controller.js +1 -2
  51. package/lib/commands/make/backend/api-serializer-attributes.js +1 -2
  52. package/lib/commands/make/backend/command.js +1 -2
  53. package/lib/commands/make/backend/event-listener.js +1 -2
  54. package/lib/commands/make/backend/handler.js +2 -5
  55. package/lib/commands/make/backend/integration-test.js +2 -4
  56. package/lib/commands/make/backend/migration.js +1 -2
  57. package/lib/commands/make/backend/model.js +1 -2
  58. package/lib/commands/make/backend/policy.js +1 -2
  59. package/lib/commands/make/backend/route.js +1 -2
  60. package/lib/commands/make/backend/service-provider.js +1 -2
  61. package/lib/commands/make/frontend/model.js +2 -5
  62. package/lib/commands/monorepo/create.d.ts +15 -0
  63. package/lib/commands/monorepo/create.js +20 -0
  64. package/lib/commands/monorepo/split.d.ts +15 -0
  65. package/lib/commands/monorepo/split.js +19 -0
  66. package/lib/commands/update/js-imports.js +1 -2
  67. package/lib/help.js +1 -1
  68. package/lib/providers/php-provider.js +2 -2
  69. package/lib/steps/gen-ext-scaffolder.d.ts +2 -2
  70. package/lib/steps/gen-ext-scaffolder.js +185 -51
  71. package/lib/steps/js/base.js +2 -4
  72. package/lib/steps/js/model.js +4 -4
  73. package/lib/steps/misc/composer.js +2 -2
  74. package/lib/steps/misc/git.d.ts +1 -1
  75. package/lib/steps/misc/git.js +2 -2
  76. package/lib/steps/misc/npm.d.ts +11 -0
  77. package/lib/steps/misc/npm.js +19 -0
  78. package/lib/steps/misc/yarn.js +2 -2
  79. package/lib/steps/monorepo/create.d.ts +17 -0
  80. package/lib/steps/monorepo/create.js +186 -0
  81. package/lib/steps/monorepo/split.d.ts +14 -0
  82. package/lib/steps/monorepo/split.js +99 -0
  83. package/lib/steps/stubs/backend/api-controller.d.ts +1 -1
  84. package/lib/steps/stubs/backend/api-controller.js +3 -0
  85. package/lib/steps/stubs/backend/api-serializer.d.ts +1 -1
  86. package/lib/steps/stubs/backend/api-serializer.js +3 -0
  87. package/lib/steps/stubs/backend/command.d.ts +0 -5
  88. package/lib/steps/stubs/backend/command.js +1 -0
  89. package/lib/steps/stubs/backend/event-listener.d.ts +1 -1
  90. package/lib/steps/stubs/backend/event-listener.js +2 -0
  91. package/lib/steps/stubs/backend/handler-command.d.ts +1 -1
  92. package/lib/steps/stubs/backend/handler-command.js +1 -0
  93. package/lib/steps/stubs/backend/handler.d.ts +1 -1
  94. package/lib/steps/stubs/backend/handler.js +4 -0
  95. package/lib/steps/stubs/backend/integration-test.d.ts +1 -1
  96. package/lib/steps/stubs/backend/integration-test.js +2 -0
  97. package/lib/steps/stubs/backend/job.d.ts +1 -1
  98. package/lib/steps/stubs/backend/job.js +1 -0
  99. package/lib/steps/stubs/backend/migration.js +6 -3
  100. package/lib/steps/stubs/backend/model.d.ts +1 -1
  101. package/lib/steps/stubs/backend/model.js +1 -0
  102. package/lib/steps/stubs/backend/policy.d.ts +1 -1
  103. package/lib/steps/stubs/backend/policy.js +2 -0
  104. package/lib/steps/stubs/backend/repository.d.ts +1 -1
  105. package/lib/steps/stubs/backend/repository.js +2 -0
  106. package/lib/steps/stubs/backend/service-provider.d.ts +1 -1
  107. package/lib/steps/stubs/backend/service-provider.js +1 -0
  108. package/lib/steps/stubs/backend/validator.d.ts +1 -1
  109. package/lib/steps/stubs/backend/validator.js +1 -0
  110. package/lib/steps/stubs/flarum-base.js +1 -1
  111. package/lib/steps/stubs/frontend/component.d.ts +0 -5
  112. package/lib/steps/stubs/frontend/component.js +1 -0
  113. package/lib/steps/stubs/frontend/modal.d.ts +0 -5
  114. package/lib/steps/stubs/frontend/modal.js +1 -0
  115. package/lib/steps/stubs/frontend/model.d.ts +0 -5
  116. package/lib/steps/stubs/frontend/model.js +1 -0
  117. package/lib/steps/stubs/js-base.js +8 -5
  118. package/lib/steps/stubs/php-base.js +10 -8
  119. package/lib/steps/update/js-imports.js +8 -2
  120. package/lib/utils/composer.d.ts +1 -0
  121. package/lib/utils/migration.js +3 -1
  122. package/lib/utils/monorepo.d.ts +24 -0
  123. package/lib/utils/monorepo.js +24 -0
  124. package/lib/utils/validation.d.ts +2 -0
  125. package/lib/utils/validation.js +6 -0
  126. package/oclif.manifest.json +1 -1
  127. package/package.json +11 -5
  128. package/php-subsystem/composer.json +9 -9
  129. package/php-subsystem/composer.lock +64 -71
  130. package/php-subsystem/vendor/composer/installed.json +54 -61
  131. package/php-subsystem/vendor/nikic/php-parser/README.md +55 -59
  132. package/php-subsystem/vendor/nikic/php-parser/composer.json +39 -39
  133. package/php-subsystem/vendor/nikic/php-parser/grammar/README.md +17 -20
@@ -7,8 +7,7 @@ const policy_2 = require("../../../steps/extenders/policy");
7
7
  const gen_ext_scaffolder_1 = require("../../../steps/gen-ext-scaffolder");
8
8
  class Policy extends base_command_1.default {
9
9
  steps(stepManager) {
10
- return stepManager
11
- .atomicGroup(stepManager => {
10
+ return stepManager.atomicGroup((stepManager) => {
12
11
  stepManager
13
12
  .namedStep('policy', new policy_1.GeneratePolicyStub(this.STUB_PATH, (0, gen_ext_scaffolder_1.genExtScaffolder)()))
14
13
  .step(new policy_2.GeneratePolicyExtender(), { optional: true, confirmationMessage: 'Generate corresponding extender?', default: true }, [
@@ -5,8 +5,7 @@ const base_command_1 = (0, tslib_1.__importDefault)(require("../../../base-comma
5
5
  const route_1 = require("../../../steps/extenders/route");
6
6
  class Route extends base_command_1.default {
7
7
  steps(stepManager) {
8
- return stepManager
9
- .step(new route_1.GenerateRoutesExtender());
8
+ return stepManager.step(new route_1.GenerateRoutesExtender());
10
9
  }
11
10
  }
12
11
  exports.default = Route;
@@ -7,8 +7,7 @@ const service_provider_2 = require("../../../steps/extenders/service-provider");
7
7
  const gen_ext_scaffolder_1 = require("../../../steps/gen-ext-scaffolder");
8
8
  class ServiceProvider extends base_command_1.default {
9
9
  steps(stepManager) {
10
- return stepManager
11
- .atomicGroup(stepManager => {
10
+ return stepManager.atomicGroup((stepManager) => {
12
11
  stepManager
13
12
  .namedStep('provider', new service_provider_1.GenerateServiceProviderStub(this.STUB_PATH, (0, gen_ext_scaffolder_1.genExtScaffolder)()))
14
13
  .step(new service_provider_2.GenerateServiceProviderExtender(), { optional: true, confirmationMessage: 'Generate corresponding extender?', default: true }, [
@@ -7,11 +7,8 @@ const model_2 = require("../../../steps/js/model");
7
7
  const gen_ext_scaffolder_1 = require("../../../steps/gen-ext-scaffolder");
8
8
  class Model extends base_command_1.default {
9
9
  steps(stepManager) {
10
- return stepManager
11
- .atomicGroup(stepManager => {
12
- stepManager
13
- .namedStep('model', new model_1.GenerateModelStub(this.STUB_PATH, (0, gen_ext_scaffolder_1.genExtScaffolder)()))
14
- .step(new model_2.GenerateModelDefinition(), {}, [
10
+ return stepManager.atomicGroup((stepManager) => {
11
+ stepManager.namedStep('model', new model_1.GenerateModelStub(this.STUB_PATH, (0, gen_ext_scaffolder_1.genExtScaffolder)())).step(new model_2.GenerateModelDefinition(), {}, [
15
12
  {
16
13
  sourceStep: 'model',
17
14
  exposedName: 'frontend',
@@ -0,0 +1,15 @@
1
+ import { StepManager } from 'boilersmith/step-manager';
2
+ import BaseCommand from '../../base-command';
3
+ import { FlarumProviders } from '../../providers';
4
+ export default class Create extends BaseCommand {
5
+ static description: string;
6
+ static flags: {
7
+ config: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
8
+ };
9
+ static args: {
10
+ name: string;
11
+ description: string;
12
+ }[];
13
+ protected requireExistingExtension: boolean;
14
+ protected steps(stepManager: StepManager<FlarumProviders>): StepManager<FlarumProviders>;
15
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const base_command_1 = (0, tslib_1.__importDefault)(require("../../base-command"));
5
+ const core_1 = require("@oclif/core");
6
+ const create_1 = require("../../steps/monorepo/create");
7
+ const gen_ext_scaffolder_1 = require("../../steps/gen-ext-scaffolder");
8
+ class Create extends base_command_1.default {
9
+ constructor() {
10
+ super(...arguments);
11
+ this.requireExistingExtension = false;
12
+ }
13
+ steps(stepManager) {
14
+ return stepManager.step(new create_1.MonorepoCreate((0, gen_ext_scaffolder_1.genExtScaffolder)(), this.flags.config));
15
+ }
16
+ }
17
+ exports.default = Create;
18
+ Create.description = 'Create a monorepo of Flarum extensions.';
19
+ Create.flags = Object.assign({ config: core_1.Flags.string({ char: 'c', required: false }) }, base_command_1.default.flags);
20
+ Create.args = [...base_command_1.default.args];
@@ -0,0 +1,15 @@
1
+ import { StepManager } from 'boilersmith/step-manager';
2
+ import BaseCommand from '../../base-command';
3
+ import { FlarumProviders } from '../../providers';
4
+ export default class Split extends BaseCommand {
5
+ static description: string;
6
+ static flags: {
7
+ force: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
+ };
9
+ static args: {
10
+ name: string;
11
+ description: string;
12
+ }[];
13
+ protected requireExistingExtension: boolean;
14
+ protected steps(stepManager: StepManager<FlarumProviders>): StepManager<FlarumProviders>;
15
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const base_command_1 = (0, tslib_1.__importDefault)(require("../../base-command"));
5
+ const core_1 = require("@oclif/core");
6
+ const split_1 = require("../../steps/monorepo/split");
7
+ class Split extends base_command_1.default {
8
+ constructor() {
9
+ super(...arguments);
10
+ this.requireExistingExtension = false;
11
+ }
12
+ steps(stepManager) {
13
+ return stepManager.step(new split_1.MonorepoSplit(this.flags.force));
14
+ }
15
+ }
16
+ exports.default = Split;
17
+ Split.description = 'Split monorepo changes into subrepos.';
18
+ Split.flags = Object.assign({ force: core_1.Flags.boolean({ char: 'f', required: false }) }, base_command_1.default.flags);
19
+ Split.args = [...base_command_1.default.args];
@@ -5,8 +5,7 @@ const js_imports_1 = require("../../steps/update/js-imports");
5
5
  const base_command_1 = (0, tslib_1.__importDefault)(require("../../base-command"));
6
6
  class UpdateJsImports extends base_command_1.default {
7
7
  steps(stepManager) {
8
- return stepManager
9
- .step(new js_imports_1.UpdateJSImports());
8
+ return stepManager.step(new js_imports_1.UpdateJSImports());
10
9
  }
11
10
  async additionalPreRunChecks(extRoot) {
12
11
  await this.ensureComposerInstallRan(extRoot);
package/lib/help.js CHANGED
@@ -12,7 +12,7 @@ function prepTopic(topic) {
12
12
  return Object.assign({}, topic, { name: chalk_1.default.green(topic.name.replace(COLON_REGEX, ' ')) });
13
13
  }
14
14
  function colorHeaders(text) {
15
- return text.replace(/(TOPICS|TOPIC|DESCRIPTION|USAGE|COMMANDS|VERSION|ARGUMENTS|OPTIONS)/g, match => {
15
+ return text.replace(/(TOPICS|TOPIC|DESCRIPTION|USAGE|COMMANDS|VERSION|ARGUMENTS|OPTIONS)/g, (match) => {
16
16
  return chalk_1.default.yellow(match);
17
17
  });
18
18
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PhpSubsystemProvider = exports.ParamTypeType = exports.ExpressionType = void 0;
4
- const node_child_process_1 = require("node:child_process");
4
+ const child_process_1 = require("child_process");
5
5
  var ExpressionType;
6
6
  (function (ExpressionType) {
7
7
  ExpressionType["SCALAR"] = "scalar";
@@ -24,7 +24,7 @@ class PhpSubsystemProvider {
24
24
  op: 'extender.add',
25
25
  params: extenderDef,
26
26
  });
27
- const res = (0, node_child_process_1.execSync)(`php ${this.phpPath}`, { input });
27
+ const res = (0, child_process_1.execSync)(`php ${this.phpPath}`, { input });
28
28
  if (!res) {
29
29
  throw new Error(`The PHP subsystem returned an invalid value: ${res}`);
30
30
  }
@@ -1,6 +1,6 @@
1
1
  import { Scaffolder } from 'boilersmith/scaffolding/scaffolder';
2
- export declare const EXTENSION_PARAMS: readonly ["packageName", "packageDescription", "packageNamespace", "authorName", "authorEmail", "extensionName", "licenseType", "mainGitBranch", "licenseText", "packageNamespaceEscapedSlash", "extensionId", "year", "backendDirectory", "frontendDirectory"];
2
+ export declare const EXTENSION_PARAMS: readonly ["packageName", "packageDescription", "packageNamespace", "authorName", "authorEmail", "extensionName", "licenseType", "mainGitBranch", "jsPackageManager", "licenseText", "extensionId", "year", "backendDirectory", "frontendDirectory"];
3
3
  export declare type ExtensionParams = typeof EXTENSION_PARAMS[number];
4
- export declare const EXTENSION_MODULES: readonly ["core", "icon", "js", "jsCommon", "css", "locale", "gitConf", "githubActions", "prettier", "typescript", "bundlewatch", "backendTesting", "editorConfig", "styleci"];
4
+ export declare const EXTENSION_MODULES: readonly ["core", "icon", "admin", "forum", "js", "jsCommon", "css", "locale", "gitConf", "githubActions", "prettier", "typescript", "bundlewatch", "backendTesting", "editorConfig", "styleci"];
5
5
  export declare type ExtensionModules = typeof EXTENSION_MODULES[number];
6
6
  export declare function genExtScaffolder(): Scaffolder<ExtensionParams, ExtensionModules>;
@@ -5,7 +5,9 @@ const tslib_1 = require("tslib");
5
5
  const scaffolder_1 = require("boilersmith/scaffolding/scaffolder");
6
6
  const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
7
7
  const mem_fs_editor_1 = require("mem-fs-editor");
8
- const node_path_1 = require("node:path");
8
+ const child_process_1 = require("child_process");
9
+ const fs_1 = require("fs");
10
+ const path_1 = require("path");
9
11
  const simple_git_1 = (0, tslib_1.__importDefault)(require("simple-git"));
10
12
  const simple_1 = (0, tslib_1.__importDefault)(require("spdx-license-list/simple"));
11
13
  const composer_1 = require("../utils/composer");
@@ -21,8 +23,8 @@ exports.EXTENSION_PARAMS = [
21
23
  'extensionName',
22
24
  'licenseType',
23
25
  'mainGitBranch',
26
+ 'jsPackageManager',
24
27
  'licenseText',
25
- 'packageNamespaceEscapedSlash',
26
28
  'extensionId',
27
29
  'year',
28
30
  'backendDirectory',
@@ -36,8 +38,8 @@ function paramNamesToDef(name) {
36
38
  name,
37
39
  type: 'text',
38
40
  message: `Package ${chalk_1.default.dim('(vendor/extension-name)')}`,
39
- validate: s => /^([\dA-Za-z-]{2,})\/([\dA-Za-z-]{2,})$/.test(s.trim()) || 'Invalid package name format',
40
- format: s => s.toLowerCase(),
41
+ validate: (s) => /^([\dA-Za-z-]{2,})\/([\dA-Za-z-]{2,})$/.test(s.trim()) || 'Invalid package name format',
42
+ format: (s) => s.toLowerCase(),
41
43
  },
42
44
  getCurrVal: async (fs, paths) => {
43
45
  const json = (0, composer_1.getComposerJson)(fs, paths);
@@ -63,11 +65,11 @@ function paramNamesToDef(name) {
63
65
  name,
64
66
  type: 'text',
65
67
  message: `Package namespace ${chalk_1.default.dim('(Vendor\\ExtensionName)')}`,
66
- validate: s => /^([\dA-Za-z]+)\\([\dA-Za-z]+)$/.test(s.trim()) || 'Invalid namespace format',
68
+ validate: (s) => /^([\dA-Za-z]+)\\([\dA-Za-z]+)$/.test(s.trim()) || 'Invalid namespace format',
67
69
  format: (str) => str &&
68
70
  str
69
71
  .split('\\')
70
- .map(s => s[0].toUpperCase() + s.slice(1))
72
+ .map((s) => s[0].toUpperCase() + s.slice(1))
71
73
  .join('\\'),
72
74
  },
73
75
  getCurrVal: async (fs, paths) => {
@@ -96,7 +98,7 @@ function paramNamesToDef(name) {
96
98
  name,
97
99
  type: 'text',
98
100
  message: 'Author email',
99
- validate: s => !s || /^[\w!#$%&*+./=?^`{|}~’-]+@[\dA-Za-z-]+(?:\.[\dA-Za-z-]+)*$/.test(s) || 'Invalid email format',
101
+ validate: (s) => !s || /^[\w!#$%&*+./=?^`{|}~’-]+@[\dA-Za-z-]+(?:\.[\dA-Za-z-]+)*$/.test(s) || 'Invalid email format',
100
102
  },
101
103
  getCurrVal: async (fs, paths) => {
102
104
  var _a, _b, _c;
@@ -110,8 +112,8 @@ function paramNamesToDef(name) {
110
112
  name,
111
113
  type: 'text',
112
114
  message: 'Extension name',
113
- validate: str => Boolean(str.trim()) || 'The extension name is required',
114
- format: str => str
115
+ validate: (str) => Boolean(str.trim()) || 'The extension name is required',
116
+ format: (str) => str
115
117
  .split(' ')
116
118
  .map((s) => (s.length > 3 ? s[0].toUpperCase() + s.slice(1) : s))
117
119
  .join(' '),
@@ -130,7 +132,7 @@ function paramNamesToDef(name) {
130
132
  name,
131
133
  type: 'autocomplete',
132
134
  message: 'License',
133
- choices: [...simple_1.default].map(e => ({ title: e, value: e })),
135
+ choices: [...simple_1.default].map((e) => ({ title: e, value: e })),
134
136
  },
135
137
  getCurrVal: async (fs, paths) => {
136
138
  var _a;
@@ -144,12 +146,6 @@ function paramNamesToDef(name) {
144
146
  uses: ['licenseType'],
145
147
  compute: async (_paths, licenseType) => (licenseType ? require(`spdx-license-list/licenses/${licenseType}`).licenseText : ''),
146
148
  };
147
- case 'packageNamespaceEscapedSlash':
148
- return {
149
- name,
150
- uses: ['packageNamespace'],
151
- compute: async (_paths, packageNamespace) => packageNamespace.replace('\\', '\\\\'),
152
- };
153
149
  case 'extensionId':
154
150
  return {
155
151
  name,
@@ -169,12 +165,37 @@ function paramNamesToDef(name) {
169
165
  type: 'text',
170
166
  message: `Main git branch ${chalk_1.default.dim('(JS will automatically build when changes are pushed to GitHub on this branch)')}`,
171
167
  // See https://stackoverflow.com/a/12093994/11091039
172
- validate: s => /^(?!.*\/\.)(?!.*\.\.)(?!\/)(?!.*\/\/)(?!.*@{)(?!.*\\)[^\000-\037 *:?[^~\177]+(?<!\.lock)(?<!\/)(?<!\.)$/.test(s.trim()) || 'Invalid git branch',
168
+ validate: (s) => /^(?!.*\/\.)(?!.*\.\.)(?!\/)(?!.*\/\/)(?!.*@{)(?!.*\\)[^\000-\037 *:?[^~\177]+(?<!\.lock)(?<!\/)(?<!\.)$/.test(s.trim()) ||
169
+ 'Invalid git branch',
173
170
  initial: 'main',
174
171
  },
175
- getCurrVal: async () => {
176
- var _a;
177
- return (_a = (await (0, simple_git_1.default)().getConfig('init.defaultBranch')).value) !== null && _a !== void 0 ? _a : 'main';
172
+ getCurrVal: async (_fs, paths) => {
173
+ var _a, _b;
174
+ const cwd = (_a = paths.monorepo()) !== null && _a !== void 0 ? _a : paths.package();
175
+ try {
176
+ const remotes = (0, child_process_1.execSync)('git remote', { cwd, timeout: 2000 }).toString().split('\n');
177
+ if (remotes.includes('origin')) {
178
+ return (0, child_process_1.execSync)("git remote show origin | grep 'HEAD branch' | cut -d' ' -f5", { cwd, timeout: 2000 }).toString();
179
+ }
180
+ }
181
+ catch (_c) { }
182
+ return (_b = (await (0, simple_git_1.default)(cwd, { timeout: { block: 2000 } }).getConfig('init.defaultBranch')).value) !== null && _b !== void 0 ? _b : 'main';
183
+ },
184
+ };
185
+ case 'jsPackageManager':
186
+ return {
187
+ prompt: {
188
+ name,
189
+ type: 'select',
190
+ message: 'JS Package Manager',
191
+ initial: 0,
192
+ choices: [
193
+ { title: 'Yarn', value: 'yarn' },
194
+ { title: 'NPM', value: 'npm' },
195
+ ],
196
+ },
197
+ getCurrVal: async (fs, paths) => {
198
+ return (0, mem_fs_editor_1.create)(fs).exists(paths.package('js/yarn.lock')) ? 'yarn' : 'npm';
178
199
  },
179
200
  };
180
201
  case 'backendDirectory':
@@ -201,6 +222,8 @@ function paramNamesToDef(name) {
201
222
  exports.EXTENSION_MODULES = [
202
223
  'core',
203
224
  'icon',
225
+ 'admin',
226
+ 'forum',
204
227
  'js',
205
228
  'jsCommon',
206
229
  'css',
@@ -222,14 +245,7 @@ function moduleNameToDef(name) {
222
245
  updatable: false,
223
246
  togglable: false,
224
247
  shortDescription: 'Core Functionality',
225
- filesToReplace: [
226
- 'extend.php',
227
- 'README.md',
228
- 'LICENSE.md',
229
- { path: 'js/src/admin/index.js', needsOtherModules: ['js'] },
230
- { path: 'js/src/forum/index.js', needsOtherModules: ['js'] },
231
- { path: 'js/src/common/index.js', needsOtherModules: ['js', 'jsCommon'] },
232
- ],
248
+ filesToReplace: ['extend.php', 'README.md', 'LICENSE.md'],
233
249
  jsonToAugment: {
234
250
  'composer.json': [
235
251
  'name',
@@ -239,15 +255,17 @@ function moduleNameToDef(name) {
239
255
  'license',
240
256
  'require.flarum/core',
241
257
  'authors',
242
- 'autoload.psr-4.${params.packageNamespaceEscapedSlash}\\',
258
+ 'autoload.psr-4.${params.packageNamespace}\\',
243
259
  'extra.flarum-extension.title',
244
260
  'extra.flarum-extension.category',
261
+ 'minimum-stability',
262
+ 'prefer-stable',
245
263
  ],
246
264
  },
247
265
  needsTemplateParams: [
248
266
  'packageName',
249
267
  'packageNamespace',
250
- 'packageNamespaceEscapedSlash',
268
+ 'packageNamespace',
251
269
  'packageDescription',
252
270
  'extensionName',
253
271
  'licenseType',
@@ -270,6 +288,50 @@ function moduleNameToDef(name) {
270
288
  },
271
289
  needsTemplateParams: [],
272
290
  };
291
+ case 'admin':
292
+ return {
293
+ name,
294
+ updatable: true,
295
+ defaultEnabled: true,
296
+ dependsOn: [],
297
+ togglable: true,
298
+ shortDescription: 'Admin Frontend',
299
+ filesToReplace: [
300
+ { path: 'js/admin.js', moduleDeps: ['js', { module: 'typescript', enabled: false }] },
301
+ { path: 'js/admin.ts', moduleDeps: ['js', { module: 'typescript', enabled: true }] },
302
+ { path: 'js/src/admin/index.js', doNotUpdate: true, moduleDeps: ['js', { module: 'typescript', enabled: false }] },
303
+ { path: 'js/src/admin/index.ts', doNotUpdate: true, moduleDeps: ['js', { module: 'typescript', enabled: true }] },
304
+ ],
305
+ jsonToAugment: {},
306
+ needsTemplateParams: [],
307
+ inferEnabled: async (_fs, paths) => {
308
+ if (!(0, fs_1.existsSync)(paths.package('js')))
309
+ undefined;
310
+ return (0, fs_1.existsSync)(paths.package('js/src/admin'));
311
+ },
312
+ };
313
+ case 'forum':
314
+ return {
315
+ name,
316
+ updatable: true,
317
+ defaultEnabled: true,
318
+ dependsOn: [],
319
+ togglable: true,
320
+ shortDescription: 'Forum Frontend',
321
+ filesToReplace: [
322
+ { path: 'js/forum.js', moduleDeps: ['js', { module: 'typescript', enabled: false }] },
323
+ { path: 'js/forum.ts', moduleDeps: ['js', { module: 'typescript', enabled: true }] },
324
+ { path: 'js/src/forum/index.js', doNotUpdate: true, moduleDeps: ['js', { module: 'typescript', enabled: false }] },
325
+ { path: 'js/src/forum/index.ts', doNotUpdate: true, moduleDeps: ['js', { module: 'typescript', enabled: true }] },
326
+ ],
327
+ jsonToAugment: {},
328
+ needsTemplateParams: [],
329
+ inferEnabled: async (_fs, paths) => {
330
+ if (!(0, fs_1.existsSync)(paths.package('js')))
331
+ undefined;
332
+ return (0, fs_1.existsSync)(paths.package('js/src/forum'));
333
+ },
334
+ };
273
335
  case 'js':
274
336
  return {
275
337
  name,
@@ -279,11 +341,24 @@ function moduleNameToDef(name) {
279
341
  shortDescription: 'Javascript',
280
342
  longDescription: "Files, tools, and scripts to build Flarum's frontend.",
281
343
  dependsOn: [],
282
- filesToReplace: ['js/webpack.config.js', 'js/admin.js', 'js/forum.js'],
344
+ filesToReplace: [
345
+ 'js/webpack.config.js',
346
+ { path: 'js/admin.js', moduleDeps: ['admin', { module: 'typescript', enabled: false }] },
347
+ { path: 'js/forum.js', moduleDeps: ['forum', { module: 'typescript', enabled: false }] },
348
+ { path: 'js/admin.ts', moduleDeps: ['admin', { module: 'typescript', enabled: true }] },
349
+ { path: 'js/forum.ts', moduleDeps: ['forum', { module: 'typescript', enabled: true }] },
350
+ { path: 'js/src/admin/index.js', doNotUpdate: true, moduleDeps: ['admin', { module: 'typescript', enabled: false }] },
351
+ { path: 'js/src/forum/index.js', doNotUpdate: true, moduleDeps: ['forum', { module: 'typescript', enabled: false }] },
352
+ { path: 'js/src/common/index.js', doNotUpdate: true, moduleDeps: ['jsCommon', { module: 'typescript', enabled: false }] },
353
+ { path: 'js/src/admin/index.ts', doNotUpdate: true, moduleDeps: ['admin', { module: 'typescript', enabled: true }] },
354
+ { path: 'js/src/forum/index.ts', doNotUpdate: true, moduleDeps: ['forum', { module: 'typescript', enabled: true }] },
355
+ { path: 'js/src/common/index.ts', doNotUpdate: true, moduleDeps: ['jsCommon', { module: 'typescript', enabled: true }] },
356
+ ],
283
357
  jsonToAugment: {
284
358
  'js/package.json': [
285
359
  'name',
286
360
  'private',
361
+ 'version',
287
362
  'devDependencies.flarum-webpack-config',
288
363
  'devDependencies.webpack',
289
364
  'devDependencies.webpack-cli',
@@ -292,7 +367,10 @@ function moduleNameToDef(name) {
292
367
  'scripts.analyze',
293
368
  ],
294
369
  },
295
- needsTemplateParams: ['packageName'],
370
+ needsTemplateParams: ['packageName', 'jsPackageManager'],
371
+ inferEnabled: async (_fs, paths) => {
372
+ return (0, fs_1.existsSync)(paths.package('js'));
373
+ },
296
374
  };
297
375
  case 'jsCommon':
298
376
  return {
@@ -303,22 +381,38 @@ function moduleNameToDef(name) {
303
381
  shortDescription: 'JS common code',
304
382
  longDescription: 'Shared code between the forum and the admin frontends',
305
383
  dependsOn: ['js'],
306
- filesToReplace: [],
384
+ filesToReplace: [
385
+ { path: 'js/admin.js', moduleDeps: ['admin', { module: 'typescript', enabled: false }] },
386
+ { path: 'js/forum.js', moduleDeps: ['forum', { module: 'typescript', enabled: false }] },
387
+ { path: 'js/admin.ts', moduleDeps: ['admin', { module: 'typescript', enabled: true }] },
388
+ { path: 'js/forum.ts', moduleDeps: ['forum', { module: 'typescript', enabled: true }] },
389
+ { path: 'js/src/common/index.js', doNotUpdate: true, moduleDeps: [{ module: 'typescript', enabled: false }] },
390
+ { path: 'js/src/common/index.ts', doNotUpdate: true, moduleDeps: [{ module: 'typescript', enabled: true }] },
391
+ ],
307
392
  jsonToAugment: {},
308
393
  needsTemplateParams: [],
394
+ inferEnabled: async (_fs, paths) => {
395
+ return (0, fs_1.existsSync)(paths.package('js/src/common'));
396
+ },
309
397
  };
310
398
  case 'css':
311
399
  return {
312
400
  name,
313
- updatable: false,
401
+ updatable: true,
314
402
  togglable: true,
315
403
  defaultEnabled: true,
316
404
  shortDescription: 'CSS',
317
405
  longDescription: "LESS starter files for Flarum's frontend styling.",
318
406
  dependsOn: [],
319
- filesToReplace: ['less/admin.less', 'less/forum.less'],
407
+ filesToReplace: [
408
+ { path: 'less/admin.less', doNotUpdate: true, moduleDeps: ['admin'] },
409
+ { path: 'less/forum.less', doNotUpdate: true, moduleDeps: ['forum'] },
410
+ ],
320
411
  jsonToAugment: {},
321
412
  needsTemplateParams: [],
413
+ inferEnabled: async (_fs, paths) => {
414
+ return (0, fs_1.existsSync)(paths.package('less'));
415
+ },
322
416
  };
323
417
  case 'locale':
324
418
  return {
@@ -329,9 +423,12 @@ function moduleNameToDef(name) {
329
423
  shortDescription: 'Locale',
330
424
  longDescription: 'Translation starter files.',
331
425
  dependsOn: [],
332
- filesToReplace: ['locale/en.yml'],
426
+ filesToReplace: [{ path: 'locale/en.yml', doNotUpdate: true }],
333
427
  jsonToAugment: {},
334
428
  needsTemplateParams: [],
429
+ inferEnabled: async (_fs, paths) => {
430
+ return (0, fs_1.existsSync)(paths.package('locale'));
431
+ },
335
432
  };
336
433
  case 'gitConf':
337
434
  return {
@@ -342,7 +439,11 @@ function moduleNameToDef(name) {
342
439
  shortDescription: 'Git Configuration',
343
440
  longDescription: 'Git config files (e.g. .gitignore, .gitattributes).',
344
441
  dependsOn: [],
345
- filesToReplace: [{ path: 'gitignore', destPath: '.gitignore' }, { path: 'js/gitignore', needsOtherModules: ['js'], destPath: 'js/.gitignore' }, '.gitattributes'],
442
+ filesToReplace: [
443
+ { path: 'gitignore', destPath: '.gitignore' },
444
+ { path: 'js/gitignore', moduleDeps: ['js'], destPath: 'js/.gitignore' },
445
+ { path: '.gitattributes', monorepoPath: '.gitattributes' },
446
+ ],
346
447
  jsonToAugment: {},
347
448
  needsTemplateParams: [],
348
449
  };
@@ -356,8 +457,17 @@ function moduleNameToDef(name) {
356
457
  longDescription: 'Automatically run checks via GitHub Actions CI. Free for open source projects.',
357
458
  dependsOn: [],
358
459
  filesToReplace: [
359
- { path: '.github/workflows/frontend.yml', monorepoPath: '.github/workflows/${params.extensionId}-frontend.yml' },
360
- { path: '.github/workflows/backend.yml', monorepoPath: '.github/workflows/${params.extensionId}-backend.yml' },
460
+ {
461
+ path: '.github/workflows/frontend.yml',
462
+ monorepoPath: '.github/workflows/${params.extensionId}-frontend.yml',
463
+ requireMonorepo: false,
464
+ moduleDeps: ['js'],
465
+ },
466
+ {
467
+ path: '.github/workflows/backend.yml',
468
+ monorepoPath: '.github/workflows/${params.extensionId}-backend.yml',
469
+ requireMonorepo: false,
470
+ },
361
471
  ],
362
472
  jsonToAugment: {},
363
473
  needsTemplateParams: ['frontendDirectory', 'backendDirectory', 'mainGitBranch', 'extensionId', 'extensionName'],
@@ -372,9 +482,21 @@ function moduleNameToDef(name) {
372
482
  dependsOn: ['js'],
373
483
  filesToReplace: [],
374
484
  jsonToAugment: {
375
- 'js/package.json': ['prettier', 'devDependencies.prettier', 'devDependencies.@flarum/prettier-config', 'scripts.format', 'scripts.format-check'],
485
+ 'js/package.json': [
486
+ 'prettier',
487
+ 'devDependencies.prettier',
488
+ 'devDependencies.@flarum/prettier-config',
489
+ 'scripts.format',
490
+ 'scripts.format-check',
491
+ ],
376
492
  },
377
493
  needsTemplateParams: [],
494
+ inferEnabled: async (_fs, paths) => {
495
+ if (!(0, fs_1.existsSync)(paths.package('js/package.json'))) {
496
+ return false;
497
+ }
498
+ return (0, fs_1.readFileSync)(paths.package('js/package.json')).includes('prettier');
499
+ },
378
500
  };
379
501
  case 'typescript':
380
502
  return {
@@ -387,15 +509,20 @@ function moduleNameToDef(name) {
387
509
  filesToReplace: ['js/tsconfig.json'],
388
510
  jsonToAugment: {
389
511
  'js/package.json': [
390
- 'prettier',
391
512
  'devDependencies.flarum-tsconfig',
392
513
  'devDependencies.typescript',
393
514
  'devDependencies.typescript-coverage-report',
515
+ 'scripts.clean-typings',
516
+ 'scripts.build-typings',
517
+ 'scripts.post-build-typings',
394
518
  'scripts.check-typings',
395
519
  'scripts.check-typings-coverage',
396
520
  ],
397
521
  },
398
522
  needsTemplateParams: [],
523
+ inferEnabled: async (_fs, paths) => {
524
+ return (0, fs_1.existsSync)(paths.package('js/tsconfig.json'));
525
+ },
399
526
  };
400
527
  case 'bundlewatch':
401
528
  return {
@@ -408,6 +535,9 @@ function moduleNameToDef(name) {
408
535
  filesToReplace: ['js/.bundlewatch.config.json'],
409
536
  jsonToAugment: {},
410
537
  needsTemplateParams: [],
538
+ inferEnabled: async (_fs, paths) => {
539
+ return (0, fs_1.existsSync)(paths.package('js/.bundlewatch.config.json'));
540
+ },
411
541
  };
412
542
  case 'backendTesting':
413
543
  return {
@@ -426,7 +556,7 @@ function moduleNameToDef(name) {
426
556
  ],
427
557
  jsonToAugment: {
428
558
  'composer.json': [
429
- 'autoload-dev.psr-4.${params.packageNamespaceEscapedSlash}\\Tests\\',
559
+ 'autoload-dev.psr-4.${params.packageNamespace}\\Tests\\',
430
560
  'scripts.test',
431
561
  'scripts.test:unit',
432
562
  'scripts.test:integration',
@@ -438,7 +568,10 @@ function moduleNameToDef(name) {
438
568
  'require-dev.flarum/testing',
439
569
  ],
440
570
  },
441
- needsTemplateParams: ['packageNamespaceEscapedSlash'],
571
+ needsTemplateParams: ['packageNamespace'],
572
+ inferEnabled: async (_fs, paths) => {
573
+ return (0, fs_1.existsSync)(paths.package('tests'));
574
+ },
442
575
  };
443
576
  case 'editorConfig':
444
577
  return {
@@ -460,9 +593,7 @@ function moduleNameToDef(name) {
460
593
  defaultEnabled: true,
461
594
  shortDescription: 'StyleCI config file',
462
595
  dependsOn: [],
463
- filesToReplace: [
464
- { path: '.styleci.yml', monorepoPath: '.styleci.yml' },
465
- ],
596
+ filesToReplace: [{ path: '.styleci.yml', monorepoPath: '.styleci.yml', requireMonorepo: false }],
466
597
  jsonToAugment: {},
467
598
  needsTemplateParams: [],
468
599
  };
@@ -475,9 +606,9 @@ function genExtScaffolder() {
475
606
  return cached;
476
607
  const moduleStatusCache = {
477
608
  get: async (module, fs, paths) => {
478
- var _a, _b, _c, _d;
609
+ var _a, _b, _c;
479
610
  const json = (0, composer_1.getComposerJson)(fs, paths);
480
- return !module.togglable || ((_d = (_c = (_b = (_a = json === null || json === void 0 ? void 0 : json.extra) === null || _a === void 0 ? void 0 : _a['flarum-cli']) === null || _b === void 0 ? void 0 : _b.modules) === null || _c === void 0 ? void 0 : _c[module.name]) !== null && _d !== void 0 ? _d : module.defaultEnabled);
611
+ return !module.togglable || ((_c = (_b = (_a = json === null || json === void 0 ? void 0 : json.extra) === null || _a === void 0 ? void 0 : _a['flarum-cli']) === null || _b === void 0 ? void 0 : _b.modules) === null || _c === void 0 ? void 0 : _c[module.name]);
481
612
  },
482
613
  set: async (module, enabled, fs, paths) => {
483
614
  const json = {
@@ -493,11 +624,14 @@ function genExtScaffolder() {
493
624
  },
494
625
  };
495
626
  const excludeScaffoldingFunc = (fs, paths) => {
496
- var _a, _b, _c;
627
+ var _a, _b, _c, _d, _e, _f;
497
628
  const json = (0, composer_1.getComposerJson)(fs, paths);
498
- return (_c = (_b = (_a = json === null || json === void 0 ? void 0 : json.extra) === null || _a === void 0 ? void 0 : _a['flarum-cli']) === null || _b === void 0 ? void 0 : _b.excludeScaffolding) !== null && _c !== void 0 ? _c : [];
629
+ return {
630
+ files: (_c = (_b = (_a = json === null || json === void 0 ? void 0 : json.extra) === null || _a === void 0 ? void 0 : _a['flarum-cli']) === null || _b === void 0 ? void 0 : _b.excludeScaffolding) !== null && _c !== void 0 ? _c : [],
631
+ configKeys: (_f = (_e = (_d = json === null || json === void 0 ? void 0 : json.extra) === null || _d === void 0 ? void 0 : _d['flarum-cli']) === null || _e === void 0 ? void 0 : _e.excludeScaffoldingConfigKeys) !== null && _f !== void 0 ? _f : {},
632
+ };
499
633
  };
500
- const scaffolder = new scaffolder_1.Scaffolder((0, node_path_1.resolve)(__dirname, '../../boilerplate/skeleton/extension'), moduleStatusCache, excludeScaffoldingFunc);
634
+ const scaffolder = new scaffolder_1.Scaffolder((0, path_1.resolve)(__dirname, '../../boilerplate/skeleton/extension'), moduleStatusCache, excludeScaffoldingFunc);
501
635
  for (const name of exports.EXTENSION_MODULES) {
502
636
  scaffolder.registerModule(moduleNameToDef(name));
503
637
  }