@vcmap/plugin-cli 2.0.10 → 2.0.12

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/src/create.js CHANGED
@@ -2,14 +2,12 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import prompts from 'prompts';
4
4
  import semver from 'semver';
5
- import util from 'util';
6
- import childProcess from 'child_process';
5
+ import tar from 'tar';
7
6
  import { logger } from '@vcsuite/cli-logger';
8
7
  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());
12
- const exec = util.promisify(childProcess.exec);
8
+ import { DepType, installDeps } from './packageJsonHelpers.js';
9
+ import { updatePeerDependencies } from './update.js';
10
+ import { name, version, promiseExec, getDirname } from './pluginCliHelper.js';
13
11
 
14
12
  /**
15
13
  * @typedef {Object} PluginTemplateOptions
@@ -20,77 +18,120 @@ const exec = util.promisify(childProcess.exec);
20
18
  * @property {string} author
21
19
  * @property {string} repository
22
20
  * @property {string} license
21
+ * @property {string} template
23
22
  * @property {Array<string>} peerDeps
23
+ * @property {boolean} gitlabCi
24
24
  */
25
25
 
26
26
  /**
27
- * @enum {number}
28
- */
29
- const DepType = {
30
- DEP: 1,
31
- PEER: 2,
32
- DEV: 3,
33
- };
34
-
35
- /**
36
- * @param {Array<string>} deps
37
- * @param {DepType} type
27
+ * @param {string} pluginName
38
28
  * @param {string} pluginPath
39
- * @returns {Promise<void>}
29
+ * @param {string[]} filter - files or dirs to be extracted
40
30
  */
41
- async function installDeps(deps, type, pluginPath) {
42
- let save = '--save';
43
- if (type === DepType.PEER) {
44
- save = '--save-peer';
45
- } else if (type === DepType.DEV) {
46
- save = '--save-dev';
31
+ async function downloadAndExtractPluginTar(pluginName, pluginPath, filter = undefined) {
32
+ const logMsg = filter ? filter.join(', ') : pluginName;
33
+ logger.spin(`Downloading and extracting ${logMsg}`);
34
+ const { stdout: packOut, stderr: packErr } = await promiseExec(`npm pack ${pluginName} --quiet`, { cwd: pluginPath });
35
+ logger.error(packErr);
36
+
37
+ const tarName = packOut.trim();
38
+ const tarPath = path.join(pluginPath, tarName);
39
+ const extractOptions = {
40
+ file: tarPath,
41
+ cwd: pluginPath,
42
+ strip: 1,
43
+ };
44
+ if (filter) {
45
+ extractOptions.filter = entryPath => filter.some(f => entryPath.includes(f));
47
46
  }
48
- const installCmd = `npm i ${save} ${deps.join(' ')}`;
49
- const { stdout, stderr } = await exec(installCmd, { cwd: pluginPath });
50
- logger.log(stdout);
51
- logger.error(stderr);
47
+ await tar.x(extractOptions);
48
+ await fs.promises.rm(tarPath);
49
+ logger.success(`Downloaded and extracted template ${logMsg}`);
50
+ logger.stopSpinner();
52
51
  }
53
52
 
54
53
  /**
55
- * @param {Array<string>} deps
54
+ * Copies an existing plugin as template and edits package.json
55
+ * @param {PluginTemplateOptions} options
56
56
  * @param {string} pluginPath
57
57
  * @returns {Promise<void>}
58
58
  */
59
- async function setUiPeerDepVersions(deps, pluginPath) {
60
- const uiPackageJsonContent = await fs.promises.readFile(
61
- path.join(pluginPath, 'node_modules', '@vcmap', 'ui', 'package.json'),
59
+ async function copyPluginTemplate(options, pluginPath) {
60
+ await downloadAndExtractPluginTar(options.template, pluginPath);
61
+
62
+ const pluginPackageJson = JSON.parse((await fs.promises.readFile(path.join(pluginPath, 'package.json'))).toString());
63
+ const userPackageJson = {
64
+ name: options.name,
65
+ version: options.version,
66
+ description: options.description,
67
+ author: options.author,
68
+ license: options.license,
69
+ };
70
+ const packageJson = { ...pluginPackageJson, ...userPackageJson };
71
+ if (options.repository) {
72
+ packageJson.repository = {
73
+ url: options.repository,
74
+ };
75
+ } else {
76
+ delete options.repository;
77
+ }
78
+
79
+ const writePackagePromise = fs.promises.writeFile(
80
+ path.join(pluginPath, 'package.json'),
81
+ JSON.stringify(packageJson, null, 2),
62
82
  );
63
- const uiPackageJson = JSON.parse(uiPackageJsonContent);
64
- deps.forEach((dep, index) => {
65
- if (uiPackageJson.peerDependencies[dep]) {
66
- deps[index] = `${dep}@${uiPackageJson.peerDependencies[dep]}`;
83
+
84
+ const configJson = JSON.parse((await fs.promises.readFile(path.join(pluginPath, 'config.json'))).toString());
85
+ configJson.name = options.name;
86
+
87
+ const writeConfigPromise = fs.promises.writeFile(
88
+ path.join(pluginPath, 'config.json'),
89
+ JSON.stringify(configJson, null, 2),
90
+ );
91
+
92
+ await Promise.all([
93
+ writePackagePromise,
94
+ writeConfigPromise,
95
+ ]);
96
+ logger.debug('created plugin template');
97
+
98
+ try {
99
+ await updatePeerDependencies(packageJson.peerDependencies, pluginPath);
100
+ logger.spin('installing dependencies... (this may take a while)');
101
+ if (packageJson.dependencies) {
102
+ const deps = Object.entries(packageJson.dependencies)
103
+ .map(([depName, depVersion]) => `${depName}@${depVersion}`);
104
+ await installDeps(deps, DepType.DEP, pluginPath);
67
105
  }
68
- });
106
+ await installDeps([`${name}@${version}`], DepType.DEV, pluginPath);
107
+ logger.success('Installed dependencies');
108
+ } catch (e) {
109
+ logger.error(e);
110
+ logger.failure('Failed installing dependencies');
111
+ }
112
+ logger.stopSpinner();
69
113
  }
70
114
 
71
115
  /**
116
+ * Creates a plugin from scratch
72
117
  * @param {PluginTemplateOptions} options
118
+ * @param {string} pluginPath
73
119
  */
74
- async function createPluginTemplate(options) {
75
- if (!options.name) {
76
- logger.error('please provide a plugin name as input parameter');
77
- process.exit(1);
120
+ async function createPluginTemplate(options, pluginPath) {
121
+ const installVitest = options.scripts && options.scripts.find(script => script.test);
122
+ if (!installVitest) {
123
+ options.scripts.push({ test: 'echo "Error: no test specified" && exit 1' });
124
+ } else {
125
+ options.scripts.push(
126
+ { coverage: 'vitest run --coverage' },
127
+ );
78
128
  }
79
- logger.info(`creating new plugin: ${options.name}`);
80
129
 
81
- const pluginPath = path.join(process.cwd(), options.name);
82
- if (fs.existsSync(pluginPath)) {
83
- logger.error('plugin with the provided name already exists');
84
- process.exit(1);
85
- }
86
-
87
- await fs.promises.mkdir(pluginPath);
88
- await fs.promises.mkdir(path.join(pluginPath, 'plugin-assets'));
89
- logger.debug('created plugin directory');
90
130
  const packageJson = {
91
131
  name: options.name,
92
132
  version: options.version,
93
133
  description: options.description,
134
+ type: 'module',
94
135
  main: 'src/index.js',
95
136
  scripts: Object.assign({ prepublishOnly: 'vcmplugin build' }, ...options.scripts),
96
137
  author: options.author,
@@ -142,6 +183,66 @@ async function createPluginTemplate(options) {
142
183
  JSON.stringify(configJson, null, 2),
143
184
  );
144
185
 
186
+ await fs.promises.mkdir(path.join(pluginPath, 'src'));
187
+ logger.debug('created src directory');
188
+
189
+ const copyIndexPromise = fs.promises.copyFile(
190
+ path.join(getDirname(), '..', 'assets', 'index.js'),
191
+ path.join(pluginPath, 'src', 'index.js'),
192
+ );
193
+
194
+ await Promise.all([
195
+ writePackagePromise,
196
+ writeConfigPromise,
197
+ copyIndexPromise,
198
+ ]);
199
+
200
+ if (installVitest) {
201
+ logger.debug('setting up test environment');
202
+ await downloadAndExtractPluginTar('@vcmap/hello-world', pluginPath, ['tests', 'vitest.config.js']);
203
+ }
204
+
205
+ try {
206
+ const peerDependencies = options.peerDeps.reduce((obj, key) => ({ ...obj, [key]: 'latest' }), {});
207
+ await updatePeerDependencies(peerDependencies, pluginPath);
208
+ logger.spin('installing dependencies... (this may take a while)');
209
+ const devDeps = [`${name}@${version}`];
210
+ if (installEsLint) {
211
+ devDeps.push('@vcsuite/eslint-config');
212
+ }
213
+ if (installVitest) {
214
+ devDeps.push('vite', 'vitest', '@vitest/coverage-c8', 'jest-canvas-mock', 'jsdom');
215
+ }
216
+ await installDeps(devDeps, DepType.DEV, pluginPath);
217
+ logger.success('Installed dependencies');
218
+ } catch (e) {
219
+ logger.error(e);
220
+ logger.failure('Failed installing dependencies');
221
+ }
222
+ logger.stopSpinner();
223
+ }
224
+
225
+ /**
226
+ * Creates a new plugin either by copying a template or from scratch
227
+ * @param {PluginTemplateOptions} options
228
+ */
229
+ async function createPlugin(options) {
230
+ if (!options.name) {
231
+ logger.error('please provide a plugin name as input parameter');
232
+ process.exit(1);
233
+ }
234
+ logger.debug(`creating new plugin: ${options.name}`);
235
+
236
+ const pluginPath = path.join(process.cwd(), options.name);
237
+ if (fs.existsSync(pluginPath)) {
238
+ logger.error('plugin with the provided name already exists');
239
+ process.exit(1);
240
+ }
241
+
242
+ await fs.promises.mkdir(pluginPath);
243
+ await fs.promises.mkdir(path.join(pluginPath, 'plugin-assets'));
244
+ logger.debug('created plugin directory');
245
+
145
246
  const writeNpmrcPromise = fs.promises.writeFile(
146
247
  path.join(pluginPath, '.npmrc'),
147
248
  'registry=https://registry.npmjs.org\n',
@@ -160,49 +261,44 @@ async function createPluginTemplate(options) {
160
261
  `# v${options.version}\nDocument features and fixes`,
161
262
  );
162
263
 
163
- await fs.promises.mkdir(path.join(pluginPath, 'src'));
164
- logger.debug('created src directory');
165
-
166
- const copyTemplatePromise = fs.promises.cp(
167
- path.join(getDirname(), '..', 'assets', 'helloWorld'),
168
- pluginPath,
169
- { recursive: true },
264
+ const copyGitIgnorePromise = fs.promises.copyFile(
265
+ path.join(getDirname(), '..', 'assets', 'gitignore'),
266
+ path.join(pluginPath, '.gitignore'),
170
267
  );
171
268
 
172
269
  await Promise.all([
173
- writePackagePromise,
174
- writeConfigPromise,
175
270
  writeNpmrcPromise,
176
271
  writeReadmePromise,
177
272
  writeChangesPromise,
178
- copyTemplatePromise,
179
273
  writeLicense(options.author, options.license, pluginPath),
274
+ copyGitIgnorePromise,
180
275
  ]);
181
276
 
277
+ if (options.gitlabCi) {
278
+ await fs.promises.copyFile(
279
+ path.join(getDirname(), '..', 'assets', '.gitlab-ci.yml'),
280
+ path.join(pluginPath, '.gitlab-ci.yml'),
281
+ );
282
+ }
182
283
 
183
- logger.spin('installing dependencies... (this may take a while)');
184
- try {
185
- await installDeps(['@vcmap/ui'], DepType.PEER, pluginPath);
186
- await setUiPeerDepVersions(options.peerDeps, pluginPath);
187
- await installDeps(options.peerDeps, DepType.PEER, pluginPath);
188
- const devDeps = [`${name}@${version}`];
189
- if (installEsLint) {
190
- devDeps.push('@vcsuite/eslint-config');
191
- }
192
- await installDeps(devDeps, DepType.DEV, pluginPath);
193
- logger.success('installed dependencies');
194
- } catch (e) {
195
- logger.error(e);
196
- logger.failure('installed dependencies');
284
+ if (options.template) {
285
+ await copyPluginTemplate(options, pluginPath);
286
+ } else {
287
+ await createPluginTemplate(options, pluginPath);
197
288
  }
198
- logger.stopSpinner();
199
- logger.success('created plugin');
289
+ logger.success(`Created plugin ${options.name}`);
200
290
  }
201
291
 
202
292
  /**
203
293
  * @returns {Promise<void>}
204
294
  */
205
295
  export default async function create() {
296
+ const templateChoices = [
297
+ { title: 'no template (basic structure)', value: null },
298
+ { title: 'hello-world', value: '@vcmap/hello-world' },
299
+ // to add further templates add a choice here
300
+ ];
301
+
206
302
  const scriptChoices = [
207
303
  { title: 'build', value: { build: 'vcmplugin build' }, selected: true },
208
304
  { title: 'pack', value: { pack: 'vcmplugin pack' }, selected: true },
@@ -210,6 +306,7 @@ export default async function create() {
210
306
  { title: 'preview', value: { preview: 'vcmplugin preview' }, selected: true },
211
307
  { title: 'buildStagingApp', value: { buildStagingApp: 'vcmplugin buildStagingApp' }, selected: true },
212
308
  { title: 'lint', value: { lint: 'eslint "{src,tests}/**/*.{js,vue}"' }, selected: true },
309
+ { title: 'test', value: { test: 'vitest' }, selected: true },
213
310
  ];
214
311
 
215
312
  const peerDependencyChoices = [
@@ -229,7 +326,6 @@ export default async function create() {
229
326
  if (!value) {
230
327
  return false;
231
328
  }
232
-
233
329
  if (fs.existsSync(path.join(process.cwd(), value))) {
234
330
  return `Directory ${value} already exists`;
235
331
  }
@@ -249,13 +345,6 @@ export default async function create() {
249
345
  message: 'Description',
250
346
  initial: '',
251
347
  },
252
- {
253
- type: 'multiselect',
254
- message: 'Add the following scripts to the package.json.',
255
- name: 'scripts',
256
- choices: scriptChoices,
257
- hint: '- Space to select. Enter to submit',
258
- },
259
348
  {
260
349
  type: 'text',
261
350
  name: 'author',
@@ -280,15 +369,37 @@ export default async function create() {
280
369
  })),
281
370
  },
282
371
  {
372
+ type: 'select',
373
+ name: 'template',
374
+ message: 'Choose an existing plugin as template',
375
+ initial: 0,
376
+ choices: templateChoices,
377
+ },
378
+ {
379
+ type: (prev, values) => (!values.template ? 'multiselect' : null),
380
+ message: 'Add the following scripts to the package.json.',
381
+ name: 'scripts',
382
+ choices: scriptChoices,
383
+ hint: '- Space to select. Enter to submit',
384
+ },
385
+ {
386
+ type: (prev, values) => (!values.template ? 'multiselect' : null),
283
387
  name: 'peerDeps',
284
- type: 'multiselect',
285
388
  message: 'Add the following peer dependencies to the package.json.',
286
389
  choices: peerDependencyChoices,
287
390
  hint: '- Space to select. Enter to submit',
288
391
  },
392
+ {
393
+ type: 'toggle',
394
+ name: 'gitlabCi',
395
+ message: 'Add gitlab-ci.yml?',
396
+ initial: false,
397
+ active: 'yes',
398
+ inactive: 'no',
399
+ },
289
400
  ];
290
401
 
291
402
  const answers = await prompts(questions, { onCancel() { process.exit(0); } });
292
403
 
293
- await createPluginTemplate(answers);
404
+ await createPlugin(answers);
294
405
  }
@@ -1,6 +1,4 @@
1
- import { fileURLToPath, URL } from 'url';
2
- import { promisify } from 'util';
3
- import { exec } from 'child_process';
1
+ import { URL } from 'url';
4
2
  import https from 'https';
5
3
  import http from 'http';
6
4
  import fs from 'fs';
@@ -8,6 +6,7 @@ import path from 'path';
8
6
  import { logger } from '@vcsuite/cli-logger';
9
7
  import { getContext, resolveContext } from './context.js';
10
8
  import { getPluginEntry, getPluginName } from './packageJsonHelpers.js';
9
+ import { promiseExec, getDirname } from './pluginCliHelper.js';
11
10
 
12
11
  /**
13
12
  * @typedef {Object} HostingOptions
@@ -17,11 +16,6 @@ import { getPluginEntry, getPluginName } from './packageJsonHelpers.js';
17
16
  * @property {boolean} [https]
18
17
  */
19
18
 
20
- /**
21
- * @type {(arg1: string, opt?: Object) => Promise<string>}
22
- */
23
- const promiseExec = promisify(exec);
24
-
25
19
  /**
26
20
  * @param {...string} pathSegments
27
21
  * @returns {string}
@@ -39,13 +33,6 @@ export function checkReservedDirectories() {
39
33
  });
40
34
  }
41
35
 
42
- /**
43
- * @returns {string}
44
- */
45
- export function getDirname() {
46
- return path.dirname(fileURLToPath(import.meta.url));
47
- }
48
-
49
36
  /**
50
37
  * @param {string} stringUrl
51
38
  * @param {string} auth
@@ -301,10 +288,14 @@ export function addIndexRoute(app, server, production, hostedVcm, auth) {
301
288
  }
302
289
 
303
290
  /**
304
- * @param {string} command
291
+ * @param {string|null} args
292
+ * @param {string} [command='run']
305
293
  * @returns {Promise<string>}
306
294
  */
307
- export function executeUiNpm(command) {
295
+ export function executeUiNpm(args, command = 'run') {
308
296
  const mapUiDir = resolveMapUi();
309
- return promiseExec(`npm run ${command}`, { cwd: mapUiDir });
297
+ if (args) {
298
+ return promiseExec(`npm ${command} ${args}`, { cwd: mapUiDir });
299
+ }
300
+ return promiseExec(`npm ${command}`, { cwd: mapUiDir });
310
301
  }
@@ -1,5 +1,7 @@
1
1
  import fs from 'fs';
2
+ import { logger } from '@vcsuite/cli-logger';
2
3
  import { resolveContext } from './context.js';
4
+ import { promiseExec } from './pluginCliHelper.js';
3
5
 
4
6
  /** @type {Object|null} */
5
7
  let packageJson = null;
@@ -7,7 +9,7 @@ let packageJson = null;
7
9
  /**
8
10
  * @returns {Promise<Object>}
9
11
  */
10
- async function getPackageJson() {
12
+ export async function getPackageJson() {
11
13
  if (!packageJson) {
12
14
  const packageJsonFileName = resolveContext('package.json');
13
15
  if (!fs.existsSync(packageJsonFileName)) {
@@ -46,3 +48,34 @@ export async function getPluginEntry() {
46
48
  return entry;
47
49
  }
48
50
 
51
+ /**
52
+ * @enum {number}
53
+ */
54
+ export const DepType = {
55
+ DEP: 1,
56
+ PEER: 2,
57
+ DEV: 3,
58
+ };
59
+
60
+ /**
61
+ * @param {Array<string>} deps
62
+ * @param {DepType} type
63
+ * @param {string} pluginPath
64
+ * @returns {Promise<void>}
65
+ */
66
+ export async function installDeps(deps, type, pluginPath) {
67
+ if (deps.length < 1) {
68
+ return;
69
+ }
70
+ let save = '--save';
71
+ if (type === DepType.PEER) {
72
+ save = '--save-peer';
73
+ } else if (type === DepType.DEV) {
74
+ save = '--save-dev';
75
+ }
76
+ const installCmd = `npm i ${save} ${deps.join(' ')}`;
77
+ logger.debug(installCmd);
78
+ const { stdout, stderr } = await promiseExec(installCmd, { cwd: pluginPath });
79
+ logger.log(stdout);
80
+ logger.error(stderr);
81
+ }
@@ -0,0 +1,41 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import util from 'util';
4
+ import childProcess from 'child_process';
5
+ import { fileURLToPath, pathToFileURL } from 'url';
6
+ import { logger } from '@vcsuite/cli-logger';
7
+ import { getContext } from './context.js';
8
+
9
+ /**
10
+ * @returns {string}
11
+ */
12
+ export function getDirname() {
13
+ return path.dirname(fileURLToPath(import.meta.url));
14
+ }
15
+
16
+ /**
17
+ * @type {string} version
18
+ * @type {string} name
19
+ */
20
+ export const { version, name } = JSON.parse(fs.readFileSync(path.join(getDirname(), '..', 'package.json')).toString());
21
+
22
+ /**
23
+ * @type {(arg1: string) => Promise<string>}
24
+ */
25
+ export const promiseExec = util.promisify(childProcess.exec);
26
+
27
+ export async function getVcmConfigJs() {
28
+ let vcmConfigJs = {};
29
+ const vcmConfigJsPath = path.resolve(getContext(), 'vcm.config.js');
30
+ if (!fs.existsSync(vcmConfigJsPath)) {
31
+ logger.debug(`${vcmConfigJsPath} not existing!`);
32
+ return vcmConfigJs;
33
+ }
34
+ try {
35
+ vcmConfigJs = await import(pathToFileURL(vcmConfigJsPath));
36
+ logger.info('Using vcm.config.js found in current project.');
37
+ } catch (err) {
38
+ logger.error(err);
39
+ }
40
+ return vcmConfigJs;
41
+ }
package/src/preview.js CHANGED
@@ -10,11 +10,13 @@ import {
10
10
  addPluginAssets,
11
11
  checkReservedDirectories,
12
12
  createConfigJsonReloadPlugin,
13
- printVcmapUiVersion, resolveMapUi,
13
+ printVcmapUiVersion,
14
+ resolveMapUi,
14
15
  } from './hostingHelpers.js';
15
16
  import build, { getDefaultConfig, getLibraryPaths } from './build.js';
16
17
  import { getContext } from './context.js';
17
18
  import setupMapUi from './setupMapUi.js';
19
+ import { getVcmConfigJs } from './pluginCliHelper.js';
18
20
 
19
21
  /**
20
22
  * @typedef {HostingOptions} PreviewOptions
@@ -61,7 +63,7 @@ async function getServerOptions(hostedVcm, https) {
61
63
  alias,
62
64
  },
63
65
  server: {
64
- middlewareMode: 'html',
66
+ middlewareMode: true,
65
67
  proxy,
66
68
  https,
67
69
  },
@@ -73,20 +75,22 @@ async function getServerOptions(hostedVcm, https) {
73
75
  * @returns {Promise<void>}
74
76
  */
75
77
  export default async function preview(options) {
76
- if (!options.vcm) {
78
+ const { default: vcmConfigJs } = await getVcmConfigJs();
79
+ const mergedOptions = { ...vcmConfigJs, ...options };
80
+ if (!mergedOptions.vcm) {
77
81
  await printVcmapUiVersion();
78
82
  }
79
83
  checkReservedDirectories();
80
84
  await build({ development: false, watch: true });
81
85
  const app = express();
82
86
  logger.info('Starting preview server...');
83
- const server = await createServer(await getServerOptions(options.vcm, options.https));
87
+ const server = await createServer(await getServerOptions(mergedOptions.vcm, mergedOptions.https));
84
88
 
85
- addMapConfigRoute(app, options.vcm ? `${options.vcm}/map.config.json` : null, options.auth, options.config, true);
86
- addIndexRoute(app, server, true, options.vcm, options.auth);
89
+ addMapConfigRoute(app, mergedOptions.vcm ? `${mergedOptions.vcm}/map.config.json` : null, mergedOptions.auth, mergedOptions.config, true);
90
+ addIndexRoute(app, server, true, mergedOptions.vcm, mergedOptions.auth);
87
91
  addPluginAssets(app, 'dist');
88
92
 
89
- if (!options.vcm) {
93
+ if (!mergedOptions.vcm) {
90
94
  logger.spin('compiling preview');
91
95
  if (!fs.existsSync(resolveMapUi('plugins', 'node_modules'))) {
92
96
  logger.info('Could not detect node_modules in map ui plugins. Assuming map UI not setup');
@@ -98,12 +102,12 @@ export default async function preview(options) {
98
102
  logger.info('@vcmap/ui built for preview');
99
103
  app.use('/assets', express.static(path.join(getContext(), 'node_modules', '@vcmap', 'ui', 'dist', 'assets')));
100
104
  app.use('/plugins', express.static(path.join(getContext(), 'dist', 'plugins')));
101
- await addConfigRoute(app, options.auth, options.config, true);
105
+ await addConfigRoute(app, mergedOptions.auth, mergedOptions.config, true);
102
106
  }
103
107
 
104
108
  app.use(server.middlewares);
105
109
 
106
- const port = options.port || 5005;
110
+ const port = mergedOptions.port || 5005;
107
111
  await app.listen(port);
108
112
  logger.info(`Server running on port ${port}`);
109
113
  }