@vcmap/plugin-cli 4.0.2 → 4.1.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 CHANGED
@@ -2,12 +2,42 @@
2
2
 
3
3
  > Part of the [VC Map Project](https://github.com/virtualcitySYSTEMS/map-ui)
4
4
 
5
- > Note: This documentation is for version @vcmap/ui 6.0.0, compatible with the [VC Map](https://github.com/virtualcitySYSTEMS/map-ui).
5
+ > Note: This documentation is for version @vcmap/ui 6, compatible with the [VC Map](https://github.com/virtualcitySYSTEMS/map-ui).
6
6
  >
7
- > [Migration Guide](https://github.com/virtualcitySYSTEMS/map-ui/blob/release-v6.0/MIGRATION_V6.md) for Plugins from @vcmap/ui 5.0.0
7
+ > [Migration Guide](https://github.com/virtualcitySYSTEMS/map-ui/blob/release-v6.0/MIGRATION_V6.md) for Plugins from @vcmap/ui 5
8
8
 
9
9
  The `@vcmap/plugin-cli` helps develop and build plugins for the **VC Map**.
10
10
 
11
+ ### Migration to Eslint9
12
+
13
+ If you are updating a plugin, you should also update to the new eslint config. To
14
+ do so, remove the eslint config and any eslint plugins (or even eslint itself) from
15
+ the devDependencies, then add the eslint config again:
16
+
17
+ ```bash
18
+ npm uninstall @vcsuite/eslint-config eslint
19
+ npm i -D @vcsuite/eslint-config
20
+ ```
21
+
22
+ You should then create a `eslint.config.js` in the root of your project.
23
+ You should then extend the `vue` or `vueTs` config, depending on
24
+ your project using typescript or not. You can then remove any .eslintrc files still left in your
25
+ project, plus the eslintConfig and eslintIgnore from your package.json.
26
+
27
+ ```bash
28
+ echo "import { configs } from '@vcsuite/eslint-config';" > eslint.config.js
29
+ echo "" >> eslint.config.js
30
+ echo "export default [" >> eslint.config.js
31
+ echo " ...configs.vueTs," >> eslint.config.js
32
+ echo " { ignores: ['node_modules/', 'dist/'] }," >> eslint.config.js
33
+ echo "];" >> eslint.config.js
34
+ echo "" >> eslint.config.js
35
+ ```
36
+
37
+ You can then remove any .eslintrc(.js) (including the one in the tests directory) files and any eslint config from your package.json.
38
+ To fix issues in the default vcs interface spec & setup, you can copy paste the template from [this projects assets folder](https://github.com/virtualcitySYSTEMS/map-plugin-cli/tree/main/assets/).
39
+ Be sure to copy the typescript or vanilla folder, depending on your project.
40
+
11
41
  ## Features
12
42
 
13
43
  - Creating basic plugin structure
@@ -189,19 +219,6 @@ This can be helpful, if you want to share specific parameters valid for a specif
189
219
  In order to do so just save a `vcm.config.js` in your plugin's root directory.
190
220
  This file has to return a js object as default export.
191
221
 
192
- Example `vcm.config.js` defining proxy and port:
193
-
194
- ```js
195
- export default {
196
- // server.proxy see https://vitejs.dev/config/server-options.html#server-proxy
197
- proxy: {
198
- // string shorthand: http://localhost:8008/foo -> https://vc.systems/foo
199
- '/foo': 'https://vc.systems',
200
- },
201
- port: 5005,
202
- };
203
- ```
204
-
205
222
  The following parameters are valid:
206
223
 
207
224
  | parameter | type | description |
@@ -213,9 +230,73 @@ The following parameters are valid:
213
230
  | vcm | string | A filename or URL to a VC Map application. Only works for `preview` command! Takes precedence over `appConfig` parameter. |
214
231
  | proxy | Object | A server proxy (see [vitejs.dev](https://vitejs.dev/config/server-options.html#server-proxy)) |
215
232
 
216
- > The `vcm` parameter uses a hosted map application to preview the plugin. The plugin is bundled and added to the application. This parameter is only working for `preview` mode.
233
+ Examples:
234
+
235
+ - defining modules:
236
+ > For the `appConfig` option, map and plugin are bundled to create a preview environment.
237
+ > You can provide modules from absolute or relative URLs or inline configurations.
238
+ > This parameter is working for both `preview` and `serve` mode.
217
239
 
218
- > For the `appConfig` option, map and plugin are bundled to create a preview environment. Here only the configuration is loaded from the provided url or object. This parameter is working for both `preview` and `serve` mode.
240
+ ```js
241
+ export default {
242
+ appConfig: {
243
+ modules: [
244
+ "https://www.virtualcitymap.de/config/www.config.json",
245
+ "./node_modules/@vcmap/ui/config/dev.config.json",
246
+ {
247
+ "name": "myCustomConfig",
248
+ "startingViewpointName": "start",
249
+ "viewpoints": [
250
+ {
251
+ "type": "Viewpoint",
252
+ "name": "start",
253
+ "groundPosition": [...],
254
+ "distance": 100
255
+ }
256
+ ],
257
+ "layers": [
258
+ {
259
+ "name": "geojsonClassification",
260
+ "type": "GeoJSONLayer",
261
+ "features": [
262
+ {
263
+ "type": "Feature",
264
+ "geometry": {
265
+ "type": "Polygon",
266
+ "coordinates": [...]
267
+ },
268
+ }
269
+ ],
270
+ "activeOnStartup": true,
271
+ },
272
+ ]
273
+ }
274
+ ]
275
+ }
276
+ }
277
+ ```
278
+
279
+ - referencing a hosted application
280
+ > The `vcm` parameter uses a hosted map application to preview the plugin. The plugin is bundled and added to the application. This parameter is only working for `preview` mode.
281
+
282
+ ```js
283
+ export default {
284
+ vcm: 'https://www.virtualcitymap.de/app.config.json',
285
+ };
286
+ ```
287
+
288
+ - defining proxy and port:
289
+
290
+ ```js
291
+ export default {
292
+ // server.proxy see https://vitejs.dev/config/server-options.html#server-proxy
293
+ proxy: {
294
+ // string shorthand: http://localhost:8008/foo -> https://vc.systems/foo
295
+ '/foo': 'https://vc.systems',
296
+ },
297
+ port: 5005,
298
+ };
299
+ ```
219
300
 
220
301
  ## About Peer Dependencies
221
302
 
@@ -9,6 +9,7 @@ stages:
9
9
  - test
10
10
  - bundle
11
11
  - deploy
12
+ - prepublish
12
13
  - version
13
14
  - publish
14
15
  - deployCluster
@@ -104,7 +105,7 @@ deployStaging:
104
105
  name: gcr.io/kaniko-project/executor:debug
105
106
  entrypoint: ['']
106
107
  script:
107
- - /kaniko/executor --context dist/ --dockerfile build/staging/Dockerfile --destination $CI_REGISTRY_IMAGE/staging:$CI_COMMIT_REF_SLUG
108
+ - /kaniko/executor --context dist/ --dockerfile node_modules/@vcmap/plugin-cli/assets/build/staging/Dockerfile --destination $CI_REGISTRY_IMAGE/staging:$CI_COMMIT_REF_SLUG
108
109
  before_script:
109
110
  - mkdir -p /kaniko/.docker
110
111
  - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
@@ -144,6 +145,24 @@ deployStagingCluster:
144
145
  project: vcsuite/devops/manifests
145
146
  branch: main
146
147
 
148
+ sshDependenciesCheck:
149
+ <<: *after_build_definition
150
+ stage: prepublish
151
+ only:
152
+ variables:
153
+ - $PUBLISH
154
+ refs:
155
+ - /^(main|release-v.*)$/
156
+ script:
157
+ - echo "Checking for SSH dependencies in package.json..."
158
+ - |
159
+ if grep -E "git(\+ssh)?://git@gitlab|ssh://git@gitlab:|gitlab:" package.json; then
160
+ echo "Error: SSH link dependencies found in package.json."
161
+ exit 1
162
+ else
163
+ echo "No SSH link dependencies found."
164
+ fi
165
+
147
166
  version:
148
167
  <<: *after_build_definition
149
168
  stage: version
@@ -1,2 +1,9 @@
1
1
  FROM httpd:2-buster
2
- COPY * /usr/local/apache2/htdocs/
2
+ COPY . /usr/local/apache2/htdocs/
3
+ # allow for proxy
4
+ RUN sed -i '/LoadModule rewrite_module/s/^#//g' /usr/local/apache2/conf/httpd.conf && \
5
+ sed -i '/LoadModule proxy_module/s/^#//g' /usr/local/apache2/conf/httpd.conf && \
6
+ sed -i '/LoadModule proxy_http_module/s/^#//g' /usr/local/apache2/conf/httpd.conf && \
7
+ sed -i '/LoadModule ssl_module/s/^#//g' /usr/local/apache2/conf/httpd.conf && \
8
+ sed -i 's#AllowOverride [Nn]one#AllowOverride All#' /usr/local/apache2/conf/httpd.conf && \
9
+ echo "SSLProxyEngine On" | tee -a /usr/local/apache2/conf/httpd.conf
@@ -0,0 +1,8 @@
1
+ import { configs } from '@vcsuite/eslint-config';
2
+
3
+ export default [
4
+ ...configs.vue,
5
+ {
6
+ ignores: ['node_modules/', 'dist/'],
7
+ },
8
+ ];
@@ -0,0 +1,8 @@
1
+ import { configs } from '@vcsuite/eslint-config';
2
+
3
+ export default [
4
+ ...configs.vueTs,
5
+ {
6
+ ignores: ['node_modules/', 'dist/'],
7
+ },
8
+ ];
package/assets/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { VcsPlugin, VcsUiApp, PluginConfigEditor } from '@vcmap/ui';
1
+ import type { VcsPlugin, VcsUiApp, PluginConfigEditor } from '@vcmap/ui';
2
2
  import { name, version, mapVersion } from '../package.json';
3
3
 
4
4
  type PluginConfig = Record<never, never>;
@@ -67,7 +67,7 @@ export default function plugin(
67
67
  /**
68
68
  * components for configuring the plugin and/ or custom items defined by the plugin
69
69
  */
70
- getConfigEditors(): PluginConfigEditor[] {
70
+ getConfigEditors(): PluginConfigEditor<object>[] {
71
71
  return [];
72
72
  },
73
73
  destroy(): void {
@@ -1,4 +1,4 @@
1
- /* eslint-disable import/no-extraneous-dependencies, import/first */
1
+ /* eslint-disable import/first */
2
2
  import { vi } from 'vitest';
3
3
 
4
4
  vi.hoisted(() => {
@@ -34,9 +34,11 @@ describe('VcsPlugin Interface test', () => {
34
34
  expect(pluginInstance).to.have.property('name', packageJSON.name);
35
35
  expect(isValidPackageName(pluginInstance.name)).to.be.true;
36
36
  });
37
+
37
38
  it('should return the plugin version from the package.json', () => {
38
39
  expect(pluginInstance).to.have.property('version', packageJSON.version);
39
40
  });
41
+
40
42
  it('should return the plugin mapVersion from the package.json', () => {
41
43
  expect(pluginInstance).to.have.property(
42
44
  'mapVersion',
@@ -51,6 +53,7 @@ describe('VcsPlugin Interface test', () => {
51
53
  expect(pluginInstance?.i18n).to.be.a('object').with.property('en');
52
54
  }
53
55
  });
56
+
54
57
  it('should use unscoped, camel-case plugin name as namespace for plugin specific i18n entries', () => {
55
58
  if (pluginInstance?.i18n) {
56
59
  expect(pluginInstance.i18n).to.be.a('object');
@@ -74,12 +77,14 @@ describe('VcsPlugin Interface test', () => {
74
77
  .throw;
75
78
  }
76
79
  });
80
+
77
81
  it('may implement onVcsAppMounted', () => {
78
82
  if (pluginInstance?.onVcsAppMounted) {
79
83
  expect(pluginInstance.onVcsAppMounted).to.be.a('function');
80
84
  expect(pluginInstance.onVcsAppMounted(new VcsUiApp())).to.not.throw;
81
85
  }
82
86
  });
87
+
83
88
  it('should implement destroy', () => {
84
89
  if (pluginInstance?.destroy) {
85
90
  expect(pluginInstance.destroy).to.be.a('function');
@@ -93,6 +98,7 @@ describe('VcsPlugin Interface test', () => {
93
98
  expect(pluginInstance.getDefaultOptions()).to.be.a('object');
94
99
  }
95
100
  });
101
+
96
102
  it('may implement toJSON returning the plugin config', () => {
97
103
  if (pluginInstance?.toJSON) {
98
104
  expect(pluginInstance.toJSON()).to.be.a('object');
@@ -0,0 +1,15 @@
1
+ /* global global */
2
+ /* eslint-disable import/first */
3
+ import { vi } from 'vitest';
4
+
5
+ vi.hoisted(() => {
6
+ global.jest = vi;
7
+ });
8
+
9
+ import ResizeObserver from 'resize-observer-polyfill';
10
+
11
+ global.ResizeObserver = ResizeObserver;
12
+
13
+ import 'jest-canvas-mock';
14
+
15
+ window.CESIUM_BASE_URL = '/node_modules/@vcmap-cesium/engine/Build/';
@@ -1,5 +1,6 @@
1
1
  import { describe, it, expect, beforeAll, afterAll } from 'vitest';
2
- import { VcsUiApp, loadPlugin, isValidPackageName, VcsPlugin } from '@vcmap/ui';
2
+ import type { VcsPlugin } from '@vcmap/ui';
3
+ import { VcsUiApp, loadPlugin, isValidPackageName } from '@vcmap/ui';
3
4
  import plugin from '../src/index.js';
4
5
  import packageJSON from '../package.json';
5
6
 
@@ -40,9 +41,11 @@ describe('VcsPlugin Interface test', () => {
40
41
  expect(pluginInstance).to.have.property('name', packageJSON.name);
41
42
  expect(isValidPackageName(pluginInstance.name)).to.be.true;
42
43
  });
44
+
43
45
  it('should return the plugin version from the package.json', () => {
44
46
  expect(pluginInstance).to.have.property('version', packageJSON.version);
45
47
  });
48
+
46
49
  it('should return the plugin mapVersion from the package.json', () => {
47
50
  expect(pluginInstance).to.have.property(
48
51
  'mapVersion',
@@ -54,11 +57,10 @@ describe('VcsPlugin Interface test', () => {
54
57
  describe('internationalization', () => {
55
58
  it('may provide an i18n object and should provide at least en as fallback language', () => {
56
59
  if (pluginInstance?.i18n) {
57
- expect(pluginInstance?.i18n)
58
- .to.be.a('object')
59
- .with.property('en');
60
+ expect(pluginInstance?.i18n).to.be.a('object').with.property('en');
60
61
  }
61
62
  });
63
+
62
64
  it('should use unscoped, camel-case plugin name as namespace for plugin specific i18n entries', () => {
63
65
  if (pluginInstance?.i18n) {
64
66
  expect(pluginInstance.i18n).to.be.a('object');
@@ -82,12 +84,16 @@ describe('VcsPlugin Interface test', () => {
82
84
  .throw;
83
85
  }
84
86
  });
87
+
85
88
  it('may implement onVcsAppMounted', () => {
86
89
  if (pluginInstance?.onVcsAppMounted) {
87
90
  expect(pluginInstance.onVcsAppMounted).to.be.a('function');
88
- expect(pluginInstance.onVcsAppMounted(new VcsUiApp())).to.not.throw;
91
+ expect(() => {
92
+ pluginInstance.onVcsAppMounted(new VcsUiApp());
93
+ }).to.not.throw;
89
94
  }
90
95
  });
96
+
91
97
  it('should implement destroy', () => {
92
98
  if (pluginInstance?.destroy) {
93
99
  expect(pluginInstance.destroy).to.be.a('function');
@@ -101,6 +107,7 @@ describe('VcsPlugin Interface test', () => {
101
107
  expect(pluginInstance.getDefaultOptions()).to.be.a('object');
102
108
  }
103
109
  });
110
+
104
111
  it('may implement toJSON returning the plugin config', () => {
105
112
  if (pluginInstance?.toJSON) {
106
113
  expect(pluginInstance.toJSON()).to.be.a('object');
@@ -142,7 +149,9 @@ describe('VcsPlugin Interface test', () => {
142
149
  });
143
150
 
144
151
  it('should reincarnate the plugin correctly', async () => {
145
- expect(() => app.plugins.remove(pluginInstance2!)).to.not.throw;
152
+ expect(() => {
153
+ app.plugins.remove(pluginInstance2!);
154
+ }).to.not.throw;
146
155
  app.plugins.remove(pluginInstance2!);
147
156
  await sleep(0);
148
157
  expect(app.plugins.getByKey(packageJSON.name)).not.to.have.property(
@@ -9,6 +9,7 @@ stages:
9
9
  - test
10
10
  - bundle
11
11
  - deploy
12
+ - prepublish
12
13
  - version
13
14
  - publish
14
15
  - deployCluster
@@ -102,7 +103,7 @@ deployStaging:
102
103
  name: gcr.io/kaniko-project/executor:debug
103
104
  entrypoint: ['']
104
105
  script:
105
- - /kaniko/executor --context dist/ --dockerfile build/staging/Dockerfile --destination $CI_REGISTRY_IMAGE/staging:$CI_COMMIT_REF_SLUG
106
+ - /kaniko/executor --context dist/ --dockerfile node_modules/@vcmap/plugin-cli/assets/build/staging/Dockerfile --destination $CI_REGISTRY_IMAGE/staging:$CI_COMMIT_REF_SLUG
106
107
  before_script:
107
108
  - mkdir -p /kaniko/.docker
108
109
  - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
@@ -142,6 +143,24 @@ deployStagingCluster:
142
143
  project: vcsuite/devops/manifests
143
144
  branch: main
144
145
 
146
+ sshDependenciesCheck:
147
+ <<: *after_build_definition
148
+ stage: prepublish
149
+ only:
150
+ variables:
151
+ - $PUBLISH
152
+ refs:
153
+ - /^(main|release-v.*)$/
154
+ script:
155
+ - echo "Checking for SSH dependencies in package.json..."
156
+ - |
157
+ if grep -E "git(\+ssh)?://git@gitlab|ssh://git@gitlab:|gitlab:" package.json; then
158
+ echo "Error: SSH link dependencies found in package.json."
159
+ exit 1
160
+ else
161
+ echo "No SSH link dependencies found."
162
+ fi
163
+
145
164
  version:
146
165
  <<: *after_build_definition
147
166
  stage: version
@@ -1,4 +1,3 @@
1
- // eslint-disable-next-line import/no-extraneous-dependencies
2
1
  import { defineConfig } from 'vite';
3
2
  import commonViteConfig from '@vcmap/ui/build/commonViteConfig.js';
4
3
 
package/cli.js CHANGED
@@ -14,6 +14,7 @@ program
14
14
  .summary('create new plugin')
15
15
  .defaultOptions()
16
16
  .option('-t --typescript', 'Create a plugin using typescript')
17
+ .option('-d --default <name>', 'use defaults')
17
18
  .safeAction(create);
18
19
 
19
20
  program
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vcmap/plugin-cli",
3
- "version": "4.0.2",
3
+ "version": "4.1.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",
@@ -42,9 +42,12 @@
42
42
  "vite-plugin-vuetify": "^2.0.4"
43
43
  },
44
44
  "peerDependencies": {
45
- "@vcmap/ui": "^6.0",
45
+ "@vcmap/ui": "^6.0.0",
46
46
  "vue": "~3.4.38"
47
47
  },
48
+ "overrides": {
49
+ "esbuild": "^0.25.0"
50
+ },
48
51
  "peerDependenciesMeta": {
49
52
  "@vcmap/ui": {
50
53
  "optional": true
@@ -54,34 +57,11 @@
54
57
  }
55
58
  },
56
59
  "devDependencies": {
57
- "@vcsuite/eslint-config": "^3.0.7",
58
- "eslint": "^8.38.0"
59
- },
60
- "eslintIgnore": [
61
- "node_modules",
62
- "assets/tests",
63
- "assets/testsTypescript",
64
- "assets/index.ts"
65
- ],
66
- "eslintConfig": {
67
- "extends": "@vcsuite/eslint-config/node",
68
- "parserOptions": {
69
- "ecmaVersion": 2020
70
- },
71
- "rules": {
72
- "import/no-unresolved": [
73
- 2,
74
- {
75
- "ignore": [
76
- "^@vcmap/ui"
77
- ]
78
- }
79
- ]
80
- }
60
+ "@vcsuite/eslint-config": "^4.0.0"
81
61
  },
82
62
  "prettier": "@vcsuite/eslint-config/prettier.js",
83
63
  "engines": {
84
- "node": ">=18.12.0 || >= 20.0.0",
85
- "npm": ">=9.0.0 || 10.0.0"
64
+ "node": ">= 20.0.0",
65
+ "npm": ">=10.0.0"
86
66
  }
87
67
  }
@@ -29,7 +29,7 @@ function getHtaccess(config) {
29
29
  `proxy settings for ${key} may be more complex, simply using rewrite to target: ${target}`,
30
30
  );
31
31
  }
32
- return `RewriteRule ^${key.replace(/^\^/, '')} ${target} [P,L]`;
32
+ return `RewriteRule ^${key.replace(/^\^/, '')}(.*) ${target}$1 [P,L]`;
33
33
  });
34
34
 
35
35
  if (htaccessLines.length > 0) {
package/src/create.js CHANGED
@@ -19,12 +19,12 @@ import {
19
19
  * @typedef {Object} PluginTemplateOptions
20
20
  * @property {string} name
21
21
  * @property {string} version
22
- * @property {string} description
22
+ * @property {string} [description]
23
23
  * @property {Array<Object>} scripts
24
- * @property {string} author
25
- * @property {string} repository
24
+ * @property {string} [author]
25
+ * @property {string} [repository]
26
26
  * @property {string} license
27
- * @property {string} template
27
+ * @property {string} [template]
28
28
  * @property {Array<string>} peerDeps
29
29
  * @property {boolean} gitlabCi
30
30
  * @property {boolean} typescript
@@ -160,14 +160,14 @@ async function createPluginTemplate(options, pluginPath) {
160
160
  if (installEsLint) {
161
161
  packageJson.eslintIgnore = ['node_modules', 'dist', 'plugin-assets'];
162
162
  if (!options.typescript) {
163
- packageJson.eslintConfig = {
164
- root: true,
165
- extends: '@vcsuite/eslint-config/vue',
166
- };
163
+ await fs.promises.copyFile(
164
+ path.join(getDirname(), '..', 'assets', 'eslintConfig.js'),
165
+ path.join(pluginPath, 'eslint.config.js'),
166
+ );
167
167
  } else {
168
168
  await fs.promises.copyFile(
169
- path.join(getDirname(), '..', 'assets', 'eslintrc.cjs'),
170
- path.join(pluginPath, '.eslintrc.cjs'),
169
+ path.join(getDirname(), '..', 'assets', 'eslintConfigTs.js'),
170
+ path.join(pluginPath, 'eslint.config.js'),
171
171
  );
172
172
  }
173
173
  packageJson.prettier = '@vcsuite/eslint-config/prettier.js';
@@ -178,13 +178,12 @@ async function createPluginTemplate(options, pluginPath) {
178
178
  JSON.stringify(packageJson, null, 2),
179
179
  );
180
180
 
181
- const configJson = {
182
- name: options.name,
183
- };
184
-
185
181
  await fs.promises.writeFile(
186
182
  path.join(pluginPath, 'config.json'),
187
- JSON.stringify(configJson, null, 2),
183
+ `{
184
+ "name": "${options.name}"
185
+ }
186
+ `,
188
187
  );
189
188
 
190
189
  if (options.template) {
@@ -205,25 +204,14 @@ async function createPluginTemplate(options, pluginPath) {
205
204
 
206
205
  if (installVitest) {
207
206
  logger.debug('setting up test environment');
208
- await fs.promises.cp(
209
- path.join(getDirname(), '..', 'assets', 'tests'),
210
- path.join(pluginPath, 'tests'),
211
- { recursive: true },
212
- );
213
- if (options.typescript) {
214
- await fs.promises.rm(
215
- path.join(pluginPath, 'tests', 'vcsPluginInterface.spec.js'),
216
- );
217
- await fs.promises.cp(
218
- path.join(getDirname(), '..', 'assets', 'testsTypescript'),
219
- path.join(pluginPath, 'tests'),
220
- { recursive: true },
221
- );
222
- await fs.promises.copyFile(
223
- path.join(getDirname(), '..', 'assets', 'eslintrcTests.cjs'),
224
- path.join(pluginPath, '.eslintrc.cjs'),
225
- );
226
- }
207
+ const testSrcPath = options.typescript
208
+ ? path.join(getDirname(), '..', 'assets', 'testsTypescript')
209
+ : path.join(getDirname(), '..', 'assets', 'tests');
210
+
211
+ await fs.promises.cp(testSrcPath, path.join(pluginPath, 'tests'), {
212
+ recursive: true,
213
+ });
214
+
227
215
  await fs.promises.copyFile(
228
216
  path.join(getDirname(), '..', 'assets', 'vitest.config.js'),
229
217
  path.join(pluginPath, 'vitest.config.js'),
@@ -291,14 +279,14 @@ async function createPluginTemplate(options, pluginPath) {
291
279
  async function createPlugin(options) {
292
280
  if (!options.name) {
293
281
  logger.error('please provide a plugin name as input parameter');
294
- process.exit(1);
282
+ throw new Error('no plugin name provided');
295
283
  }
296
284
  logger.debug(`creating new plugin: ${options.name}`);
297
285
 
298
286
  const pluginPath = path.join(process.cwd(), options.name);
299
287
  if (fs.existsSync(pluginPath)) {
300
288
  logger.error('plugin with the provided name already exists');
301
- process.exit(1);
289
+ throw new Error('path already exists');
302
290
  }
303
291
 
304
292
  await fs.promises.mkdir(pluginPath);
@@ -314,14 +302,17 @@ async function createPlugin(options) {
314
302
  path.join(pluginPath, 'README.md'),
315
303
  [
316
304
  `# ${options.name}`,
305
+ '',
317
306
  '> Part of the [VC Map Project](https://github.com/virtualcitySYSTEMS/map-ui)',
307
+ '',
318
308
  'describe your plugin',
309
+ '',
319
310
  ].join('\n'),
320
311
  );
321
312
 
322
313
  const writeChangesPromise = fs.promises.writeFile(
323
314
  path.join(pluginPath, 'CHANGELOG.md'),
324
- `# v${options.version}\nDocument features and fixes`,
315
+ `# v${options.version}\n\nDocument features and fixes\n`,
325
316
  );
326
317
 
327
318
  const copyGitIgnorePromise = fs.promises.copyFile(
@@ -351,11 +342,6 @@ async function createPlugin(options) {
351
342
  path.join(getDirname(), '..', 'assets', gitlabFile),
352
343
  path.join(pluginPath, '.gitlab-ci.yml'),
353
344
  );
354
- await fs.promises.cp(
355
- path.join(getDirname(), '..', 'assets', 'build'),
356
- path.join(pluginPath, 'build'),
357
- { recursive: true },
358
- );
359
345
  }
360
346
 
361
347
  if (options.typescript) {
@@ -364,8 +350,8 @@ async function createPlugin(options) {
364
350
  path.join(pluginPath, 'tsconfig.json'),
365
351
  );
366
352
  await fs.promises.copyFile(
367
- path.join(getDirname(), '..', 'assets', 'eslintrc.cjs'),
368
- path.join(pluginPath, '.eslintrc.cjs'),
353
+ path.join(getDirname(), '..', 'assets', 'eslintConfigTs.js'),
354
+ path.join(pluginPath, 'eslint.config.js'),
369
355
  );
370
356
  }
371
357
 
@@ -375,9 +361,10 @@ async function createPlugin(options) {
375
361
  }
376
362
 
377
363
  /**
364
+ * @param {{ default?: string }} cliOptions
378
365
  * @returns {Promise<void>}
379
366
  */
380
- export default async function create() {
367
+ export default async function create(cliOptions) {
381
368
  const templateChoices = [
382
369
  { title: 'no template (basic structure)', value: null },
383
370
  { title: 'hello-world', value: '@vcmap-show-case/hello-world' },
@@ -521,15 +508,29 @@ export default async function create() {
521
508
  },
522
509
  ];
523
510
 
524
- const answers = await prompts(questions, {
525
- onCancel() {
526
- process.exit(0);
527
- },
528
- });
511
+ if (cliOptions.default) {
512
+ logger.info(`creating default plugin ${cliOptions.default}`);
513
+ await createPlugin({
514
+ name: cliOptions.default,
515
+ version: '1.0.0',
516
+ scripts: scriptChoices.filter((s) => s.selected).map((s) => s.value),
517
+ license: LicenseType.MIT,
518
+ peerDeps: [],
519
+ gitlabCi: true,
520
+ typescript: true,
521
+ });
522
+ } else {
523
+ const answers = await prompts(questions, {
524
+ onCancel() {
525
+ // eslint-disable-next-line n/no-process-exit
526
+ process.exit(0);
527
+ },
528
+ });
529
529
 
530
- if (answers.template && answers.typescript) {
531
- answers.typescript = !!answers.keepTs;
532
- }
530
+ if (answers.template && answers.typescript) {
531
+ answers.typescript = !!answers.keepTs;
532
+ }
533
533
 
534
- await createPlugin(answers);
534
+ await createPlugin(answers);
535
+ }
535
536
  }
@@ -48,6 +48,7 @@ Command.prototype.safeAction = function safeAction(action) {
48
48
  logger.error(e);
49
49
  }
50
50
  logger.stopSpinner();
51
+ // eslint-disable-next-line n/no-process-exit
51
52
  process.exit(1);
52
53
  }
53
54
  });
@@ -244,12 +244,18 @@ export function addAppConfigRoute(
244
244
  production,
245
245
  ) {
246
246
  app.get('/app.config.json', (req, res) => {
247
- getAppConfigJson(appConfig, auth, production, configFile).then((config) => {
248
- const stringConfig = JSON.stringify(config, null, 2);
249
- res.setHeader('Content-Type', 'application/json');
250
- res.write(stringConfig);
251
- res.end();
252
- });
247
+ getAppConfigJson(appConfig, auth, production, configFile)
248
+ .then((config) => {
249
+ const stringConfig = JSON.stringify(config, null, 2);
250
+ res.setHeader('Content-Type', 'application/json');
251
+ res.write(stringConfig);
252
+ res.end();
253
+ })
254
+ .catch((e) => {
255
+ logger.error(e);
256
+ res.statusCode = 500;
257
+ res.end();
258
+ });
253
259
  });
254
260
  }
255
261
 
package/src/licenses.js CHANGED
@@ -7,19 +7,18 @@ import path from 'path';
7
7
  * @returns {string}
8
8
  */
9
9
  function mit(user, year) {
10
- return `
11
- Copyright ${year} ${user}
10
+ return `Copyright ${year} ${user}
12
11
 
13
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
14
13
  documentation files (the "Software"), to deal in the Software without restriction, including without limitation
15
- the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
14
+ the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
16
15
  and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
17
16
 
18
17
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
19
18
 
20
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
21
- THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
22
- OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
20
+ THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
21
+ OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
22
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
23
  `;
25
24
  }
@@ -30,8 +29,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR TH
30
29
  * @returns {string}
31
30
  */
32
31
  function apache(user, year) {
33
- return `
34
- Copyright ${year} ${user}
32
+ return `Copyright ${year} ${user}
35
33
 
36
34
  Licensed under the Apache License, Version 2.0 (the "License");
37
35
  you may not use this file except in compliance with the License.
@@ -53,8 +51,7 @@ limitations under the License.
53
51
  * @returns {string}
54
52
  */
55
53
  function gpl3(user, year) {
56
- return `
57
- Copyright (C) ${year} ${user}
54
+ return `Copyright (C) ${year} ${user}
58
55
 
59
56
  This program is free software: you can redistribute it and/or modify
60
57
  it under the terms of the GNU General Public License as published by
@@ -77,8 +74,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
77
74
  * @returns {string}
78
75
  */
79
76
  function isc(user, year) {
80
- return `
81
- Copyright (c) ${year}, ${user}
77
+ return `Copyright (c) ${year}, ${user}
82
78
 
83
79
  Permission to use, copy, modify, and/or distribute this software for any
84
80
  purpose with or without fee is hereby granted, provided that the above
package/src/pack.js CHANGED
@@ -80,12 +80,12 @@ async function zip(name) {
80
80
  const read = fs.createReadStream(fileName);
81
81
  const write = fs.createWriteStream(`${fileName}.gz`);
82
82
 
83
- await new Promise((res, rej) => {
83
+ await new Promise((resolve, reject) => {
84
84
  pipeline([read, createGzip(), write], (err) => {
85
85
  if (err) {
86
- rej(err);
86
+ reject(err);
87
87
  } else {
88
- res();
88
+ resolve();
89
89
  }
90
90
  });
91
91
  });
@@ -1,25 +0,0 @@
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
- };
@@ -1,25 +0,0 @@
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', './tests/tsconfig.json'],
18
- },
19
- rules: {
20
- '@typescript-eslint/no-non-null-assertion': 'off',
21
- },
22
- },
23
- ],
24
- ignorePatterns: ['dist/', 'node_modules/'],
25
- };
@@ -1,6 +0,0 @@
1
- {
2
- "extends": ["@vcsuite/eslint-config/mocha"],
3
- "rules": {
4
- "import/extensions": ["error", "always"]
5
- }
6
- }