@stencil/core 2.15.0 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/index.cjs +157 -70
- package/cli/index.js +157 -70
- package/cli/package.json +1 -1
- package/compiler/package.json +1 -1
- package/compiler/stencil.js +719 -174
- package/compiler/stencil.min.js +2 -2
- package/dependencies.json +1 -1
- package/dev-server/client/index.js +3 -3
- package/dev-server/client/package.json +1 -1
- package/dev-server/client/test/hmr-util.spec.d.ts +1 -0
- package/dev-server/client/test/status.spec.d.ts +1 -0
- package/dev-server/connector.html +3 -3
- package/dev-server/index.js +1 -1
- package/dev-server/package.json +1 -1
- package/dev-server/server-process.js +3 -3
- package/internal/app-data/package.json +1 -1
- package/internal/client/css-shim.js +2 -2
- package/internal/client/dom.js +1 -1
- package/internal/client/index.js +11 -9
- package/internal/client/package.json +1 -1
- package/internal/client/patch-browser.js +1 -1
- package/internal/client/patch-esm.js +1 -1
- package/internal/client/polyfills/css-shim.js +1 -1
- package/internal/client/shadow-css.js +2 -3
- package/internal/hydrate/index.js +34 -29
- package/internal/hydrate/package.json +1 -1
- package/internal/hydrate/runner.js +1 -1
- package/internal/hydrate/shadow-css.js +9 -9
- package/internal/package.json +1 -1
- package/internal/stencil-private.d.ts +39 -3
- package/internal/stencil-public-compiler.d.ts +69 -3
- package/internal/stencil-public-docs.d.ts +3 -0
- package/internal/testing/index.js +34 -29
- package/internal/testing/package.json +1 -1
- package/internal/testing/shadow-css.js +9 -9
- package/mock-doc/index.cjs +18 -4
- package/mock-doc/index.d.ts +12 -2
- package/mock-doc/index.js +18 -4
- package/mock-doc/package.json +1 -1
- package/package.json +24 -17
- package/screenshot/package.json +1 -1
- package/sys/node/autoprefixer.js +1 -1
- package/sys/node/index.js +2046 -1338
- package/sys/node/node-fetch.js +1 -1
- package/sys/node/package.json +1 -1
- package/sys/node/worker.js +1 -1
- package/testing/index.js +8 -8
- package/testing/jest/test/jest-config.spec.d.ts +1 -0
- package/testing/jest/test/jest-preprocessor.spec.d.ts +1 -0
- package/testing/jest/test/jest-runner.spec.d.ts +1 -0
- package/testing/jest/test/jest-serializer.spec.d.ts +1 -0
- package/testing/package.json +1 -1
package/cli/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
Stencil CLI (CommonJS) v2.
|
|
2
|
+
Stencil CLI (CommonJS) v2.16.0 | MIT Licensed | https://stenciljs.com
|
|
3
3
|
*/
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
@@ -259,15 +259,16 @@ const pathComponents = (path, rootLength) => {
|
|
|
259
259
|
* @returns an error message if the tag has an invalid name, undefined if the tag name passes all checks
|
|
260
260
|
*/
|
|
261
261
|
const validateComponentTag = (tag) => {
|
|
262
|
+
// we want to check this first since we call some String.prototype methods below
|
|
263
|
+
if (typeof tag !== 'string') {
|
|
264
|
+
return `Tag "${tag}" must be a string type`;
|
|
265
|
+
}
|
|
262
266
|
if (tag !== tag.trim()) {
|
|
263
267
|
return `Tag can not contain white spaces`;
|
|
264
268
|
}
|
|
265
269
|
if (tag !== tag.toLowerCase()) {
|
|
266
270
|
return `Tag can not contain upper case characters`;
|
|
267
271
|
}
|
|
268
|
-
if (typeof tag !== 'string') {
|
|
269
|
-
return `Tag "${tag}" must be a string type`;
|
|
270
|
-
}
|
|
271
272
|
if (tag.length === 0) {
|
|
272
273
|
return `Received empty tag value`;
|
|
273
274
|
}
|
|
@@ -329,9 +330,19 @@ const parseFlags = (args, sys) => {
|
|
|
329
330
|
});
|
|
330
331
|
return flags;
|
|
331
332
|
};
|
|
333
|
+
/**
|
|
334
|
+
* Parse command line arguments that are whitelisted via the BOOLEAN_ARG_OPTS,
|
|
335
|
+
* STRING_ARG_OPTS, and NUMBER_ARG_OPTS arrays in this file. Handles leading
|
|
336
|
+
* dashes on arguments, aliases that are defined for a small number of argument
|
|
337
|
+
* types, and parsing values for non-boolean arguments (e.g. port number).
|
|
338
|
+
*
|
|
339
|
+
* @param flags a ConfigFlags object
|
|
340
|
+
* @param args an array of command-line arguments to parse
|
|
341
|
+
* @param knownArgs an array to which all recognized, legal arguments are added
|
|
342
|
+
*/
|
|
332
343
|
const parseArgs = (flags, args, knownArgs) => {
|
|
333
|
-
|
|
334
|
-
const alias =
|
|
344
|
+
BOOLEAN_ARG_OPTS.forEach((booleanName) => {
|
|
345
|
+
const alias = ARG_OPTS_ALIASES[booleanName];
|
|
335
346
|
const flagKey = configCase(booleanName);
|
|
336
347
|
if (typeof flags[flagKey] !== 'boolean') {
|
|
337
348
|
flags[flagKey] = null;
|
|
@@ -359,8 +370,8 @@ const parseArgs = (flags, args, knownArgs) => {
|
|
|
359
370
|
}
|
|
360
371
|
});
|
|
361
372
|
});
|
|
362
|
-
|
|
363
|
-
const alias =
|
|
373
|
+
STRING_ARG_OPTS.forEach((stringName) => {
|
|
374
|
+
const alias = ARG_OPTS_ALIASES[stringName];
|
|
364
375
|
const flagKey = configCase(stringName);
|
|
365
376
|
if (typeof flags[flagKey] !== 'string') {
|
|
366
377
|
flags[flagKey] = null;
|
|
@@ -403,8 +414,8 @@ const parseArgs = (flags, args, knownArgs) => {
|
|
|
403
414
|
}
|
|
404
415
|
}
|
|
405
416
|
});
|
|
406
|
-
|
|
407
|
-
const alias =
|
|
417
|
+
NUMBER_ARG_OPTS.forEach((numberName) => {
|
|
418
|
+
const alias = ARG_OPTS_ALIASES[numberName];
|
|
408
419
|
const flagKey = configCase(numberName);
|
|
409
420
|
if (typeof flags[flagKey] !== 'number') {
|
|
410
421
|
flags[flagKey] = null;
|
|
@@ -448,50 +459,56 @@ const parseArgs = (flags, args, knownArgs) => {
|
|
|
448
459
|
};
|
|
449
460
|
const configCase = (prop) => {
|
|
450
461
|
prop = dashToPascalCase(prop);
|
|
451
|
-
return prop.charAt(0).toLowerCase() + prop.
|
|
462
|
+
return prop.charAt(0).toLowerCase() + prop.slice(1);
|
|
452
463
|
};
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
464
|
+
const BOOLEAN_ARG_OPTS = [
|
|
465
|
+
'build',
|
|
466
|
+
'cache',
|
|
467
|
+
'check-version',
|
|
468
|
+
'ci',
|
|
469
|
+
'compare',
|
|
470
|
+
'debug',
|
|
471
|
+
'dev',
|
|
472
|
+
'devtools',
|
|
473
|
+
'docs',
|
|
474
|
+
'e2e',
|
|
475
|
+
'es5',
|
|
476
|
+
'esm',
|
|
477
|
+
'headless',
|
|
478
|
+
'help',
|
|
479
|
+
'log',
|
|
480
|
+
'open',
|
|
481
|
+
'prerender',
|
|
482
|
+
'prerender-external',
|
|
483
|
+
'prod',
|
|
484
|
+
'profile',
|
|
485
|
+
'service-worker',
|
|
486
|
+
'screenshot',
|
|
487
|
+
'serve',
|
|
488
|
+
'skip-node-check',
|
|
489
|
+
'spec',
|
|
490
|
+
'ssr',
|
|
491
|
+
'stats',
|
|
492
|
+
'update-screenshot',
|
|
493
|
+
'verbose',
|
|
494
|
+
'version',
|
|
495
|
+
'watch',
|
|
496
|
+
];
|
|
497
|
+
const NUMBER_ARG_OPTS = ['max-workers', 'port'];
|
|
498
|
+
const STRING_ARG_OPTS = [
|
|
499
|
+
'address',
|
|
500
|
+
'config',
|
|
501
|
+
'docs-json',
|
|
502
|
+
'emulate',
|
|
503
|
+
'log-level',
|
|
504
|
+
'root',
|
|
505
|
+
'screenshot-connector',
|
|
506
|
+
];
|
|
507
|
+
const ARG_OPTS_ALIASES = {
|
|
508
|
+
config: 'c',
|
|
509
|
+
help: 'h',
|
|
510
|
+
port: 'p',
|
|
511
|
+
version: 'v',
|
|
495
512
|
};
|
|
496
513
|
const getNpmConfigEnvArgs = (sys) => {
|
|
497
514
|
// process.env.npm_config_argv
|
|
@@ -513,7 +530,7 @@ const getNpmConfigEnvArgs = (sys) => {
|
|
|
513
530
|
const dependencies = [
|
|
514
531
|
{
|
|
515
532
|
name: "@stencil/core",
|
|
516
|
-
version: "2.
|
|
533
|
+
version: "2.16.0",
|
|
517
534
|
main: "compiler/stencil.js",
|
|
518
535
|
resources: [
|
|
519
536
|
"package.json",
|
|
@@ -950,10 +967,10 @@ async function updateConfig(sys, newOptions) {
|
|
|
950
967
|
|
|
951
968
|
const isOutputTargetDocs = (o) => o.type === DOCS_README || o.type === DOCS_JSON || o.type === DOCS_CUSTOM || o.type === DOCS_VSCODE;
|
|
952
969
|
const DOCS_CUSTOM = 'docs-custom';
|
|
953
|
-
const DOCS_JSON =
|
|
954
|
-
const DOCS_README =
|
|
955
|
-
const DOCS_VSCODE =
|
|
956
|
-
const WWW =
|
|
970
|
+
const DOCS_JSON = 'docs-json';
|
|
971
|
+
const DOCS_README = 'docs-readme';
|
|
972
|
+
const DOCS_VSCODE = 'docs-vscode';
|
|
973
|
+
const WWW = 'www';
|
|
957
974
|
|
|
958
975
|
/**
|
|
959
976
|
* Used to within taskBuild to provide the component_count property.
|
|
@@ -1290,7 +1307,14 @@ const IS_NODE_ENV = typeof global !== 'undefined' &&
|
|
|
1290
1307
|
(!global.origin || typeof global.origin !== 'string');
|
|
1291
1308
|
|
|
1292
1309
|
/**
|
|
1293
|
-
* Task to generate component boilerplate.
|
|
1310
|
+
* Task to generate component boilerplate and write it to disk. This task can
|
|
1311
|
+
* cause the program to exit with an error under various circumstances, such as
|
|
1312
|
+
* being called in an inappropriate place, being asked to overwrite files that
|
|
1313
|
+
* already exist, etc.
|
|
1314
|
+
*
|
|
1315
|
+
* @param coreCompiler the CoreCompiler we're using currently, here we're
|
|
1316
|
+
* mainly accessing the `path` module
|
|
1317
|
+
* @param config the user-supplied config, which we need here to access `.sys`.
|
|
1294
1318
|
*/
|
|
1295
1319
|
const taskGenerate = async (coreCompiler, config) => {
|
|
1296
1320
|
if (!IS_NODE_ENV) {
|
|
@@ -1320,10 +1344,16 @@ const taskGenerate = async (coreCompiler, config) => {
|
|
|
1320
1344
|
const testFolder = extensionsToGenerate.some(isTest) ? 'test' : '';
|
|
1321
1345
|
const outDir = path.join(absoluteSrcDir, 'components', dir, componentName);
|
|
1322
1346
|
await config.sys.createDir(path.join(outDir, testFolder), { recursive: true });
|
|
1323
|
-
const
|
|
1347
|
+
const filesToGenerate = extensionsToGenerate.map((extension) => ({
|
|
1348
|
+
extension,
|
|
1349
|
+
path: getFilepathForFile(coreCompiler, outDir, componentName, extension),
|
|
1350
|
+
}));
|
|
1351
|
+
await checkForOverwrite(filesToGenerate, config);
|
|
1352
|
+
const writtenFiles = await Promise.all(filesToGenerate.map((file) => getBoilerplateAndWriteFile(config, componentName, extensionsToGenerate.includes('css'), file))).catch((error) => config.logger.error(error));
|
|
1324
1353
|
if (!writtenFiles) {
|
|
1325
1354
|
return config.sys.exit(1);
|
|
1326
1355
|
}
|
|
1356
|
+
// TODO(STENCIL-424): Investigate moving these console.log calls to config.logger.info
|
|
1327
1357
|
console.log();
|
|
1328
1358
|
console.log(`${config.logger.gray('$')} stencil generate ${input}`);
|
|
1329
1359
|
console.log();
|
|
@@ -1333,6 +1363,9 @@ const taskGenerate = async (coreCompiler, config) => {
|
|
|
1333
1363
|
};
|
|
1334
1364
|
/**
|
|
1335
1365
|
* Show a checkbox prompt to select the files to be generated.
|
|
1366
|
+
*
|
|
1367
|
+
* @returns a read-only array of `GenerableExtension`, the extensions that the user has decided
|
|
1368
|
+
* to generate
|
|
1336
1369
|
*/
|
|
1337
1370
|
const chooseFilesToGenerate = async () => {
|
|
1338
1371
|
const { prompt } = await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('../sys/node/prompts.js')); });
|
|
@@ -1348,22 +1381,76 @@ const chooseFilesToGenerate = async () => {
|
|
|
1348
1381
|
})).filesToGenerate;
|
|
1349
1382
|
};
|
|
1350
1383
|
/**
|
|
1351
|
-
* Get a
|
|
1384
|
+
* Get a filepath for a file we want to generate!
|
|
1385
|
+
*
|
|
1386
|
+
* The filepath for a given file depends on the path, the user-supplied
|
|
1387
|
+
* component name, the extension, and whether we're inside of a test directory.
|
|
1388
|
+
*
|
|
1389
|
+
* @param coreCompiler the compiler we're using, here to acces the `.path` module
|
|
1390
|
+
* @param path path to where we're going to generate the component
|
|
1391
|
+
* @param componentName the user-supplied name for the generated component
|
|
1392
|
+
* @param extension the file extension
|
|
1393
|
+
* @returns the full filepath to the component (with a possible `test` directory
|
|
1394
|
+
* added)
|
|
1352
1395
|
*/
|
|
1353
|
-
const
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1396
|
+
const getFilepathForFile = (coreCompiler, path, componentName, extension) => isTest(extension)
|
|
1397
|
+
? coreCompiler.path.join(path, 'test', `${componentName}.${extension}`)
|
|
1398
|
+
: coreCompiler.path.join(path, `${componentName}.${extension}`);
|
|
1399
|
+
/**
|
|
1400
|
+
* Get the boilerplate for a file and write it to disk
|
|
1401
|
+
*
|
|
1402
|
+
* @param config the current config, needed for file operations
|
|
1403
|
+
* @param componentName the component name (user-supplied)
|
|
1404
|
+
* @param withCss are we generating CSS?
|
|
1405
|
+
* @param file the file we want to write
|
|
1406
|
+
* @returns a `Promise<string>` which holds the full filepath we've written to,
|
|
1407
|
+
* used to print out a little summary of our activity to the user.
|
|
1408
|
+
*/
|
|
1409
|
+
const getBoilerplateAndWriteFile = async (config, componentName, withCss, file) => {
|
|
1410
|
+
const boilerplate = getBoilerplateByExtension(componentName, file.extension, withCss);
|
|
1411
|
+
await config.sys.writeFile(file.path, boilerplate);
|
|
1412
|
+
return file.path;
|
|
1413
|
+
};
|
|
1414
|
+
/**
|
|
1415
|
+
* Check to see if any of the files we plan to write already exist and would
|
|
1416
|
+
* therefore be overwritten if we proceed, because we'd like to not overwrite
|
|
1417
|
+
* people's code!
|
|
1418
|
+
*
|
|
1419
|
+
* This function will check all the filepaths and if it finds any files log an
|
|
1420
|
+
* error and exit with an error code. If it doesn't find anything it will just
|
|
1421
|
+
* peacefully return `Promise<void>`.
|
|
1422
|
+
*
|
|
1423
|
+
* @param files the files we want to check
|
|
1424
|
+
* @param config the Config object, used here to get access to `sys.readFile`
|
|
1425
|
+
*/
|
|
1426
|
+
const checkForOverwrite = async (files, config) => {
|
|
1427
|
+
const alreadyPresent = [];
|
|
1428
|
+
await Promise.all(files.map(async ({ path }) => {
|
|
1429
|
+
if ((await config.sys.readFile(path)) !== undefined) {
|
|
1430
|
+
alreadyPresent.push(path);
|
|
1431
|
+
}
|
|
1432
|
+
}));
|
|
1433
|
+
if (alreadyPresent.length > 0) {
|
|
1434
|
+
config.logger.error('Generating code would overwrite the following files:', ...alreadyPresent.map((path) => '\t' + path));
|
|
1435
|
+
await config.sys.exit(1);
|
|
1436
|
+
}
|
|
1361
1437
|
};
|
|
1438
|
+
/**
|
|
1439
|
+
* Check if an extension is for a test
|
|
1440
|
+
*
|
|
1441
|
+
* @param extension the extension we want to check
|
|
1442
|
+
* @returns a boolean indicating whether or not its a test
|
|
1443
|
+
*/
|
|
1362
1444
|
const isTest = (extension) => {
|
|
1363
1445
|
return extension === 'e2e.ts' || extension === 'spec.tsx';
|
|
1364
1446
|
};
|
|
1365
1447
|
/**
|
|
1366
1448
|
* Get the boilerplate for a file by its extension.
|
|
1449
|
+
*
|
|
1450
|
+
* @param tagName the name of the component we're generating
|
|
1451
|
+
* @param extension the file extension we want boilerplate for (.css, tsx, etc)
|
|
1452
|
+
* @param withCss a boolean indicating whether we're generating a CSS file
|
|
1453
|
+
* @returns a string container the file boilerplate for the supplied extension
|
|
1367
1454
|
*/
|
|
1368
1455
|
const getBoilerplateByExtension = (tagName, extension, withCss) => {
|
|
1369
1456
|
switch (extension) {
|
|
@@ -1453,7 +1540,7 @@ describe('${name}', () => {
|
|
|
1453
1540
|
/**
|
|
1454
1541
|
* Convert a dash case string to pascal case.
|
|
1455
1542
|
*/
|
|
1456
|
-
const toPascalCase = (str) => str.split('-').reduce((res, part) => res + part[0].toUpperCase() + part.
|
|
1543
|
+
const toPascalCase = (str) => str.split('-').reduce((res, part) => res + part[0].toUpperCase() + part.slice(1), '');
|
|
1457
1544
|
|
|
1458
1545
|
const taskTelemetry = async (config, sys, logger) => {
|
|
1459
1546
|
const prompt = logger.dim(sys.details.platform === 'windows' ? '>' : '$');
|
package/cli/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
Stencil CLI v2.
|
|
2
|
+
Stencil CLI v2.16.0 | MIT Licensed | https://stenciljs.com
|
|
3
3
|
*/
|
|
4
4
|
const toLowerCase = (str) => str.toLowerCase();
|
|
5
5
|
const dashToPascalCase = (str) => toLowerCase(str)
|
|
@@ -235,15 +235,16 @@ const pathComponents = (path, rootLength) => {
|
|
|
235
235
|
* @returns an error message if the tag has an invalid name, undefined if the tag name passes all checks
|
|
236
236
|
*/
|
|
237
237
|
const validateComponentTag = (tag) => {
|
|
238
|
+
// we want to check this first since we call some String.prototype methods below
|
|
239
|
+
if (typeof tag !== 'string') {
|
|
240
|
+
return `Tag "${tag}" must be a string type`;
|
|
241
|
+
}
|
|
238
242
|
if (tag !== tag.trim()) {
|
|
239
243
|
return `Tag can not contain white spaces`;
|
|
240
244
|
}
|
|
241
245
|
if (tag !== tag.toLowerCase()) {
|
|
242
246
|
return `Tag can not contain upper case characters`;
|
|
243
247
|
}
|
|
244
|
-
if (typeof tag !== 'string') {
|
|
245
|
-
return `Tag "${tag}" must be a string type`;
|
|
246
|
-
}
|
|
247
248
|
if (tag.length === 0) {
|
|
248
249
|
return `Received empty tag value`;
|
|
249
250
|
}
|
|
@@ -305,9 +306,19 @@ const parseFlags = (args, sys) => {
|
|
|
305
306
|
});
|
|
306
307
|
return flags;
|
|
307
308
|
};
|
|
309
|
+
/**
|
|
310
|
+
* Parse command line arguments that are whitelisted via the BOOLEAN_ARG_OPTS,
|
|
311
|
+
* STRING_ARG_OPTS, and NUMBER_ARG_OPTS arrays in this file. Handles leading
|
|
312
|
+
* dashes on arguments, aliases that are defined for a small number of argument
|
|
313
|
+
* types, and parsing values for non-boolean arguments (e.g. port number).
|
|
314
|
+
*
|
|
315
|
+
* @param flags a ConfigFlags object
|
|
316
|
+
* @param args an array of command-line arguments to parse
|
|
317
|
+
* @param knownArgs an array to which all recognized, legal arguments are added
|
|
318
|
+
*/
|
|
308
319
|
const parseArgs = (flags, args, knownArgs) => {
|
|
309
|
-
|
|
310
|
-
const alias =
|
|
320
|
+
BOOLEAN_ARG_OPTS.forEach((booleanName) => {
|
|
321
|
+
const alias = ARG_OPTS_ALIASES[booleanName];
|
|
311
322
|
const flagKey = configCase(booleanName);
|
|
312
323
|
if (typeof flags[flagKey] !== 'boolean') {
|
|
313
324
|
flags[flagKey] = null;
|
|
@@ -335,8 +346,8 @@ const parseArgs = (flags, args, knownArgs) => {
|
|
|
335
346
|
}
|
|
336
347
|
});
|
|
337
348
|
});
|
|
338
|
-
|
|
339
|
-
const alias =
|
|
349
|
+
STRING_ARG_OPTS.forEach((stringName) => {
|
|
350
|
+
const alias = ARG_OPTS_ALIASES[stringName];
|
|
340
351
|
const flagKey = configCase(stringName);
|
|
341
352
|
if (typeof flags[flagKey] !== 'string') {
|
|
342
353
|
flags[flagKey] = null;
|
|
@@ -379,8 +390,8 @@ const parseArgs = (flags, args, knownArgs) => {
|
|
|
379
390
|
}
|
|
380
391
|
}
|
|
381
392
|
});
|
|
382
|
-
|
|
383
|
-
const alias =
|
|
393
|
+
NUMBER_ARG_OPTS.forEach((numberName) => {
|
|
394
|
+
const alias = ARG_OPTS_ALIASES[numberName];
|
|
384
395
|
const flagKey = configCase(numberName);
|
|
385
396
|
if (typeof flags[flagKey] !== 'number') {
|
|
386
397
|
flags[flagKey] = null;
|
|
@@ -424,50 +435,56 @@ const parseArgs = (flags, args, knownArgs) => {
|
|
|
424
435
|
};
|
|
425
436
|
const configCase = (prop) => {
|
|
426
437
|
prop = dashToPascalCase(prop);
|
|
427
|
-
return prop.charAt(0).toLowerCase() + prop.
|
|
438
|
+
return prop.charAt(0).toLowerCase() + prop.slice(1);
|
|
428
439
|
};
|
|
429
|
-
const
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
440
|
+
const BOOLEAN_ARG_OPTS = [
|
|
441
|
+
'build',
|
|
442
|
+
'cache',
|
|
443
|
+
'check-version',
|
|
444
|
+
'ci',
|
|
445
|
+
'compare',
|
|
446
|
+
'debug',
|
|
447
|
+
'dev',
|
|
448
|
+
'devtools',
|
|
449
|
+
'docs',
|
|
450
|
+
'e2e',
|
|
451
|
+
'es5',
|
|
452
|
+
'esm',
|
|
453
|
+
'headless',
|
|
454
|
+
'help',
|
|
455
|
+
'log',
|
|
456
|
+
'open',
|
|
457
|
+
'prerender',
|
|
458
|
+
'prerender-external',
|
|
459
|
+
'prod',
|
|
460
|
+
'profile',
|
|
461
|
+
'service-worker',
|
|
462
|
+
'screenshot',
|
|
463
|
+
'serve',
|
|
464
|
+
'skip-node-check',
|
|
465
|
+
'spec',
|
|
466
|
+
'ssr',
|
|
467
|
+
'stats',
|
|
468
|
+
'update-screenshot',
|
|
469
|
+
'verbose',
|
|
470
|
+
'version',
|
|
471
|
+
'watch',
|
|
472
|
+
];
|
|
473
|
+
const NUMBER_ARG_OPTS = ['max-workers', 'port'];
|
|
474
|
+
const STRING_ARG_OPTS = [
|
|
475
|
+
'address',
|
|
476
|
+
'config',
|
|
477
|
+
'docs-json',
|
|
478
|
+
'emulate',
|
|
479
|
+
'log-level',
|
|
480
|
+
'root',
|
|
481
|
+
'screenshot-connector',
|
|
482
|
+
];
|
|
483
|
+
const ARG_OPTS_ALIASES = {
|
|
484
|
+
config: 'c',
|
|
485
|
+
help: 'h',
|
|
486
|
+
port: 'p',
|
|
487
|
+
version: 'v',
|
|
471
488
|
};
|
|
472
489
|
const getNpmConfigEnvArgs = (sys) => {
|
|
473
490
|
// process.env.npm_config_argv
|
|
@@ -489,7 +506,7 @@ const getNpmConfigEnvArgs = (sys) => {
|
|
|
489
506
|
const dependencies = [
|
|
490
507
|
{
|
|
491
508
|
name: "@stencil/core",
|
|
492
|
-
version: "2.
|
|
509
|
+
version: "2.16.0",
|
|
493
510
|
main: "compiler/stencil.js",
|
|
494
511
|
resources: [
|
|
495
512
|
"package.json",
|
|
@@ -926,10 +943,10 @@ async function updateConfig(sys, newOptions) {
|
|
|
926
943
|
|
|
927
944
|
const isOutputTargetDocs = (o) => o.type === DOCS_README || o.type === DOCS_JSON || o.type === DOCS_CUSTOM || o.type === DOCS_VSCODE;
|
|
928
945
|
const DOCS_CUSTOM = 'docs-custom';
|
|
929
|
-
const DOCS_JSON =
|
|
930
|
-
const DOCS_README =
|
|
931
|
-
const DOCS_VSCODE =
|
|
932
|
-
const WWW =
|
|
946
|
+
const DOCS_JSON = 'docs-json';
|
|
947
|
+
const DOCS_README = 'docs-readme';
|
|
948
|
+
const DOCS_VSCODE = 'docs-vscode';
|
|
949
|
+
const WWW = 'www';
|
|
933
950
|
|
|
934
951
|
/**
|
|
935
952
|
* Used to within taskBuild to provide the component_count property.
|
|
@@ -1266,7 +1283,14 @@ const IS_NODE_ENV = typeof global !== 'undefined' &&
|
|
|
1266
1283
|
(!global.origin || typeof global.origin !== 'string');
|
|
1267
1284
|
|
|
1268
1285
|
/**
|
|
1269
|
-
* Task to generate component boilerplate.
|
|
1286
|
+
* Task to generate component boilerplate and write it to disk. This task can
|
|
1287
|
+
* cause the program to exit with an error under various circumstances, such as
|
|
1288
|
+
* being called in an inappropriate place, being asked to overwrite files that
|
|
1289
|
+
* already exist, etc.
|
|
1290
|
+
*
|
|
1291
|
+
* @param coreCompiler the CoreCompiler we're using currently, here we're
|
|
1292
|
+
* mainly accessing the `path` module
|
|
1293
|
+
* @param config the user-supplied config, which we need here to access `.sys`.
|
|
1270
1294
|
*/
|
|
1271
1295
|
const taskGenerate = async (coreCompiler, config) => {
|
|
1272
1296
|
if (!IS_NODE_ENV) {
|
|
@@ -1296,10 +1320,16 @@ const taskGenerate = async (coreCompiler, config) => {
|
|
|
1296
1320
|
const testFolder = extensionsToGenerate.some(isTest) ? 'test' : '';
|
|
1297
1321
|
const outDir = path.join(absoluteSrcDir, 'components', dir, componentName);
|
|
1298
1322
|
await config.sys.createDir(path.join(outDir, testFolder), { recursive: true });
|
|
1299
|
-
const
|
|
1323
|
+
const filesToGenerate = extensionsToGenerate.map((extension) => ({
|
|
1324
|
+
extension,
|
|
1325
|
+
path: getFilepathForFile(coreCompiler, outDir, componentName, extension),
|
|
1326
|
+
}));
|
|
1327
|
+
await checkForOverwrite(filesToGenerate, config);
|
|
1328
|
+
const writtenFiles = await Promise.all(filesToGenerate.map((file) => getBoilerplateAndWriteFile(config, componentName, extensionsToGenerate.includes('css'), file))).catch((error) => config.logger.error(error));
|
|
1300
1329
|
if (!writtenFiles) {
|
|
1301
1330
|
return config.sys.exit(1);
|
|
1302
1331
|
}
|
|
1332
|
+
// TODO(STENCIL-424): Investigate moving these console.log calls to config.logger.info
|
|
1303
1333
|
console.log();
|
|
1304
1334
|
console.log(`${config.logger.gray('$')} stencil generate ${input}`);
|
|
1305
1335
|
console.log();
|
|
@@ -1309,6 +1339,9 @@ const taskGenerate = async (coreCompiler, config) => {
|
|
|
1309
1339
|
};
|
|
1310
1340
|
/**
|
|
1311
1341
|
* Show a checkbox prompt to select the files to be generated.
|
|
1342
|
+
*
|
|
1343
|
+
* @returns a read-only array of `GenerableExtension`, the extensions that the user has decided
|
|
1344
|
+
* to generate
|
|
1312
1345
|
*/
|
|
1313
1346
|
const chooseFilesToGenerate = async () => {
|
|
1314
1347
|
const { prompt } = await import('../sys/node/prompts.js');
|
|
@@ -1324,22 +1357,76 @@ const chooseFilesToGenerate = async () => {
|
|
|
1324
1357
|
})).filesToGenerate;
|
|
1325
1358
|
};
|
|
1326
1359
|
/**
|
|
1327
|
-
* Get a
|
|
1360
|
+
* Get a filepath for a file we want to generate!
|
|
1361
|
+
*
|
|
1362
|
+
* The filepath for a given file depends on the path, the user-supplied
|
|
1363
|
+
* component name, the extension, and whether we're inside of a test directory.
|
|
1364
|
+
*
|
|
1365
|
+
* @param coreCompiler the compiler we're using, here to acces the `.path` module
|
|
1366
|
+
* @param path path to where we're going to generate the component
|
|
1367
|
+
* @param componentName the user-supplied name for the generated component
|
|
1368
|
+
* @param extension the file extension
|
|
1369
|
+
* @returns the full filepath to the component (with a possible `test` directory
|
|
1370
|
+
* added)
|
|
1328
1371
|
*/
|
|
1329
|
-
const
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1372
|
+
const getFilepathForFile = (coreCompiler, path, componentName, extension) => isTest(extension)
|
|
1373
|
+
? coreCompiler.path.join(path, 'test', `${componentName}.${extension}`)
|
|
1374
|
+
: coreCompiler.path.join(path, `${componentName}.${extension}`);
|
|
1375
|
+
/**
|
|
1376
|
+
* Get the boilerplate for a file and write it to disk
|
|
1377
|
+
*
|
|
1378
|
+
* @param config the current config, needed for file operations
|
|
1379
|
+
* @param componentName the component name (user-supplied)
|
|
1380
|
+
* @param withCss are we generating CSS?
|
|
1381
|
+
* @param file the file we want to write
|
|
1382
|
+
* @returns a `Promise<string>` which holds the full filepath we've written to,
|
|
1383
|
+
* used to print out a little summary of our activity to the user.
|
|
1384
|
+
*/
|
|
1385
|
+
const getBoilerplateAndWriteFile = async (config, componentName, withCss, file) => {
|
|
1386
|
+
const boilerplate = getBoilerplateByExtension(componentName, file.extension, withCss);
|
|
1387
|
+
await config.sys.writeFile(file.path, boilerplate);
|
|
1388
|
+
return file.path;
|
|
1389
|
+
};
|
|
1390
|
+
/**
|
|
1391
|
+
* Check to see if any of the files we plan to write already exist and would
|
|
1392
|
+
* therefore be overwritten if we proceed, because we'd like to not overwrite
|
|
1393
|
+
* people's code!
|
|
1394
|
+
*
|
|
1395
|
+
* This function will check all the filepaths and if it finds any files log an
|
|
1396
|
+
* error and exit with an error code. If it doesn't find anything it will just
|
|
1397
|
+
* peacefully return `Promise<void>`.
|
|
1398
|
+
*
|
|
1399
|
+
* @param files the files we want to check
|
|
1400
|
+
* @param config the Config object, used here to get access to `sys.readFile`
|
|
1401
|
+
*/
|
|
1402
|
+
const checkForOverwrite = async (files, config) => {
|
|
1403
|
+
const alreadyPresent = [];
|
|
1404
|
+
await Promise.all(files.map(async ({ path }) => {
|
|
1405
|
+
if ((await config.sys.readFile(path)) !== undefined) {
|
|
1406
|
+
alreadyPresent.push(path);
|
|
1407
|
+
}
|
|
1408
|
+
}));
|
|
1409
|
+
if (alreadyPresent.length > 0) {
|
|
1410
|
+
config.logger.error('Generating code would overwrite the following files:', ...alreadyPresent.map((path) => '\t' + path));
|
|
1411
|
+
await config.sys.exit(1);
|
|
1412
|
+
}
|
|
1337
1413
|
};
|
|
1414
|
+
/**
|
|
1415
|
+
* Check if an extension is for a test
|
|
1416
|
+
*
|
|
1417
|
+
* @param extension the extension we want to check
|
|
1418
|
+
* @returns a boolean indicating whether or not its a test
|
|
1419
|
+
*/
|
|
1338
1420
|
const isTest = (extension) => {
|
|
1339
1421
|
return extension === 'e2e.ts' || extension === 'spec.tsx';
|
|
1340
1422
|
};
|
|
1341
1423
|
/**
|
|
1342
1424
|
* Get the boilerplate for a file by its extension.
|
|
1425
|
+
*
|
|
1426
|
+
* @param tagName the name of the component we're generating
|
|
1427
|
+
* @param extension the file extension we want boilerplate for (.css, tsx, etc)
|
|
1428
|
+
* @param withCss a boolean indicating whether we're generating a CSS file
|
|
1429
|
+
* @returns a string container the file boilerplate for the supplied extension
|
|
1343
1430
|
*/
|
|
1344
1431
|
const getBoilerplateByExtension = (tagName, extension, withCss) => {
|
|
1345
1432
|
switch (extension) {
|
|
@@ -1429,7 +1516,7 @@ describe('${name}', () => {
|
|
|
1429
1516
|
/**
|
|
1430
1517
|
* Convert a dash case string to pascal case.
|
|
1431
1518
|
*/
|
|
1432
|
-
const toPascalCase = (str) => str.split('-').reduce((res, part) => res + part[0].toUpperCase() + part.
|
|
1519
|
+
const toPascalCase = (str) => str.split('-').reduce((res, part) => res + part[0].toUpperCase() + part.slice(1), '');
|
|
1433
1520
|
|
|
1434
1521
|
const taskTelemetry = async (config, sys, logger) => {
|
|
1435
1522
|
const prompt = logger.dim(sys.details.platform === 'windows' ? '>' : '$');
|