@vcmap/plugin-cli 1.1.1 → 2.0.3

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/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@vcmap/plugin-cli",
3
- "version": "1.1.1",
4
- "description": "A CLI to help develop and build plugins for the virtualcityMAP",
3
+ "version": "2.0.3",
4
+ "description": "A CLI to help develop and build plugins for the VC Map",
5
5
  "main": "index.js",
6
+ "type": "module",
6
7
  "bin": {
7
8
  "vcmplugin": "cli.js"
8
9
  },
@@ -10,9 +11,14 @@
10
11
  "lint": "eslint . --env node",
11
12
  "test": "echo \"Error: no test specified\" && exit 1"
12
13
  },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/virtualcitySYSTEMS/map-plugin-cli.git"
17
+ },
13
18
  "author": "Ben Kuster <bkuster@virtualcitysystems.de>",
14
19
  "license": "MIT",
15
20
  "files": [
21
+ "assets/",
16
22
  "src/",
17
23
  "cli.js",
18
24
  "README.md",
@@ -20,35 +26,58 @@
20
26
  "LICENSE.md"
21
27
  ],
22
28
  "dependencies": {
23
- "@babel/core": "^7.10.2",
24
- "@babel/runtime": "^7.13.10",
29
+ "@vcmap/rollup-plugin-vcs-ol": "^1.0.1",
25
30
  "@vcsuite/cli-logger": "^1.0.0",
26
- "@vue/babel-preset-app": "^4.5.4",
27
31
  "archiver": "^5.0.0",
28
- "autoprefixer": "^9.8.6",
29
- "babel-loader": "^8.1.0",
30
32
  "commander": "^6.0.0",
31
- "css-loader": "^3.6.0",
32
- "postcss-loader": "^3.0.0",
33
+ "express": "^4.17.3",
33
34
  "prompts": "^2.4.1",
35
+ "sass": "1.32.13",
34
36
  "semver": "^7.3.5",
35
- "terser-webpack-plugin": "^5.1.1",
36
- "url-loader": "^4.1.0",
37
+ "unplugin-vue-components": "^0.17.21",
37
38
  "vinyl-fs": "^3.0.3",
38
- "vue": "^2.6.12",
39
- "vue-loader": "^15.9.6",
40
- "vue-template-compiler": "^2.6.12",
41
- "webpack": "^5.36.2",
42
- "webpack-dev-server": "^3.11.2"
39
+ "vite": "^2.9.1",
40
+ "vite-plugin-vue2": "^1.7.3",
41
+ "vue-template-compiler": "^2.6.14"
42
+ },
43
+ "peerDependencies": {
44
+ "@vcmap/ui": "^5.0.0-rc.6",
45
+ "vue": "^2.6.14"
46
+ },
47
+ "peerDependenciesMeta": {
48
+ "@vcmap/ui": {
49
+ "optional": true
50
+ },
51
+ "vue": {
52
+ "optional": true
53
+ }
43
54
  },
44
55
  "devDependencies": {
45
- "@vcsuite/eslint-config": "^1.0.0",
46
- "eslint": "^7.25.0"
56
+ "@vcsuite/eslint-config": "^2.1.1",
57
+ "eslint": "^8.9.0"
47
58
  },
48
59
  "eslintIgnore": [
49
- "node_modules"
60
+ "node_modules",
61
+ "assets/helloWorld"
50
62
  ],
51
63
  "eslintConfig": {
52
- "extends": "@vcsuite/eslint-config/node"
64
+ "extends": "@vcsuite/eslint-config/node",
65
+ "parserOptions": {
66
+ "ecmaVersion": 2020
67
+ },
68
+ "rules": {
69
+ "import/no-unresolved": [
70
+ 2,
71
+ {
72
+ "ignore": [
73
+ "^@vcmap/ui"
74
+ ]
75
+ }
76
+ ]
77
+ }
78
+ },
79
+ "engines": {
80
+ "node": "^16.14.0",
81
+ "npm": "^8.3.0"
53
82
  }
54
83
  }
package/src/build.js CHANGED
@@ -1,32 +1,94 @@
1
- const webpack = require('webpack');
2
- const { logger } = require('@vcsuite/cli-logger');
3
- const { getPluginName } = require('./packageJsonHelpers');
4
- const { getProdWebpackConfig } = require('./getWebpackConfig');
1
+ import path from 'path';
2
+ import fs from 'fs/promises';
3
+ import { createVuePlugin } from 'vite-plugin-vue2';
4
+ import vcsOl from '@vcmap/rollup-plugin-vcs-ol';
5
+ import { logger } from '@vcsuite/cli-logger';
6
+ import { VuetifyResolver } from 'unplugin-vue-components/dist/resolvers.js';
7
+ import Components from 'unplugin-vue-components/dist/vite.js';
8
+ import { getPluginEntry, getPluginName } from './packageJsonHelpers.js';
9
+ import { getContext } from './context.js';
5
10
 
6
- async function build(options) {
7
- function webpackHandler(err, stats) {
8
- if (err) {
9
- logger.error(err);
10
- } else if (stats.hasErrors()) {
11
- logger.error(stats.compilation.errors);
12
- } else {
13
- logger.success(`built ${options.pluginName}`);
14
- }
15
- logger.stopSpinner();
16
- }
11
+ /**
12
+ * @typedef {Object} BuildOptions
13
+ * @property {boolean} [development]
14
+ * @property {boolean} [watch]
15
+ */
17
16
 
18
- options.pluginName = options.pluginName || await getPluginName();
19
- logger.spin(`compiling ${options.pluginName}`);
20
- options.mode = options.development ? 'development' : 'production';
17
+ export function getDefaultConfig() {
18
+ return {
19
+ publicDir: false,
20
+ plugins: [
21
+ createVuePlugin(),
22
+ Components({
23
+ resolvers: [
24
+ VuetifyResolver(),
25
+ ],
26
+ dirs: ['./src'],
27
+ include: [],
28
+ exclude: [],
29
+ }),
30
+ vcsOl(),
31
+ ],
32
+ };
33
+ }
21
34
 
22
- const config = await getProdWebpackConfig(options);
23
- const compiler = webpack(config);
35
+ /**
36
+ * @param {string} pluginName
37
+ * @returns {Object<string, string>}
38
+ */
39
+ export async function getLibraryPaths(pluginName) {
40
+ const { libraries } = await import('@vcmap/ui/build/buildHelpers.js');
41
+ const pluginPath = path.join('plugins', ...pluginName.split('/'));
42
+ const libraryPaths = {};
43
+ Object.entries(libraries).forEach(([library, assetName]) => {
44
+ const assetPath = path.join('assets', `${assetName}.js`);
24
45
 
25
- if (options.watch) {
26
- compiler.watch({}, webpackHandler);
27
- } else {
28
- compiler.run(webpackHandler);
29
- }
46
+ libraryPaths[library] = path.relative(pluginPath, assetPath);
47
+ });
48
+ return libraryPaths;
30
49
  }
31
50
 
32
- module.exports = build;
51
+ /**
52
+ * @param {BuildOptions} options
53
+ * @returns {Promise<void>}
54
+ */
55
+ export default async function buildModule(options) {
56
+ const entry = await getPluginEntry();
57
+ if (path.relative('src', entry).startsWith('.')) {
58
+ logger.warning(`detected irregular entry ${entry}`);
59
+ logger.warning('vuetify component resolution expects source files to be within "src"');
60
+ }
61
+
62
+ const pluginName = await getPluginName();
63
+ const libraryPaths = await getLibraryPaths(pluginName);
64
+ const distPath = path.join(getContext(), 'dist');
65
+ await fs.rm(distPath, { recursive: true, force: true });
66
+ await fs.mkdir(distPath);
67
+ const external = Object.keys(libraryPaths);
68
+ const config = {
69
+ ...getDefaultConfig(),
70
+ esbuild: {
71
+ minify: !options.development,
72
+ },
73
+ build: {
74
+ write: false,
75
+ emptyOutDir: false,
76
+ lib: {
77
+ entry,
78
+ formats: ['es'],
79
+ fileName: () => 'index.js',
80
+ },
81
+ rollupOptions: {
82
+ external,
83
+ output: {
84
+ paths: libraryPaths,
85
+ },
86
+ },
87
+ watch: options.watch ? {
88
+ skipWrite: true,
89
+ } : null,
90
+ },
91
+ };
92
+ const { buildLibrary } = await import('@vcmap/ui/build/buildHelpers.js');
93
+ await buildLibrary(config, '', 'index', '', true);
94
+ }
package/src/context.js CHANGED
@@ -1,9 +1,9 @@
1
- const path = require('path');
2
- const fs = require('fs');
1
+ import path from 'path';
2
+ import fs from 'fs';
3
3
 
4
4
  let context = null;
5
5
 
6
- function setContext(c) {
6
+ export function setContext(c) {
7
7
  if (context) {
8
8
  throw new Error('cannot set context twice');
9
9
  }
@@ -13,17 +13,10 @@ function setContext(c) {
13
13
  context = path.resolve(c);
14
14
  }
15
15
 
16
- function getContext() {
16
+ export function getContext() {
17
17
  return context || process.cwd();
18
18
  }
19
19
 
20
- function resolveContext(...dir) {
20
+ export function resolveContext(...dir) {
21
21
  return path.join(getContext(), ...dir);
22
22
  }
23
-
24
-
25
- module.exports = {
26
- getContext,
27
- resolveContext,
28
- setContext,
29
- };
package/src/create.js CHANGED
@@ -1,12 +1,14 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const prompts = require('prompts');
4
- const semver = require('semver');
5
- const util = require('util');
6
- const childProcess = require('child_process');
7
- const { logger } = require('@vcsuite/cli-logger');
8
- const { version, name } = require('../package.json');
9
- const { LicenseType, writeLicense } = require('./licenses');
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import prompts from 'prompts';
4
+ import semver from 'semver';
5
+ import util from 'util';
6
+ import childProcess from 'child_process';
7
+ import { logger } from '@vcsuite/cli-logger';
8
+ import { LicenseType, writeLicense } from './licenses.js';
9
+ import { getDirname } from './hostingHelpers.js';
10
+
11
+ export const { version, name } = JSON.parse(fs.readFileSync(path.join(getDirname(), '..', 'package.json')).toString());
10
12
 
11
13
  /**
12
14
  * @typedef {Object} PluginTemplateOptions
@@ -15,9 +17,11 @@ const { LicenseType, writeLicense } = require('./licenses');
15
17
  * @property {string} description
16
18
  * @property {Array<Object>} scripts
17
19
  * @property {string} author
20
+ * @property {string} repository
18
21
  * @property {string} license
19
- * @property {string} mapVersion
20
- * @property {boolean} addDevDep
22
+ * @property {string} registry
23
+ * @property {boolean} addCiCd
24
+ * @property {Array<string>} peerDeps
21
25
  */
22
26
 
23
27
  /**
@@ -37,23 +41,49 @@ async function createPluginTemplate(options) {
37
41
  }
38
42
 
39
43
  await fs.promises.mkdir(pluginPath);
44
+ await fs.promises.mkdir(path.join(pluginPath, 'plugin-assets'));
40
45
  logger.debug('created plugin directory');
41
-
42
46
  const packageJson = {
43
47
  name: options.name,
44
48
  version: options.version,
45
49
  description: options.description,
46
50
  main: 'src/index.js',
47
- scripts: Object.assign({}, ...options.scripts),
51
+ scripts: Object.assign({ prepublishOnly: 'vcmplugin build' }, ...options.scripts),
48
52
  author: options.author,
49
53
  license: options.license,
50
- engines: {
51
- vcm: options.mapVersion,
52
- },
53
54
  dependencies: {},
54
- devDependencies: options.addDevDep ? { [name]: `^${version}` } : {},
55
+ keywords: [
56
+ 'vcmap',
57
+ 'plugin',
58
+ ],
59
+ files: [
60
+ 'src/',
61
+ 'dist/',
62
+ 'plugin-assets/',
63
+ 'LICENSE.md',
64
+ 'README.md',
65
+ ],
66
+ exports: {
67
+ '.': './src/index.js',
68
+ './dist': './dist/index.js',
69
+ },
55
70
  };
56
71
 
72
+ if (options.repository) {
73
+ packageJson.repository = {
74
+ url: options.repository,
75
+ };
76
+ }
77
+
78
+ const installEsLint = options.scripts.find(script => script.lint);
79
+ if (installEsLint) {
80
+ packageJson.eslintIgnore = ['node_modules'];
81
+ packageJson.eslintConfig = {
82
+ root: true,
83
+ extends: '@vcsuite/eslint-config/vue',
84
+ };
85
+ }
86
+
57
87
  const writePackagePromise = fs.promises.writeFile(
58
88
  path.join(pluginPath, 'package.json'),
59
89
  JSON.stringify(packageJson, null, 2),
@@ -61,7 +91,6 @@ async function createPluginTemplate(options) {
61
91
 
62
92
  const configJson = {
63
93
  name: options.name,
64
- version: options.version,
65
94
  };
66
95
 
67
96
  const writeConfigPromise = fs.promises.writeFile(
@@ -69,6 +98,11 @@ async function createPluginTemplate(options) {
69
98
  JSON.stringify(configJson, null, 2),
70
99
  );
71
100
 
101
+ const writeNpmrcPromise = fs.promises.writeFile(
102
+ path.join(pluginPath, '.npmrc'),
103
+ `registry=${options.registry}\n`,
104
+ );
105
+
72
106
  const writeReadmePromise = fs.promises.writeFile(
73
107
  path.join(pluginPath, 'README.md'),
74
108
  [
@@ -77,36 +111,47 @@ async function createPluginTemplate(options) {
77
111
  ].join('\n'),
78
112
  );
79
113
 
114
+ const writeChangesPromise = fs.promises.writeFile(
115
+ path.join(pluginPath, 'CHANGES.md'),
116
+ `# v${options.version}\nDocument features and fixes`,
117
+ );
118
+
80
119
  await fs.promises.mkdir(path.join(pluginPath, 'src'));
81
120
  logger.debug('created src directory');
82
121
 
83
- const writeIndexPromise = fs.promises.writeFile(
84
- path.join(pluginPath, 'src', 'index.js'),
85
- ['import { version } from \'../package.json\';',
86
- '',
87
- 'export default {',
88
- ' version,',
89
- ' // preInitialize',
90
- ' // postInitialize',
91
- ' // registerUiPlugin',
92
- ' // postUiInitialize',
93
- '};'].join('\n'),
122
+ const copyTemplatePromise = fs.promises.cp(
123
+ path.join(getDirname(), '..', 'assets', 'helloWorld'),
124
+ pluginPath,
125
+ { recursive: true },
94
126
  );
95
127
 
96
128
  await Promise.all([
97
129
  writePackagePromise,
98
130
  writeConfigPromise,
131
+ writeNpmrcPromise,
99
132
  writeReadmePromise,
100
- writeIndexPromise,
133
+ writeChangesPromise,
134
+ copyTemplatePromise,
101
135
  writeLicense(options.author, options.license, pluginPath),
102
136
  ]);
103
137
 
104
- logger.spin('installing dependencies...');
138
+
139
+ logger.spin('installing dependencies... (this may take a while)');
105
140
  const exec = util.promisify(childProcess.exec);
106
141
  try {
107
- const { stdout, stderr } = await exec('npm i', { cwd: pluginPath });
142
+ options.peerDeps.push('@vcmap/ui');
143
+ const installCmd = `npm i --save-peer ${options.peerDeps.join(' ')}`;
144
+ const { stdout, stderr } = await exec(installCmd, { cwd: pluginPath });
108
145
  logger.log(stdout);
109
146
  logger.error(stderr);
147
+ const devDeps = [`${name}@${version}`];
148
+ if (installEsLint) {
149
+ devDeps.push('@vcsuite/eslint-config');
150
+ }
151
+ const installDevCmd = `npm i --save-dev ${devDeps.join(' ')}`;
152
+ const { stdout: stdoutDev, stderr: stderrDev } = await exec(installDevCmd, { cwd: pluginPath });
153
+ logger.log(stdoutDev);
154
+ logger.error(stderrDev);
110
155
  logger.success('installed dependencies');
111
156
  } catch (e) {
112
157
  logger.error(e);
@@ -119,11 +164,21 @@ async function createPluginTemplate(options) {
119
164
  /**
120
165
  * @returns {Promise<void>}
121
166
  */
122
- async function create() {
167
+ export default async function create() {
123
168
  const scriptChoices = [
124
- { title: 'build', value: { build: 'vcmplugin build' } },
125
- { title: 'pack', value: { pack: 'vcmplugin pack' } },
126
- { title: 'test', value: { test: 'echo "Error: no test specified" && exit 1' } },
169
+ { title: 'build', value: { build: 'vcmplugin build' }, selected: true },
170
+ { title: 'pack', value: { pack: 'vcmplugin pack' }, selected: true },
171
+ { title: 'start', value: { start: 'vcmplugin serve' }, selected: true },
172
+ { title: 'preview', value: { preview: 'vcmplugin preview' }, selected: true },
173
+ { title: 'lint', value: { lint: 'eslint "{src,tests}/**/*.{js,vue}"' }, selected: true },
174
+ ];
175
+
176
+ const peerDependencyChoices = [
177
+ { title: '@vcsuite/ui-components', value: '@vcsuite/ui-components', selected: true },
178
+ { title: '@vcmap/core', value: '@vcmap/core' },
179
+ { title: '@vcmap/cesium', value: '@vcmap/cesium' },
180
+ { title: 'ol', value: 'ol@~6.13.0' },
181
+ { title: '@vue/composition-api', value: '@vue/composition-api@~1.4.5' },
127
182
  ];
128
183
 
129
184
  const questions = [
@@ -168,6 +223,12 @@ async function create() {
168
223
  message: 'Author',
169
224
  initial: 'author <email>',
170
225
  },
226
+ {
227
+ type: 'text',
228
+ name: 'repository',
229
+ message: 'Repository url',
230
+ // initial: (prev, values) => `https://github.com/virtualcitySYSTEMS/${values.name}.git`,
231
+ },
171
232
  {
172
233
  type: 'select',
173
234
  name: 'license',
@@ -181,15 +242,22 @@ async function create() {
181
242
  },
182
243
  {
183
244
  type: 'text',
184
- name: 'mapVersion',
185
- message: 'Map version',
186
- initial: '>=4.0',
245
+ name: 'registry',
246
+ message: 'Set default npm registry',
247
+ initial: 'https://registry.npmjs.org',
248
+ },
249
+ {
250
+ name: 'peerDeps',
251
+ type: 'multiselect',
252
+ message: 'Add the following peer dependencies to the package.json.',
253
+ choices: peerDependencyChoices,
254
+ hint: '- Space to select. Enter to submit',
187
255
  },
188
256
  {
189
257
  type: 'toggle',
190
- name: 'addDevDep',
191
- message: 'Add vcmplugin-cli as dev dependency?',
192
- initial: true,
258
+ name: 'addCiCd',
259
+ message: 'Add default VCS gitlab ci/cd?',
260
+ initial: false,
193
261
  active: 'yes',
194
262
  inactive: 'no',
195
263
  },
@@ -199,5 +267,3 @@ async function create() {
199
267
 
200
268
  await createPluginTemplate(answers);
201
269
  }
202
-
203
- module.exports = create;
@@ -1,25 +1,23 @@
1
- const { Command } = require('commander');
2
- const { logger } = require('@vcsuite/cli-logger');
3
- const { setContext } = require('./context');
1
+ import { Command } from 'commander';
2
+ import { logger } from '@vcsuite/cli-logger';
3
+ import { setContext } from './context.js';
4
4
 
5
5
  Command.prototype.defaultOptions = function defaultOptions() {
6
6
  this
7
- .option('-n, --plugin-name [name]', 'a name override to use. extracts the name from the package.json by default')
8
7
  .option('--context [path]', 'an optional context, default is cwd', (value) => {
9
8
  setContext(value);
10
9
  return value;
11
- })
12
- .option('--no-condense-whitespace', 'do not condense white space')
13
- .option('-e, --entry <entry>', 'entrypoint override');
10
+ });
14
11
 
15
12
  return this;
16
13
  };
17
14
 
18
- Command.prototype.defaultBuildOptions = function defaultBuildOptions() {
15
+ Command.prototype.defaultServeOptions = function defaultServeOptions() {
19
16
  this
20
- .defaultOptions()
21
- .option('-l, --library [name]', 'whether to create a library with [name] or not')
22
- .option('--library-target [target]', 'library target', 'commonjs2');
17
+ .option('-p, --port [port]', 'the port to listen on', /\d+/)
18
+ .option('--auth <user:password>', 'an optional auth to append to proxy requests')
19
+ .option('-c, --config <config>', 'a config override to not use the default plugin config')
20
+ .option('--https', 'use https for serving');
23
21
 
24
22
  return this;
25
23
  };