@vcmap/plugin-cli 2.1.4 → 2.1.6
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 +115 -74
- package/assets/.gitlab-ci.yml +2 -2
- package/assets/index.html +29 -29
- package/assets/index.js +15 -4
- package/cli.js +13 -24
- package/index.js +0 -1
- package/package.json +9 -5
- package/src/build.js +11 -9
- package/src/buildStagingApp.js +32 -9
- package/src/create.js +82 -45
- package/src/defaultCommand.js +15 -7
- package/src/hostingHelpers.js +101 -64
- package/src/pack.js +11 -4
- package/src/pluginCliHelper.js +11 -1
- package/src/preview.js +42 -13
- package/src/serve.js +41 -30
- package/src/update.js +5 -2
package/src/hostingHelpers.js
CHANGED
|
@@ -10,7 +10,7 @@ import { promiseExec, getDirname } from './pluginCliHelper.js';
|
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @typedef {Object} HostingOptions
|
|
13
|
-
* @property {string} [config] - an optional fileName to use for configuring the plugin
|
|
13
|
+
* @property {string|Object} [config] - an optional configObject or fileName to use for configuring the plugin
|
|
14
14
|
* @property {string} [auth] - potential auth string to download assets (index.html, config) with
|
|
15
15
|
* @property {number} [port]
|
|
16
16
|
* @property {boolean} [https]
|
|
@@ -21,16 +21,23 @@ import { promiseExec, getDirname } from './pluginCliHelper.js';
|
|
|
21
21
|
* @returns {string}
|
|
22
22
|
*/
|
|
23
23
|
export function resolveMapUi(...pathSegments) {
|
|
24
|
-
return path.join(
|
|
24
|
+
return path.join(
|
|
25
|
+
getContext(),
|
|
26
|
+
'node_modules',
|
|
27
|
+
'@vcmap',
|
|
28
|
+
'ui',
|
|
29
|
+
...pathSegments,
|
|
30
|
+
);
|
|
25
31
|
}
|
|
26
32
|
|
|
27
33
|
export function checkReservedDirectories() {
|
|
28
|
-
['assets', 'plugins', 'config']
|
|
29
|
-
.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
+
['assets', 'plugins', 'config'].forEach((dir) => {
|
|
35
|
+
if (fs.existsSync(path.join(getContext(), dir))) {
|
|
36
|
+
logger.warning(
|
|
37
|
+
`found reserved directory ${dir}. serving my not work as exptected`,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
34
41
|
}
|
|
35
42
|
|
|
36
43
|
/**
|
|
@@ -47,7 +54,9 @@ export function httpGet(stringUrl, auth, handler) {
|
|
|
47
54
|
};
|
|
48
55
|
|
|
49
56
|
if (auth) {
|
|
50
|
-
options.headers = {
|
|
57
|
+
options.headers = {
|
|
58
|
+
Authorization: `Basic ${Buffer.from(auth).toString('base64')}`,
|
|
59
|
+
};
|
|
51
60
|
}
|
|
52
61
|
if (url.protocol === 'https:') {
|
|
53
62
|
https.get(options, handler);
|
|
@@ -57,11 +66,11 @@ export function httpGet(stringUrl, auth, handler) {
|
|
|
57
66
|
}
|
|
58
67
|
|
|
59
68
|
/**
|
|
60
|
-
* @param {string} fileName
|
|
69
|
+
* @param {string|undefined} fileName
|
|
61
70
|
* @returns {Promise<Object>}
|
|
62
71
|
*/
|
|
63
72
|
export async function readConfigJson(fileName) {
|
|
64
|
-
const configFileName = fileName
|
|
73
|
+
const configFileName = fileName ?? resolveContext('config.json');
|
|
65
74
|
let config = {};
|
|
66
75
|
if (fs.existsSync(configFileName)) {
|
|
67
76
|
const content = await fs.promises.readFile(configFileName);
|
|
@@ -71,6 +80,18 @@ export async function readConfigJson(fileName) {
|
|
|
71
80
|
return config;
|
|
72
81
|
}
|
|
73
82
|
|
|
83
|
+
/**
|
|
84
|
+
* @param {string|undefined} pluginConfig
|
|
85
|
+
* @returns {Promise<Object>}
|
|
86
|
+
*/
|
|
87
|
+
export async function getPluginConfig(pluginConfig) {
|
|
88
|
+
const isObject = typeof pluginConfig === 'object' && pluginConfig !== null;
|
|
89
|
+
if (isObject) {
|
|
90
|
+
return pluginConfig;
|
|
91
|
+
}
|
|
92
|
+
return readConfigJson(pluginConfig);
|
|
93
|
+
}
|
|
94
|
+
|
|
74
95
|
const configMap = new Map();
|
|
75
96
|
|
|
76
97
|
/**
|
|
@@ -79,7 +100,9 @@ const configMap = new Map();
|
|
|
79
100
|
export async function printVcmapUiVersion() {
|
|
80
101
|
const packageJsonPath = resolveMapUi('package.json');
|
|
81
102
|
if (!fs.existsSync(packageJsonPath)) {
|
|
82
|
-
throw new Error(
|
|
103
|
+
throw new Error(
|
|
104
|
+
`Cannot find the @vcmap/ui package in ${getContext()}. Are you sure you installed it?`,
|
|
105
|
+
);
|
|
83
106
|
}
|
|
84
107
|
|
|
85
108
|
const content = await fs.promises.readFile(packageJsonPath);
|
|
@@ -88,37 +111,51 @@ export async function printVcmapUiVersion() {
|
|
|
88
111
|
}
|
|
89
112
|
|
|
90
113
|
/**
|
|
91
|
-
*
|
|
114
|
+
* Deletes plugin from other inline configs and adds a temporary config containing the pluginConfig
|
|
115
|
+
* @param {Object} appConfig
|
|
92
116
|
* @param {Object} pluginConfig
|
|
93
117
|
* @param {boolean} production
|
|
94
118
|
* @returns {Promise<void>}
|
|
95
119
|
*/
|
|
96
|
-
export async function
|
|
97
|
-
|
|
120
|
+
export async function reWriteAppConfig(appConfig, pluginConfig, production) {
|
|
121
|
+
const name = await getPluginName();
|
|
122
|
+
pluginConfig.name = name;
|
|
98
123
|
pluginConfig.entry = production ? 'dist/index.js' : await getPluginEntry();
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
124
|
+
appConfig.modules = appConfig.modules ?? [];
|
|
125
|
+
appConfig.modules.forEach((config) => {
|
|
126
|
+
if (Array.isArray(config.plugins)) {
|
|
127
|
+
config.plugins = config.plugins.filter((p) => p.name !== name);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
appConfig.modules.push({ plugins: [pluginConfig] });
|
|
106
131
|
}
|
|
107
132
|
|
|
108
133
|
/**
|
|
109
|
-
* @param {string} [
|
|
134
|
+
* @param {string} [appConfig] - fs or https to config. defaults to @vcmap/ui/app.config.json
|
|
110
135
|
* @param {string} [auth]
|
|
111
136
|
* @param {boolean} [production]
|
|
112
137
|
* @param {string} [configFile]
|
|
113
138
|
* @returns {Promise<unknown>}
|
|
114
139
|
*/
|
|
115
|
-
export function
|
|
116
|
-
const usedConfig =
|
|
117
|
-
if (configMap.has('
|
|
118
|
-
return Promise.resolve(configMap.get('
|
|
140
|
+
export function getAppConfigJson(appConfig, auth, production, configFile) {
|
|
141
|
+
const usedConfig = appConfig || resolveMapUi('app.config.json');
|
|
142
|
+
if (configMap.has('app.config.json')) {
|
|
143
|
+
return Promise.resolve(configMap.get('app.config.json'));
|
|
119
144
|
}
|
|
120
|
-
const
|
|
145
|
+
const isObject = typeof appConfig === 'object' && appConfig !== null;
|
|
146
|
+
const isWebVcm = !isObject && /^https?:\/\//.test(usedConfig);
|
|
121
147
|
return new Promise((resolve, reject) => {
|
|
148
|
+
async function handleAppConfig(data) {
|
|
149
|
+
try {
|
|
150
|
+
const appConfigJson = JSON.parse(data);
|
|
151
|
+
configMap.set('app.config.json', appConfigJson);
|
|
152
|
+
const pluginConfig = await getPluginConfig(configFile);
|
|
153
|
+
await reWriteAppConfig(appConfigJson, pluginConfig, production);
|
|
154
|
+
resolve(appConfigJson);
|
|
155
|
+
} catch (e) {
|
|
156
|
+
reject(e);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
122
159
|
function handleStream(stream) {
|
|
123
160
|
let data = '';
|
|
124
161
|
stream.on('data', (chunk) => {
|
|
@@ -126,18 +163,12 @@ export function getConfigJson(mapConfig, auth, production, configFile) {
|
|
|
126
163
|
});
|
|
127
164
|
|
|
128
165
|
stream.on('close', async () => {
|
|
129
|
-
|
|
130
|
-
const configJson = JSON.parse(data);
|
|
131
|
-
configMap.set('map.config.json', configJson);
|
|
132
|
-
const pluginConfig = await readConfigJson(configFile);
|
|
133
|
-
await reWriteConfig(configJson, pluginConfig, production);
|
|
134
|
-
resolve(configJson);
|
|
135
|
-
} catch (e) {
|
|
136
|
-
reject(e);
|
|
137
|
-
}
|
|
166
|
+
await handleAppConfig(data);
|
|
138
167
|
});
|
|
139
168
|
}
|
|
140
|
-
if (
|
|
169
|
+
if (isObject) {
|
|
170
|
+
handleAppConfig(JSON.stringify(appConfig));
|
|
171
|
+
} else if (isWebVcm) {
|
|
141
172
|
httpGet(usedConfig, auth, (res) => {
|
|
142
173
|
if (res.statusCode < 400) {
|
|
143
174
|
handleStream(res);
|
|
@@ -188,32 +219,35 @@ export function createConfigJsonReloadPlugin() {
|
|
|
188
219
|
|
|
189
220
|
/**
|
|
190
221
|
* @param {Express} app
|
|
191
|
-
* @param {string}
|
|
222
|
+
* @param {string} appConfig
|
|
192
223
|
* @param {string} [auth]
|
|
193
224
|
* @param {string} [configFile]
|
|
194
225
|
* @param {boolean} [production]
|
|
195
226
|
*/
|
|
196
|
-
export function
|
|
197
|
-
app
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
227
|
+
export function addAppConfigRoute(
|
|
228
|
+
app,
|
|
229
|
+
appConfig,
|
|
230
|
+
auth,
|
|
231
|
+
configFile,
|
|
232
|
+
production,
|
|
233
|
+
) {
|
|
234
|
+
app.get('/app.config.json', (req, res) => {
|
|
235
|
+
getAppConfigJson(appConfig, auth, production, configFile).then((config) => {
|
|
236
|
+
const stringConfig = JSON.stringify(config, null, 2);
|
|
237
|
+
res.setHeader('Content-Type', 'application/json');
|
|
238
|
+
res.write(stringConfig);
|
|
239
|
+
res.end();
|
|
240
|
+
});
|
|
205
241
|
});
|
|
206
242
|
}
|
|
207
243
|
|
|
208
244
|
/**
|
|
209
245
|
* @param {Express} app
|
|
210
|
-
* @param {string} [auth]
|
|
211
|
-
* @param {string} [configFileName]
|
|
212
|
-
* @param {boolean} [production]
|
|
213
246
|
*/
|
|
214
|
-
export async function addConfigRoute(app
|
|
247
|
+
export async function addConfigRoute(app) {
|
|
248
|
+
// IDEA pass in available plugins and strip unavailable ones?
|
|
215
249
|
const mapUiDir = resolveMapUi();
|
|
216
|
-
const
|
|
250
|
+
const pluginName = await getPluginName();
|
|
217
251
|
|
|
218
252
|
app.get('/config*', async (req, res) => {
|
|
219
253
|
const { url } = req;
|
|
@@ -226,7 +260,9 @@ export async function addConfigRoute(app, auth, configFileName, production) { //
|
|
|
226
260
|
const configContent = await fs.promises.readFile(fileName);
|
|
227
261
|
const config = JSON.parse(configContent);
|
|
228
262
|
configMap.set(url, config);
|
|
229
|
-
|
|
263
|
+
if (Array.isArray(config.plugins)) {
|
|
264
|
+
config.plugins = config.plugins.filter((p) => p.name !== pluginName);
|
|
265
|
+
}
|
|
230
266
|
response = JSON.stringify(config);
|
|
231
267
|
} catch (e) {
|
|
232
268
|
configMap.delete(url);
|
|
@@ -249,9 +285,9 @@ export async function addConfigRoute(app, auth, configFileName, production) { //
|
|
|
249
285
|
* @returns {Promise<string>}
|
|
250
286
|
*/
|
|
251
287
|
export async function getMapUiIndexHtml(production) {
|
|
252
|
-
const indexHtmlFileName = production
|
|
253
|
-
resolveMapUi('dist', 'index.html')
|
|
254
|
-
path.join(getDirname(), '..', 'assets', 'index.html');
|
|
288
|
+
const indexHtmlFileName = production
|
|
289
|
+
? resolveMapUi('dist', 'index.html')
|
|
290
|
+
: path.join(getDirname(), '..', 'assets', 'index.html');
|
|
255
291
|
const buffer = await fs.promises.readFile(indexHtmlFileName);
|
|
256
292
|
return buffer.toString();
|
|
257
293
|
}
|
|
@@ -275,15 +311,16 @@ export function addPluginAssets(app, base) {
|
|
|
275
311
|
*/
|
|
276
312
|
export function addIndexRoute(app, server, production, hostedVcm, auth) {
|
|
277
313
|
app.get('/', async (req, res) => {
|
|
278
|
-
let originalIndex = hostedVcm
|
|
279
|
-
await getIndexHtml(`${hostedVcm}/`, auth)
|
|
280
|
-
await getMapUiIndexHtml(production); // TODO change hosted vcm index via option?
|
|
314
|
+
let originalIndex = hostedVcm
|
|
315
|
+
? await getIndexHtml(`${hostedVcm}/`, auth)
|
|
316
|
+
: await getMapUiIndexHtml(production); // TODO change hosted vcm index via option?
|
|
281
317
|
|
|
282
|
-
originalIndex = await server.transformIndexHtml(
|
|
318
|
+
originalIndex = await server.transformIndexHtml(
|
|
319
|
+
'/index.html',
|
|
320
|
+
originalIndex,
|
|
321
|
+
);
|
|
283
322
|
|
|
284
|
-
res.status(200)
|
|
285
|
-
.set({ 'Content-Type': 'text/html' })
|
|
286
|
-
.end(originalIndex);
|
|
323
|
+
res.status(200).set({ 'Content-Type': 'text/html' }).end(originalIndex);
|
|
287
324
|
});
|
|
288
325
|
}
|
|
289
326
|
|
package/src/pack.js
CHANGED
|
@@ -5,7 +5,6 @@ import { getPluginName } from './packageJsonHelpers.js';
|
|
|
5
5
|
import { resolveContext } from './context.js';
|
|
6
6
|
import build from './build.js';
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
/**
|
|
10
9
|
* @returns {Promise<void>}
|
|
11
10
|
*/
|
|
@@ -29,7 +28,10 @@ async function ensureConfigJson() {
|
|
|
29
28
|
}
|
|
30
29
|
}
|
|
31
30
|
}
|
|
32
|
-
await fs.promises.writeFile(
|
|
31
|
+
await fs.promises.writeFile(
|
|
32
|
+
resolveContext('dist', 'config.json'),
|
|
33
|
+
JSON.stringify(config, null, 2),
|
|
34
|
+
);
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
/**
|
|
@@ -38,7 +40,9 @@ async function ensureConfigJson() {
|
|
|
38
40
|
*/
|
|
39
41
|
function zip(name) {
|
|
40
42
|
return new Promise((resolve, reject) => {
|
|
41
|
-
const zipStream = fs.createWriteStream(
|
|
43
|
+
const zipStream = fs.createWriteStream(
|
|
44
|
+
resolveContext('dist', `${name.replace(/\//, '-')}.zip`),
|
|
45
|
+
);
|
|
42
46
|
const archive = archiver('zip', { zlib: { level: 5 } });
|
|
43
47
|
|
|
44
48
|
zipStream.on('close', () => {
|
|
@@ -67,7 +71,10 @@ function zip(name) {
|
|
|
67
71
|
});
|
|
68
72
|
|
|
69
73
|
if (fs.existsSync(resolveContext('plugin-assets'))) {
|
|
70
|
-
archive.directory(
|
|
74
|
+
archive.directory(
|
|
75
|
+
resolveContext('plugin-assets'),
|
|
76
|
+
`${name}/plugin-assets`,
|
|
77
|
+
);
|
|
71
78
|
}
|
|
72
79
|
|
|
73
80
|
archive.finalize().then(() => {
|
package/src/pluginCliHelper.js
CHANGED
|
@@ -17,13 +17,23 @@ 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 } = JSON.parse(
|
|
21
|
+
fs.readFileSync(path.join(getDirname(), '..', 'package.json')).toString(),
|
|
22
|
+
);
|
|
21
23
|
|
|
22
24
|
/**
|
|
23
25
|
* @type {(arg1: string) => Promise<string>}
|
|
24
26
|
*/
|
|
25
27
|
export const promiseExec = util.promisify(childProcess.exec);
|
|
26
28
|
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {ServeOptions} VcmConfigJs
|
|
31
|
+
* @property {Object} proxy - see https://vitejs.dev/config/server-options.html#server-proxy
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @returns {Promise<VcmConfigJs>}
|
|
36
|
+
*/
|
|
27
37
|
export async function getVcmConfigJs() {
|
|
28
38
|
let vcmConfigJs = {};
|
|
29
39
|
const vcmConfigJsPath = path.resolve(getContext(), 'vcm.config.js');
|
package/src/preview.js
CHANGED
|
@@ -6,14 +6,18 @@ import { logger } from '@vcsuite/cli-logger';
|
|
|
6
6
|
import {
|
|
7
7
|
addConfigRoute,
|
|
8
8
|
addIndexRoute,
|
|
9
|
-
|
|
9
|
+
addAppConfigRoute,
|
|
10
10
|
addPluginAssets,
|
|
11
11
|
checkReservedDirectories,
|
|
12
12
|
createConfigJsonReloadPlugin,
|
|
13
13
|
printVcmapUiVersion,
|
|
14
14
|
resolveMapUi,
|
|
15
15
|
} from './hostingHelpers.js';
|
|
16
|
-
import build, {
|
|
16
|
+
import build, {
|
|
17
|
+
buildMapUI,
|
|
18
|
+
getDefaultConfig,
|
|
19
|
+
getLibraryPaths,
|
|
20
|
+
} from './build.js';
|
|
17
21
|
import { getContext } from './context.js';
|
|
18
22
|
import setupMapUi from './setupMapUi.js';
|
|
19
23
|
import { getVcmConfigJs } from './pluginCliHelper.js';
|
|
@@ -58,9 +62,7 @@ async function getServerOptions(hostedVcm, https) {
|
|
|
58
62
|
|
|
59
63
|
return {
|
|
60
64
|
publicDir: false,
|
|
61
|
-
plugins: [
|
|
62
|
-
createConfigJsonReloadPlugin(),
|
|
63
|
-
],
|
|
65
|
+
plugins: [createConfigJsonReloadPlugin()],
|
|
64
66
|
resolve: {
|
|
65
67
|
alias,
|
|
66
68
|
},
|
|
@@ -77,7 +79,7 @@ async function getServerOptions(hostedVcm, https) {
|
|
|
77
79
|
* @returns {Promise<void>}
|
|
78
80
|
*/
|
|
79
81
|
export default async function preview(options) {
|
|
80
|
-
const
|
|
82
|
+
const vcmConfigJs = await getVcmConfigJs();
|
|
81
83
|
const mergedOptions = { ...vcmConfigJs, ...options };
|
|
82
84
|
if (!mergedOptions.vcm) {
|
|
83
85
|
await printVcmapUiVersion();
|
|
@@ -90,25 +92,52 @@ export default async function preview(options) {
|
|
|
90
92
|
await build({ development: false, watch: true });
|
|
91
93
|
const app = express();
|
|
92
94
|
logger.info('Starting preview server...');
|
|
93
|
-
const server = await createServer(
|
|
95
|
+
const server = await createServer(
|
|
96
|
+
await getServerOptions(mergedOptions.vcm, mergedOptions.https),
|
|
97
|
+
);
|
|
94
98
|
|
|
95
|
-
|
|
99
|
+
addAppConfigRoute(
|
|
100
|
+
app,
|
|
101
|
+
mergedOptions.vcm ? `${mergedOptions.vcm}/app.config.json` : null,
|
|
102
|
+
mergedOptions.auth,
|
|
103
|
+
mergedOptions.config,
|
|
104
|
+
true,
|
|
105
|
+
);
|
|
96
106
|
addIndexRoute(app, server, true, mergedOptions.vcm, mergedOptions.auth);
|
|
97
107
|
addPluginAssets(app, 'dist');
|
|
98
108
|
|
|
99
109
|
if (!mergedOptions.vcm) {
|
|
100
110
|
logger.spin('compiling preview');
|
|
101
111
|
if (!fs.existsSync(resolveMapUi('plugins', 'node_modules'))) {
|
|
102
|
-
logger.info(
|
|
112
|
+
logger.info(
|
|
113
|
+
'Could not detect node_modules in map ui plugins. Assuming map UI not setup',
|
|
114
|
+
);
|
|
103
115
|
await setupMapUi();
|
|
104
116
|
}
|
|
105
|
-
const { buildPluginsForPreview } = await import(
|
|
117
|
+
const { buildPluginsForPreview } = await import(
|
|
118
|
+
'@vcmap/ui/build/buildHelpers.js'
|
|
119
|
+
);
|
|
106
120
|
await buildPluginsForPreview(getDefaultConfig(), true);
|
|
107
121
|
logger.stopSpinner();
|
|
108
122
|
logger.info('@vcmap/ui built for preview');
|
|
109
|
-
app.use(
|
|
110
|
-
|
|
111
|
-
|
|
123
|
+
app.use(
|
|
124
|
+
'/assets',
|
|
125
|
+
express.static(
|
|
126
|
+
path.join(
|
|
127
|
+
getContext(),
|
|
128
|
+
'node_modules',
|
|
129
|
+
'@vcmap',
|
|
130
|
+
'ui',
|
|
131
|
+
'dist',
|
|
132
|
+
'assets',
|
|
133
|
+
),
|
|
134
|
+
),
|
|
135
|
+
);
|
|
136
|
+
app.use(
|
|
137
|
+
'/plugins',
|
|
138
|
+
express.static(path.join(getContext(), 'dist', 'plugins')),
|
|
139
|
+
);
|
|
140
|
+
await addConfigRoute(app);
|
|
112
141
|
}
|
|
113
142
|
|
|
114
143
|
app.use(server.middlewares);
|
package/src/serve.js
CHANGED
|
@@ -8,24 +8,29 @@ import { getContext } from './context.js';
|
|
|
8
8
|
import {
|
|
9
9
|
addConfigRoute,
|
|
10
10
|
addIndexRoute,
|
|
11
|
-
|
|
11
|
+
addAppConfigRoute,
|
|
12
|
+
addPluginAssets,
|
|
12
13
|
checkReservedDirectories,
|
|
13
14
|
createConfigJsonReloadPlugin,
|
|
14
15
|
printVcmapUiVersion,
|
|
15
16
|
resolveMapUi,
|
|
16
17
|
} from './hostingHelpers.js';
|
|
17
|
-
import { getPluginName } from './packageJsonHelpers.js';
|
|
18
|
+
import { getPackageJson, getPluginName } from './packageJsonHelpers.js';
|
|
18
19
|
import { getVcmConfigJs } from './pluginCliHelper.js';
|
|
19
20
|
import { buildMapUI } from './build.js';
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* @typedef {HostingOptions} ServeOptions
|
|
23
|
-
* @property {string} [
|
|
24
|
+
* @property {string|Object} [appConfig] - an optional configObject resp. fileName or URL to an app config
|
|
24
25
|
*/
|
|
25
26
|
|
|
26
27
|
async function getProxy(protocol, port) {
|
|
27
|
-
const { default: getPluginProxies } = await import(
|
|
28
|
-
|
|
28
|
+
const { default: getPluginProxies } = await import(
|
|
29
|
+
'@vcmap/ui/build/getPluginProxies.js'
|
|
30
|
+
);
|
|
31
|
+
const { determineHostIpFromInterfaces } = await import(
|
|
32
|
+
'@vcmap/ui/build/determineHost.js'
|
|
33
|
+
);
|
|
29
34
|
const { getInlinePlugins } = await import('@vcmap/ui/build/buildHelpers.js');
|
|
30
35
|
|
|
31
36
|
const target = `${protocol}://${determineHostIpFromInterfaces()}:${port}`;
|
|
@@ -36,16 +41,25 @@ async function getProxy(protocol, port) {
|
|
|
36
41
|
proxy[`^/plugins/${inlinePlugin}/.*`] = {
|
|
37
42
|
target,
|
|
38
43
|
rewrite: (route) => {
|
|
39
|
-
const rest = route.replace(
|
|
44
|
+
const rest = route.replace(
|
|
45
|
+
new RegExp(`^/plugins/${inlinePlugin}/`),
|
|
46
|
+
'',
|
|
47
|
+
);
|
|
40
48
|
const file = rest || 'index.js';
|
|
41
|
-
return path.posix.join(
|
|
49
|
+
return path.posix.join(
|
|
50
|
+
path.relative(getContext(), mapUiPlugins),
|
|
51
|
+
inlinePlugin,
|
|
52
|
+
file,
|
|
53
|
+
);
|
|
42
54
|
},
|
|
43
55
|
};
|
|
44
56
|
});
|
|
45
57
|
|
|
46
58
|
const pluginRoutes = Object.keys(proxy);
|
|
47
59
|
const name = await getPluginName();
|
|
48
|
-
const hasThisPlugin = pluginRoutes.find(p =>
|
|
60
|
+
const hasThisPlugin = pluginRoutes.find((p) =>
|
|
61
|
+
p.startsWith(`^/plugins/${name}`),
|
|
62
|
+
);
|
|
49
63
|
|
|
50
64
|
if (hasThisPlugin) {
|
|
51
65
|
delete proxy[hasThisPlugin];
|
|
@@ -60,7 +74,7 @@ async function getProxy(protocol, port) {
|
|
|
60
74
|
// Cesium engine assets are not part of Build
|
|
61
75
|
proxy['/node_modules/@vcmap-cesium/engine/Build/Assets'] = {
|
|
62
76
|
target,
|
|
63
|
-
rewrite: p => p.replace(/Build/, 'Source'),
|
|
77
|
+
rewrite: (p) => p.replace(/Build/, 'Source'),
|
|
64
78
|
};
|
|
65
79
|
return proxy;
|
|
66
80
|
}
|
|
@@ -71,10 +85,12 @@ async function getProxy(protocol, port) {
|
|
|
71
85
|
*/
|
|
72
86
|
export default async function serve(options) {
|
|
73
87
|
if (!fs.existsSync(path.join(getContext(), 'node_modules', '@vcmap', 'ui'))) {
|
|
74
|
-
logger.error(
|
|
88
|
+
logger.error(
|
|
89
|
+
'Can only serve in dev mode, if the map ui is a dependency of the current context',
|
|
90
|
+
);
|
|
75
91
|
return;
|
|
76
92
|
}
|
|
77
|
-
const
|
|
93
|
+
const vcmConfigJs = await getVcmConfigJs();
|
|
78
94
|
const mergedOptions = { ...vcmConfigJs, ...options };
|
|
79
95
|
await printVcmapUiVersion();
|
|
80
96
|
// In case @vcmap/ui is linked via git+ssh, dist folder is not available and must be built first
|
|
@@ -87,6 +103,7 @@ export default async function serve(options) {
|
|
|
87
103
|
|
|
88
104
|
logger.info('Starting development server...');
|
|
89
105
|
const proxy = await getProxy(mergedOptions.https ? 'https' : 'http', port);
|
|
106
|
+
const { peerDependencies } = await getPackageJson();
|
|
90
107
|
|
|
91
108
|
const server = await createServer({
|
|
92
109
|
root: getContext(),
|
|
@@ -95,25 +112,13 @@ export default async function serve(options) {
|
|
|
95
112
|
alias: {
|
|
96
113
|
'@cesium/engine': '@vcmap-cesium/engine',
|
|
97
114
|
},
|
|
115
|
+
dedupe: Object.keys(peerDependencies),
|
|
98
116
|
},
|
|
99
117
|
optimizeDeps: {
|
|
100
|
-
exclude: [
|
|
101
|
-
|
|
102
|
-
'@vcmap/core',
|
|
103
|
-
'ol',
|
|
104
|
-
'proj4',
|
|
105
|
-
],
|
|
106
|
-
include: [
|
|
107
|
-
'fast-deep-equal',
|
|
108
|
-
'rbush-knn',
|
|
109
|
-
'pbf',
|
|
110
|
-
'@vcmap-cesium/engine',
|
|
111
|
-
],
|
|
118
|
+
exclude: ['@vcmap/ui', '@vcmap/core', 'ol', 'proj4'],
|
|
119
|
+
include: ['fast-deep-equal', 'rbush-knn', 'pbf', '@vcmap-cesium/engine'],
|
|
112
120
|
},
|
|
113
|
-
plugins: [
|
|
114
|
-
createVuePlugin(),
|
|
115
|
-
createConfigJsonReloadPlugin(),
|
|
116
|
-
],
|
|
121
|
+
plugins: [createVuePlugin(), createConfigJsonReloadPlugin()],
|
|
117
122
|
server: {
|
|
118
123
|
middlewareMode: true,
|
|
119
124
|
https: mergedOptions.https,
|
|
@@ -122,16 +127,22 @@ export default async function serve(options) {
|
|
|
122
127
|
css: {
|
|
123
128
|
preprocessorOptions: {
|
|
124
129
|
sass: {
|
|
125
|
-
additionalData:
|
|
130
|
+
additionalData:
|
|
131
|
+
"\n@import './node_modules/@vcmap/ui/src/styles/variables.scss'\n",
|
|
126
132
|
},
|
|
127
133
|
},
|
|
128
134
|
},
|
|
129
135
|
});
|
|
130
136
|
|
|
131
|
-
|
|
137
|
+
addAppConfigRoute(
|
|
138
|
+
app,
|
|
139
|
+
mergedOptions.appConfig,
|
|
140
|
+
mergedOptions.auth,
|
|
141
|
+
mergedOptions.config,
|
|
142
|
+
);
|
|
132
143
|
addIndexRoute(app, server);
|
|
133
144
|
addPluginAssets(app, 'src');
|
|
134
|
-
await addConfigRoute(app
|
|
145
|
+
await addConfigRoute(app);
|
|
135
146
|
|
|
136
147
|
app.use(server.middlewares);
|
|
137
148
|
|
package/src/update.js
CHANGED
|
@@ -15,8 +15,11 @@ export async function updatePeerDependencies(pluginPeer, pluginPath) {
|
|
|
15
15
|
const peerDeps = [`${mapName}@latest`]; // @vcmap/ui is a required peer dep and will be updated in any case
|
|
16
16
|
if (pluginPeer) {
|
|
17
17
|
const pluginPeerDeps = Object.keys(pluginPeer)
|
|
18
|
-
.filter(
|
|
19
|
-
|
|
18
|
+
.filter(
|
|
19
|
+
(depName) =>
|
|
20
|
+
!!mapPeer[depName] && pluginPeer[depName] !== mapPeer[depName],
|
|
21
|
+
)
|
|
22
|
+
.map((depName) => `${depName}@${mapPeer[depName]}`);
|
|
20
23
|
peerDeps.push(...pluginPeerDeps);
|
|
21
24
|
}
|
|
22
25
|
logger.spin('Updating peer dependencies');
|