@flarum/cli 2.0.0-beta.13 → 2.0.0-beta.16
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.
- package/README.md +136 -39
- package/bin/run +2 -1
- package/bin/splitsh-lite-darwin +0 -0
- package/bin/splitsh-lite-linux +0 -0
- package/boilerplate/skeleton/extension/.gitattributes +16 -14
- package/boilerplate/skeleton/extension/.github/workflows/backend.yml +1 -1
- package/boilerplate/skeleton/extension/.github/workflows/frontend.yml +3 -1
- package/boilerplate/skeleton/extension/LICENSE.md +1 -1
- package/boilerplate/skeleton/extension/composer.json +6 -4
- package/boilerplate/skeleton/extension/js/package.json +5 -1
- package/boilerplate/skeleton/extension/js/tsconfig.json +10 -2
- package/boilerplate/skeleton/extension/locale/en.yml +1 -1
- package/boilerplate/skeleton/extension/tests/phpunit.integration.xml +1 -0
- package/lib/base-command.d.ts +3 -1
- package/lib/base-command.js +44 -31
- package/lib/boilersmith/io.d.ts +28 -8
- package/lib/boilersmith/io.js +4 -2
- package/lib/boilersmith/paths.d.ts +2 -2
- package/lib/boilersmith/paths.js +7 -7
- package/lib/boilersmith/scaffolding/audit-step-factory.js +11 -11
- package/lib/boilersmith/scaffolding/infra-step-factory.js +2 -2
- package/lib/boilersmith/scaffolding/init-step-factory.js +5 -5
- package/lib/boilersmith/scaffolding/module.d.ts +19 -8
- package/lib/boilersmith/scaffolding/module.js +56 -19
- package/lib/boilersmith/scaffolding/scaffolder.d.ts +4 -1
- package/lib/boilersmith/scaffolding/scaffolder.js +32 -32
- package/lib/boilersmith/scaffolding/template-param.d.ts +1 -1
- package/lib/boilersmith/scaffolding/template-param.js +2 -2
- package/lib/boilersmith/step-manager.d.ts +0 -1
- package/lib/boilersmith/step-manager.js +10 -20
- package/lib/boilersmith/steps/stub-base.js +3 -3
- package/lib/boilersmith/utils/clone-and-fill.js +1 -1
- package/lib/boilersmith/utils/commit-async.d.ts +2 -0
- package/lib/boilersmith/utils/commit-async.js +15 -0
- package/lib/boilersmith/utils/read-tpl.js +2 -2
- package/lib/commands/audit/infra.d.ts +1 -1
- package/lib/commands/audit/infra.js +30 -8
- package/lib/commands/infra.d.ts +2 -2
- package/lib/commands/infra.js +18 -12
- package/lib/commands/init.d.ts +1 -1
- package/lib/commands/init.js +4 -2
- package/lib/commands/make/backend/api-controller.js +1 -2
- package/lib/commands/make/backend/api-serializer-attributes.js +1 -2
- package/lib/commands/make/backend/command.js +1 -2
- package/lib/commands/make/backend/event-listener.js +1 -2
- package/lib/commands/make/backend/handler.js +2 -5
- package/lib/commands/make/backend/integration-test.js +2 -4
- package/lib/commands/make/backend/migration.js +1 -2
- package/lib/commands/make/backend/model.js +1 -2
- package/lib/commands/make/backend/policy.js +1 -2
- package/lib/commands/make/backend/route.js +1 -2
- package/lib/commands/make/backend/service-provider.js +1 -2
- package/lib/commands/make/frontend/model.js +2 -5
- package/lib/commands/monorepo/create.d.ts +15 -0
- package/lib/commands/monorepo/create.js +20 -0
- package/lib/commands/monorepo/split.d.ts +15 -0
- package/lib/commands/monorepo/split.js +19 -0
- package/lib/commands/update/js-imports.js +1 -2
- package/lib/help.js +1 -1
- package/lib/providers/php-provider.js +2 -2
- package/lib/steps/gen-ext-scaffolder.d.ts +1 -1
- package/lib/steps/gen-ext-scaffolder.js +114 -64
- package/lib/steps/js/base.js +2 -4
- package/lib/steps/js/model.js +4 -4
- package/lib/steps/misc/composer.js +2 -2
- package/lib/steps/misc/git.d.ts +1 -1
- package/lib/steps/misc/git.js +2 -2
- package/lib/steps/misc/npm.d.ts +11 -0
- package/lib/steps/misc/npm.js +19 -0
- package/lib/steps/misc/yarn.js +2 -2
- package/lib/steps/monorepo/create.d.ts +17 -0
- package/lib/steps/monorepo/create.js +186 -0
- package/lib/steps/monorepo/split.d.ts +14 -0
- package/lib/steps/monorepo/split.js +95 -0
- package/lib/steps/stubs/backend/api-controller.d.ts +1 -1
- package/lib/steps/stubs/backend/api-controller.js +3 -0
- package/lib/steps/stubs/backend/api-serializer.d.ts +1 -1
- package/lib/steps/stubs/backend/api-serializer.js +3 -0
- package/lib/steps/stubs/backend/command.d.ts +0 -5
- package/lib/steps/stubs/backend/command.js +1 -0
- package/lib/steps/stubs/backend/event-listener.d.ts +1 -1
- package/lib/steps/stubs/backend/event-listener.js +2 -0
- package/lib/steps/stubs/backend/handler-command.d.ts +1 -1
- package/lib/steps/stubs/backend/handler-command.js +1 -0
- package/lib/steps/stubs/backend/handler.d.ts +1 -1
- package/lib/steps/stubs/backend/handler.js +4 -0
- package/lib/steps/stubs/backend/integration-test.d.ts +1 -1
- package/lib/steps/stubs/backend/integration-test.js +2 -0
- package/lib/steps/stubs/backend/job.d.ts +1 -1
- package/lib/steps/stubs/backend/job.js +1 -0
- package/lib/steps/stubs/backend/migration.js +6 -3
- package/lib/steps/stubs/backend/model.d.ts +1 -1
- package/lib/steps/stubs/backend/model.js +1 -0
- package/lib/steps/stubs/backend/policy.d.ts +1 -1
- package/lib/steps/stubs/backend/policy.js +2 -0
- package/lib/steps/stubs/backend/repository.d.ts +1 -1
- package/lib/steps/stubs/backend/repository.js +2 -0
- package/lib/steps/stubs/backend/service-provider.d.ts +1 -1
- package/lib/steps/stubs/backend/service-provider.js +1 -0
- package/lib/steps/stubs/backend/validator.d.ts +1 -1
- package/lib/steps/stubs/backend/validator.js +1 -0
- package/lib/steps/stubs/flarum-base.js +1 -1
- package/lib/steps/stubs/frontend/component.d.ts +0 -5
- package/lib/steps/stubs/frontend/component.js +1 -0
- package/lib/steps/stubs/frontend/modal.d.ts +0 -5
- package/lib/steps/stubs/frontend/modal.js +1 -0
- package/lib/steps/stubs/frontend/model.d.ts +0 -5
- package/lib/steps/stubs/frontend/model.js +1 -0
- package/lib/steps/stubs/js-base.js +8 -5
- package/lib/steps/stubs/php-base.js +10 -8
- package/lib/steps/update/js-imports.js +8 -2
- package/lib/utils/composer.d.ts +1 -0
- package/lib/utils/migration.js +3 -1
- package/lib/utils/monorepo.d.ts +24 -0
- package/lib/utils/monorepo.js +24 -0
- package/lib/utils/validation.d.ts +2 -0
- package/lib/utils/validation.js +6 -0
- package/oclif.manifest.json +1 -1
- package/package.json +7 -3
- package/php-subsystem/composer.json +9 -9
- package/php-subsystem/composer.lock +64 -71
- package/php-subsystem/vendor/composer/installed.json +54 -61
- package/php-subsystem/vendor/nikic/php-parser/README.md +55 -59
- package/php-subsystem/vendor/nikic/php-parser/composer.json +39 -39
- package/php-subsystem/vendor/nikic/php-parser/grammar/README.md +17 -20
package/README.md
CHANGED
|
@@ -11,33 +11,47 @@ A CLI for developing Flarum extensions</p>
|
|
|
11
11
|
<img width=720 src="https://sycho9.github.io/flarum-cli.svg" alt="terminal_example">
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<!-- tocstop -->
|
|
14
|
+
- [Introduction](#introduction)
|
|
15
|
+
- [Installation](#installation)
|
|
16
|
+
- [Updating](#updating)
|
|
17
|
+
- [Usage](#usage)
|
|
18
|
+
- [Commands](#commands)
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
## Introduction
|
|
21
|
+
|
|
22
|
+
One of our core values is **_Framework First_**, Flarum is as much a framework for extension development as it is a forum platform.
|
|
23
23
|
|
|
24
24
|
This tool was built to simplify the development of Flarum extensions by automating some repetitive and menial tasks. It allows to generate boilerplate skeleton for a new extension, common backend classes and frontend components, extenders, as well as other maintenance tasks.
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
27
28
|
<!-- installation -->
|
|
29
|
+
|
|
28
30
|
```sh-session
|
|
29
31
|
$ npm install -g @flarum/cli
|
|
30
32
|
```
|
|
33
|
+
|
|
31
34
|
<!-- installationstop -->
|
|
32
35
|
|
|
33
|
-
|
|
36
|
+
## Updating
|
|
37
|
+
|
|
38
|
+
<!-- updating -->
|
|
39
|
+
|
|
40
|
+
```sh-session
|
|
41
|
+
$ npm update -g @flarum/cli
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
<!-- updatingstop -->
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
34
48
|
<!-- usage -->
|
|
35
49
|
```sh-session
|
|
36
50
|
$ npm install -g @flarum/cli
|
|
37
51
|
$ flarum-cli COMMAND
|
|
38
52
|
running command...
|
|
39
53
|
$ flarum-cli (-v|--version|version)
|
|
40
|
-
@flarum/cli/2.0.0-beta.
|
|
54
|
+
@flarum/cli/2.0.0-beta.16 linux-x64 node-v16.14.2
|
|
41
55
|
$ flarum-cli --help [COMMAND]
|
|
42
56
|
USAGE
|
|
43
57
|
$ flarum-cli COMMAND
|
|
@@ -59,32 +73,117 @@ or
|
|
|
59
73
|
flarum-cli --help
|
|
60
74
|
```
|
|
61
75
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
76
|
+
## Commands
|
|
77
|
+
|
|
78
|
+
The CLI has different types of commands for different tasks:
|
|
79
|
+
|
|
80
|
+
**Initialisation**
|
|
81
|
+
|
|
82
|
+
- `flarum-cli init [PATH]`: Generates a blank extension skeleton, including all recommended infrastructure.
|
|
83
|
+
|
|
84
|
+
**Infrastructure**: See the [infrastructure](#infrastructure-modules) section for more information.
|
|
85
|
+
|
|
86
|
+
- `flarum-cli infra [MODULE] [PATH]`: Adds (or updates) infrastructure for some part of extension infrastructure. You can see all available modules by running `fl-dev infra --help`.
|
|
87
|
+
|
|
88
|
+
**Audit**: These commands help you make sure your extension is up to date.
|
|
89
|
+
|
|
90
|
+
- `flarum-cli audit infra [--monorepo] [--fix]` Check that infrastructure files are up to date for all enabled modules.
|
|
91
|
+
|
|
92
|
+
**Backend Boilerplate Generation**: Generates different types of backend classes and/or extenders, ready to be used.
|
|
93
|
+
|
|
94
|
+
- `flarum-cli make backend api-controller [PATH]`
|
|
95
|
+
- `flarum-cli make backend api-serializer [PATH]`
|
|
96
|
+
- `flarum-cli make backend api-serializer-attributes [PATH]`
|
|
97
|
+
- `flarum-cli make backend command [PATH]`
|
|
98
|
+
- `flarum-cli make backend event-listener [PATH]`
|
|
99
|
+
- `flarum-cli make backend handler [PATH]`
|
|
100
|
+
- `flarum-cli make backend integration-test [PATH]`
|
|
101
|
+
- `flarum-cli make backend job [PATH]`
|
|
102
|
+
- `flarum-cli make backend migration [PATH]`
|
|
103
|
+
- `flarum-cli make backend model [PATH]`
|
|
104
|
+
- `flarum-cli make backend policy [PATH]`
|
|
105
|
+
- `flarum-cli make backend repository [PATH]`
|
|
106
|
+
- `flarum-cli make backend route [PATH]`
|
|
107
|
+
- `flarum-cli make backend service-provider [PATH]`
|
|
108
|
+
- `flarum-cli make backend validator [PATH]`
|
|
109
|
+
|
|
110
|
+
**Frontend Boilerplate Generation**: Generate frontend components/classes, ready to be used.
|
|
111
|
+
|
|
112
|
+
- `flarum-cli make frontend component [PATH]`
|
|
113
|
+
- `flarum-cli make frontend modal [PATH]`
|
|
114
|
+
- `flarum-cli make frontend model [PATH]`
|
|
115
|
+
|
|
116
|
+
**Code Updates**: These commands help update extensions for newer versions of Flarum.
|
|
117
|
+
|
|
118
|
+
- `flarum-cli update js-imports [PATH]`: Adds admin/forum/common namespaces to all JS imports from flarum core.
|
|
119
|
+
|
|
120
|
+
_And of course, you can always use the help command to see a list of all available commands with their descriptions:_
|
|
121
|
+
|
|
122
|
+
- `flarum-cli help [COMMAND]`
|
|
123
|
+
|
|
124
|
+
All commands can use a `--no-interaction` flag to proceed with default values for prompts when possible.
|
|
125
|
+
|
|
126
|
+
## 🔥 The Most Powerful Commands
|
|
127
|
+
|
|
128
|
+
Of all the aforementioned commands, the two most powerful ones that will make a huge difference, are the extension initialisation command and the backend **model** generation command. The former obviously allows to kickstart the extension with the recommended skeleton from the Core Dev team, while the latter not only creates the backend model, it allows to create all the classes related to the model, from just its name:
|
|
129
|
+
|
|
130
|
+
- Table migration
|
|
131
|
+
- Policy
|
|
132
|
+
- API Serializer
|
|
133
|
+
- CRUD API Controllers
|
|
134
|
+
- CRUD Handlers
|
|
135
|
+
- Repository
|
|
136
|
+
- Validator
|
|
137
|
+
- Routes
|
|
138
|
+
- Related Extenders
|
|
139
|
+
|
|
140
|
+
[center]
|
|
141
|
+

|
|
142
|
+

|
|
143
|
+
[/center]
|
|
144
|
+
|
|
145
|
+
## Infrastructure Modules
|
|
146
|
+
|
|
147
|
+
If you maintain more than just a few extensions, keeping the infrastructure up to date can be very tedious.
|
|
148
|
+
We heavily value developer experience, and make it a point to support automated testing, static analysis, formatting, and other tools
|
|
149
|
+
that help you work more happily and efficiently. However, all this means that there's a lot of config files to keep track of.
|
|
150
|
+
|
|
151
|
+
The idea behind Flarum CLI's infrastructure modules is simple: the config for some feature is associated with a "module".
|
|
152
|
+
For example, the "typescript" module includes:
|
|
153
|
+
|
|
154
|
+
- The `js/tsconfig.json` file
|
|
155
|
+
- Dependency reqs for `typescript`, `typescript-coverage-report`, and `flarum-tsconfig` in the `package.json` file.
|
|
156
|
+
- Script configuration to check type safety and type coverage in the `package.json` file.
|
|
157
|
+
|
|
158
|
+
So to enable the `typescript` module, all Flarum CLI has to do is update those files and JSON config keys to the latest version.
|
|
159
|
+
|
|
160
|
+
Please note that running `flarum-cli infra` or `flarum-cli audit infra --fix` will only add new files/keys and overwrite existing ones; it will not delete old files or config keys.
|
|
161
|
+
|
|
162
|
+
Also, we strongly recommend carefully looking over the changes made by these commands before committing them: they should work the vast majority of the time, but there could be some corner cases.
|
|
163
|
+
|
|
164
|
+
### Excluding Files
|
|
165
|
+
|
|
166
|
+
Sometimes, you'll want to customize some of these configuration files, and prevent `flarum-cli infra [MODULE]` or `flarum-cli audit infra --fix` from overriding your changes. You can also exclude any files from these updates by adding their relative path to the "extra.flarum-cli.excludeScaffolding" key's array in your extension's `composer.json` file. For example, if you wanted to exclude your tsconfig file from any updates by the infra system, your `composer.json` should look as follows:
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
...
|
|
171
|
+
"extra": {
|
|
172
|
+
"flarum-cli": {
|
|
173
|
+
"excludeScaffolding": [
|
|
174
|
+
"js/tsconfig.json"
|
|
175
|
+
],
|
|
176
|
+
"excludeScaffoldingConfigKeys": {
|
|
177
|
+
"composer.json": [
|
|
178
|
+
"scripts.test:setup"
|
|
179
|
+
],
|
|
180
|
+
...
|
|
181
|
+
},
|
|
182
|
+
...
|
|
183
|
+
}
|
|
184
|
+
...
|
|
185
|
+
}
|
|
186
|
+
```
|
|
88
187
|
|
|
89
188
|
## For Maintainers
|
|
90
189
|
|
|
@@ -163,7 +262,6 @@ Sharing parameters is done via the following process:
|
|
|
163
262
|
- What the param is consumed at
|
|
164
263
|
- If the param value is falsy, should the consumer step run at all? Useful for variable dependencies.
|
|
165
264
|
|
|
166
|
-
|
|
167
265
|
For example:
|
|
168
266
|
|
|
169
267
|
```ts
|
|
@@ -199,7 +297,6 @@ For example:
|
|
|
199
297
|
.run(new Paths({...}), new PromptsIO(), {php: new PhpProvider(...)});
|
|
200
298
|
```
|
|
201
299
|
|
|
202
|
-
|
|
203
300
|
#### Step Composability and Atomic Groups
|
|
204
301
|
|
|
205
302
|
As noted above, steps should work by modifying and returning an in-memory filesystem.
|
package/bin/run
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
const { resolve } = require('path');
|
|
2
3
|
|
|
3
|
-
require('module-alias').addAlias('boilersmith',
|
|
4
|
+
require('module-alias').addAlias('boilersmith', resolve(__dirname, '..', 'lib', 'boilersmith'));
|
|
4
5
|
|
|
5
6
|
const oclif = require('@oclif/core');
|
|
6
7
|
|
|
Binary file
|
|
Binary file
|
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
**/.gitattributes export-ignore
|
|
2
|
+
**/.gitignore export-ignore
|
|
3
|
+
**/.gitmodules export-ignore
|
|
4
|
+
**/.github export-ignore
|
|
5
|
+
**/.travis export-ignore
|
|
6
|
+
**/.travis.yml export-ignore
|
|
7
|
+
**/.editorconfig export-ignore
|
|
8
|
+
**/.styleci.yml export-ignore
|
|
9
9
|
|
|
10
|
-
phpunit.xml export-ignore
|
|
11
|
-
tests export-ignore
|
|
10
|
+
**/phpunit.xml export-ignore
|
|
11
|
+
**/tests export-ignore
|
|
12
12
|
|
|
13
|
-
js/dist
|
|
14
|
-
js/dist
|
|
15
|
-
js/dist-typings
|
|
16
|
-
js/
|
|
13
|
+
**/js/dist/**/* -diff
|
|
14
|
+
**/js/dist/**/* linguist-generated
|
|
15
|
+
**/js/dist-typings/**/* -diff
|
|
16
|
+
**/js/dist-typings/**/* linguist-generated
|
|
17
|
+
**/js/yarn.lock -diff
|
|
18
|
+
**/js/package-lock.json -diff
|
|
17
19
|
|
|
18
20
|
* text=auto eol=lf
|
|
@@ -15,6 +15,8 @@ jobs:
|
|
|
15
15
|
enable_typescript: <%= modules.typescript %>
|
|
16
16
|
|
|
17
17
|
frontend_directory: <%= params.frontendDirectory %>
|
|
18
|
+
backend_directory: <%= params.backendDirectory %>
|
|
19
|
+
js_package_manager: <%= params.jsPackageManager %>
|
|
18
20
|
main_git_branch: <%= params.mainGitBranch %>
|
|
19
21
|
secrets:
|
|
20
|
-
bundlewatch_github_token: ${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }}
|
|
22
|
+
bundlewatch_github_token: ${{ secrets.BUNDLEWATCH_GITHUB_TOKEN }}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
<%- params.licenseText %>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"type": "flarum-extension",
|
|
8
8
|
"license": "<%= params.licenseType %>",
|
|
9
9
|
"require": {
|
|
10
|
-
"flarum/core": "^1.
|
|
10
|
+
"flarum/core": "^1.2.0"
|
|
11
11
|
},
|
|
12
12
|
"require-dev": {
|
|
13
13
|
"flarum/testing": "^1.0.0"
|
|
@@ -22,13 +22,13 @@
|
|
|
22
22
|
<% if (params.packageNamespace) { %>
|
|
23
23
|
"autoload": {
|
|
24
24
|
"psr-4": {
|
|
25
|
-
"<%= params.
|
|
25
|
+
"<%= params.packageNamespace %>\\": "src/"
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
<% } %>
|
|
29
29
|
"autoload-dev": {
|
|
30
30
|
"psr-4": {
|
|
31
|
-
"<%= params.
|
|
31
|
+
"<%= params.packageNamespace %>\\Tests\\": "tests/"
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
"extra": {
|
|
@@ -56,5 +56,7 @@
|
|
|
56
56
|
"test:unit": "Runs all unit tests.",
|
|
57
57
|
"test:integration": "Runs all integration tests.",
|
|
58
58
|
"test:setup": "Sets up a database for use with integration tests. Execute this only once."
|
|
59
|
-
}
|
|
59
|
+
},
|
|
60
|
+
"minimum-stability": "dev",
|
|
61
|
+
"prefer-stable": true
|
|
60
62
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@<%= params.packageName %>",
|
|
3
3
|
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
4
5
|
"prettier": "@flarum/prettier-config",
|
|
5
6
|
"dependencies": {
|
|
6
7
|
},
|
|
@@ -17,9 +18,12 @@
|
|
|
17
18
|
"scripts": {
|
|
18
19
|
"dev": "webpack --mode development --watch",
|
|
19
20
|
"build": "webpack --mode production",
|
|
20
|
-
"analyze": "cross-env ANALYZER=true
|
|
21
|
+
"analyze": "cross-env ANALYZER=true <%= params.jsPackageManager %> run build",
|
|
21
22
|
"format": "prettier --write src",
|
|
22
23
|
"format-check": "prettier --check src",
|
|
24
|
+
"clean-typings": "npx rimraf dist-typings && mkdir dist-typings",
|
|
25
|
+
"build-typings": "<%= params.jsPackageManager %> run clean-typings && ([ -e src/@types ] && cp -r src/@types dist-typings/@types || true) && tsc && <%= params.jsPackageManager %> run post-build-typings",
|
|
26
|
+
"post-build-typings": "find dist-typings -type f -name '*.d.ts' -print0 | xargs -0 sed -i 's,../src/@types,@types,g'",
|
|
23
27
|
"check-typings": "tsc --noEmit --emitDeclarationOnly false",
|
|
24
28
|
"check-typings-coverage": "typescript-coverage-report"
|
|
25
29
|
}
|
|
@@ -4,13 +4,21 @@
|
|
|
4
4
|
// This will match all .ts, .tsx, .d.ts, .js, .jsx files in your `src` folder
|
|
5
5
|
// and also tells your Typescript server to read core's global typings for
|
|
6
6
|
// access to `dayjs` and `$` in the global namespace.
|
|
7
|
-
"include": [
|
|
7
|
+
"include": [
|
|
8
|
+
"src/**/*",
|
|
9
|
+
"../vendor/*/*/js/dist-typings/@types/**/*",
|
|
10
|
+
// <CUSTOM-1>
|
|
11
|
+
// </CUSTOM-1>
|
|
12
|
+
"@types/**/*"
|
|
13
|
+
],
|
|
8
14
|
"compilerOptions": {
|
|
9
15
|
// This will output typings to `dist-typings`
|
|
10
16
|
"declarationDir": "./dist-typings",
|
|
11
17
|
"baseUrl": ".",
|
|
12
18
|
"paths": {
|
|
13
|
-
"flarum/*": ["../vendor/flarum/core/js/dist-typings/*"]
|
|
19
|
+
"flarum/*": ["../vendor/flarum/core/js/dist-typings/*"],
|
|
20
|
+
// <CUSTOM-2>
|
|
21
|
+
// </CUSTOM-2>
|
|
14
22
|
}
|
|
15
23
|
}
|
|
16
24
|
}
|
package/lib/base-command.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export default abstract class BaseCommand extends Command {
|
|
|
23
23
|
protected welcomeMessage(): string;
|
|
24
24
|
protected goodbyeMessage(): string;
|
|
25
25
|
protected additionalPreRunChecks(_extRoot: string): Promise<void>;
|
|
26
|
-
protected abstract steps(stepManager: StepManager<FlarumProviders
|
|
26
|
+
protected abstract steps(stepManager: StepManager<FlarumProviders>, extRoot: string): StepManager<FlarumProviders>;
|
|
27
27
|
protected genIO(): IO;
|
|
28
28
|
protected monorepoPaths(options: {
|
|
29
29
|
includeCore: boolean;
|
|
@@ -31,7 +31,9 @@ export default abstract class BaseCommand extends Command {
|
|
|
31
31
|
includePhpPackages: boolean;
|
|
32
32
|
includeJSPackages: boolean;
|
|
33
33
|
}): string[];
|
|
34
|
+
protected isFlarumMonorepo(path: string): boolean;
|
|
34
35
|
protected isFlarumCore(path: string): boolean;
|
|
36
|
+
protected jsPackageManager(currDir: string): 'yarn' | 'npm' | null;
|
|
35
37
|
protected getFlarumExtensionRoot(currDir: string): Promise<{
|
|
36
38
|
path: string;
|
|
37
39
|
type: LocationType;
|
package/lib/base-command.js
CHANGED
|
@@ -4,16 +4,18 @@ exports.LocationType = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const core_1 = require("@oclif/core");
|
|
6
6
|
const cli_ux_1 = (0, tslib_1.__importDefault)(require("cli-ux"));
|
|
7
|
-
const
|
|
7
|
+
const path_1 = require("path");
|
|
8
8
|
const globby_1 = (0, tslib_1.__importDefault)(require("globby"));
|
|
9
|
-
const
|
|
10
|
-
const
|
|
9
|
+
const child_process_1 = require("child_process");
|
|
10
|
+
const fs_1 = require("fs");
|
|
11
11
|
const io_1 = require("boilersmith/io");
|
|
12
12
|
const step_manager_1 = require("boilersmith/step-manager");
|
|
13
13
|
const paths_1 = require("boilersmith/paths");
|
|
14
14
|
const php_provider_1 = require("./providers/php-provider");
|
|
15
15
|
const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
|
|
16
16
|
const errors_1 = require("@oclif/errors");
|
|
17
|
+
const monorepo_1 = require("./utils/monorepo");
|
|
18
|
+
const mem_fs_1 = require("mem-fs");
|
|
17
19
|
var LocationType;
|
|
18
20
|
(function (LocationType) {
|
|
19
21
|
LocationType[LocationType["FLARUM_EXTENSION"] = 0] = "FLARUM_EXTENSION";
|
|
@@ -23,7 +25,7 @@ var LocationType;
|
|
|
23
25
|
class BaseCommand extends core_1.Command {
|
|
24
26
|
constructor() {
|
|
25
27
|
super(...arguments);
|
|
26
|
-
this.STUB_PATH = (0,
|
|
28
|
+
this.STUB_PATH = (0, path_1.resolve)(__dirname, '../boilerplate/stubs/');
|
|
27
29
|
this.dry = false;
|
|
28
30
|
this.requireExistingExtension = true;
|
|
29
31
|
}
|
|
@@ -51,10 +53,9 @@ class BaseCommand extends core_1.Command {
|
|
|
51
53
|
requestedDir: path,
|
|
52
54
|
package: extRoot,
|
|
53
55
|
});
|
|
54
|
-
const phpProvider = new php_provider_1.PhpSubsystemProvider((0,
|
|
55
|
-
const out = await this.steps(new step_manager_1.StepManager())
|
|
56
|
-
|
|
57
|
-
const errorMessages = out.messages.filter(m => m.type === 'error');
|
|
56
|
+
const phpProvider = new php_provider_1.PhpSubsystemProvider((0, path_1.resolve)(__dirname, '../php-subsystem/index.php'));
|
|
57
|
+
const out = await this.steps(new step_manager_1.StepManager(), extRoot).run(paths, this.genIO(), { php: phpProvider }, this.dry);
|
|
58
|
+
const errorMessages = out.messages.filter((m) => m.type === 'error');
|
|
58
59
|
this.log('\n\n');
|
|
59
60
|
if (out.succeeded && errorMessages.length === 0) {
|
|
60
61
|
this.log(chalk_1.default.bold(chalk_1.default.underline(chalk_1.default.green('Success! The following steps were completed:'))));
|
|
@@ -66,7 +67,7 @@ class BaseCommand extends core_1.Command {
|
|
|
66
67
|
}
|
|
67
68
|
this.log(chalk_1.default.bold(chalk_1.default.yellow('The steps that completed were:')));
|
|
68
69
|
}
|
|
69
|
-
else if (out.error
|
|
70
|
+
else if (out.error.startsWith('EEXIT:')) {
|
|
70
71
|
this.log(chalk_1.default.bold(chalk_1.default.underline(chalk_1.default.red('Exiting.'))));
|
|
71
72
|
if (out.stepsRan.length > 0) {
|
|
72
73
|
this.log(chalk_1.default.bold(chalk_1.default.yellow('Before the exit, the following steps were completed:')));
|
|
@@ -86,7 +87,7 @@ class BaseCommand extends core_1.Command {
|
|
|
86
87
|
for (const stepName of out.stepsRan)
|
|
87
88
|
this.log(`- ${chalk_1.default.dim(stepName)}`);
|
|
88
89
|
this.log('');
|
|
89
|
-
const nonErrorMessages = out.messages.filter(m => m.type !== 'error');
|
|
90
|
+
const nonErrorMessages = out.messages.filter((m) => m.type !== 'error');
|
|
90
91
|
if (nonErrorMessages.length > 0) {
|
|
91
92
|
this.log('');
|
|
92
93
|
this.log('The following messages were generated during execution:');
|
|
@@ -118,45 +119,53 @@ class BaseCommand extends core_1.Command {
|
|
|
118
119
|
return new io_1.PromptsIO({}, [], this.flags['no-interaction'], errors_1.exit);
|
|
119
120
|
}
|
|
120
121
|
monorepoPaths(options) {
|
|
122
|
+
var _a, _b;
|
|
121
123
|
try {
|
|
122
|
-
const monorepoConfig = (0,
|
|
123
|
-
const contents = JSON.parse(monorepoConfig.toString());
|
|
124
|
+
const monorepoConfig = (0, monorepo_1.getMonorepoConf)((0, mem_fs_1.create)(), new paths_1.NodePaths({ package: process.cwd() }));
|
|
124
125
|
return [
|
|
125
|
-
...(options.includeCore ? [
|
|
126
|
-
...(options.includeExtensions ?
|
|
127
|
-
...(options.includePhpPackages ?
|
|
128
|
-
...(options.includeJSPackages ?
|
|
126
|
+
...(options.includeCore && monorepoConfig.packages.core ? [(0, monorepo_1.corePath)(monorepoConfig.packages.core.name)] : []),
|
|
127
|
+
...(options.includeExtensions ? monorepoConfig.packages.extensions : []).map((ext) => (0, monorepo_1.extensionPath)(ext.name)),
|
|
128
|
+
...(options.includePhpPackages ? (_a = monorepoConfig.packages.composer) !== null && _a !== void 0 ? _a : [] : []).map((lib) => (0, monorepo_1.composerPath)(lib.name)),
|
|
129
|
+
...(options.includeJSPackages ? (_b = monorepoConfig.packages.npm) !== null && _b !== void 0 ? _b : [] : []).map((lib) => (0, monorepo_1.npmPath)(lib.name)),
|
|
129
130
|
];
|
|
130
131
|
}
|
|
131
|
-
catch (
|
|
132
|
+
catch (_c) {
|
|
132
133
|
this.error('Could not run monorepo command: `flarum-monorepo.json` file is missing or invalid.');
|
|
133
134
|
}
|
|
134
135
|
}
|
|
136
|
+
isFlarumMonorepo(path) {
|
|
137
|
+
return (0, fs_1.existsSync)((0, path_1.resolve)(path, 'flarum-monorepo.json'));
|
|
138
|
+
}
|
|
135
139
|
isFlarumCore(path) {
|
|
136
140
|
try {
|
|
137
|
-
const composerJsonPath = (0,
|
|
138
|
-
const val = JSON.parse((0,
|
|
141
|
+
const composerJsonPath = (0, path_1.resolve)(path, 'composer.json');
|
|
142
|
+
const val = JSON.parse((0, fs_1.readFileSync)(composerJsonPath, 'utf8'));
|
|
139
143
|
return val.name === 'flarum/core';
|
|
140
144
|
}
|
|
141
145
|
catch (_a) {
|
|
142
146
|
return false;
|
|
143
147
|
}
|
|
144
148
|
}
|
|
149
|
+
jsPackageManager(currDir) {
|
|
150
|
+
if (!(0, fs_1.existsSync)((0, path_1.resolve)(currDir, 'js')))
|
|
151
|
+
return null;
|
|
152
|
+
return (0, fs_1.existsSync)((0, path_1.resolve)(currDir, 'js/yarn.lock')) ? 'yarn' : 'npm';
|
|
153
|
+
}
|
|
145
154
|
async getFlarumExtensionRoot(currDir) {
|
|
146
|
-
let currPath = (0,
|
|
155
|
+
let currPath = (0, path_1.resolve)(currDir);
|
|
147
156
|
while (currPath !== '/') {
|
|
148
|
-
if ((0,
|
|
157
|
+
if ((0, fs_1.existsSync)((0, path_1.resolve)(currPath, 'flarum-monorepo.json'))) {
|
|
149
158
|
return { path: currPath, type: LocationType.FLARUM_MONOREPO };
|
|
150
159
|
}
|
|
151
|
-
if ((0,
|
|
160
|
+
if ((0, fs_1.existsSync)((0, path_1.resolve)(currPath, 'composer.json')) && (0, fs_1.existsSync)((0, path_1.resolve)(currPath, 'extend.php'))) {
|
|
152
161
|
return { path: currPath, type: LocationType.FLARUM_EXTENSION };
|
|
153
162
|
}
|
|
154
163
|
if (this.isFlarumCore(currPath)) {
|
|
155
164
|
return { path: currPath, type: LocationType.FLARUM_CORE };
|
|
156
165
|
}
|
|
157
|
-
currPath = (0,
|
|
166
|
+
currPath = (0, path_1.resolve)(currPath, '..');
|
|
158
167
|
}
|
|
159
|
-
this.error(`${(0,
|
|
168
|
+
this.error(`${(0, path_1.resolve)(currDir)} is not located in a valid Flarum package!
|
|
160
169
|
- Flarum extensions must contain (at a minimum) 'extend.php' and 'composer.json' files.
|
|
161
170
|
- Flarum core must contain a 'composer.json' file with the name 'flarum/core'.
|
|
162
171
|
- Flarum monorepos must have a valid 'flarum-monorepo.json' file`);
|
|
@@ -165,14 +174,14 @@ class BaseCommand extends core_1.Command {
|
|
|
165
174
|
const verify = await this.genIO().getParam({
|
|
166
175
|
name: 'verify',
|
|
167
176
|
type: 'confirm',
|
|
168
|
-
message: `Work in Flarum package located at ${(0,
|
|
177
|
+
message: `Work in Flarum package located at ${(0, path_1.resolve)(extRoot)}?`,
|
|
169
178
|
initial: true,
|
|
170
179
|
});
|
|
171
180
|
if (!verify)
|
|
172
181
|
this.exit();
|
|
173
182
|
}
|
|
174
183
|
async ensureComposerInstallRan(extRoot) {
|
|
175
|
-
if ((0,
|
|
184
|
+
if ((0, fs_1.existsSync)((0, path_1.resolve)(extRoot, 'vendor/flarum/core/composer.json')))
|
|
176
185
|
return;
|
|
177
186
|
this.log("This command requires `composer install` to have been ran in your extension's root directory.");
|
|
178
187
|
const composer = await this.genIO().getParam({
|
|
@@ -183,7 +192,7 @@ class BaseCommand extends core_1.Command {
|
|
|
183
192
|
});
|
|
184
193
|
if (composer) {
|
|
185
194
|
cli_ux_1.default.action.start('Installing composer packages');
|
|
186
|
-
(0,
|
|
195
|
+
(0, child_process_1.execSync)('composer install', { cwd: extRoot });
|
|
187
196
|
cli_ux_1.default.action.stop();
|
|
188
197
|
}
|
|
189
198
|
else {
|
|
@@ -197,7 +206,7 @@ class BaseCommand extends core_1.Command {
|
|
|
197
206
|
*/
|
|
198
207
|
async confirmOverrideFiles(dir, pattern, confirmationMessage) {
|
|
199
208
|
const paths = Array.isArray(pattern) ? pattern : [pattern];
|
|
200
|
-
const files = await (0, globby_1.default)(paths.map(p => (0,
|
|
209
|
+
const files = await (0, globby_1.default)(paths.map((p) => (0, path_1.resolve)(dir, p)));
|
|
201
210
|
const empty = files.length === 0 || (files.length === 1 && files[0] === '.git');
|
|
202
211
|
if (empty)
|
|
203
212
|
return false;
|
|
@@ -212,13 +221,17 @@ class BaseCommand extends core_1.Command {
|
|
|
212
221
|
return true;
|
|
213
222
|
}
|
|
214
223
|
async deleteFiles(dir, pattern) {
|
|
215
|
-
const pathsToDelete = await (0, globby_1.default)((0,
|
|
216
|
-
pathsToDelete.forEach(
|
|
224
|
+
const pathsToDelete = await (0, globby_1.default)((0, path_1.resolve)(dir, pattern));
|
|
225
|
+
pathsToDelete.forEach(fs_1.unlinkSync);
|
|
217
226
|
}
|
|
218
227
|
}
|
|
219
228
|
exports.default = BaseCommand;
|
|
220
229
|
BaseCommand.flags = {
|
|
221
|
-
'no-interaction': core_1.Flags.boolean({
|
|
230
|
+
'no-interaction': core_1.Flags.boolean({
|
|
231
|
+
char: 'n',
|
|
232
|
+
description: 'Do not ask any interactive questions, assume defaults. When impossible, error.',
|
|
233
|
+
default: false,
|
|
234
|
+
}),
|
|
222
235
|
help: core_1.Flags.help({ char: 'h' }),
|
|
223
236
|
};
|
|
224
237
|
BaseCommand.args = [
|
package/lib/boilersmith/io.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import { PromptObject } from 'prompts';
|
|
1
|
+
import { PromptObject, PromptType } from 'prompts';
|
|
2
|
+
declare type BooleanPromptType = PromptType & ('confirm' | 'toggle');
|
|
3
|
+
declare type StringPromptType = PromptType & ('text' | 'password' | 'invisible' | 'autocomplete');
|
|
4
|
+
declare type DatePromptType = PromptType & 'date';
|
|
5
|
+
declare type ListPromptType = PromptType & 'list';
|
|
2
6
|
export declare type ParamDef<N extends string = string> = Omit<PromptObject<N>, 'name'> & {
|
|
3
7
|
name: N;
|
|
8
|
+
message: string;
|
|
4
9
|
};
|
|
5
10
|
export declare type Message = {
|
|
6
11
|
type: 'info' | 'warning' | 'error';
|
|
@@ -11,7 +16,19 @@ export interface IO {
|
|
|
11
16
|
/**
|
|
12
17
|
* Prompt the user for some input data.
|
|
13
18
|
*/
|
|
14
|
-
getParam
|
|
19
|
+
getParam(param: ParamDef & {
|
|
20
|
+
type: BooleanPromptType;
|
|
21
|
+
}, noCache?: boolean): Promise<boolean>;
|
|
22
|
+
getParam(param: ParamDef & {
|
|
23
|
+
type: StringPromptType;
|
|
24
|
+
}, noCache?: boolean): Promise<string>;
|
|
25
|
+
getParam(param: ParamDef & {
|
|
26
|
+
type: DatePromptType;
|
|
27
|
+
}, noCache?: boolean): Promise<Date>;
|
|
28
|
+
getParam(param: ParamDef & {
|
|
29
|
+
type: ListPromptType;
|
|
30
|
+
}, noCache?: boolean): Promise<string[]>;
|
|
31
|
+
getParam<T>(param: ParamDef, noCache?: boolean): Promise<T>;
|
|
15
32
|
/**
|
|
16
33
|
* Check if some data has already been prompted for.
|
|
17
34
|
*/
|
|
@@ -32,13 +49,16 @@ export interface IO {
|
|
|
32
49
|
declare type OnCancel = () => void;
|
|
33
50
|
export declare class PromptsIO implements IO {
|
|
34
51
|
supportsAnsiColor: boolean;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
52
|
+
protected cache: Map<string, unknown>;
|
|
53
|
+
protected messages: Message[];
|
|
54
|
+
protected noInteraction: boolean;
|
|
55
|
+
protected onCancel?: OnCancel;
|
|
56
|
+
protected prev?: {
|
|
57
|
+
val: any;
|
|
58
|
+
prompt: ParamDef;
|
|
59
|
+
};
|
|
40
60
|
constructor(initial?: Record<string, unknown>, messages?: Message[], noInteraction?: boolean, onCancel?: OnCancel);
|
|
41
|
-
getParam<T>(paramDef: ParamDef): Promise<T>;
|
|
61
|
+
getParam<T>(paramDef: ParamDef, noCache?: boolean): Promise<T>;
|
|
42
62
|
hasCached(name: string): boolean;
|
|
43
63
|
/**
|
|
44
64
|
* @internal
|