@vcmap/plugin-cli 2.1.18 → 3.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.
- package/README.md +29 -2
- package/assets/eslintrc.cjs +25 -0
- package/assets/index.ts +78 -0
- package/assets/ts.gitlab-ci.yml +179 -0
- package/assets/tsconfig.json +34 -0
- package/cli.js +4 -0
- package/package.json +6 -5
- package/src/build.js +4 -11
- package/src/create.js +74 -14
- package/src/ensureTypes.js +16 -0
- package/src/hostingHelpers.js +2 -2
- package/src/packageJsonHelpers.js +7 -9
- package/src/pluginCliHelper.js +1 -1
- package/src/update.js +2 -2
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ The `@vcmap/plugin-cli` helps develop and build plugins for the **VC Map**.
|
|
|
18
18
|
|
|
19
19
|
## Prerequisite
|
|
20
20
|
|
|
21
|
-
You need [nodejs](https://nodejs.org/en/)
|
|
21
|
+
You need [nodejs](https://nodejs.org/en/) 18 and npm installed on your system
|
|
22
22
|
to use this tool.
|
|
23
23
|
|
|
24
24
|
## Installation
|
|
@@ -51,6 +51,33 @@ All commands have (optional) cli options. Run `vcmplugin --help` or `vcmplugin h
|
|
|
51
51
|
For `serve` and `preview` you can alternatively define a `vcs.config.js` in your plugin's root directory.
|
|
52
52
|
For more information see [here](#vcm-config-js).
|
|
53
53
|
|
|
54
|
+
## Folder structure
|
|
55
|
+
|
|
56
|
+
As of v3, all plugins must follow the same rudimentary folder structure, as depicted below:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
-| src/
|
|
60
|
+
-| index.js
|
|
61
|
+
-| package.json
|
|
62
|
+
-| README.md
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
And for TS based plugins:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
-| src/
|
|
69
|
+
-| index.ts
|
|
70
|
+
-| package.json
|
|
71
|
+
-| README.md
|
|
72
|
+
-| tsconfig.json
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
It is important to, not that the entry point for _building_ the plugin (and
|
|
76
|
+
the file which exports the default export for the plugin interface) **MUST** be
|
|
77
|
+
located at `./src/index.js` or `./src/index.ts` respectively. If you have created
|
|
78
|
+
your plugin using any version of the `@vcmap/plugins-cli`, this will already be
|
|
79
|
+
the case.
|
|
80
|
+
|
|
54
81
|
### 1. Creating a new plugin
|
|
55
82
|
|
|
56
83
|
To create a new plugin template, run the following:
|
|
@@ -62,7 +89,7 @@ vcmplugin create
|
|
|
62
89
|
This will open a command prompt helping you to create the basic [structure of a plugin](#vc-map-plugins).
|
|
63
90
|
Be sure to check out the [peer dependecy section](#about-peer-dependencies) as well.
|
|
64
91
|
|
|
65
|
-
Optionally, in
|
|
92
|
+
Optionally, in the create-prompt you can choose an existing plugin [@vcmap/hello-world](https://www.npmjs.com/package/@vcmap/hello-world) as a template.
|
|
66
93
|
|
|
67
94
|
### 2. Serving a plugin for development
|
|
68
95
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
+
// const sharedLib = require('eslint-config-airbnb-typescript/lib/shared.js');
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
root: true,
|
|
6
|
+
extends: ['@vcsuite/eslint-config/vue-ts'],
|
|
7
|
+
env: {
|
|
8
|
+
node: true,
|
|
9
|
+
},
|
|
10
|
+
rules: {
|
|
11
|
+
'no-restricted-syntax': 'off',
|
|
12
|
+
},
|
|
13
|
+
overrides: [
|
|
14
|
+
{
|
|
15
|
+
files: ['*.ts', '*.vue'],
|
|
16
|
+
parserOptions: {
|
|
17
|
+
project: ['./tsconfig.json'],
|
|
18
|
+
},
|
|
19
|
+
rules: {
|
|
20
|
+
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
ignorePatterns: ['dist/', 'node_modules/'],
|
|
25
|
+
};
|
package/assets/index.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { VcsPlugin, VcsUiApp, PluginConfigEditor } from '@vcmap/ui';
|
|
2
|
+
import { name, version, mapVersion } from '../package.json';
|
|
3
|
+
|
|
4
|
+
type PluginConfig = Record<never, never>;
|
|
5
|
+
type PluginState = Record<never, never>;
|
|
6
|
+
|
|
7
|
+
type MyPlugin = VcsPlugin<PluginConfig, PluginState>;
|
|
8
|
+
|
|
9
|
+
export default function plugin(
|
|
10
|
+
config: PluginConfig,
|
|
11
|
+
baseUrl: string,
|
|
12
|
+
): MyPlugin {
|
|
13
|
+
// eslint-disable-next-line no-console
|
|
14
|
+
console.log(config, baseUrl);
|
|
15
|
+
return {
|
|
16
|
+
get name(): string {
|
|
17
|
+
return name;
|
|
18
|
+
},
|
|
19
|
+
get version(): string {
|
|
20
|
+
return version;
|
|
21
|
+
},
|
|
22
|
+
get mapVersion(): string {
|
|
23
|
+
return mapVersion;
|
|
24
|
+
},
|
|
25
|
+
initialize(vcsUiApp: VcsUiApp, state?: PluginState): Promise<void> {
|
|
26
|
+
// eslint-disable-next-line no-console
|
|
27
|
+
console.log(
|
|
28
|
+
'Called before loading the rest of the current context. Passed in the containing Vcs UI App ',
|
|
29
|
+
vcsUiApp,
|
|
30
|
+
state,
|
|
31
|
+
);
|
|
32
|
+
return Promise.resolve();
|
|
33
|
+
},
|
|
34
|
+
onVcsAppMounted(vcsUiApp: VcsUiApp): void {
|
|
35
|
+
// eslint-disable-next-line no-console
|
|
36
|
+
console.log(
|
|
37
|
+
'Called when the root UI component is mounted and managers are ready to accept components',
|
|
38
|
+
vcsUiApp,
|
|
39
|
+
);
|
|
40
|
+
},
|
|
41
|
+
/**
|
|
42
|
+
* should return all default values of the configuration
|
|
43
|
+
*/
|
|
44
|
+
getDefaultOptions(): PluginConfig {
|
|
45
|
+
return {};
|
|
46
|
+
},
|
|
47
|
+
/**
|
|
48
|
+
* should return the plugin's serialization excluding all default values
|
|
49
|
+
*/
|
|
50
|
+
toJSON(): PluginConfig {
|
|
51
|
+
// eslint-disable-next-line no-console
|
|
52
|
+
console.log('Called when serializing this plugin instance');
|
|
53
|
+
return {};
|
|
54
|
+
},
|
|
55
|
+
/**
|
|
56
|
+
* should return the plugins state
|
|
57
|
+
* @param {boolean} forUrl
|
|
58
|
+
* @returns {PluginState}
|
|
59
|
+
*/
|
|
60
|
+
getState(forUrl?: boolean): PluginState {
|
|
61
|
+
// eslint-disable-next-line no-console
|
|
62
|
+
console.log('Called when collecting state, e.g. for create link', forUrl);
|
|
63
|
+
return {
|
|
64
|
+
prop: '*',
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
/**
|
|
68
|
+
* components for configuring the plugin and/ or custom items defined by the plugin
|
|
69
|
+
*/
|
|
70
|
+
getConfigEditors(): PluginConfigEditor[] {
|
|
71
|
+
return [];
|
|
72
|
+
},
|
|
73
|
+
destroy(): void {
|
|
74
|
+
// eslint-disable-next-line no-console
|
|
75
|
+
console.log('hook to cleanup');
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
default:
|
|
2
|
+
image: gitlab.virtualcitysystems.de:5050/vcsuite/devops/gitlabrunner/node:18-bullseye
|
|
3
|
+
|
|
4
|
+
variables:
|
|
5
|
+
GIT_CLONE_PATH: $CI_BUILDS_DIR/$CI_PROJECT_PATH_SLUG/$CI_COMMIT_REF_SLUG
|
|
6
|
+
|
|
7
|
+
stages:
|
|
8
|
+
- build
|
|
9
|
+
- test
|
|
10
|
+
- bundle
|
|
11
|
+
- deploy
|
|
12
|
+
- version
|
|
13
|
+
- publish
|
|
14
|
+
- deployCluster
|
|
15
|
+
|
|
16
|
+
.template: &job_definition
|
|
17
|
+
only:
|
|
18
|
+
- /^(feature-.*|hotfix-.*|main|release-.*)$/
|
|
19
|
+
tags:
|
|
20
|
+
- linux-2.0
|
|
21
|
+
|
|
22
|
+
build:
|
|
23
|
+
<<: *job_definition
|
|
24
|
+
script:
|
|
25
|
+
- npm ci
|
|
26
|
+
- npm run ensure-types
|
|
27
|
+
before_script:
|
|
28
|
+
- mkdir -p ~/.ssh
|
|
29
|
+
- chmod 700 ~/.ssh
|
|
30
|
+
- echo "$SSH_RUNNER_KEY" | tr -d '\r' > ~/.ssh/id_rsa
|
|
31
|
+
- chmod 600 ~/.ssh/id_rsa
|
|
32
|
+
- ssh-keyscan gitlab.virtualcitysystems.de >> ~/.ssh/known_hosts
|
|
33
|
+
- chmod 644 ~/.ssh/known_hosts
|
|
34
|
+
- git config user.name "Gitlab Runner"
|
|
35
|
+
- git config user.email "gitlab-runner@vc.systems"
|
|
36
|
+
stage: build
|
|
37
|
+
|
|
38
|
+
.after_build_template: &after_build_definition
|
|
39
|
+
<<: *job_definition
|
|
40
|
+
variables:
|
|
41
|
+
GIT_STRATEGY: none
|
|
42
|
+
|
|
43
|
+
.staging_build_template: &staging_build_template
|
|
44
|
+
<<: *after_build_definition
|
|
45
|
+
except:
|
|
46
|
+
variables:
|
|
47
|
+
- $PUBLISH
|
|
48
|
+
|
|
49
|
+
lint:
|
|
50
|
+
<<: *after_build_definition
|
|
51
|
+
stage: test
|
|
52
|
+
script:
|
|
53
|
+
- npm run lint
|
|
54
|
+
|
|
55
|
+
type-check:
|
|
56
|
+
<<: *after_build_definition
|
|
57
|
+
stage: test
|
|
58
|
+
script:
|
|
59
|
+
- npm run type-check
|
|
60
|
+
|
|
61
|
+
test:
|
|
62
|
+
<<: *after_build_definition
|
|
63
|
+
stage: test
|
|
64
|
+
script:
|
|
65
|
+
- npm run coverage -- --reporter junit --outputFile test-report.xml
|
|
66
|
+
coverage: '/^Statements\s*:\s*([^%]+)/'
|
|
67
|
+
artifacts:
|
|
68
|
+
reports:
|
|
69
|
+
junit: test-report.xml
|
|
70
|
+
|
|
71
|
+
audit:
|
|
72
|
+
<<: *after_build_definition
|
|
73
|
+
stage: test
|
|
74
|
+
script:
|
|
75
|
+
- npm audit --production --audit-level=low
|
|
76
|
+
|
|
77
|
+
buildPreview:
|
|
78
|
+
<<: *staging_build_template
|
|
79
|
+
stage: bundle
|
|
80
|
+
script:
|
|
81
|
+
- npm run buildStagingApp
|
|
82
|
+
|
|
83
|
+
bundle:
|
|
84
|
+
<<: *after_build_definition
|
|
85
|
+
stage: bundle
|
|
86
|
+
only:
|
|
87
|
+
variables:
|
|
88
|
+
- $PUBLISH
|
|
89
|
+
refs:
|
|
90
|
+
- /^(main|release-v.*)$/
|
|
91
|
+
script:
|
|
92
|
+
- npm run build
|
|
93
|
+
|
|
94
|
+
deployStaging:
|
|
95
|
+
<<: *staging_build_template
|
|
96
|
+
stage: deploy
|
|
97
|
+
environment:
|
|
98
|
+
name: staging/$CI_COMMIT_REF_SLUG
|
|
99
|
+
url: http://$CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG.stagingcluster.intern.virtualcitysystems.de
|
|
100
|
+
on_stop: stopEnvironment
|
|
101
|
+
image:
|
|
102
|
+
name: gcr.io/kaniko-project/executor:debug
|
|
103
|
+
entrypoint: ['']
|
|
104
|
+
script:
|
|
105
|
+
- /kaniko/executor --context dist/ --dockerfile build/staging/Dockerfile --destination $CI_REGISTRY_IMAGE/staging:$CI_COMMIT_REF_SLUG
|
|
106
|
+
before_script:
|
|
107
|
+
- mkdir -p /kaniko/.docker
|
|
108
|
+
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
|
|
109
|
+
|
|
110
|
+
stopEnvironment:
|
|
111
|
+
stage: deploy
|
|
112
|
+
variables:
|
|
113
|
+
GIT_STRATEGY: none
|
|
114
|
+
image:
|
|
115
|
+
name: bitnami/kubectl:latest
|
|
116
|
+
entrypoint: ['']
|
|
117
|
+
tags:
|
|
118
|
+
- linux-2.0
|
|
119
|
+
script:
|
|
120
|
+
- echo "Stop environment staging/$CI_COMMIT_REF_NAME"
|
|
121
|
+
- echo "Delete namespace on k9s $CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG"
|
|
122
|
+
- kubectl config use-context vcsuite/cluster-management:agent
|
|
123
|
+
- kubectl delete namespace $CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG
|
|
124
|
+
when: manual
|
|
125
|
+
environment:
|
|
126
|
+
name: staging/$CI_COMMIT_REF_SLUG
|
|
127
|
+
action: stop
|
|
128
|
+
|
|
129
|
+
deployStagingCluster:
|
|
130
|
+
stage: deployCluster
|
|
131
|
+
except:
|
|
132
|
+
variables:
|
|
133
|
+
- $PUBLISH
|
|
134
|
+
inherit:
|
|
135
|
+
variables: false
|
|
136
|
+
variables:
|
|
137
|
+
STAGE_BRANCH: $CI_COMMIT_REF_SLUG
|
|
138
|
+
STAGE_PROJECT_NAME: $CI_PROJECT_PATH_SLUG
|
|
139
|
+
STAGE_REGISTRY_IMAGE: $CI_REGISTRY_IMAGE
|
|
140
|
+
STAGE_NAMESPACE: $CI_PROJECT_PATH_SLUG-$CI_COMMIT_REF_SLUG
|
|
141
|
+
trigger:
|
|
142
|
+
project: vcsuite/devops/manifests
|
|
143
|
+
branch: main
|
|
144
|
+
|
|
145
|
+
version:
|
|
146
|
+
<<: *after_build_definition
|
|
147
|
+
stage: version
|
|
148
|
+
only:
|
|
149
|
+
variables:
|
|
150
|
+
- $PUBLISH
|
|
151
|
+
refs:
|
|
152
|
+
- /^(main|release-v.*)$/
|
|
153
|
+
script:
|
|
154
|
+
- npm version patch -m "%s [skip-ci]"
|
|
155
|
+
- TAG=`git describe --abbrev=0`
|
|
156
|
+
- echo git push git@gitlab:vcsuite/"$CI_PROJECT_PATH".git
|
|
157
|
+
- git push git@gitlab:"$CI_PROJECT_PATH".git $TAG
|
|
158
|
+
- git push git@gitlab:"$CI_PROJECT_PATH".git HEAD:$CI_COMMIT_REF_NAME
|
|
159
|
+
before_script:
|
|
160
|
+
- mkdir -p ~/.ssh
|
|
161
|
+
- chmod 700 ~/.ssh
|
|
162
|
+
- echo "$SSH_RUNNER_KEY" | tr -d '\r' > ~/.ssh/id_rsa
|
|
163
|
+
- chmod 600 ~/.ssh/id_rsa
|
|
164
|
+
- ssh-keyscan gitlab >> ~/.ssh/known_hosts
|
|
165
|
+
- chmod 644 ~/.ssh/known_hosts
|
|
166
|
+
- git config user.name "Gitlab Runner"
|
|
167
|
+
- git config user.email "gitlab-runner@vc.systems"
|
|
168
|
+
|
|
169
|
+
publish:
|
|
170
|
+
<<: *after_build_definition
|
|
171
|
+
stage: publish
|
|
172
|
+
only:
|
|
173
|
+
refs:
|
|
174
|
+
- /^(main|release-v.*)$/
|
|
175
|
+
variables:
|
|
176
|
+
- $PUBLISH
|
|
177
|
+
script:
|
|
178
|
+
- npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}"
|
|
179
|
+
- npm publish --registry https://registry.npmjs.org --access public
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es2022",
|
|
4
|
+
"module": "es2022",
|
|
5
|
+
"incremental": false,
|
|
6
|
+
"lib": ["esnext", "dom"],
|
|
7
|
+
"allowJs": true,
|
|
8
|
+
"checkJs": false,
|
|
9
|
+
"declaration": false,
|
|
10
|
+
"rootDir": ".",
|
|
11
|
+
/* Strict Type-Checking Options */
|
|
12
|
+
"strict": true,
|
|
13
|
+
"noImplicitAny": true,
|
|
14
|
+
"strictNullChecks": true,
|
|
15
|
+
|
|
16
|
+
/* Additional Checks */
|
|
17
|
+
"noImplicitReturns": false,
|
|
18
|
+
"noUnusedLocals": true,
|
|
19
|
+
"noUnusedParameters": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": false,
|
|
21
|
+
"noImplicitThis": false,
|
|
22
|
+
|
|
23
|
+
/* Module Resolution Options */
|
|
24
|
+
"baseUrl": ".",
|
|
25
|
+
"moduleResolution": "node",
|
|
26
|
+
"resolveJsonModule": true,
|
|
27
|
+
"esModuleInterop": true,
|
|
28
|
+
"preserveSymlinks": true,
|
|
29
|
+
"allowSyntheticDefaultImports": true,
|
|
30
|
+
"skipLibCheck": true
|
|
31
|
+
},
|
|
32
|
+
"exclude": ["dist/", "build/", ".tests/"],
|
|
33
|
+
"include": ["src/"]
|
|
34
|
+
}
|
package/cli.js
CHANGED
|
@@ -5,6 +5,7 @@ import { create, serve, build, pack, preview, update } from './index.js';
|
|
|
5
5
|
import { version } from './src/pluginCliHelper.js';
|
|
6
6
|
import setupMapUi from './src/setupMapUi.js';
|
|
7
7
|
import buildStagingApp from './src/buildStagingApp.js';
|
|
8
|
+
import ensureTypes from './src/ensureTypes.js';
|
|
8
9
|
|
|
9
10
|
program.version(version);
|
|
10
11
|
|
|
@@ -12,6 +13,7 @@ program
|
|
|
12
13
|
.command('create')
|
|
13
14
|
.summary('create new plugin')
|
|
14
15
|
.defaultOptions()
|
|
16
|
+
.option('-t --typescript', 'Create a plugin using typescript')
|
|
15
17
|
.safeAction(create);
|
|
16
18
|
|
|
17
19
|
program
|
|
@@ -67,4 +69,6 @@ program
|
|
|
67
69
|
)
|
|
68
70
|
.safeAction(update);
|
|
69
71
|
|
|
72
|
+
program.command('ensure-types').action(ensureTypes);
|
|
73
|
+
|
|
70
74
|
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vcmap/plugin-cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "A CLI to help develop and build plugins for the VC Map",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
"sass": "1.32.13",
|
|
39
39
|
"semver": "^7.5.4",
|
|
40
40
|
"tar": "^6.1.15",
|
|
41
|
-
"vite": "^4.
|
|
41
|
+
"vite": "^4.5.2",
|
|
42
42
|
"vue-template-compiler": "~2.7.14"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"@vcmap/ui": "^5.0
|
|
45
|
+
"@vcmap/ui": "^5.1.0",
|
|
46
46
|
"vue": "~2.7.14"
|
|
47
47
|
},
|
|
48
48
|
"peerDependenciesMeta": {
|
|
@@ -54,12 +54,13 @@
|
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@vcsuite/eslint-config": "^3.0.
|
|
57
|
+
"@vcsuite/eslint-config": "^3.0.6",
|
|
58
58
|
"eslint": "^8.38.0"
|
|
59
59
|
},
|
|
60
60
|
"eslintIgnore": [
|
|
61
61
|
"node_modules",
|
|
62
|
-
"assets/tests"
|
|
62
|
+
"assets/tests",
|
|
63
|
+
"assets/index.ts"
|
|
63
64
|
],
|
|
64
65
|
"eslintConfig": {
|
|
65
66
|
"extends": "@vcsuite/eslint-config/node",
|
package/src/build.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
-
import { rm, mkdir } from 'fs/promises';
|
|
3
|
-
import fs from 'fs';
|
|
2
|
+
import { rm, mkdir } from 'node:fs/promises';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
4
|
import vue2 from '@vitejs/plugin-vue2';
|
|
5
5
|
import vcsOl from '@vcmap/rollup-plugin-vcs-ol';
|
|
6
6
|
import { logger } from '@vcsuite/cli-logger';
|
|
7
|
-
import {
|
|
7
|
+
import { getEntry, getPluginName } from './packageJsonHelpers.js';
|
|
8
8
|
import { getContext } from './context.js';
|
|
9
9
|
import { executeUiNpm, resolveMapUi } from './hostingHelpers.js';
|
|
10
10
|
|
|
@@ -44,14 +44,7 @@ export async function getLibraryPaths(pluginName) {
|
|
|
44
44
|
* @returns {Promise<void>}
|
|
45
45
|
*/
|
|
46
46
|
export default async function buildModule(options) {
|
|
47
|
-
const entry = await
|
|
48
|
-
if (path.relative('src', entry).startsWith('.')) {
|
|
49
|
-
logger.warning(`detected irregular entry ${entry}`);
|
|
50
|
-
logger.warning(
|
|
51
|
-
'vuetify component resolution expects source files to be within "src"',
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
47
|
+
const entry = await getEntry();
|
|
55
48
|
const pluginName = await getPluginName();
|
|
56
49
|
const libraryPaths = await getLibraryPaths(pluginName);
|
|
57
50
|
const distPath = path.join(getContext(), 'dist');
|
package/src/create.js
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import prompts from 'prompts';
|
|
4
|
-
import
|
|
4
|
+
import { minVersion, parse, valid } from 'semver';
|
|
5
5
|
import tar from 'tar';
|
|
6
6
|
import { logger } from '@vcsuite/cli-logger';
|
|
7
7
|
import { LicenseType, writeLicense } from './licenses.js';
|
|
8
8
|
import { DepType, installDeps, setVcMapVersion } from './packageJsonHelpers.js';
|
|
9
9
|
import { updatePeerDependencies } from './update.js';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
name,
|
|
12
|
+
version,
|
|
13
|
+
promiseExec,
|
|
14
|
+
getDirname,
|
|
15
|
+
peerDependencies as cliPeerDependencies,
|
|
16
|
+
} from './pluginCliHelper.js';
|
|
11
17
|
|
|
12
18
|
/**
|
|
13
19
|
* @typedef {Object} PluginTemplateOptions
|
|
@@ -21,6 +27,7 @@ import { name, version, promiseExec, getDirname } from './pluginCliHelper.js';
|
|
|
21
27
|
* @property {string} template
|
|
22
28
|
* @property {Array<string>} peerDeps
|
|
23
29
|
* @property {boolean} gitlabCi
|
|
30
|
+
* @property {boolean} typescript
|
|
24
31
|
*/
|
|
25
32
|
|
|
26
33
|
/**
|
|
@@ -29,15 +36,25 @@ import { name, version, promiseExec, getDirname } from './pluginCliHelper.js';
|
|
|
29
36
|
* @returns {Object}
|
|
30
37
|
*/
|
|
31
38
|
function createPackageJson(options) {
|
|
39
|
+
const typescriptScripts = options.typescript
|
|
40
|
+
? {
|
|
41
|
+
'type-check': 'vue-tsc --noEmit',
|
|
42
|
+
'ensure-types': 'vcmplugin ensure-types',
|
|
43
|
+
}
|
|
44
|
+
: {};
|
|
45
|
+
const main = options.typescript ? 'dist/index.js' : 'src/index.js';
|
|
32
46
|
return {
|
|
33
47
|
name: options.name,
|
|
34
48
|
version: options.version,
|
|
35
49
|
description: options.description,
|
|
36
50
|
type: 'module',
|
|
37
|
-
main
|
|
51
|
+
main,
|
|
38
52
|
scripts: Object.assign(
|
|
39
|
-
{
|
|
53
|
+
{
|
|
54
|
+
prepublishOnly: 'vcmplugin build',
|
|
55
|
+
},
|
|
40
56
|
...options.scripts,
|
|
57
|
+
typescriptScripts,
|
|
41
58
|
),
|
|
42
59
|
author: options.author,
|
|
43
60
|
license: options.license,
|
|
@@ -52,7 +69,7 @@ function createPackageJson(options) {
|
|
|
52
69
|
'CHANGELOG.md',
|
|
53
70
|
],
|
|
54
71
|
exports: {
|
|
55
|
-
'.': '
|
|
72
|
+
'.': options.typescript ? 'dist/index.js' : 'src/index.js',
|
|
56
73
|
'./dist': './dist/index.js',
|
|
57
74
|
},
|
|
58
75
|
};
|
|
@@ -142,10 +159,12 @@ async function createPluginTemplate(options, pluginPath) {
|
|
|
142
159
|
const installEsLint = options.scripts.find((script) => script.lint);
|
|
143
160
|
if (installEsLint) {
|
|
144
161
|
packageJson.eslintIgnore = ['node_modules', 'dist', 'plugin-assets'];
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
162
|
+
if (!options.typescript) {
|
|
163
|
+
packageJson.eslintConfig = {
|
|
164
|
+
root: true,
|
|
165
|
+
extends: '@vcsuite/eslint-config/vue',
|
|
166
|
+
};
|
|
167
|
+
}
|
|
149
168
|
packageJson.prettier = '@vcsuite/eslint-config/prettier.js';
|
|
150
169
|
}
|
|
151
170
|
|
|
@@ -172,9 +191,10 @@ async function createPluginTemplate(options, pluginPath) {
|
|
|
172
191
|
logger.debug('created src directory');
|
|
173
192
|
}
|
|
174
193
|
|
|
194
|
+
const indexFile = options.typescript ? 'index.ts' : 'index.js';
|
|
175
195
|
await fs.promises.copyFile(
|
|
176
|
-
path.join(getDirname(), '..', 'assets',
|
|
177
|
-
path.join(pluginPath, 'src',
|
|
196
|
+
path.join(getDirname(), '..', 'assets', indexFile),
|
|
197
|
+
path.join(pluginPath, 'src', indexFile),
|
|
178
198
|
);
|
|
179
199
|
}
|
|
180
200
|
|
|
@@ -196,7 +216,11 @@ async function createPluginTemplate(options, pluginPath) {
|
|
|
196
216
|
(obj, key) => ({ ...obj, [key]: 'latest' }),
|
|
197
217
|
{},
|
|
198
218
|
);
|
|
199
|
-
|
|
219
|
+
const { major, minor } = parse(
|
|
220
|
+
minVersion(cliPeerDependencies['@vcmap/ui']),
|
|
221
|
+
);
|
|
222
|
+
const mapVersion = `^${major}.${minor}`;
|
|
223
|
+
await updatePeerDependencies(peerDependencies, pluginPath, { mapVersion });
|
|
200
224
|
logger.spin('installing dependencies... (this may take a while)');
|
|
201
225
|
const devDeps = [`${name}@${version}`];
|
|
202
226
|
if (installEsLint) {
|
|
@@ -211,6 +235,9 @@ async function createPluginTemplate(options, pluginPath) {
|
|
|
211
235
|
'jsdom',
|
|
212
236
|
);
|
|
213
237
|
}
|
|
238
|
+
if (options.typescript) {
|
|
239
|
+
devDeps.push('typescript', 'vue-tsc');
|
|
240
|
+
}
|
|
214
241
|
await installDeps(devDeps, DepType.DEV, pluginPath);
|
|
215
242
|
logger.success('Installed dependencies');
|
|
216
243
|
} catch (e) {
|
|
@@ -280,8 +307,11 @@ async function createPlugin(options) {
|
|
|
280
307
|
]);
|
|
281
308
|
|
|
282
309
|
if (options.gitlabCi) {
|
|
310
|
+
const gitlabFile = options.typescript
|
|
311
|
+
? 'ts.gitlab-ci.yml'
|
|
312
|
+
: '.gitlab-ci.yml';
|
|
283
313
|
await fs.promises.copyFile(
|
|
284
|
-
path.join(getDirname(), '..', 'assets',
|
|
314
|
+
path.join(getDirname(), '..', 'assets', gitlabFile),
|
|
285
315
|
path.join(pluginPath, '.gitlab-ci.yml'),
|
|
286
316
|
);
|
|
287
317
|
await fs.promises.cp(
|
|
@@ -291,6 +321,17 @@ async function createPlugin(options) {
|
|
|
291
321
|
);
|
|
292
322
|
}
|
|
293
323
|
|
|
324
|
+
if (options.typescript) {
|
|
325
|
+
await fs.promises.copyFile(
|
|
326
|
+
path.join(getDirname(), '..', 'assets', 'tsconfig.json'),
|
|
327
|
+
path.join(pluginPath, 'tsconfig.json'),
|
|
328
|
+
);
|
|
329
|
+
await fs.promises.copyFile(
|
|
330
|
+
path.join(getDirname(), '..', 'assets', 'eslintrc.cjs'),
|
|
331
|
+
path.join(pluginPath, '.eslintrc.cjs'),
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
|
|
294
335
|
await createPluginTemplate(options, pluginPath);
|
|
295
336
|
await setVcMapVersion(pluginPath);
|
|
296
337
|
logger.success(`Created plugin ${options.name}`);
|
|
@@ -367,7 +408,7 @@ export default async function create() {
|
|
|
367
408
|
name: 'version',
|
|
368
409
|
message: 'Version',
|
|
369
410
|
initial: '1.0.0',
|
|
370
|
-
validate: (value) => !!
|
|
411
|
+
validate: (value) => !!valid(value),
|
|
371
412
|
},
|
|
372
413
|
{
|
|
373
414
|
type: 'text',
|
|
@@ -397,6 +438,14 @@ export default async function create() {
|
|
|
397
438
|
value: type,
|
|
398
439
|
})),
|
|
399
440
|
},
|
|
441
|
+
{
|
|
442
|
+
type: 'toggle',
|
|
443
|
+
name: 'typescript',
|
|
444
|
+
message: 'Create plugin using typescript (recommended).',
|
|
445
|
+
initial: true,
|
|
446
|
+
active: 'yes',
|
|
447
|
+
inactive: 'no',
|
|
448
|
+
},
|
|
400
449
|
{
|
|
401
450
|
type: 'select',
|
|
402
451
|
name: 'template',
|
|
@@ -404,6 +453,13 @@ export default async function create() {
|
|
|
404
453
|
initial: 0,
|
|
405
454
|
choices: templateChoices,
|
|
406
455
|
},
|
|
456
|
+
{
|
|
457
|
+
type: (prev, values) => (values.typescript && prev ? 'confirm' : null),
|
|
458
|
+
name: 'keepTs',
|
|
459
|
+
message:
|
|
460
|
+
'The selected template is not in typescript. You will have to manually transform it. Keep typescript?',
|
|
461
|
+
initial: true,
|
|
462
|
+
},
|
|
407
463
|
{
|
|
408
464
|
type: 'multiselect',
|
|
409
465
|
message: 'Add the following scripts to the package.json.',
|
|
@@ -434,5 +490,9 @@ export default async function create() {
|
|
|
434
490
|
},
|
|
435
491
|
});
|
|
436
492
|
|
|
493
|
+
if (answers.template && answers.typescript) {
|
|
494
|
+
answers.typescript = !!answers.keepTs;
|
|
495
|
+
}
|
|
496
|
+
|
|
437
497
|
await createPlugin(answers);
|
|
438
498
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { executeUiNpm, resolveMapUi } from './hostingHelpers.js';
|
|
3
|
+
import { getPackageJson } from './packageJsonHelpers.js';
|
|
4
|
+
|
|
5
|
+
export default async function ensureTypes() {
|
|
6
|
+
const packageJson = await getPackageJson();
|
|
7
|
+
if (packageJson.devDependencies?.typescript) {
|
|
8
|
+
const indexTs = resolveMapUi('index.d.ts');
|
|
9
|
+
|
|
10
|
+
if (!existsSync(indexTs)) {
|
|
11
|
+
console.log('building types');
|
|
12
|
+
await executeUiNpm('build-types -- --skipValidation');
|
|
13
|
+
}
|
|
14
|
+
console.log('types ensured');
|
|
15
|
+
}
|
|
16
|
+
}
|
package/src/hostingHelpers.js
CHANGED
|
@@ -5,7 +5,7 @@ import fs from 'fs';
|
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { logger } from '@vcsuite/cli-logger';
|
|
7
7
|
import { getContext, resolveContext } from './context.js';
|
|
8
|
-
import {
|
|
8
|
+
import { getPluginName, getEntry } from './packageJsonHelpers.js';
|
|
9
9
|
import { promiseExec, getDirname } from './pluginCliHelper.js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -119,7 +119,7 @@ export async function printVcmapUiVersion() {
|
|
|
119
119
|
export async function reWriteAppConfig(appConfig, pluginConfig, production) {
|
|
120
120
|
const name = await getPluginName();
|
|
121
121
|
pluginConfig.name = name;
|
|
122
|
-
pluginConfig.entry = production ? 'dist/index.js' : await
|
|
122
|
+
pluginConfig.entry = production ? 'dist/index.js' : await getEntry();
|
|
123
123
|
appConfig.modules = appConfig.modules ?? [];
|
|
124
124
|
appConfig.modules.forEach((config) => {
|
|
125
125
|
if (Array.isArray(config.plugins)) {
|
|
@@ -3,7 +3,7 @@ import { writeFile, readFile } from 'fs/promises';
|
|
|
3
3
|
import { parse, satisfies, validRange } from 'semver';
|
|
4
4
|
import { logger } from '@vcsuite/cli-logger';
|
|
5
5
|
import path from 'path';
|
|
6
|
-
import { getContext } from './context.js';
|
|
6
|
+
import { getContext, resolveContext } from './context.js';
|
|
7
7
|
import { promiseExec } from './pluginCliHelper.js';
|
|
8
8
|
|
|
9
9
|
/** @type {Object|null} */
|
|
@@ -42,17 +42,15 @@ export async function getPluginName() {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
|
+
* Gets the entry of the package
|
|
45
46
|
* @returns {Promise<string>}
|
|
46
47
|
*/
|
|
47
|
-
export async function
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
entry = entry || main;
|
|
52
|
-
if (!entry) {
|
|
53
|
-
throw new Error('Could not determine entry point');
|
|
48
|
+
export async function getEntry() {
|
|
49
|
+
const isTS = resolveContext('src', 'index.ts');
|
|
50
|
+
if (existsSync(isTS)) {
|
|
51
|
+
return 'src/index.ts';
|
|
54
52
|
}
|
|
55
|
-
return
|
|
53
|
+
return 'src/index.js';
|
|
56
54
|
}
|
|
57
55
|
|
|
58
56
|
/**
|
package/src/pluginCliHelper.js
CHANGED
|
@@ -17,7 +17,7 @@ export function getDirname() {
|
|
|
17
17
|
* @type {string} version
|
|
18
18
|
* @type {string} name
|
|
19
19
|
*/
|
|
20
|
-
export const { version, name } = JSON.parse(
|
|
20
|
+
export const { version, name, peerDependencies } = JSON.parse(
|
|
21
21
|
fs.readFileSync(path.join(getDirname(), '..', 'package.json')).toString(),
|
|
22
22
|
);
|
|
23
23
|
|
package/src/update.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { logger } from '@vcsuite/cli-logger';
|
|
2
|
-
import {
|
|
2
|
+
import { validRange } from 'semver';
|
|
3
3
|
import {
|
|
4
4
|
checkVcMapVersion,
|
|
5
5
|
DepType,
|
|
@@ -26,7 +26,7 @@ export async function updatePeerDependencies(
|
|
|
26
26
|
pluginPath,
|
|
27
27
|
options = {},
|
|
28
28
|
) {
|
|
29
|
-
if (options.mapVersion && !
|
|
29
|
+
if (options.mapVersion && !validRange(options.mapVersion)) {
|
|
30
30
|
logger.error(
|
|
31
31
|
`The mapVersion ${options.mapVersion} is not valid. Using 'latest' instead`,
|
|
32
32
|
);
|