@flarum/cli 1.0.0 → 2.0.0-beta.1

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 (185) hide show
  1. package/README.md +2 -2
  2. package/bin/run +5 -3
  3. package/boilerplate/skeleton/extension/.gitattributes +16 -3
  4. package/boilerplate/skeleton/extension/.github/workflows/backend.yml +15 -0
  5. package/boilerplate/skeleton/extension/.github/workflows/frontend.yml +20 -0
  6. package/boilerplate/skeleton/extension/.styleci.yml +14 -0
  7. package/boilerplate/skeleton/extension/LICENSE.md +1 -0
  8. package/boilerplate/skeleton/extension/README.md +7 -7
  9. package/boilerplate/skeleton/extension/composer.json +11 -9
  10. package/boilerplate/skeleton/extension/extend.php +10 -10
  11. package/boilerplate/skeleton/extension/js/admin.js +2 -1
  12. package/boilerplate/skeleton/extension/js/forum.js +2 -1
  13. package/boilerplate/skeleton/extension/js/package.json +13 -9
  14. package/boilerplate/skeleton/extension/js/src/admin/index.js +4 -2
  15. package/boilerplate/skeleton/extension/js/src/common/index.js +5 -0
  16. package/boilerplate/skeleton/extension/js/src/forum/index.js +4 -2
  17. package/boilerplate/skeleton/extension/js/tsconfig.json +6 -1
  18. package/boilerplate/skeleton/extension/locale/en.yml +1 -1
  19. package/boilerplate/stubs/migration.php +1 -1
  20. package/lib/base-command.d.ts +27 -6
  21. package/lib/base-command.js +131 -41
  22. package/lib/boilersmith/exposed-param-manager.d.ts +8 -0
  23. package/lib/boilersmith/exposed-param-manager.js +31 -0
  24. package/lib/boilersmith/io.d.ts +50 -0
  25. package/lib/boilersmith/io.js +72 -0
  26. package/lib/boilersmith/paths.d.ts +22 -0
  27. package/lib/boilersmith/paths.js +29 -0
  28. package/lib/boilersmith/scaffolding/audit-step-factory.d.ts +5 -0
  29. package/lib/boilersmith/scaffolding/audit-step-factory.js +54 -0
  30. package/lib/boilersmith/scaffolding/infra-step-factory.d.ts +5 -0
  31. package/lib/boilersmith/scaffolding/infra-step-factory.js +34 -0
  32. package/lib/boilersmith/scaffolding/init-step-factory.d.ts +5 -0
  33. package/lib/boilersmith/scaffolding/init-step-factory.js +34 -0
  34. package/lib/boilersmith/scaffolding/module.d.ts +68 -0
  35. package/lib/boilersmith/scaffolding/module.js +111 -0
  36. package/lib/boilersmith/scaffolding/scaffolder.d.ts +32 -0
  37. package/lib/boilersmith/scaffolding/scaffolder.js +203 -0
  38. package/lib/boilersmith/scaffolding/template-param.d.ts +23 -0
  39. package/lib/boilersmith/scaffolding/template-param.js +46 -0
  40. package/lib/boilersmith/step-manager.d.ts +85 -0
  41. package/lib/boilersmith/step-manager.js +234 -0
  42. package/lib/boilersmith/steps/stub-base.d.ts +53 -0
  43. package/lib/boilersmith/steps/stub-base.js +54 -0
  44. package/lib/{utils → boilersmith/utils}/clone-and-fill.d.ts +0 -0
  45. package/lib/{utils → boilersmith/utils}/clone-and-fill.js +2 -2
  46. package/lib/boilersmith/utils/cond-format.d.ts +1 -0
  47. package/lib/boilersmith/utils/cond-format.js +8 -0
  48. package/lib/boilersmith/utils/json-leaf-paths.d.ts +7 -0
  49. package/lib/boilersmith/utils/json-leaf-paths.js +17 -0
  50. package/lib/boilersmith/utils/read-tpl.d.ts +2 -0
  51. package/lib/boilersmith/utils/read-tpl.js +10 -0
  52. package/lib/boilersmith/utils/rename-keys.d.ts +1 -0
  53. package/lib/boilersmith/utils/rename-keys.js +7 -0
  54. package/lib/commands/audit/infra.d.ts +16 -0
  55. package/lib/commands/audit/infra.js +27 -0
  56. package/lib/commands/infra.d.ts +20 -0
  57. package/lib/commands/infra.js +55 -0
  58. package/lib/commands/init.d.ts +4 -3
  59. package/lib/commands/init.js +8 -6
  60. package/lib/commands/make/backend/api-controller.d.ts +4 -3
  61. package/lib/commands/make/backend/api-controller.js +3 -2
  62. package/lib/commands/make/backend/api-serializer-attributes.d.ts +4 -3
  63. package/lib/commands/make/backend/api-serializer-attributes.js +1 -1
  64. package/lib/commands/make/backend/api-serializer.d.ts +4 -3
  65. package/lib/commands/make/backend/api-serializer.js +3 -2
  66. package/lib/commands/make/backend/command.d.ts +4 -3
  67. package/lib/commands/make/backend/command.js +3 -2
  68. package/lib/commands/make/backend/event-listener.d.ts +4 -3
  69. package/lib/commands/make/backend/event-listener.js +3 -2
  70. package/lib/commands/make/backend/handler.d.ts +4 -3
  71. package/lib/commands/make/backend/handler.js +4 -3
  72. package/lib/commands/make/backend/integration-test.d.ts +4 -3
  73. package/lib/commands/make/backend/integration-test.js +3 -2
  74. package/lib/commands/make/backend/job.d.ts +4 -3
  75. package/lib/commands/make/backend/job.js +3 -2
  76. package/lib/commands/make/backend/migration.d.ts +4 -3
  77. package/lib/commands/make/backend/migration.js +3 -2
  78. package/lib/commands/make/backend/model.d.ts +4 -3
  79. package/lib/commands/make/backend/model.js +22 -21
  80. package/lib/commands/make/backend/policy.d.ts +4 -3
  81. package/lib/commands/make/backend/policy.js +3 -2
  82. package/lib/commands/make/backend/repository.d.ts +4 -3
  83. package/lib/commands/make/backend/repository.js +3 -2
  84. package/lib/commands/make/backend/route.d.ts +4 -3
  85. package/lib/commands/make/backend/route.js +1 -1
  86. package/lib/commands/make/backend/service-provider.d.ts +4 -3
  87. package/lib/commands/make/backend/service-provider.js +3 -2
  88. package/lib/commands/make/backend/validator.d.ts +4 -3
  89. package/lib/commands/make/backend/validator.js +3 -2
  90. package/lib/commands/make/frontend/component.d.ts +4 -3
  91. package/lib/commands/make/frontend/component.js +3 -2
  92. package/lib/commands/make/frontend/modal.d.ts +4 -3
  93. package/lib/commands/make/frontend/modal.js +3 -2
  94. package/lib/commands/make/frontend/model.d.ts +4 -3
  95. package/lib/commands/make/frontend/model.js +3 -2
  96. package/lib/commands/update/js-imports.d.ts +4 -3
  97. package/lib/commands/update/js-imports.js +1 -1
  98. package/lib/help.d.ts +5 -6
  99. package/lib/help.js +5 -4
  100. package/lib/index.d.ts +1 -1
  101. package/lib/index.js +3 -2
  102. package/lib/providers/index.d.ts +5 -0
  103. package/lib/providers/index.js +2 -0
  104. package/lib/{provider → providers}/php-provider.d.ts +0 -0
  105. package/lib/{provider → providers}/php-provider.js +2 -2
  106. package/lib/steps/extenders/api-serializer.js +2 -3
  107. package/lib/steps/extenders/base.d.ts +10 -10
  108. package/lib/steps/extenders/base.js +11 -11
  109. package/lib/steps/extenders/console-command.js +2 -3
  110. package/lib/steps/extenders/event.js +2 -3
  111. package/lib/steps/extenders/policy.js +2 -3
  112. package/lib/steps/extenders/route.js +2 -3
  113. package/lib/steps/extenders/service-provider.js +2 -3
  114. package/lib/steps/gen-ext-scaffolder.d.ts +6 -0
  115. package/lib/steps/gen-ext-scaffolder.js +508 -0
  116. package/lib/steps/js/base.d.ts +9 -9
  117. package/lib/steps/js/base.js +11 -11
  118. package/lib/steps/js/model.d.ts +5 -5
  119. package/lib/steps/js/model.js +8 -13
  120. package/lib/steps/misc/composer.d.ts +5 -6
  121. package/lib/steps/misc/composer.js +3 -3
  122. package/lib/steps/misc/git.d.ts +11 -0
  123. package/lib/steps/misc/git.js +20 -0
  124. package/lib/steps/misc/yarn.d.ts +5 -6
  125. package/lib/steps/misc/yarn.js +3 -3
  126. package/lib/steps/stubs/backend/api-controller.d.ts +1 -8
  127. package/lib/steps/stubs/backend/api-controller.js +2 -3
  128. package/lib/steps/stubs/backend/api-serializer.d.ts +4 -9
  129. package/lib/steps/stubs/backend/api-serializer.js +4 -4
  130. package/lib/steps/stubs/backend/command.d.ts +0 -5
  131. package/lib/steps/stubs/backend/command.js +1 -1
  132. package/lib/steps/stubs/backend/event-listener.d.ts +0 -5
  133. package/lib/steps/stubs/backend/event-listener.js +1 -1
  134. package/lib/steps/stubs/backend/handler-command.js +1 -1
  135. package/lib/steps/stubs/backend/handler.js +1 -1
  136. package/lib/steps/stubs/backend/migration.d.ts +4 -5
  137. package/lib/steps/stubs/backend/migration.js +8 -8
  138. package/lib/steps/stubs/backend/model.d.ts +4 -4
  139. package/lib/steps/stubs/backend/model.js +4 -4
  140. package/lib/steps/stubs/backend/policy.d.ts +0 -5
  141. package/lib/steps/stubs/backend/policy.js +1 -1
  142. package/lib/steps/stubs/backend/repository.d.ts +0 -5
  143. package/lib/steps/stubs/backend/repository.js +1 -1
  144. package/lib/steps/stubs/flarum-base.d.ts +9 -0
  145. package/lib/steps/stubs/flarum-base.js +10 -0
  146. package/lib/steps/stubs/frontend/component.js +0 -1
  147. package/lib/steps/stubs/frontend/modal.js +0 -1
  148. package/lib/steps/stubs/frontend/model.d.ts +4 -4
  149. package/lib/steps/stubs/frontend/model.js +3 -3
  150. package/lib/steps/stubs/js-base.d.ts +6 -7
  151. package/lib/steps/stubs/js-base.js +11 -16
  152. package/lib/steps/stubs/php-base.d.ts +7 -8
  153. package/lib/steps/stubs/php-base.js +12 -20
  154. package/lib/steps/update/js-imports.d.ts +5 -6
  155. package/lib/steps/update/js-imports.js +13 -17
  156. package/lib/utils/composer.d.ts +64 -0
  157. package/lib/utils/composer.js +8 -0
  158. package/lib/utils/migration.js +3 -3
  159. package/lib/utils/model-name.js +6 -6
  160. package/lib/utils/validation.d.ts +10 -7
  161. package/lib/utils/validation.js +9 -6
  162. package/oclif.manifest.json +1 -1
  163. package/package.json +53 -31
  164. package/php-subsystem/src/NodeVisitors/AddExtender.php +2 -1
  165. package/boilerplate/skeleton/extension/.github/workflows/build.yml +0 -32
  166. package/boilerplate/skeleton/extension/.github/workflows/lint.yml +0 -32
  167. package/boilerplate/skeleton/extension/.github/workflows/test.yml +0 -78
  168. package/lib/commands/infra/backend-testing.d.ts +0 -14
  169. package/lib/commands/infra/backend-testing.js +0 -26
  170. package/lib/provider/param-provider.d.ts +0 -15
  171. package/lib/provider/param-provider.js +0 -39
  172. package/lib/provider/path-provider.d.ts +0 -19
  173. package/lib/provider/path-provider.js +0 -24
  174. package/lib/steps/infra/backend-testing.d.ts +0 -8
  175. package/lib/steps/infra/backend-testing.js +0 -22
  176. package/lib/steps/infra/base.d.ts +0 -20
  177. package/lib/steps/infra/base.js +0 -36
  178. package/lib/steps/init/extension-skeleton.d.ts +0 -12
  179. package/lib/steps/init/extension-skeleton.js +0 -142
  180. package/lib/steps/step-manager.d.ts +0 -71
  181. package/lib/steps/step-manager.js +0 -173
  182. package/lib/steps/stubs/base.d.ts +0 -49
  183. package/lib/steps/stubs/base.js +0 -58
  184. package/lib/utils/extension-metadata.d.ts +0 -2
  185. package/lib/utils/extension-metadata.js +0 -21
@@ -1,14 +0,0 @@
1
- import { StepManager } from '../../steps/step-manager';
2
- import BaseCommand from '../../base-command';
3
- export default class BackendTesting extends BaseCommand {
4
- static description: string;
5
- static flags: {
6
- [x: string]: import("@oclif/command/lib/flags").IFlag<any>;
7
- };
8
- static args: {
9
- name: string;
10
- description: string;
11
- }[];
12
- protected steps(stepManager: StepManager): StepManager;
13
- protected additionalPreRunChecks(extRoot: string): Promise<void>;
14
- }
@@ -1,26 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- const composer_1 = require("../../steps/misc/composer");
5
- const base_command_1 = tslib_1.__importDefault(require("../../base-command"));
6
- const backend_testing_1 = require("../../steps/infra/backend-testing");
7
- class BackendTesting extends base_command_1.default {
8
- steps(stepManager) {
9
- return stepManager
10
- .namedStep('testing', new backend_testing_1.BackendTestingInfra())
11
- .step(new composer_1.ComposerInstall(), { optional: true, confirmationMessage: 'Run `composer update`? (recommended)', default: true }, [
12
- {
13
- sourceStep: 'testing',
14
- exposedName: '__succeeded',
15
- dontRunIfFalsy: true,
16
- },
17
- ]);
18
- }
19
- async additionalPreRunChecks(extRoot) {
20
- await this.confirmOverrideFiles(extRoot, 'tests/integration/setup.php', 'Test infrastructure files already exist. Overwrite with the latest version?');
21
- }
22
- }
23
- exports.default = BackendTesting;
24
- BackendTesting.description = 'Add/Update backend testing infrastructure';
25
- BackendTesting.flags = Object.assign({}, base_command_1.default.flags);
26
- BackendTesting.args = [...base_command_1.default.args];
@@ -1,15 +0,0 @@
1
- import { Options, PromptObject } from 'prompts';
2
- export declare type ParamDef = PromptObject;
3
- export declare const PROMPTS_OPTIONS: Options;
4
- export declare class ParamProvider {
5
- private cache;
6
- constructor(initial?: Record<string, unknown>);
7
- get<T>(paramDef: ParamDef): Promise<T>;
8
- has(name: string): boolean;
9
- /**
10
- * @internal
11
- */
12
- cached(): Record<string, unknown>;
13
- }
14
- export declare type ParamProviderFactory = (initial: Record<string, unknown>) => ParamProvider;
15
- export declare const paramProviderFactory: ParamProviderFactory;
@@ -1,39 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.paramProviderFactory = exports.ParamProvider = exports.PROMPTS_OPTIONS = void 0;
4
- const tslib_1 = require("tslib");
5
- const prompts_1 = tslib_1.__importDefault(require("prompts"));
6
- const errors_1 = require("@oclif/errors");
7
- exports.PROMPTS_OPTIONS = { onCancel: () => errors_1.exit() };
8
- class ParamProvider {
9
- constructor(initial = {}) {
10
- this.cache = new Map();
11
- this.cache = new Map(Object.entries(initial));
12
- }
13
- async get(paramDef) {
14
- const paramName = paramDef.name;
15
- if (this.cache.has(paramName)) {
16
- return this.cache.get(paramName);
17
- }
18
- const res = await prompts_1.default(paramDef, exports.PROMPTS_OPTIONS);
19
- const resValue = res[paramName];
20
- this.cache.set(paramName, resValue);
21
- return resValue;
22
- }
23
- has(name) {
24
- return this.cache.has(name);
25
- }
26
- /**
27
- * @internal
28
- */
29
- cached() {
30
- return [...this.cache].reduce((obj, [key, value]) => {
31
- obj[key] = value;
32
- return obj;
33
- }, {});
34
- }
35
- }
36
- exports.ParamProvider = ParamProvider;
37
- exports.paramProviderFactory = (initial = {}) => {
38
- return new ParamProvider(initial);
39
- };
@@ -1,19 +0,0 @@
1
- export interface PathProvider {
2
- cwd(...path: string[]): string;
3
- ext(...path: string[]): string;
4
- boilerplate(...path: string[]): string;
5
- requestedDir(...path: string[]): string | null;
6
- }
7
- interface Paths {
8
- ext: string;
9
- requestedDir?: string;
10
- }
11
- export declare class PathFsProvider implements PathProvider {
12
- private paths;
13
- constructor(paths: Paths);
14
- cwd(...path: string[]): string;
15
- ext(...path: string[]): string;
16
- boilerplate(...path: string[]): string;
17
- requestedDir(...path: string[]): string | null;
18
- }
19
- export {};
@@ -1,24 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PathFsProvider = void 0;
4
- const path_1 = require("path");
5
- class PathFsProvider {
6
- constructor(paths) {
7
- this.paths = paths;
8
- }
9
- cwd(...path) {
10
- return path_1.resolve(process.cwd(), ...path);
11
- }
12
- ext(...path) {
13
- return path_1.resolve(this.paths.ext, ...path);
14
- }
15
- boilerplate(...path) {
16
- return path_1.resolve(__dirname, '../../boilerplate', ...path);
17
- }
18
- requestedDir(...path) {
19
- if (!this.paths.requestedDir)
20
- return null;
21
- return path_1.resolve(this.paths.requestedDir, ...path);
22
- }
23
- }
24
- exports.PathFsProvider = PathFsProvider;
@@ -1,8 +0,0 @@
1
- import { BaseInfraStep } from './base';
2
- export declare class BackendTestingInfra extends BaseInfraStep {
3
- type: string;
4
- protected filesToReplace: string[];
5
- protected jsonToAugment: {
6
- 'composer.json': string[];
7
- };
8
- }
@@ -1,22 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BackendTestingInfra = void 0;
4
- const base_1 = require("./base");
5
- class BackendTestingInfra extends base_1.BaseInfraStep {
6
- constructor() {
7
- super(...arguments);
8
- this.type = 'Add/update backend testing infrastructure';
9
- this.filesToReplace = [
10
- 'tests/phpunit.integration.xml',
11
- 'tests/phpunit.unit.xml',
12
- 'tests/fixtures/.gitkeep',
13
- 'tests/integration/setup.php',
14
- 'tests/unit/.gitkeep',
15
- '.github/workflows/test.yml',
16
- ];
17
- this.jsonToAugment = {
18
- 'composer.json': ['scripts', 'scripts-description', 'require-dev'],
19
- };
20
- }
21
- }
22
- exports.BackendTestingInfra = BackendTestingInfra;
@@ -1,20 +0,0 @@
1
- import { Store } from 'mem-fs';
2
- import { ParamProvider } from '../../provider/param-provider';
3
- import { PathProvider } from '../../provider/path-provider';
4
- import { PhpProvider } from '../../provider/php-provider';
5
- import { Step } from '../step-manager';
6
- export declare abstract class BaseInfraStep implements Step {
7
- abstract type: string;
8
- composable: boolean;
9
- /**
10
- * A list of file paths to replace from the boilerplate
11
- */
12
- protected abstract filesToReplace: string[];
13
- /**
14
- * A map of names of JSON files to keys which should be deep-merged from the boilerplate.
15
- */
16
- protected abstract jsonToAugment: Record<string, string[]>;
17
- run(fs: Store, pathProvider: PathProvider, _paramProvider: ParamProvider, _phpProvider: PhpProvider): Promise<Store>;
18
- exposes: never[];
19
- getExposed(_pathProvider: PathProvider, _paramProvider: ParamProvider): Record<string, unknown>;
20
- }
@@ -1,36 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BaseInfraStep = void 0;
4
- const mem_fs_editor_1 = require("mem-fs-editor");
5
- const pick_1 = require("@zodash/pick");
6
- const extension_metadata_1 = require("../../utils/extension-metadata");
7
- class BaseInfraStep {
8
- constructor() {
9
- this.composable = true;
10
- this.exposes = [];
11
- }
12
- async run(fs, pathProvider, _paramProvider, _phpProvider) {
13
- const fsEditor = mem_fs_editor_1.create(fs);
14
- this.filesToReplace.forEach(filePath => {
15
- fsEditor.copy(pathProvider.boilerplate(`skeleton/extension/${filePath}`), pathProvider.ext(filePath));
16
- });
17
- const fakeInitData = extension_metadata_1.extensionMetadata(fsEditor.readJSON(pathProvider.ext('composer.json')));
18
- fakeInitData.packageNamespace = fakeInitData.packageNamespace.replace('\\', '\\\\');
19
- Object.keys(this.jsonToAugment).forEach(jsonPath => {
20
- const boilerplatePath = pathProvider.boilerplate('skeleton/extension', jsonPath);
21
- const boilerplateTmpPath = pathProvider.boilerplate('skeleton/extension', `${jsonPath}.tmp`);
22
- // We copy it to resolve template tags.
23
- fsEditor.copyTpl(boilerplatePath, boilerplateTmpPath, fakeInitData);
24
- const boilerplateComposerJson = fsEditor.readJSON(boilerplateTmpPath);
25
- fsEditor.delete(boilerplateTmpPath);
26
- const fieldsToAugment = this.jsonToAugment[jsonPath];
27
- const relevant = pick_1.pick(boilerplateComposerJson, fieldsToAugment);
28
- fsEditor.extendJSON(pathProvider.ext(jsonPath), relevant);
29
- });
30
- return fs;
31
- }
32
- getExposed(_pathProvider, _paramProvider) {
33
- return {};
34
- }
35
- }
36
- exports.BaseInfraStep = BaseInfraStep;
@@ -1,12 +0,0 @@
1
- import { Store } from 'mem-fs';
2
- import { ParamProvider } from '../../provider/param-provider';
3
- import { PathProvider } from '../../provider/path-provider';
4
- import { PhpProvider } from '../../provider/php-provider';
5
- import { Step } from '../step-manager';
6
- export declare class ExtensionSkeleton implements Step {
7
- type: string;
8
- composable: boolean;
9
- run(fs: Store, pathProvider: PathProvider, paramProvider: ParamProvider, _phpProvider: PhpProvider): Promise<Store>;
10
- exposes: string[];
11
- getExposed(_pathProvider: PathProvider, paramProvider: ParamProvider): Record<string, unknown>;
12
- }
@@ -1,142 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ExtensionSkeleton = void 0;
4
- const tslib_1 = require("tslib");
5
- const pick_1 = require("@zodash/pick");
6
- const chalk_1 = tslib_1.__importDefault(require("chalk"));
7
- const mem_fs_editor_1 = require("mem-fs-editor");
8
- const simple_1 = tslib_1.__importDefault(require("spdx-license-list/simple"));
9
- const extension_metadata_1 = require("../../utils/extension-metadata");
10
- class ExtensionSkeleton {
11
- constructor() {
12
- this.type = 'Generate extension skeleton';
13
- this.composable = true;
14
- this.exposes = ['useJs'];
15
- }
16
- async run(fs, pathProvider, paramProvider, _phpProvider) {
17
- const fsEditor = mem_fs_editor_1.create(fs);
18
- const packageName = await paramProvider.get({
19
- name: 'packageName',
20
- type: 'text',
21
- message: `Package ${chalk_1.default.dim('(vendor/extension-name)')}`,
22
- validate: s => /^([0-9a-zA-Z-]{2,})\/([0-9a-zA-Z-]{2,})$/.test(s.trim()) || 'Invalid package name format',
23
- format: s => s.toLowerCase(),
24
- });
25
- const packageDescription = await paramProvider.get({
26
- name: 'packageDescription',
27
- type: 'text',
28
- message: 'Package description',
29
- });
30
- const namespace = await paramProvider.get({
31
- name: 'namespace',
32
- type: 'text',
33
- message: `Package namespace ${chalk_1.default.dim('(Vendor\\ExtensionName)')}`,
34
- validate: s => /^([0-9a-zA-Z]+)\\([0-9a-zA-Z]+)$/.test(s.trim()) || 'Invalid namespace format',
35
- format: (str) => str &&
36
- str
37
- .split('\\')
38
- .map(s => s[0].toUpperCase() + s.slice(1))
39
- .join('\\'),
40
- });
41
- const authorName = await paramProvider.get({
42
- name: 'authorName',
43
- type: 'text',
44
- message: 'Author name',
45
- });
46
- const authorEmail = await paramProvider.get({
47
- name: 'authorEmail',
48
- type: 'text',
49
- message: 'Author email',
50
- validate: s => !s || /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test(s) || 'Invalid email format',
51
- });
52
- const extensionName = await paramProvider.get({
53
- name: 'extensionName',
54
- type: 'text',
55
- message: 'Extension name',
56
- validate: str => Boolean(str.trim()) || 'The extension name is required',
57
- format: str => str
58
- .split(' ')
59
- .map((s) => (s.length > 3 ? s[0].toUpperCase() + s.slice(1) : s))
60
- .join(' '),
61
- });
62
- const licenseType = await paramProvider.get({
63
- name: 'license',
64
- type: 'autocomplete',
65
- message: 'License',
66
- choices: [...simple_1.default].map(e => ({ title: e, value: e })),
67
- });
68
- const admin = await paramProvider.get({
69
- name: 'admin',
70
- type: 'confirm',
71
- message: 'Admin CSS & JS',
72
- initial: true,
73
- });
74
- const forum = await paramProvider.get({
75
- name: 'forum',
76
- type: 'confirm',
77
- message: 'Forum CSS & JS',
78
- initial: true,
79
- });
80
- const useLocale = await paramProvider.get({
81
- name: 'useLocale',
82
- type: 'confirm',
83
- message: 'Locale',
84
- initial: true,
85
- });
86
- const useJs = await paramProvider.get({
87
- name: 'useJs',
88
- type: () => (admin || forum) && 'confirm',
89
- message: 'Javascript',
90
- initial: true,
91
- });
92
- const useCss = await paramProvider.get({
93
- name: 'useCss',
94
- type: () => (admin || forum) && 'confirm',
95
- message: 'CSS',
96
- initial: true,
97
- });
98
- const tpl = {
99
- namespace,
100
- packageName,
101
- packageDescription,
102
- authorName,
103
- authorEmail,
104
- extensionName,
105
- licenseType,
106
- admin,
107
- forum,
108
- useLocale,
109
- useJs,
110
- useCss,
111
- packageNamespace: namespace.replace(/\\/, '\\\\'),
112
- year: new Date().getFullYear().toString(),
113
- extensionId: extension_metadata_1.extensionId(packageName),
114
- };
115
- fsEditor.copyTpl(pathProvider.boilerplate('skeleton/extension'), pathProvider.ext(''), tpl, undefined, { globOptions: { dot: true } });
116
- const license = await require(`spdx-license-list/licenses/${licenseType}`);
117
- fsEditor.write(pathProvider.ext('LICENSE.md'), license.licenseText);
118
- if (!useLocale)
119
- fsEditor.delete(pathProvider.ext('locale'));
120
- if (!useJs) {
121
- fsEditor.delete(pathProvider.ext('js/.prettierrc.json'));
122
- fsEditor.delete(pathProvider.ext('js'));
123
- }
124
- if (!useCss)
125
- fsEditor.delete(pathProvider.ext('less'));
126
- if (!admin) {
127
- fsEditor.delete(pathProvider.ext('less/admin.less'));
128
- fsEditor.delete(pathProvider.ext('js/src/admin'));
129
- fsEditor.delete(pathProvider.ext('js/admin.js'));
130
- }
131
- if (!forum) {
132
- fsEditor.delete(pathProvider.ext('less/forum.less'));
133
- fsEditor.delete(pathProvider.ext('js/src/forum'));
134
- fsEditor.delete(pathProvider.ext('js/forum.js'));
135
- }
136
- return fs;
137
- }
138
- getExposed(_pathProvider, paramProvider) {
139
- return pick_1.pick(paramProvider.cached(), this.exposes);
140
- }
141
- }
142
- exports.ExtensionSkeleton = ExtensionSkeleton;
@@ -1,71 +0,0 @@
1
- import { Store } from 'mem-fs';
2
- import { ParamProvider, ParamProviderFactory } from '../provider/param-provider';
3
- import { PathProvider } from '../provider/path-provider';
4
- import { PhpProvider } from '../provider/php-provider';
5
- export interface Step {
6
- /**
7
- * A short string describing what the step does.
8
- */
9
- type: string;
10
- /**
11
- * Can this step be composed with other steps?
12
- *
13
- * This is the case if the step makes no changes to the disk filesystem while running.
14
- */
15
- composable: boolean;
16
- /**
17
- * A list of names of params that this step exposes to other steps.
18
- */
19
- exposes: string[];
20
- run: (fs: Store, pathProvider: PathProvider, paramProvider: ParamProvider, phpProvider: PhpProvider) => Promise<Store>;
21
- /**
22
- * Return an object of exposed params.
23
- *
24
- * The pathProvider and paramProvider will be the same objects provided to the `run` method.
25
- */
26
- getExposed(pathProvider: PathProvider, paramProvider: ParamProvider): Record<string, unknown>;
27
- }
28
- interface ShouldRunConfig {
29
- optional?: boolean;
30
- confirmationMessage?: string;
31
- default?: boolean;
32
- }
33
- interface StoredStep {
34
- name?: string;
35
- step: Step;
36
- shouldRun: ShouldRunConfig;
37
- dependencies: StepDependency[];
38
- predefinedParams: PredefinedParameters;
39
- }
40
- interface StepDependency {
41
- sourceStep: string;
42
- exposedName: string;
43
- consumedName?: string;
44
- dontRunIfFalsy?: boolean;
45
- modifier?: (value: unknown) => string;
46
- }
47
- declare type PredefinedParameters = Record<string, unknown>;
48
- export declare class StepManager {
49
- protected steps: Array<StoredStep | AtomicStepManager>;
50
- protected namedSteps: Map<string, StoredStep>;
51
- protected exposedParams: Map<string, Record<string, unknown>>;
52
- /**
53
- * A step is an incremental operation that updates the filesystem.
54
- */
55
- step(step: Step, shouldRun?: ShouldRunConfig, dependencies?: StepDependency[], predefinedParams?: PredefinedParameters): this;
56
- namedStep(name: string, step: Step, shouldRun?: ShouldRunConfig, dependencies?: StepDependency[], predefinedParams?: PredefinedParameters): this;
57
- atomicGroup(callback: (stepManager: AtomicStepManager) => void): this;
58
- protected validateDependencies(step: Step, dependencies: StepDependency[]): void;
59
- run(pathProvider: PathProvider, paramProviderFactory: ParamProviderFactory, phpProvider: PhpProvider): Promise<string[]>;
60
- protected stepShouldRun(storedStep: StoredStep, paramProviderFactory: ParamProviderFactory): Promise<boolean>;
61
- protected runStep(storedStep: StoredStep, pathProvider: PathProvider, paramProviderFactory: ParamProviderFactory, phpProvider: PhpProvider, fs?: Store): Promise<Store>;
62
- protected commit(fs: Store): Promise<boolean>;
63
- }
64
- declare class AtomicStepManager extends StepManager {
65
- constructor(parentNamedSteps: Map<string, StoredStep>, parentExposedParams: Map<string, Record<string, unknown>>);
66
- step(step: Step, shouldRun?: ShouldRunConfig, dependencies?: StepDependency[], predefinedParams?: PredefinedParameters): this;
67
- namedStep(name: string, step: Step, shouldRun?: ShouldRunConfig, dependencies?: StepDependency[], predefinedParams?: PredefinedParameters): this;
68
- atomicGroup(_callback: (stepManager: AtomicStepManager) => void): this;
69
- run(pathProvider: PathProvider, paramProviderFactory: ParamProviderFactory, phpProvider: PhpProvider): Promise<string[]>;
70
- }
71
- export {};
@@ -1,173 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StepManager = void 0;
4
- /* eslint-disable no-await-in-loop */
5
- const mem_fs_1 = require("mem-fs");
6
- const mem_fs_editor_1 = require("mem-fs-editor");
7
- class StepManager {
8
- constructor() {
9
- this.steps = [];
10
- this.namedSteps = new Map();
11
- this.exposedParams = new Map();
12
- }
13
- /**
14
- * A step is an incremental operation that updates the filesystem.
15
- */
16
- step(step, shouldRun = {}, dependencies = [], predefinedParams = {}) {
17
- this.validateDependencies(step, dependencies);
18
- this.steps = [...this.steps, { step, shouldRun, dependencies, predefinedParams }];
19
- return this;
20
- }
21
- namedStep(name, step, shouldRun = {}, dependencies = [], predefinedParams = {}) {
22
- if (this.namedSteps.has(name)) {
23
- throw new Error(`Named steps must have unique names. A step with name "${name}" already exists.`);
24
- }
25
- this.validateDependencies(step, dependencies);
26
- const newStep = { name, step, shouldRun, dependencies, predefinedParams };
27
- this.steps = [...this.steps, newStep];
28
- this.namedSteps.set(name, newStep);
29
- return this;
30
- }
31
- atomicGroup(callback) {
32
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
33
- const atomicCollection = new AtomicStepManager(this.namedSteps, this.exposedParams);
34
- callback(atomicCollection);
35
- this.steps = [...this.steps, atomicCollection];
36
- return this;
37
- }
38
- validateDependencies(step, dependencies) {
39
- const format = (strings) => strings
40
- .map(s => `"${s}"`)
41
- .join(', ');
42
- const missingDependencySteps = dependencies
43
- .map(dep => dep.sourceStep)
44
- .filter(stepName => !this.namedSteps.has(stepName));
45
- if (missingDependencySteps.length > 0) {
46
- throw new Error(`Step of type "${step.type}" depends on nonexistent named steps ${format(missingDependencySteps)}`);
47
- }
48
- const missingDependencyParams = [];
49
- const missingDependencyParamSteps = [];
50
- dependencies.forEach(dependency => {
51
- const sourceStep = this.namedSteps.get(dependency.sourceStep);
52
- if (!(sourceStep === null || sourceStep === void 0 ? void 0 : sourceStep.step.exposes.includes(dependency.exposedName)) && dependency.exposedName !== '__succeeded') {
53
- missingDependencyParamSteps.push(sourceStep === null || sourceStep === void 0 ? void 0 : sourceStep.name);
54
- missingDependencyParams.push(dependency.exposedName);
55
- }
56
- });
57
- if (missingDependencyParamSteps.length > 0) {
58
- throw new Error(`Step of type "${step.type}" depends on nonexistent exposed params ${format(missingDependencyParams)} from named steps ${format(missingDependencyParamSteps)}`);
59
- }
60
- }
61
- async run(pathProvider, paramProviderFactory, phpProvider) {
62
- const stepNames = [];
63
- for (let i = 0; i < this.steps.length; i++) {
64
- const storedStep = this.steps[i];
65
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
66
- if (storedStep instanceof AtomicStepManager) {
67
- const res = await storedStep.run(pathProvider, paramProviderFactory, phpProvider);
68
- stepNames.push(...res);
69
- }
70
- else {
71
- const shouldRun = await this.stepShouldRun(storedStep, paramProviderFactory);
72
- if (!shouldRun)
73
- continue;
74
- const fs = await this.runStep(storedStep, pathProvider, paramProviderFactory, phpProvider);
75
- await this.commit(fs);
76
- stepNames.push(storedStep.step.type);
77
- }
78
- }
79
- return stepNames;
80
- }
81
- async stepShouldRun(storedStep, paramProviderFactory) {
82
- let allDependenciesRan = true;
83
- let noRequiredNonFalsyDependenciesAreFalsy = true;
84
- storedStep.dependencies.forEach(dep => {
85
- if (!this.exposedParams.has(dep.sourceStep))
86
- allDependenciesRan = false;
87
- const sourceDeps = this.exposedParams.get(dep.sourceStep);
88
- if (dep.exposedName !== '__succeeded' && dep.dontRunIfFalsy && !sourceDeps[dep.exposedName]) {
89
- noRequiredNonFalsyDependenciesAreFalsy = false;
90
- }
91
- });
92
- if (!allDependenciesRan || !noRequiredNonFalsyDependenciesAreFalsy)
93
- return false;
94
- if (!storedStep.shouldRun.optional)
95
- return true;
96
- const promptConfirm = await paramProviderFactory({ context: 'Confirm Step' }).get({
97
- name: 'execute_step',
98
- message: storedStep.shouldRun.confirmationMessage || `Run step of type "${storedStep.step.type}"?`,
99
- initial: storedStep.shouldRun.default || false,
100
- type: 'confirm',
101
- });
102
- return promptConfirm;
103
- }
104
- async runStep(storedStep, pathProvider, paramProviderFactory, phpProvider, fs = mem_fs_1.create()) {
105
- const initial = storedStep.dependencies.reduce((initial, dep) => {
106
- let depValue;
107
- if (dep.exposedName === '__succeeded') {
108
- depValue = this.exposedParams.has(dep.sourceStep);
109
- }
110
- else {
111
- depValue = this.exposedParams.get(dep.sourceStep)[dep.exposedName];
112
- }
113
- if (dep.modifier) {
114
- depValue = dep.modifier(depValue);
115
- }
116
- initial[dep.consumedName || dep.exposedName] = depValue;
117
- return initial;
118
- }, {});
119
- const paramProvider = paramProviderFactory(Object.assign(Object.assign({}, initial), storedStep.predefinedParams));
120
- const newFs = await storedStep.step.run(fs, pathProvider, paramProvider, phpProvider);
121
- if (storedStep.name) {
122
- this.exposedParams.set(storedStep.name, storedStep.step.getExposed(pathProvider, paramProvider));
123
- }
124
- return newFs;
125
- }
126
- async commit(fs) {
127
- return new Promise((resolve, _reject) => {
128
- mem_fs_editor_1.create(fs).commit(err => {
129
- if (err) {
130
- throw new Error(err);
131
- }
132
- resolve(true);
133
- });
134
- });
135
- }
136
- }
137
- exports.StepManager = StepManager;
138
- class AtomicStepManager extends StepManager {
139
- constructor(parentNamedSteps, parentExposedParams) {
140
- super();
141
- this.namedSteps = parentNamedSteps;
142
- this.exposedParams = parentExposedParams;
143
- }
144
- step(step, shouldRun = {}, dependencies = [], predefinedParams = {}) {
145
- if (!step.composable) {
146
- throw new Error(`Step of type "${step.type}" is not composable, and cannot be added to an atomic group.`);
147
- }
148
- return super.step(step, shouldRun, dependencies, predefinedParams);
149
- }
150
- namedStep(name, step, shouldRun = {}, dependencies = [], predefinedParams = {}) {
151
- if (!step.composable) {
152
- throw new Error(`Step of type "${step.type}" is not composable, and cannot be added to an atomic group.`);
153
- }
154
- return super.namedStep(name, step, shouldRun, dependencies, predefinedParams);
155
- }
156
- atomicGroup(_callback) {
157
- throw new Error("Atomic groups can't be nested.");
158
- }
159
- async run(pathProvider, paramProviderFactory, phpProvider) {
160
- let fs = mem_fs_1.create();
161
- const stepNames = [];
162
- for (let i = 0; i < this.steps.length; i++) {
163
- const storedStep = this.steps[i];
164
- const shouldRun = await this.stepShouldRun(storedStep, paramProviderFactory);
165
- if (!shouldRun)
166
- continue;
167
- fs = await this.runStep(storedStep, pathProvider, paramProviderFactory, phpProvider, fs);
168
- stepNames.push(storedStep.step.type);
169
- }
170
- await this.commit(fs);
171
- return stepNames;
172
- }
173
- }