@polylith/builder 0.0.37 → 0.0.39
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/App.js +183 -97
- package/ConfigApp.js +23 -9
- package/ConfigFeature.js +1 -0
- package/Files.js +79 -48
- package/index.js +8 -1
- package/package.json +1 -1
- package/plugin-copy-resources.js +9 -7
- package/plugin-features.js +0 -3
- package/plugin-jsconfig.js +8 -28
- package/plugin-loader.js +3 -3
- package/plugin-main-html.js +45 -47
- package/types.js +60 -0
- package/utils.js +24 -3
package/App.js
CHANGED
|
@@ -7,33 +7,18 @@ import * as resolve from '@rollup/plugin-node-resolve';
|
|
|
7
7
|
import commonjs from '@rollup/plugin-commonjs';
|
|
8
8
|
import html from 'rollup-plugin-html';
|
|
9
9
|
import livereload from 'rollup-plugin-livereload';
|
|
10
|
+
import styles from "rollup-plugin-styles";
|
|
10
11
|
|
|
11
12
|
import loader from './plugin-loader.js';
|
|
12
13
|
import mainHTML from './plugin-main-html.js';
|
|
13
14
|
import features from './plugin-features.js';
|
|
14
|
-
import styles from "rollup-plugin-styles";
|
|
15
15
|
import resources from "./plugin-copy-resources.js";
|
|
16
16
|
import jsconfig from "./plugin-jsconfig.js";
|
|
17
17
|
|
|
18
|
+
import {forceToPosix, fileExists} from './utils.js'
|
|
18
19
|
import ConfigFeature from './ConfigFeature.js';
|
|
19
20
|
import Files from './Files.js';
|
|
20
21
|
|
|
21
|
-
/**
|
|
22
|
-
* call this function to check if the given file exists
|
|
23
|
-
*
|
|
24
|
-
* @param {String} path the name of the file
|
|
25
|
-
* @returns {Promise<Boolean>} true if the file exists
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
async function fileExists(path) {
|
|
29
|
-
try {
|
|
30
|
-
await stat(path)
|
|
31
|
-
return true;
|
|
32
|
-
} catch (e) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
22
|
/**
|
|
38
23
|
* The base class for applications. Applications inherit from this class
|
|
39
24
|
*/
|
|
@@ -42,16 +27,15 @@ export default class App {
|
|
|
42
27
|
* Construct the app object.
|
|
43
28
|
*
|
|
44
29
|
* @param {String} name a name for the app
|
|
45
|
-
* @param {String} root the root directory of the project.
|
|
46
|
-
*
|
|
30
|
+
* @param {String} root the full path to the root directory of the project.
|
|
31
|
+
* All other paths will be relative to this path.
|
|
47
32
|
* @param {String} index the relative path to the main source file from the
|
|
48
33
|
* root. All source paths will be assumed to be relative to this path.
|
|
49
34
|
* @param {String} dest the relative path to the destination folder from the
|
|
50
35
|
* root for rolled up files
|
|
51
36
|
*/
|
|
52
|
-
|
|
53
37
|
constructor(name, root, index, dest) {
|
|
54
|
-
root =
|
|
38
|
+
root = forceToPosix(root);
|
|
55
39
|
this.root = root;
|
|
56
40
|
|
|
57
41
|
var filename = path.posix.join(root, index);
|
|
@@ -69,30 +53,62 @@ export default class App {
|
|
|
69
53
|
this.manualChunkType = 'function';
|
|
70
54
|
this.manualChunks = [];
|
|
71
55
|
this.files = new Files(this.sourcePath, this.destPath);
|
|
56
|
+
this.cssSpecs = [];
|
|
72
57
|
this.cssFiles = [];
|
|
73
58
|
this.liveReload = true;
|
|
59
|
+
this.templateVariables = {};
|
|
60
|
+
this.ns = name.toUpperCase();
|
|
61
|
+
this.ns = this.ns.replace(/[- ]*?/g, '_');
|
|
62
|
+
this.codeVariables = {};
|
|
74
63
|
}
|
|
75
64
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Call this method to set the code variable name space. An object with this
|
|
67
|
+
* name will be attached to the window object with the code variables as
|
|
68
|
+
* members. The default value for the name space is the app name in upper
|
|
69
|
+
* snake case.
|
|
70
|
+
*
|
|
71
|
+
* @param {String} ns the name space name for added code variables. This
|
|
72
|
+
* must be a valid JavaScript identifier.
|
|
73
|
+
*/
|
|
74
|
+
setNamespace(ns) {
|
|
75
|
+
this.ns = ns;
|
|
79
76
|
}
|
|
80
77
|
|
|
81
78
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
79
|
+
* Call this method to add a code variable to the output html file. This
|
|
80
|
+
* variable will be added the namsespace for the app.
|
|
84
81
|
*
|
|
82
|
+
* @param {String} name the name of tyhe variable. This must be a valid
|
|
83
|
+
* JavaScript identifier.
|
|
84
|
+
* @param {*} value the value of the variable to set. This can be any type
|
|
85
|
+
* that can be serialized through JSON.
|
|
86
|
+
*/
|
|
87
|
+
addCodeVariable(name, value) {
|
|
88
|
+
this.codeVariables[name] = value;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Call this method to get the replacement value for ${codeVariables}. This
|
|
93
|
+
* will be the code that adds all the codeVariables to the namespace.
|
|
85
94
|
*
|
|
86
|
-
* @
|
|
87
|
-
|
|
95
|
+
* @returns {String} the replacement value for the codeVariables template
|
|
96
|
+
* variable;
|
|
88
97
|
*/
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
98
|
+
getCodeVariablesValue() {
|
|
99
|
+
var names = Object.keys(this.codeVariables);
|
|
100
|
+
if (names.length === 0) return '';
|
|
101
|
+
|
|
102
|
+
var members = names.map(function(name) {
|
|
103
|
+
return ` ${name}: ${JSON.stringify(this.codeVariables[name])},`
|
|
104
|
+
}, this);
|
|
94
105
|
|
|
95
|
-
|
|
106
|
+
var codeBlock =
|
|
107
|
+
` ${this.ns} = {
|
|
108
|
+
${members.join('\n')}
|
|
109
|
+
}
|
|
110
|
+
`;
|
|
111
|
+
return codeBlock;
|
|
96
112
|
}
|
|
97
113
|
|
|
98
114
|
/**
|
|
@@ -109,23 +125,67 @@ export default class App {
|
|
|
109
125
|
return './' + path;
|
|
110
126
|
}
|
|
111
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Call this method with true to reload the browser when any files in the
|
|
130
|
+
* destination folder have changed.
|
|
131
|
+
*
|
|
132
|
+
* @param {Bollean} on set to true to turn on destination watching
|
|
133
|
+
*/
|
|
112
134
|
setLiveReload(on) {
|
|
113
135
|
this.liveReload = on;
|
|
114
136
|
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Call this method to set the template for the main application html. This
|
|
140
|
+
* template file must have the required replacement strings for basic
|
|
141
|
+
* functionality. Call setTemplateVariable to create application specific
|
|
142
|
+
* repalcement values.
|
|
143
|
+
*
|
|
144
|
+
* @param {String} source the relative path from the application root to the
|
|
145
|
+
* html template
|
|
146
|
+
* @param {String} destination the relative path to the destination file
|
|
147
|
+
*/
|
|
115
148
|
setHtmlTemplate(source, destination) {
|
|
116
149
|
this.htmlTemplate = {source: source, destination: destination};
|
|
117
150
|
}
|
|
118
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Call this method to set the value of a template variable. Template
|
|
154
|
+
* variables specify a location in the html template where the value will be
|
|
155
|
+
* inserted. To specify where the value should be inserted in the template
|
|
156
|
+
* file add the string "${variableName}" in the location.
|
|
157
|
+
*
|
|
158
|
+
* @param {*} name
|
|
159
|
+
* @param {*} value
|
|
160
|
+
*/
|
|
161
|
+
setTemplateVariable(name, value) {
|
|
162
|
+
this.templateVariables[name] = value;
|
|
163
|
+
}
|
|
164
|
+
|
|
119
165
|
addConfig(config, root) {
|
|
120
166
|
this.configs[root] = config;
|
|
121
167
|
}
|
|
122
168
|
|
|
123
|
-
|
|
169
|
+
/**
|
|
170
|
+
* Call this method to add specifications for application css files These
|
|
171
|
+
* css files will be included in the html template
|
|
172
|
+
*
|
|
173
|
+
* @param {ResourceSpecList} specs the specification for the css files. These
|
|
174
|
+
* will also be added as resources to be copied.
|
|
175
|
+
*/
|
|
176
|
+
addMainCss(specs) {
|
|
177
|
+
this.cssSpecs = [...this.cssSpecs, ...specs];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Call this method to find all the css files specified by the css specs
|
|
182
|
+
*/
|
|
183
|
+
async findMainCss() {
|
|
124
184
|
var files = new Files(this.sourcePath, this.destPath)
|
|
125
185
|
|
|
126
|
-
//
|
|
186
|
+
// Find all the files frem the added css speces
|
|
127
187
|
specs.forEach(function(spec) {
|
|
128
|
-
files.
|
|
188
|
+
files.addResourceSpec('', spec);
|
|
129
189
|
}, this)
|
|
130
190
|
|
|
131
191
|
var expanded = await files.findAllFiles();
|
|
@@ -141,30 +201,32 @@ export default class App {
|
|
|
141
201
|
|
|
142
202
|
/**
|
|
143
203
|
* Call this method to add a list of resources that will be moved to the
|
|
144
|
-
* destination path when the application is built.
|
|
145
|
-
* feature root, or the source path
|
|
204
|
+
* destination path when the application is built.
|
|
146
205
|
*
|
|
147
|
-
* @param {
|
|
206
|
+
* @param {String} root the relative path from the source root to the path
|
|
207
|
+
* to the origin of the caller. This will either be a feature root, or
|
|
208
|
+
* empty for the main applicatio the source pathPaths specified in the
|
|
209
|
+
* resource spec are assumed to be relative to this.-
|
|
210
|
+
* @param {Array<ReourceSpec>} resourceSpecs the copy specs
|
|
148
211
|
* for all the resources being added.
|
|
149
|
-
* @param {String} root the path to the origin of the caller. Paths in
|
|
150
|
-
* the spec are assumed to be relative to this.
|
|
151
212
|
*/
|
|
152
213
|
addResources(root, resourceSpecs) {
|
|
153
214
|
resourceSpecs.forEach(function(spec) {
|
|
154
|
-
this.files.
|
|
215
|
+
this.files.addResourceSpec(root, spec);
|
|
155
216
|
}, this)
|
|
156
217
|
}
|
|
157
218
|
|
|
158
219
|
/**
|
|
159
220
|
* Call this method to add a feature to the application. This method is
|
|
160
221
|
* given a path to the root of the feature. At build time the builder will
|
|
161
|
-
* look directory for a file named build.js and if found
|
|
162
|
-
* call the default function passing it a pointner to this
|
|
222
|
+
* look in the feature directory for a file named build.js and if found
|
|
223
|
+
* import it and call the default function passing it a pointner to this
|
|
224
|
+
* object.
|
|
163
225
|
*
|
|
164
226
|
* If there is no build.js file the builder will look for a build.json file.
|
|
165
227
|
* If present that json will be loaded and used to build the feature.
|
|
166
228
|
*
|
|
167
|
-
* If that is not found it will look for an index.js file
|
|
229
|
+
* If that is not found it will look for an index.js file, and if found it
|
|
168
230
|
* will add that to the list of feature index files which will be
|
|
169
231
|
* automatically imported when the built code imports the @polylith/features
|
|
170
232
|
* module
|
|
@@ -223,54 +285,53 @@ export default class App {
|
|
|
223
285
|
}
|
|
224
286
|
|
|
225
287
|
/**
|
|
226
|
-
*
|
|
227
|
-
* default.
|
|
288
|
+
* This is called by rollup if no manual chunk specifiers are added,
|
|
228
289
|
*
|
|
229
|
-
* @param {String}
|
|
290
|
+
* @param {String} filename this is the filename of the current file being
|
|
230
291
|
* processed by rollup
|
|
231
292
|
*
|
|
232
293
|
* @returns {String} the chunk name if there is a match
|
|
233
294
|
*/
|
|
234
|
-
defaultManualChunks(
|
|
235
|
-
if (
|
|
295
|
+
defaultManualChunks(filename) {
|
|
296
|
+
if (filename.includes('node_modules')) {
|
|
236
297
|
return 'vendor';
|
|
237
298
|
}
|
|
238
299
|
}
|
|
239
300
|
|
|
240
301
|
/**
|
|
241
|
-
* This is called when manual chunk specifications have been added
|
|
242
|
-
* array.
|
|
302
|
+
* This is called by rollup when manual chunk specifications have been added
|
|
303
|
+
* as an array.
|
|
243
304
|
*
|
|
244
|
-
* @param {String}
|
|
305
|
+
* @param {String} filename this is the filename of the current file being
|
|
245
306
|
* processed by rollup
|
|
246
|
-
* @returns {String} the name
|
|
307
|
+
* @returns {String} the name oo the chunk if there is a matching chunk
|
|
247
308
|
* name specifier
|
|
248
309
|
*/
|
|
249
|
-
handleManualChunksArray(
|
|
250
|
-
var
|
|
310
|
+
handleManualChunksArray(filename) {
|
|
311
|
+
var posixFilename = forceToPosix(filename);
|
|
251
312
|
var result = this.manualChunks.find(function(spec) {
|
|
252
|
-
return
|
|
313
|
+
return posixFilename.includes(spec.includes);
|
|
253
314
|
})
|
|
254
315
|
|
|
255
316
|
if (result) return result.name;
|
|
256
317
|
}
|
|
257
318
|
|
|
258
319
|
/**
|
|
259
|
-
* This is called when the manual chunk specifiers are functions.
|
|
260
|
-
* registered function is called in the reverse order to how they were
|
|
320
|
+
* This is called by rollup when the manual chunk specifiers are functions.
|
|
321
|
+
* Each registered function is called in the reverse order to how they were
|
|
261
322
|
* added.
|
|
262
323
|
*
|
|
263
|
-
* @param {String}
|
|
324
|
+
* @param {String} filename this is the filename of the current file being
|
|
264
325
|
* processed by rollup
|
|
265
326
|
* @returns the chunk name if any of the callbacks return one
|
|
266
327
|
*/
|
|
267
|
-
handleManualChunksCallbacks(
|
|
268
|
-
var
|
|
328
|
+
handleManualChunksCallbacks(filename) {
|
|
329
|
+
var posixFilename = forceToPosix(filename);
|
|
269
330
|
if (this.manualChunks.length === 0) {
|
|
270
|
-
return this.defaultManualChunks(
|
|
331
|
+
return this.defaultManualChunks(posixFilename);
|
|
271
332
|
} else {
|
|
272
|
-
for (
|
|
273
|
-
var result =
|
|
333
|
+
for (chunk of this.manualChunks) {
|
|
334
|
+
var result = chunk(posixFilename);
|
|
274
335
|
if (result) return result;
|
|
275
336
|
}
|
|
276
337
|
}
|
|
@@ -343,40 +404,62 @@ export default class App {
|
|
|
343
404
|
|
|
344
405
|
/**
|
|
345
406
|
*
|
|
407
|
+
* @param {String} root the relative path from the source root to the
|
|
408
|
+
* feature directory. Loadable paths are assumed to be relative to this
|
|
409
|
+
* directory
|
|
346
410
|
* @param {String} name unique name of the loadable that will be passed to
|
|
347
411
|
* the load method
|
|
348
|
-
* @param {String}
|
|
349
|
-
* point of the loadable.
|
|
412
|
+
* @param {String} index the relative path from the source folder to the
|
|
413
|
+
* entry point of the loadable.
|
|
350
414
|
* @param {String} [prefix] if given, the prefix on services created in
|
|
351
415
|
* this loadable. When the loadable has been loaded, the start and
|
|
352
416
|
* ready methods will be called on all services starting with this
|
|
353
417
|
* prefix.
|
|
354
|
-
* @param {
|
|
355
|
-
* css files that will included when the
|
|
418
|
+
* @param {ResourceSpecList} [css] if give, it will be a list of resource
|
|
419
|
+
* specifications for the css files that will be included when the
|
|
420
|
+
* module is loaded
|
|
356
421
|
*/
|
|
357
|
-
async addLoadable(root, name,
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
422
|
+
async addLoadable(root, name, index, prefix, css) {
|
|
423
|
+
var indexPath = path.posix.join(this.sourcePath, index);
|
|
424
|
+
this.loadables.push({name, index: indexPath, prefix, root, css});
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Call this method to locate all the css files for a loadable. These css
|
|
429
|
+
* files will be loaded into the browser when this loadable has been loaded
|
|
430
|
+
*
|
|
431
|
+
* @param {Loadable} loadable
|
|
432
|
+
*/
|
|
433
|
+
async findLoadableCss(loadable) {
|
|
434
|
+
if (loadable.css) {
|
|
361
435
|
var files = new Files(this.sourcePath, this.destPath)
|
|
362
|
-
css.forEach(function(spec) {
|
|
363
|
-
files.
|
|
436
|
+
loadable.css.forEach(function(spec) {
|
|
437
|
+
files.addResourceSpec(loadable.root, spec);
|
|
364
438
|
}, this)
|
|
439
|
+
|
|
365
440
|
var expanded = await files.findAllFiles();
|
|
366
441
|
var keys = Object.keys(expanded);
|
|
367
|
-
|
|
442
|
+
|
|
443
|
+
var cssUris = keys.map(function(key){
|
|
368
444
|
var file = expanded[key];
|
|
369
|
-
|
|
445
|
+
return file.uri
|
|
370
446
|
}, this)
|
|
371
|
-
}
|
|
372
447
|
|
|
373
|
-
|
|
374
|
-
|
|
448
|
+
loadable.css = cssUris;
|
|
449
|
+
}
|
|
375
450
|
}
|
|
376
451
|
|
|
377
|
-
|
|
378
|
-
|
|
452
|
+
/**
|
|
453
|
+
* Call this method to build the template variable for the main html css
|
|
454
|
+
* files
|
|
455
|
+
*
|
|
456
|
+
* @returns {Promise<String>} the value of the mainCss template variable
|
|
457
|
+
*/
|
|
458
|
+
async buildMainCss() {
|
|
379
459
|
var cssTags = '';
|
|
460
|
+
|
|
461
|
+
await this.findMainCss();
|
|
462
|
+
|
|
380
463
|
this.cssFiles.forEach(function(uri) {
|
|
381
464
|
cssTags += ` <link rel="stylesheet" href="${uri}"></link>`
|
|
382
465
|
}, this);
|
|
@@ -385,25 +468,28 @@ export default class App {
|
|
|
385
468
|
}
|
|
386
469
|
|
|
387
470
|
/**
|
|
388
|
-
* The build method calls this
|
|
389
|
-
* object
|
|
471
|
+
* The build method calls this to create the rollup configuration object
|
|
390
472
|
*
|
|
391
473
|
* @returns {Object} rollup configuration object
|
|
392
474
|
*/
|
|
393
475
|
|
|
394
|
-
buildConfiguration() {
|
|
476
|
+
async buildConfiguration() {
|
|
395
477
|
var input = [this.fullIndexPath];
|
|
396
|
-
this.loadables.forEach(function(spec) {
|
|
397
|
-
input.push(spec.path);
|
|
398
|
-
});
|
|
399
478
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
479
|
+
// using a for loop because we are making an async call
|
|
480
|
+
for (let loadable of loadables) {
|
|
481
|
+
// find all the css files for the loadables
|
|
482
|
+
await this.findLoadableCss(loadable);
|
|
483
|
+
input.push(loadable.index);
|
|
403
484
|
}
|
|
404
485
|
|
|
405
486
|
var manualChunks = this.getManualChunks();
|
|
406
|
-
var mainCss = this.buildMainCss();
|
|
487
|
+
var mainCss = await this.buildMainCss();
|
|
488
|
+
var codeVariables = this.getCodeVariablesValue();
|
|
489
|
+
|
|
490
|
+
this.templateVariables['mainCss'] = mainCss;
|
|
491
|
+
this.templateVariables['codeVariables'] = codeVariables;
|
|
492
|
+
|
|
407
493
|
var plugins = [
|
|
408
494
|
resolve.nodeResolve({
|
|
409
495
|
extensions: ['.js', '.jsx']
|
|
@@ -424,7 +510,7 @@ export default class App {
|
|
|
424
510
|
root: this.root,
|
|
425
511
|
source: this.htmlTemplate.source,
|
|
426
512
|
destination: this.htmlTemplate.destination,
|
|
427
|
-
|
|
513
|
+
templateVars: this.templateVariables,
|
|
428
514
|
}),
|
|
429
515
|
resources(this.name, this.files)
|
|
430
516
|
];
|
|
@@ -449,9 +535,9 @@ export default class App {
|
|
|
449
535
|
return '[name]-[hash][extname]';
|
|
450
536
|
},
|
|
451
537
|
entryFileNames: function(chunkInfo) {
|
|
452
|
-
var entry =
|
|
538
|
+
var entry = forceToPosix(chunkInfo.facadeModuleId);
|
|
453
539
|
var found = this.loadables.find(function(loadable) {
|
|
454
|
-
return loadable.
|
|
540
|
+
return loadable.index === entry;
|
|
455
541
|
}, this);
|
|
456
542
|
var exists = Boolean(found);
|
|
457
543
|
|
|
@@ -478,7 +564,7 @@ export default class App {
|
|
|
478
564
|
|
|
479
565
|
async build() {
|
|
480
566
|
await this.buildFeatures();
|
|
481
|
-
this.config = this.buildConfiguration();
|
|
567
|
+
this.config = await this.buildConfiguration();
|
|
482
568
|
|
|
483
569
|
const bundle = await rollup.rollup(this.config.input);
|
|
484
570
|
await bundle.generate(this.config.output);
|
package/ConfigApp.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import App from './App.js';
|
|
2
2
|
import path from 'node:path/posix';
|
|
3
|
+
import {forceToPosix} from './utils.js'
|
|
3
4
|
|
|
5
|
+
/**
|
|
6
|
+
* This class is used to build an application from a configuration file.
|
|
7
|
+
*/
|
|
4
8
|
export default class ConfigApp extends App {
|
|
5
9
|
constructor (config, root) {
|
|
6
|
-
root =
|
|
10
|
+
root = forceToPosix(root);
|
|
7
11
|
var name = config.name || 'unnamed';
|
|
8
|
-
var index = config.index ||
|
|
9
|
-
var dest = config.dest ||
|
|
12
|
+
var index = config.index || 'src/index.js';
|
|
13
|
+
var dest = config.dest || 'dist';
|
|
10
14
|
|
|
11
15
|
super(name, root, index, dest);
|
|
12
16
|
this.config = config;
|
|
@@ -14,20 +18,30 @@ export default class ConfigApp extends App {
|
|
|
14
18
|
if (!index.template || !index.template.source) throw new Error('html source not defined in config file');
|
|
15
19
|
var source = index.template.source;
|
|
16
20
|
var sourceFilename = path.basename(source);
|
|
17
|
-
var destination = index.template.destination || path.join(dest, sourceFilename)
|
|
21
|
+
var destination = index.template.destination || path.join(dest, sourceFilename);
|
|
18
22
|
this.setHtmlTemplate(source, destination);
|
|
19
23
|
|
|
20
|
-
if (config.manualChunks)
|
|
24
|
+
if (config.manualChunks) {
|
|
25
|
+
config.manualChunks.forEach(function(chunk) {
|
|
26
|
+
this.addManualChunks(chunk);
|
|
27
|
+
}, this)
|
|
28
|
+
}
|
|
29
|
+
|
|
21
30
|
if (this.config.features) {
|
|
22
31
|
this.config.features.forEach(function(feature) {
|
|
23
32
|
this.addFeature(feature);
|
|
24
33
|
}.bind(this))
|
|
25
34
|
}
|
|
26
35
|
|
|
27
|
-
if (config.resources) ;
|
|
28
|
-
|
|
36
|
+
if (config.resources && Array.isArray(config.resources)) this.addResources('', config.resources);
|
|
37
|
+
if (config.css) this.addMainCss(css);
|
|
29
38
|
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
if (config.variables) {
|
|
40
|
+
var names = Object.keys(config.variables);
|
|
41
|
+
|
|
42
|
+
names.forEach(function(name) {
|
|
43
|
+
this.addCodeVariable(name, config.variables[name]);
|
|
44
|
+
}, this)
|
|
45
|
+
}
|
|
32
46
|
}
|
|
33
47
|
}
|
package/ConfigFeature.js
CHANGED
package/Files.js
CHANGED
|
@@ -3,27 +3,8 @@ import path from 'node:path/posix'
|
|
|
3
3
|
import {ensureDir} from 'fs-extra';
|
|
4
4
|
import { copyFile } from 'node:fs/promises';
|
|
5
5
|
import App from './App.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
* @typedef {Object} CopySpec
|
|
9
|
-
* @property {String} dest the relative path of the copy destination from the
|
|
10
|
-
* application's destination path.
|
|
11
|
-
* @property {String} cwd the relative path from the spec root to search for
|
|
12
|
-
* files
|
|
13
|
-
* @property {String} glob the search expression for the files to copy, in glob
|
|
14
|
-
* format
|
|
15
|
-
* @property {Boolean} [keepNest] if true then the nesting of the found file
|
|
16
|
-
* relative to the cwd property will be retained when the file is copied.
|
|
17
|
-
* Defaults to false
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @typedef {Object} FileSpec
|
|
22
|
-
* @property {String} name the full path to the file being copied
|
|
23
|
-
* @property {String} searchRoot the absolute path to where the search started
|
|
24
|
-
* @property {CopySpec} spec the specifier for how to find and copy files
|
|
25
|
-
*/
|
|
26
|
-
|
|
6
|
+
import {forceToPosix} from './utils.js'
|
|
7
|
+
import './types.js'
|
|
27
8
|
/**
|
|
28
9
|
* create an instance of this class to specify and and copy files from source
|
|
29
10
|
* to destination.
|
|
@@ -40,6 +21,7 @@ export default class Files {
|
|
|
40
21
|
constructor(src, dest) {
|
|
41
22
|
this.dest = dest;
|
|
42
23
|
this.src = src;
|
|
24
|
+
/** @type {CopyInfoList} */
|
|
43
25
|
this.files = {};
|
|
44
26
|
this.specs = [];
|
|
45
27
|
}
|
|
@@ -52,20 +34,23 @@ export default class Files {
|
|
|
52
34
|
* @param {String} root the originating path of the specifier. This is a
|
|
53
35
|
* relative path from the project src path. This is probably the location
|
|
54
36
|
* of the feature, or empty for the src path itself.
|
|
55
|
-
* @param {
|
|
37
|
+
* @param {ResourceSpec} spec the specification for how to find and copy files
|
|
56
38
|
*/
|
|
57
|
-
|
|
39
|
+
addResourceSpec(root, spec) {
|
|
58
40
|
spec.root = root;
|
|
59
41
|
this.specs.push(spec);
|
|
60
42
|
}
|
|
61
43
|
|
|
62
44
|
/**
|
|
63
|
-
* call this
|
|
45
|
+
* call this method to generate the destination filename from the spec and
|
|
64
46
|
* the source filename
|
|
65
47
|
*
|
|
66
|
-
* @param {
|
|
67
|
-
*
|
|
68
|
-
* @
|
|
48
|
+
* @param {String} searchRoot the full path to the directory where the
|
|
49
|
+
* search started that found this file
|
|
50
|
+
* @param {ResourceSpec} spec the spec that found the file
|
|
51
|
+
* @param {String} srcFilename the full path to the source file
|
|
52
|
+
*
|
|
53
|
+
* @returns {String} the full path to the destination file
|
|
69
54
|
*/
|
|
70
55
|
makeDestination(searchRoot, spec, srcFilename) {
|
|
71
56
|
var fullPath = searchRoot;
|
|
@@ -87,35 +72,84 @@ export default class Files {
|
|
|
87
72
|
* different specs then the spec with the longest search root will take
|
|
88
73
|
* presidence, since it is the spec with the greatest specificity
|
|
89
74
|
*
|
|
90
|
-
* @param {
|
|
91
|
-
*
|
|
92
|
-
* @param {
|
|
75
|
+
* @param {String} searchRoot the full path to the directory where the
|
|
76
|
+
* search started that found this file
|
|
77
|
+
* @param {Array.<String>} files full paths to files that have been found
|
|
78
|
+
* @param {ResourceSpec} spec the spec that was used to find these files.
|
|
79
|
+
*
|
|
80
|
+
* @returns {CopyInfoList} the list of files found for this spec
|
|
93
81
|
*/
|
|
94
82
|
addFiles(searchRoot, files, spec) {
|
|
83
|
+
/** @type {CopyInfoList} */
|
|
84
|
+
var foundFiles = {};
|
|
85
|
+
|
|
95
86
|
// the rule here is that files that are found by multiple specs will be
|
|
96
87
|
// controlled according to the spec with the deepest nested search path.
|
|
97
|
-
// Since file paths here are absolute
|
|
88
|
+
// Since file paths here are absolute this will always be based on the
|
|
98
89
|
// string length.
|
|
99
90
|
files.forEach(function(file) {
|
|
100
|
-
file =
|
|
91
|
+
file = forceToPosix(file);
|
|
92
|
+
|
|
101
93
|
// reconcile conflicts
|
|
102
94
|
if (this.files[file]) {
|
|
103
95
|
var copyInfo = this.files[file];
|
|
104
96
|
if (copyInfo.searchRoot.length > searchRoot.length) return;
|
|
105
97
|
}
|
|
98
|
+
|
|
106
99
|
var destination = this.makeDestination(searchRoot, spec, file);
|
|
107
100
|
var uri = destination.slice(this.dest.length + 1);
|
|
108
101
|
|
|
109
|
-
|
|
102
|
+
foundFiles[file] = {
|
|
110
103
|
name: file,
|
|
104
|
+
searchRoot: searchRoot,
|
|
111
105
|
destFilename: destination,
|
|
112
106
|
uri: uri,
|
|
113
|
-
searchRoot: searchRoot,
|
|
114
107
|
spec: spec,
|
|
115
108
|
}
|
|
116
|
-
}, this)
|
|
109
|
+
}, this);
|
|
110
|
+
|
|
111
|
+
this.files = {...this.files, ...foundFiles}
|
|
112
|
+
|
|
113
|
+
return foundFiles;
|
|
117
114
|
}
|
|
118
115
|
|
|
116
|
+
/**
|
|
117
|
+
* Call this method to get all the folders where files can copied from
|
|
118
|
+
*
|
|
119
|
+
* @returns {Array.<String>}
|
|
120
|
+
*/
|
|
121
|
+
getAllFolders() {
|
|
122
|
+
var folders = this.specs.map(function(spec){
|
|
123
|
+
return path.join(this.src, spec.root, spec.cwd);
|
|
124
|
+
}, this);
|
|
125
|
+
|
|
126
|
+
return folders;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Call this method to copy a single file into its destination location
|
|
132
|
+
*
|
|
133
|
+
* @param {String} file the full path of the file to be copied
|
|
134
|
+
*/
|
|
135
|
+
async copyOneFile(file, updated) {
|
|
136
|
+
file = forceToPosix(file);
|
|
137
|
+
|
|
138
|
+
var destination = this.files[file] && this.files[file].destFilename;
|
|
139
|
+
|
|
140
|
+
if (destination && updated) {
|
|
141
|
+
console.log(`file ${file} updated, copied to ${destination}`);
|
|
142
|
+
await copyFile(file, destination);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Call this method to find all the files specified by a spec.
|
|
148
|
+
*
|
|
149
|
+
* @param {ResourceSpec} spec the specification for the files to find
|
|
150
|
+
*
|
|
151
|
+
* @returns {Promise.<CopyInfoList>} all the files that have been found so far.
|
|
152
|
+
*/
|
|
119
153
|
async findFiles(spec) {
|
|
120
154
|
var searchRoot = path.join(this.src, spec.root, spec.cwd);
|
|
121
155
|
var options = {
|
|
@@ -136,17 +170,16 @@ export default class Files {
|
|
|
136
170
|
|
|
137
171
|
/**
|
|
138
172
|
* Call this method to locate all the files to be found from all the copy
|
|
139
|
-
* specs that have been added
|
|
173
|
+
* specs that have been added.
|
|
140
174
|
*
|
|
141
|
-
* @returns {Promise<
|
|
142
|
-
*
|
|
175
|
+
* @returns {Promise<CopyInfoList>} the list of all files that have
|
|
176
|
+
* been found. This is also stored in the object variable this.files
|
|
143
177
|
*/
|
|
144
178
|
async findAllFiles() {
|
|
145
179
|
if (this.filesFound) return this.files;
|
|
146
180
|
|
|
147
181
|
// using a for loop here because we are making async calls
|
|
148
|
-
for (let
|
|
149
|
-
let spec = this.specs[idx];
|
|
182
|
+
for (let spec of this.specs) {
|
|
150
183
|
await this.findFiles(spec);
|
|
151
184
|
}
|
|
152
185
|
|
|
@@ -156,22 +189,20 @@ export default class Files {
|
|
|
156
189
|
}
|
|
157
190
|
|
|
158
191
|
/**
|
|
159
|
-
* Call this method to copy all the files that have been specified
|
|
160
|
-
*
|
|
192
|
+
* Call this method to copy all the files that have been specified by
|
|
193
|
+
* calling addResourceSpec to their destination directories
|
|
161
194
|
*/
|
|
162
195
|
async copyFiles() {
|
|
163
196
|
await this.findAllFiles();
|
|
164
197
|
|
|
165
198
|
var filenames = Object.keys(this.files);
|
|
199
|
+
|
|
166
200
|
// using a for loop because we are making async calls
|
|
167
|
-
for (let
|
|
168
|
-
let srcFilename = filenames[idx];
|
|
201
|
+
for (let srcFilename of filenames) {
|
|
169
202
|
let destFilename = this.files[srcFilename].destFilename;
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
// unintended consequences
|
|
203
|
+
let destFilePath = path.dirname(destFilename);
|
|
204
|
+
|
|
173
205
|
try {
|
|
174
|
-
// console.log(`copying ${srcFilename} to ${destFilename}`);
|
|
175
206
|
await ensureDir(destFilePath);
|
|
176
207
|
await copyFile(srcFilename, destFilename);
|
|
177
208
|
} catch (e) {
|
package/index.js
CHANGED
|
@@ -2,5 +2,12 @@ import App from './App.js'
|
|
|
2
2
|
import Feature from './Feature.js';
|
|
3
3
|
import ConfigApp from './ConfigApp.js';
|
|
4
4
|
import ConfigFeature from './ConfigFeature.js';
|
|
5
|
+
import utils from './utils.js';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
var utilsExport = {
|
|
8
|
+
forceToPosix: utils.forceToPosix,
|
|
9
|
+
fileExists: utils.fileExists,
|
|
10
|
+
fileToPath: utils.fileToPath,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export {App, Feature, ConfigApp, ConfigFeature, utilsExport as utils};
|
package/package.json
CHANGED
package/plugin-copy-resources.js
CHANGED
|
@@ -10,13 +10,15 @@ export default function(name, files) {
|
|
|
10
10
|
return {
|
|
11
11
|
name: "copy-resources",
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
var
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
buildStart() {
|
|
14
|
+
var folders = files.getAllFolders();
|
|
15
|
+
folders.forEach(function(name) {
|
|
16
|
+
this.addWatchFile(name);
|
|
17
|
+
}, this);
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
watchChange(file, event) {
|
|
21
|
+
files.copyOneFile(file);
|
|
20
22
|
},
|
|
21
23
|
|
|
22
24
|
async generateBundle(outputOptions, bundleInfo) {
|
package/plugin-features.js
CHANGED
package/plugin-jsconfig.js
CHANGED
|
@@ -1,25 +1,6 @@
|
|
|
1
1
|
import path from 'node:path/posix';
|
|
2
2
|
import {readFile, writeFile, stat} from 'node:fs/promises';
|
|
3
|
-
|
|
4
|
-
async function fileExists(path) {
|
|
5
|
-
try {
|
|
6
|
-
await stat(path)
|
|
7
|
-
return true;
|
|
8
|
-
} catch (e) {
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function fixPath(src) {
|
|
14
|
-
src = src.replace('file:', '');
|
|
15
|
-
src = src.replace('///', '');
|
|
16
|
-
src = src.replace(/.:/, '');
|
|
17
|
-
src = src.replace(/\\/g, '/');
|
|
18
|
-
|
|
19
|
-
return src;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
3
|
+
import {forceToPosix, fileExists} from './utils.js'
|
|
23
4
|
|
|
24
5
|
/**
|
|
25
6
|
* Matches pattern with a single star against search.
|
|
@@ -58,20 +39,19 @@ function matchStar(pattern, search) {
|
|
|
58
39
|
|
|
59
40
|
async function findPathMatch(base, source, paths) {
|
|
60
41
|
var patterns = Object.keys(paths);
|
|
61
|
-
var source =
|
|
42
|
+
var source = forceToPosix(source);
|
|
62
43
|
|
|
63
44
|
if (source.indexOf(base) === 0) return
|
|
64
|
-
// source = source.slice(base.length);
|
|
65
45
|
|
|
66
|
-
for(let
|
|
67
|
-
let pattern = patterns[patternIdx];
|
|
46
|
+
for (let pattern of patterns) {
|
|
68
47
|
let searches = paths[pattern];
|
|
69
48
|
let capture = matchStar(pattern, source);
|
|
70
|
-
if (!capture) continue;
|
|
71
49
|
|
|
50
|
+
if (!capture) continue;
|
|
72
51
|
if (!Array.isArray(searches)) continue;
|
|
73
|
-
|
|
74
|
-
|
|
52
|
+
|
|
53
|
+
for (let search of searches) {
|
|
54
|
+
var tryName = path.join(base, search.replace('*', capture));
|
|
75
55
|
|
|
76
56
|
if (await fileExists(tryName)) {
|
|
77
57
|
return tryName;
|
|
@@ -111,7 +91,7 @@ export default function jsconfig(root) {
|
|
|
111
91
|
name: 'jsconfig',
|
|
112
92
|
|
|
113
93
|
async resolveId (source, importer, options) {
|
|
114
|
-
source =
|
|
94
|
+
source = forceToPosix(source);
|
|
115
95
|
|
|
116
96
|
if (previouslyMatched[source] !== undefined) return previouslyMatched[source];
|
|
117
97
|
previouslyMatched[source] === null;
|
package/plugin-loader.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'node:path/posix';
|
|
2
2
|
import {readFile, writeFile, stat} from 'node:fs/promises';
|
|
3
|
-
import {
|
|
3
|
+
import {forceToPosix} from './utils.js';
|
|
4
4
|
var templateSource;
|
|
5
5
|
|
|
6
6
|
function makeSource(loadables) {
|
|
@@ -38,7 +38,7 @@ ${serviceStr}
|
|
|
38
38
|
|
|
39
39
|
var switchStr =
|
|
40
40
|
` case '${loadable.name}':
|
|
41
|
-
promise = import('${loadable.
|
|
41
|
+
promise = import('${loadable.index}')${prefixStr}
|
|
42
42
|
break;
|
|
43
43
|
`
|
|
44
44
|
loadableSwitches += switchStr;
|
|
@@ -64,7 +64,7 @@ export default function loader(loadables) {
|
|
|
64
64
|
},
|
|
65
65
|
|
|
66
66
|
async load (id) {
|
|
67
|
-
var root = path.dirname(
|
|
67
|
+
var root = path.dirname(forceToPosix(import.meta.url));
|
|
68
68
|
if (!templateSource) {
|
|
69
69
|
templateSource = await readFile(path.join(root, 'loaderTemplate.txt'), 'utf-8');
|
|
70
70
|
}
|
package/plugin-main-html.js
CHANGED
|
@@ -6,12 +6,6 @@ import {readFile, writeFile} from 'node:fs/promises';
|
|
|
6
6
|
const INVALID_ARGS_ERROR =
|
|
7
7
|
"[plugin-main-html] You did not provide a template or target!";
|
|
8
8
|
|
|
9
|
-
/**
|
|
10
|
-
* Takes an HTML file as a template and replaces variables.
|
|
11
|
-
* @param {Object} options The options object.
|
|
12
|
-
* @return {Object} The rollup code object.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
9
|
function createScriptTags(scripts) {
|
|
16
10
|
var tags = '';
|
|
17
11
|
scripts.forEach(function(script) {
|
|
@@ -22,54 +16,58 @@ function createScriptTags(scripts) {
|
|
|
22
16
|
return tags;
|
|
23
17
|
}
|
|
24
18
|
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Takes an HTML file as a template and replaces template variables with
|
|
21
|
+
* assigned values
|
|
22
|
+
*
|
|
23
|
+
* @param {Object} options The options object.
|
|
24
|
+
* @return {Object} The rollup plugin object.
|
|
25
|
+
*/
|
|
26
|
+
export default function(options = {}) {
|
|
27
|
+
|
|
28
|
+
var { root, source, destination, templateVars } = options;
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
return {
|
|
31
|
+
name: "main-html-template",
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
var names = Object.keys(bundleInfo);
|
|
36
|
-
var scripts;
|
|
33
|
+
async generateBundle(outputOptions, bundleInfo) {
|
|
34
|
+
var includes = [];
|
|
35
|
+
var names = Object.keys(bundleInfo);
|
|
36
|
+
var scripts;
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
if (!destination && !source) throw new Error(INVALID_ARGS_ERROR);
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
names.forEach(function(name) {
|
|
41
|
+
var entry = bundleInfo[name];
|
|
42
|
+
if (!entry.isDynamicEntry) {
|
|
43
|
+
includes.push(name);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
scripts = createScriptTags(includes);
|
|
48
|
+
templateVars["scripts"] = scripts;
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
var sourceFilePath = path.join(root, source);
|
|
51
|
+
var destinationFilePath = path.join(root, destination);
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
var content = await readFile(sourceFilePath, 'utf-8');
|
|
55
|
-
if (replaceVars) {
|
|
56
|
-
var varNames = Object.keys(replaceVars);
|
|
57
|
-
varNames.forEach(function(name) {
|
|
58
|
-
var replacement = replaceVars[name]
|
|
59
|
-
var escapedName = escapeStringRegexp('${' + name + '}');
|
|
60
|
-
var regex = new RegExp(escapedName, 'g');
|
|
61
|
-
content = content.replace(regex, replacement);
|
|
62
|
-
});
|
|
63
|
-
}
|
|
53
|
+
var content = await readFile(sourceFilePath, 'utf-8');
|
|
64
54
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
55
|
+
if (templateVars) {
|
|
56
|
+
var varNames = Object.keys(templateVars);
|
|
57
|
+
varNames.forEach(function(name) {
|
|
58
|
+
var replacement = templateVars[name]
|
|
59
|
+
var escapedName = escapeStringRegexp('${' + name + '}');
|
|
60
|
+
var regex = new RegExp(escapedName, 'g');
|
|
61
|
+
content = content.replace(regex, replacement);
|
|
62
|
+
});
|
|
71
63
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
64
|
+
|
|
65
|
+
// remove template vars that were not replaced
|
|
66
|
+
content = content.replace(/\$\{.*?\}/, '');
|
|
67
|
+
|
|
68
|
+
// write the injected template to a file
|
|
69
|
+
await ensureFile(destinationFilePath);
|
|
70
|
+
writeFile(destinationFilePath, content, 'utf-8');
|
|
71
|
+
},
|
|
72
|
+
};
|
|
75
73
|
}
|
package/types.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** @module types */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This type defines how to locate a set of files that will be copied to the
|
|
5
|
+
* dest folder.
|
|
6
|
+
*
|
|
7
|
+
* @typedef {Object} ResourceSpec
|
|
8
|
+
* @property {String} dest the relative path of the copy destination from the
|
|
9
|
+
* application's destination path.
|
|
10
|
+
* @property {String} cwd the relative path from the spec root to search for
|
|
11
|
+
* files
|
|
12
|
+
* @property {String} glob the search expression for the files to copy, in glob
|
|
13
|
+
* format
|
|
14
|
+
* @property {Boolean} [keepNest] if true then the nesting of the found file
|
|
15
|
+
* relative to the cwd property will be retained when the file is copied.
|
|
16
|
+
* Defaults to false
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* This type defines a list of ResourceSpec
|
|
21
|
+
*
|
|
22
|
+
* @typedef {Array.<ResourceSpec} ResourceSpecList
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* This defines the specification for a file that has been found from a
|
|
27
|
+
* ResourceSpec
|
|
28
|
+
*
|
|
29
|
+
* @typedef {Object} CopyInfo
|
|
30
|
+
* @property {String} name the full path to the file found
|
|
31
|
+
* @property {String} searchRoot the absolute path to where the search started.
|
|
32
|
+
* @property {String} destFilename the absolute path to where the file be copied
|
|
33
|
+
* @property {String} uri the path to the file relative to the destination
|
|
34
|
+
* directory. This can be used to reference the file from the output
|
|
35
|
+
* application.
|
|
36
|
+
* @property {ResourceSpec} spec the specifier used to locate this file
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* This type defines a list of CopyInfos
|
|
41
|
+
*
|
|
42
|
+
* @typedef {Object.<String, CopyInfo>} CopyInfoList
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* This specifies what is in a loadable object
|
|
47
|
+
*
|
|
48
|
+
* @typedef {Object} Loadable
|
|
49
|
+
* @property {String} name this is the name the loadable will be known as. This
|
|
50
|
+
* will be the string passed to the load function
|
|
51
|
+
* @property {String} root the relative path from the source directory to the
|
|
52
|
+
* root of the feature. All feature paths are assumed to be relative to
|
|
53
|
+
* this
|
|
54
|
+
* @property {String} index the absolute path to the loadables index file
|
|
55
|
+
* @property {String} prefix if given then all services that begin with this
|
|
56
|
+
* prefix will go through the start sequence when loaded
|
|
57
|
+
* @property {ResourceSpecList|Array<String>} css is either the specification for
|
|
58
|
+
* where to find the css files to load, or during build, an array of the
|
|
59
|
+
* uris for each css file.
|
|
60
|
+
*/
|
package/utils.js
CHANGED
|
@@ -1,16 +1,37 @@
|
|
|
1
1
|
import path from 'node:path/posix';
|
|
2
2
|
import {readFile, writeFile, stat} from 'node:fs/promises';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* call this function to force the file path to use posix notation and remove
|
|
6
|
+
* all drive information.
|
|
7
|
+
*
|
|
8
|
+
*
|
|
9
|
+
* @param {String} src the filename wqe
|
|
10
|
+
* @returns {String} the new path
|
|
11
|
+
*/
|
|
12
|
+
export function forceToPosix(src) {
|
|
5
13
|
src = src.replace('file:', '');
|
|
6
14
|
src = src.replace('///', '');
|
|
7
|
-
src = src.replace(
|
|
15
|
+
src = src.replace(/.*?:/, '');
|
|
8
16
|
src = src.replace(/\\/g, '/');
|
|
9
17
|
|
|
10
18
|
return src;
|
|
11
19
|
}
|
|
12
20
|
|
|
13
|
-
|
|
21
|
+
export function fileToPath(filename) {
|
|
22
|
+
filename = fixPath(filename);
|
|
23
|
+
return path.dirname(filename);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* call this function to check if the given file exists
|
|
29
|
+
*
|
|
30
|
+
* @param {String} path the name of the file
|
|
31
|
+
* @returns {Promise<Boolean>} true if the file exists
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
export async function fileExists(path) {
|
|
14
35
|
try {
|
|
15
36
|
await stat(path)
|
|
16
37
|
return true;
|