@stencil/core 5.0.0-alpha.27 → 5.0.0-alpha.29
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/dist/app-data/index.d.ts +1 -1
- package/dist/{client-CvcvHKz4.mjs → client-D1MsT-Rp.mjs} +373 -238
- package/dist/compiler/index.d.mts +2 -3
- package/dist/compiler/index.mjs +3 -3
- package/dist/compiler/utils/index.d.mts +272 -2
- package/dist/compiler/utils/index.mjs +4 -3
- package/dist/{compiler-D43Ied7R.mjs → compiler-BbS9TDF_.mjs} +1845 -1118
- package/dist/declarations/stencil-ext-modules.d.ts +5 -5
- package/dist/declarations/stencil-public-compiler.d.ts +108 -40
- package/dist/declarations/stencil-public-docs.d.ts +9 -0
- package/dist/declarations/stencil-public-runtime.d.ts +81 -6
- package/dist/fragment-Di1hWOC8.mjs +4 -0
- package/dist/{index-F3IidHM1.d.mts → index-BHj3EBl2.d.mts} +395 -312
- package/dist/{index-xAkMgLX_.d.ts → index-D2PAsXxx.d.ts} +133 -9
- package/dist/index-VK8okIiF.d.mts +108 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.mjs +91 -2
- package/dist/jsx-runtime.mjs +2 -1
- package/dist/{node-DKVq_Ud0.mjs → node-BQR4L-TG.mjs} +60 -58
- package/dist/reactive-controller-BdCpSAQP.d.mts +13 -0
- package/dist/{regular-expression-CFVJOTUh.mjs → regular-expression-XqU5zmPp.mjs} +20 -3
- package/dist/{chunk-z9aeyW2b.mjs → rolldown-runtime-BhDjJH2R.mjs} +1 -1
- package/dist/runtime/client/lazy.js +411 -165
- package/dist/runtime/client/runtime.d.ts +136 -9
- package/dist/runtime/client/runtime.js +411 -165
- package/dist/runtime/index.d.ts +5 -3
- package/dist/runtime/index.js +410 -163
- package/dist/runtime/server/index.d.mts +80 -8
- package/dist/runtime/server/index.mjs +333 -158
- package/dist/runtime/server/runner.d.mts +3 -0
- package/dist/runtime/server/runner.mjs +232 -308
- package/dist/signals/index.d.ts +2 -0
- package/dist/sys/node/index.d.mts +1 -2
- package/dist/sys/node/index.mjs +1 -1
- package/dist/sys/node/worker.d.mts +1 -1
- package/dist/sys/node/worker.mjs +6 -3
- package/dist/testing/index.d.mts +4 -9
- package/dist/testing/index.mjs +74 -56
- package/dist/util-BIa-iHnt.mjs +724 -0
- package/dist/validation-Dd3g77T5.mjs +778 -0
- package/package.json +27 -27
- package/dist/index-3fu7WQs4.d.mts +0 -205
- package/dist/validation-ByxKj8bC.mjs +0 -1458
- /package/{LICENSE.md → LICENSE} +0 -0
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { n as __require } from "./
|
|
2
|
-
import { O as HYDRATED_CSS, f as scopeCss } from "./client-
|
|
3
|
-
import { $ as
|
|
4
|
-
import {
|
|
5
|
-
import { i as
|
|
1
|
+
import { n as __require } from "./rolldown-runtime-BhDjJH2R.mjs";
|
|
2
|
+
import { O as HYDRATED_CSS, f as scopeCss } from "./client-D1MsT-Rp.mjs";
|
|
3
|
+
import { $ as TYPES, B as GLOBAL_STYLE, C as ASSETS, D as COLLECTION_MANIFEST_FILE_NAME, E as COLLECTION_APP_DATA_FILE_NAME, F as DOCS_JSON, I as DOCS_README, O as COPY, R as EVENT_FLAGS, T as COLLECTION, W as LOADER_BUNDLE, X as STATS, Y as STANDALONE, Z as STYLE_EXT, _ as sortBy, a as fromEntries, b as toTitleCase, d as isNumber$1, et as VALID_CONFIG_OUTPUT_TARGETS, f as isObject, h as noop, i as flatOne, j as DIST_LAZY, l as isFunction, m as mergeIntoWith, n as dashToPascalCase, o as isBoolean$1, p as isString$1, tt as WATCH_FLAGS, u as isIterable, x as unique, y as toDashCase, z as GENERATED_DTS } from "./regular-expression-XqU5zmPp.mjs";
|
|
4
|
+
import { S as formatComponentRuntimeMeta, T as byteSize, _ as loadRolldownDiagnostics, a as getSourceMappingUrlForEndOfFile, b as splitLineBreaks, c as err, f as augmentDiagnosticWithNode, g as isRolldownError, h as createOnWarnFn, i as getInlineSourceMappingUrlLinker, l as map, m as loadTypeScriptDiagnostics, n as validateComponentTag, p as loadTypeScriptDiagnostic, r as isRemoteUrl, s as rolldownToStencilSourceMap, t as validateComponentModes, u as ok, w as stringifyRuntimeData, x as isRootPath, y as normalizeDiagnostics } from "./validation-Dd3g77T5.mjs";
|
|
5
|
+
import { $ as catchError, A as isOutputTargetDocsVscode, B as relativeImport, C as isOutputTargetDistLazy, D as isOutputTargetDocsCustomElementsManifest, E as isOutputTargetDocsCustom, F as isOutputTargetStandalone, G as normalizeFsPathQuery, H as join$2, I as isOutputTargetStats, J as resolve$2, K as normalizePath, L as isOutputTargetTypes, M as isOutputTargetLoaderBundle, N as isOutputTargetSsr, O as isOutputTargetDocsJson, P as isOutputTargetSsrWasm, Q as buildWarn, R as isOutputTargetWww, S as isOutputTargetCustom, T as isOutputTargetDocsAgentSkill, W as normalizeFsPath, X as buildError, Z as buildJsonFileError, a as hasDependency, b as isOutputTargetCollection, d as parsePackageJson, et as hasError, f as readOnlyArrayHasStringMember, g as getComponentsDtsSrcFilePath, h as filterExcludedComponents, i as getTextDocs, j as isOutputTargetGlobalStyle, k as isOutputTargetDocsReadme, l as isTsFile, m as filterActiveTargets, n as createJsVarName, o as isDtsFile, p as readPackageJson, q as relative$1, r as generatePreamble, rt as isGlob, t as addDocBlock, tt as hasWarning, u as isTsxFile, v as getComponentsFromModules, w as isOutputTargetDocs, x as isOutputTargetCopy, y as isOutputTargetAssets, z as isValidConfigOutputTarget } from "./util-BIa-iHnt.mjs";
|
|
6
|
+
import { i as CustomElementsExportBehaviorOptions, o as buildEvents, r as createNodeLogger, t as createNodeSys } from "./node-BQR4L-TG.mjs";
|
|
6
7
|
import ts, { default as ts$1 } from "typescript";
|
|
7
8
|
import { readFileSync } from "node:fs";
|
|
8
9
|
import { basename, dirname, isAbsolute, join, resolve } from "node:path";
|
|
9
10
|
import { fileURLToPath } from "node:url";
|
|
10
11
|
import picomatch from "picomatch";
|
|
11
|
-
import path
|
|
12
|
+
import path, { basename as basename$1, dirname as dirname$1, extname, isAbsolute as isAbsolute$1, join as join$1 } from "path";
|
|
12
13
|
import { cloneDocument, createDocument, serializeNodeToHtml } from "@stencil/mock-doc";
|
|
13
14
|
import postcss from "postcss";
|
|
14
15
|
import postcssSafeParser from "postcss-safe-parser";
|
|
@@ -28,9 +29,9 @@ import { createJiti } from "jiti";
|
|
|
28
29
|
import * as process$1 from "process";
|
|
29
30
|
import { dataToEsm } from "@rollup/pluginutils";
|
|
30
31
|
//#region src/version.ts
|
|
31
|
-
const version = "5.0.0-alpha.
|
|
32
|
-
const buildId = "
|
|
33
|
-
const vermoji = "
|
|
32
|
+
const version = "5.0.0-alpha.29";
|
|
33
|
+
const buildId = "1786998516";
|
|
34
|
+
const vermoji = "👾";
|
|
34
35
|
/**
|
|
35
36
|
* Get the installed version of a tool/dependency.
|
|
36
37
|
* Handles packages with exports maps that point to subdirectories.
|
|
@@ -41,7 +42,9 @@ const vermoji = "🏎";
|
|
|
41
42
|
*/
|
|
42
43
|
function getToolVersion(name) {
|
|
43
44
|
try {
|
|
44
|
-
|
|
45
|
+
const entryUrl = import.meta.resolve(name);
|
|
46
|
+
const entryPath = fileURLToPath(entryUrl);
|
|
47
|
+
let dir = dirname(entryPath);
|
|
45
48
|
while (dir !== dirname(dir)) {
|
|
46
49
|
const pkgPath = join(dir, "package.json");
|
|
47
50
|
try {
|
|
@@ -161,7 +164,8 @@ const getModuleLegacy = (compilerCtx, sourceFilePath) => {
|
|
|
161
164
|
else {
|
|
162
165
|
const sourceFileDir = dirname$1(sourceFilePath);
|
|
163
166
|
const sourceFileExt = extname(sourceFilePath);
|
|
164
|
-
const
|
|
167
|
+
const sourceFileName = basename$1(sourceFilePath, sourceFileExt);
|
|
168
|
+
const jsFilePath = join$2(sourceFileDir, sourceFileName + ".js");
|
|
165
169
|
const moduleFile = {
|
|
166
170
|
sourceFilePath,
|
|
167
171
|
jsFilePath,
|
|
@@ -190,6 +194,7 @@ const getModuleLegacy = (compilerCtx, sourceFilePath) => {
|
|
|
190
194
|
htmlAttrNames: [],
|
|
191
195
|
htmlTagNames: [],
|
|
192
196
|
htmlParts: [],
|
|
197
|
+
htmlSlots: [],
|
|
193
198
|
isCollectionDependency: false,
|
|
194
199
|
isLegacy: false,
|
|
195
200
|
localImports: [],
|
|
@@ -256,7 +261,7 @@ const resetModuleLegacy = (moduleFile) => {
|
|
|
256
261
|
*/
|
|
257
262
|
const getTsOptionsToExtend = (config) => {
|
|
258
263
|
const cacheDir = config.cacheDir || config.sys.tmpDirSync();
|
|
259
|
-
|
|
264
|
+
const tsOptions = {
|
|
260
265
|
experimentalDecorators: true,
|
|
261
266
|
declaration: config.outputTargets.some(isOutputTargetTypes),
|
|
262
267
|
module: config.tsCompilerOptions?.module || ts.ModuleKind.ESNext,
|
|
@@ -269,6 +274,8 @@ const getTsOptionsToExtend = (config) => {
|
|
|
269
274
|
incremental: config.enableCache !== false,
|
|
270
275
|
tsBuildInfoFile: config.enableCache !== false ? join$2(cacheDir, ".tsbuildinfo") : void 0
|
|
271
276
|
};
|
|
277
|
+
if (config.tsCompilerOptions?.skipLibCheck === void 0) tsOptions.skipLibCheck = true;
|
|
278
|
+
return tsOptions;
|
|
272
279
|
};
|
|
273
280
|
//#endregion
|
|
274
281
|
//#region src/compiler/transpile/create-build-program.ts
|
|
@@ -489,7 +496,7 @@ const getModuleImports = (moduleMap, filePath, importedModules) => {
|
|
|
489
496
|
* build - everything else is a component-derived flag that the consumer recomputes itself
|
|
490
497
|
* by scanning all components (including those from the collection).
|
|
491
498
|
*/
|
|
492
|
-
const COLLECTION_CONFIG_FLAGS = new Set([
|
|
499
|
+
const COLLECTION_CONFIG_FLAGS = /* @__PURE__ */ new Set([
|
|
493
500
|
"lightDomPatches",
|
|
494
501
|
"slotChildNodes",
|
|
495
502
|
"slotCloneNode",
|
|
@@ -753,11 +760,12 @@ function hostRefElementInternalsPropAccess() {
|
|
|
753
760
|
*/
|
|
754
761
|
const updateLazyComponentConstructor = (classMembers, classNode, moduleFile, cmp) => {
|
|
755
762
|
const cstrMethodArgs = [ts.factory.createParameterDeclaration(void 0, void 0, ts.factory.createIdentifier(HOST_REF_ARG))];
|
|
756
|
-
|
|
763
|
+
const cstrStatements = [
|
|
757
764
|
registerInstanceStatement(moduleFile),
|
|
758
765
|
...addCreateEvents(moduleFile, cmp),
|
|
759
766
|
...createLazyAttachInternalsBinding(cmp)
|
|
760
|
-
]
|
|
767
|
+
];
|
|
768
|
+
updateConstructor(classNode, classMembers, cstrStatements, cstrMethodArgs);
|
|
761
769
|
};
|
|
762
770
|
/**
|
|
763
771
|
* Create a statement containing an expression calling the `registerInstance`
|
|
@@ -951,19 +959,7 @@ function findTypeWithName(module, typeName) {
|
|
|
951
959
|
function getOriginalTypeName(identifier, checker) {
|
|
952
960
|
const possiblyAliasedSymbol = checker.getSymbolAtLocation(identifier);
|
|
953
961
|
if (!possiblyAliasedSymbol) return;
|
|
954
|
-
return
|
|
955
|
-
}
|
|
956
|
-
/**
|
|
957
|
-
* Check if a symbol is an alias of another symbol and, if so, use the
|
|
958
|
-
* {@link ts.TypeChecker} to resolve the original. If not, just return the same
|
|
959
|
-
* symbol.
|
|
960
|
-
*
|
|
961
|
-
* @param symbol the symbol of interest
|
|
962
|
-
* @param checker a {@link ts.TypeChecker}
|
|
963
|
-
* @returns a de-aliased symbol
|
|
964
|
-
*/
|
|
965
|
-
function unalias(symbol, checker) {
|
|
966
|
-
return symbol.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
962
|
+
return resolveAliasedSymbol(checker, possiblyAliasedSymbol).getName();
|
|
967
963
|
}
|
|
968
964
|
/**
|
|
969
965
|
* Check that a {@link ts.Node} is a type-declaration-like node. For our
|
|
@@ -1264,38 +1260,41 @@ const objectLiteralToObjectMap = (objectLiteral, typeChecker, diagnostics, error
|
|
|
1264
1260
|
const propName = getTextOfPropertyName(propAssignment.name);
|
|
1265
1261
|
let val;
|
|
1266
1262
|
if (ts.isShorthandPropertyAssignment(propAssignment)) val = getIdentifierValue(propName);
|
|
1267
|
-
else if (ts.isPropertyAssignment(propAssignment))
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1263
|
+
else if (ts.isPropertyAssignment(propAssignment)) {
|
|
1264
|
+
if (ts.isCallExpression(propAssignment.initializer) && typeChecker && (ts.isIdentifier(propAssignment.initializer.expression) && propAssignment.initializer.expression.text === "resolveVar" || ts.isPropertyAccessExpression(propAssignment.initializer.expression) && ts.isIdentifier(propAssignment.initializer.expression.name) && propAssignment.initializer.expression.name.text === "resolveVar")) {
|
|
1265
|
+
if (propAssignment.initializer.arguments.length === 1) val = resolveVarInObjectLiteral(propAssignment.initializer.arguments[0], typeChecker, diagnostics, propAssignment.initializer);
|
|
1266
|
+
else val = propAssignment.initializer;
|
|
1267
|
+
} else switch (propAssignment.initializer.kind) {
|
|
1268
|
+
case ts.SyntaxKind.ArrayLiteralExpression:
|
|
1269
|
+
val = arrayLiteralToArray(propAssignment.initializer);
|
|
1270
|
+
break;
|
|
1271
|
+
case ts.SyntaxKind.ObjectLiteralExpression:
|
|
1272
|
+
val = objectLiteralToObjectMap(propAssignment.initializer, typeChecker, diagnostics, errorNode);
|
|
1273
|
+
break;
|
|
1274
|
+
case ts.SyntaxKind.StringLiteral:
|
|
1275
|
+
val = propAssignment.initializer.text;
|
|
1276
|
+
break;
|
|
1277
|
+
case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
|
|
1278
|
+
val = propAssignment.initializer.text;
|
|
1279
|
+
break;
|
|
1280
|
+
case ts.SyntaxKind.TrueKeyword:
|
|
1281
|
+
val = true;
|
|
1282
|
+
break;
|
|
1283
|
+
case ts.SyntaxKind.FalseKeyword:
|
|
1284
|
+
val = false;
|
|
1285
|
+
break;
|
|
1286
|
+
case ts.SyntaxKind.Identifier:
|
|
1287
|
+
const escapedText = propAssignment.initializer.escapedText;
|
|
1288
|
+
if (escapedText === "String") val = String;
|
|
1289
|
+
else if (escapedText === "Number") val = Number;
|
|
1290
|
+
else if (escapedText === "Boolean") val = Boolean;
|
|
1291
|
+
else if (escapedText === "undefined") val = void 0;
|
|
1292
|
+
else if (escapedText === "null") val = null;
|
|
1293
|
+
else val = getIdentifierValue(propAssignment.initializer.escapedText);
|
|
1294
|
+
break;
|
|
1295
|
+
case ts.SyntaxKind.PropertyAccessExpression:
|
|
1296
|
+
default: val = propAssignment.initializer;
|
|
1297
|
+
}
|
|
1299
1298
|
}
|
|
1300
1299
|
final[propName] = val;
|
|
1301
1300
|
}
|
|
@@ -1313,7 +1312,8 @@ const objectLiteralToObjectMap = (objectLiteral, typeChecker, diagnostics, error
|
|
|
1313
1312
|
*/
|
|
1314
1313
|
const resolveVarInObjectLiteral = (node, typeChecker, _diagnostics, _errorNode) => {
|
|
1315
1314
|
if (ts.isIdentifier(node)) {
|
|
1316
|
-
|
|
1315
|
+
let symbol = typeChecker.getSymbolAtLocation(node);
|
|
1316
|
+
if (symbol && symbol.flags & ts.SymbolFlags.Alias) symbol = typeChecker.getAliasedSymbol(symbol);
|
|
1317
1317
|
if (!symbol || !symbol.valueDeclaration) throw new Error(`resolveVar() cannot resolve the value of "${node.text}" at compile time. Only const variables and object properties with string literal values are supported.`);
|
|
1318
1318
|
const declaration = symbol.valueDeclaration;
|
|
1319
1319
|
if (ts.isVariableDeclaration(declaration)) {
|
|
@@ -1403,6 +1403,14 @@ const getEntityName = (entity) => {
|
|
|
1403
1403
|
else return getEntityName(entity.left);
|
|
1404
1404
|
};
|
|
1405
1405
|
/**
|
|
1406
|
+
* Resolve a TypeScript alias to its original symbol.
|
|
1407
|
+
*
|
|
1408
|
+
* @param checker a TypeScript type checker
|
|
1409
|
+
* @param symbol the symbol to resolve, if one was found
|
|
1410
|
+
* @returns the original symbol for an alias, the provided symbol otherwise, or `undefined`
|
|
1411
|
+
*/
|
|
1412
|
+
const resolveAliasedSymbol = (checker, symbol) => symbol && (symbol.flags & ts.SymbolFlags.Alias) !== 0 ? checker.getAliasedSymbol(symbol) : symbol;
|
|
1413
|
+
/**
|
|
1406
1414
|
* Recursively walks the provided AST to collect all TypeScript type references that are found
|
|
1407
1415
|
*
|
|
1408
1416
|
* @param checker a {@link ts.TypeChecker} instance
|
|
@@ -1429,6 +1437,11 @@ const getAllTypeReferences = (checker, node) => {
|
|
|
1429
1437
|
type: checker.getTypeFromTypeNode(typeRef)
|
|
1430
1438
|
});
|
|
1431
1439
|
});
|
|
1440
|
+
} else if (ts.isTypeQueryNode(currentNode) && ts.isIdentifier(currentNode.exprName)) {
|
|
1441
|
+
if (resolveAliasedSymbol(checker, checker.getSymbolAtLocation(currentNode.exprName))?.declarations?.some((declaration) => ts.isEnumDeclaration(declaration) || ts.isClassDeclaration(declaration))) referencedTypes.push({
|
|
1442
|
+
name: getEntityName(currentNode.exprName),
|
|
1443
|
+
type: checker.getTypeAtLocation(currentNode.exprName)
|
|
1444
|
+
});
|
|
1432
1445
|
}
|
|
1433
1446
|
return ts.forEachChild(currentNode, visit);
|
|
1434
1447
|
};
|
|
@@ -1469,30 +1482,50 @@ const getTypeReferenceLocation = (typeName, type, sourceFile, checker, program)
|
|
|
1469
1482
|
const importName = importElement.name;
|
|
1470
1483
|
const originalTypeName = getOriginalTypeName(importName, checker);
|
|
1471
1484
|
const importedAs = importElement.propertyName ? importElement.propertyName.getText() : typeName;
|
|
1472
|
-
const
|
|
1473
|
-
|
|
1485
|
+
const importedSymbol = resolveAliasedSymbol(checker, checker.getSymbolAtLocation(importName));
|
|
1486
|
+
const declaration = importedSymbol?.valueDeclaration ?? importedSymbol?.declarations?.[0];
|
|
1487
|
+
const enumOrClassDeclaration = declaration && (ts.isClassDeclaration(declaration) || ts.isEnumDeclaration(declaration)) ? declaration : void 0;
|
|
1488
|
+
if (importedSymbol && enumOrClassDeclaration) type = checker.getTypeOfSymbolAtLocation(importedSymbol, enumOrClassDeclaration);
|
|
1489
|
+
else {
|
|
1490
|
+
const typeDecl = findTypeWithName(importHomeModule, originalTypeName);
|
|
1491
|
+
if (typeDecl) type = checker.getTypeAtLocation(typeDecl);
|
|
1492
|
+
}
|
|
1493
|
+
const typeSourceFile = enumOrClassDeclaration?.getSourceFile() ?? importHomeModule;
|
|
1474
1494
|
return {
|
|
1475
1495
|
location: "import",
|
|
1476
1496
|
path: localImportPath,
|
|
1477
|
-
id: addToLibrary(type, originalTypeName, checker, normalizePath(
|
|
1497
|
+
id: addToLibrary(type, originalTypeName, checker, normalizePath(typeSourceFile.fileName, false)),
|
|
1478
1498
|
referenceLocation: importedAs
|
|
1479
1499
|
};
|
|
1480
1500
|
}
|
|
1481
1501
|
}
|
|
1482
|
-
|
|
1502
|
+
const localExport = sourceFile.statements.reduce((exportInfo, st) => {
|
|
1503
|
+
if (exportInfo) return exportInfo;
|
|
1504
|
+
if (ts.isExportAssignment(st) && !st.isExportEquals && ts.isIdentifier(st.expression) && st.expression.getText() === typeName) return { isDefault: true };
|
|
1505
|
+
if (ts.isExportDeclaration(st) && !st.moduleSpecifier && ts.isNamedExports(st.exportClause)) {
|
|
1506
|
+
const exportSpecifier = st.exportClause.elements.find((element) => (element.propertyName ?? element.name).getText() === typeName);
|
|
1507
|
+
if (exportSpecifier) {
|
|
1508
|
+
const exportedName = exportSpecifier.name.getText();
|
|
1509
|
+
return exportedName === "default" ? { isDefault: true } : { referenceLocation: exportedName === typeName ? void 0 : exportedName };
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1483
1512
|
const statementModifiers = retrieveTsModifiers(st);
|
|
1484
|
-
const isDeclarationExported = (statement) => statement.name
|
|
1513
|
+
const isDeclarationExported = (statement) => statement.name?.getText() === typeName && Array.isArray(statementModifiers) && statementModifiers.some((mod) => mod.kind === ts.SyntaxKind.ExportKeyword);
|
|
1485
1514
|
const isInterfaceDeclarationExported = ts.isInterfaceDeclaration(st) && isDeclarationExported(st);
|
|
1486
1515
|
const isTypeAliasDeclarationExported = ts.isTypeAliasDeclaration(st) && isDeclarationExported(st);
|
|
1487
1516
|
const isEnumDeclarationExported = ts.isEnumDeclaration(st) && isDeclarationExported(st);
|
|
1488
|
-
const
|
|
1489
|
-
|
|
1490
|
-
|
|
1517
|
+
const isClassDeclarationExported = ts.isClassDeclaration(st) && isDeclarationExported(st);
|
|
1518
|
+
if (!(isInterfaceDeclarationExported || isTypeAliasDeclarationExported || isEnumDeclarationExported || isClassDeclarationExported)) return;
|
|
1519
|
+
return statementModifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.DefaultKeyword) ? { isDefault: true } : {};
|
|
1520
|
+
}, void 0);
|
|
1521
|
+
if (localExport) {
|
|
1491
1522
|
const id = addToLibrary(type, typeName, checker, sourceFile.fileName);
|
|
1492
1523
|
return {
|
|
1493
1524
|
location: "local",
|
|
1494
1525
|
path: sourceFile.fileName,
|
|
1495
|
-
id
|
|
1526
|
+
id,
|
|
1527
|
+
...localExport.isDefault ? { isDefault: true } : {},
|
|
1528
|
+
...localExport.referenceLocation ? { referenceLocation: localExport.referenceLocation } : {}
|
|
1496
1529
|
};
|
|
1497
1530
|
}
|
|
1498
1531
|
const defaultImportDeclaration = sourceFile.statements.find((st) => {
|
|
@@ -1502,19 +1535,19 @@ const getTypeReferenceLocation = (typeName, type, sourceFile, checker, program)
|
|
|
1502
1535
|
});
|
|
1503
1536
|
if (defaultImportDeclaration) {
|
|
1504
1537
|
const localImportPath = defaultImportDeclaration.moduleSpecifier.text;
|
|
1505
|
-
const
|
|
1506
|
-
const
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
}
|
|
1538
|
+
const defaultImportName = defaultImportDeclaration.importClause.name;
|
|
1539
|
+
const importedSymbol = resolveAliasedSymbol(checker, checker.getSymbolAtLocation(defaultImportName));
|
|
1540
|
+
const declaration = importedSymbol?.valueDeclaration ?? importedSymbol?.declarations?.[0];
|
|
1541
|
+
if (importedSymbol && declaration) {
|
|
1542
|
+
if (ts.isClassDeclaration(declaration) || ts.isEnumDeclaration(declaration)) type = checker.getTypeOfSymbolAtLocation(importedSymbol, declaration);
|
|
1543
|
+
const declarationNodeName = declaration.name;
|
|
1544
|
+
const declarationName = declarationNodeName && ts.isIdentifier(declarationNodeName) ? declarationNodeName.getText() : importedSymbol.getName();
|
|
1545
|
+
return {
|
|
1546
|
+
location: "import",
|
|
1547
|
+
path: localImportPath,
|
|
1548
|
+
id: addToLibrary(type, declarationName === "default" ? typeName : declarationName, checker, normalizePath(declaration.getSourceFile().fileName, false)),
|
|
1549
|
+
isDefault: true
|
|
1550
|
+
};
|
|
1518
1551
|
}
|
|
1519
1552
|
}
|
|
1520
1553
|
return {
|
|
@@ -1559,7 +1592,8 @@ const getTypeReferenceLocation = (typeName, type, sourceFile, checker, program)
|
|
|
1559
1592
|
*/
|
|
1560
1593
|
const resolveType = (checker, type, typeNode) => {
|
|
1561
1594
|
if (typeNode && ts.isArrayTypeNode(typeNode)) {
|
|
1562
|
-
const
|
|
1595
|
+
const elementType = checker.getTypeFromTypeNode(typeNode.elementType);
|
|
1596
|
+
const elementResolved = resolveType(checker, elementType, typeNode.elementType);
|
|
1563
1597
|
return elementResolved.includes(" | ") ? `(${elementResolved})[]` : `${elementResolved}[]`;
|
|
1564
1598
|
}
|
|
1565
1599
|
const set = /* @__PURE__ */ new Set();
|
|
@@ -1613,13 +1647,18 @@ const parseDocsType = (checker, type, parts) => {
|
|
|
1613
1647
|
const elemStr = sortedParts.join(" | ");
|
|
1614
1648
|
parts.add(sortedParts.length > 1 ? `(${elemStr})[]` : `${elemStr}[]`);
|
|
1615
1649
|
} else parts.add(typeToString(checker, type));
|
|
1616
|
-
} else if (type.aliasSymbol)
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1650
|
+
} else if (type.aliasSymbol) {
|
|
1651
|
+
if (type.aliasTypeArguments && type.aliasTypeArguments.length > 0) type.aliasTypeArguments.forEach((argType) => {
|
|
1652
|
+
parseDocsType(checker, argType, parts);
|
|
1653
|
+
});
|
|
1654
|
+
else if (type.aliasSymbol.declarations && type.aliasSymbol.declarations.length > 0) {
|
|
1655
|
+
const aliasedType = checker.getTypeAtLocation(type.aliasSymbol.declarations[0]);
|
|
1656
|
+
if (aliasedType && aliasedType !== type) parseDocsType(checker, aliasedType, parts);
|
|
1657
|
+
else {
|
|
1658
|
+
const text = typeToString(checker, type);
|
|
1659
|
+
parts.add(text);
|
|
1660
|
+
}
|
|
1661
|
+
} else {
|
|
1623
1662
|
const text = typeToString(checker, type);
|
|
1624
1663
|
parts.add(text);
|
|
1625
1664
|
}
|
|
@@ -1627,10 +1666,6 @@ const parseDocsType = (checker, type, parts) => {
|
|
|
1627
1666
|
const text = typeToString(checker, type);
|
|
1628
1667
|
parts.add(text);
|
|
1629
1668
|
}
|
|
1630
|
-
else {
|
|
1631
|
-
const text = typeToString(checker, type);
|
|
1632
|
-
parts.add(text);
|
|
1633
|
-
}
|
|
1634
1669
|
};
|
|
1635
1670
|
/**
|
|
1636
1671
|
* Retrieves a Stencil `Module` entity from the compiler context for a given TypeScript `SourceFile`
|
|
@@ -1658,7 +1693,8 @@ const getComponentMeta = (compilerCtx, tsSourceFile, node) => {
|
|
|
1658
1693
|
if (meta) return meta;
|
|
1659
1694
|
const moduleFile = getModuleFromSourceFile(compilerCtx, tsSourceFile);
|
|
1660
1695
|
if (moduleFile != null && node.members != null) {
|
|
1661
|
-
const
|
|
1696
|
+
const staticMembers = node.members.filter(isStaticGetter);
|
|
1697
|
+
const tagName = getComponentTagName(staticMembers);
|
|
1662
1698
|
if (typeof tagName === "string") return moduleFile.cmps.find((cmp) => cmp.tagName === tagName);
|
|
1663
1699
|
}
|
|
1664
1700
|
};
|
|
@@ -2100,7 +2136,8 @@ const generateAppDataModule = (build, config) => {
|
|
|
2100
2136
|
return `export const BUILD = ${JSON.stringify(build, null, 2)};\nexport const Env = ${JSON.stringify(config.env ?? {})};\nexport const NAMESPACE = ${JSON.stringify(config.fsNamespace)};\n`;
|
|
2101
2137
|
};
|
|
2102
2138
|
const serializeCollectionManifest = (config, compilerCtx, buildCtx) => {
|
|
2103
|
-
const
|
|
2139
|
+
const localCmps = buildCtx.moduleFiles.filter((mod) => !mod.isCollectionDependency).flatMap((mod) => mod.cmps);
|
|
2140
|
+
const buildFlags = getBuildFeatures(localCmps);
|
|
2104
2141
|
buildFlags.hydrateClientSide = config.outputTargets.some(isOutputTargetSsr);
|
|
2105
2142
|
const ldp = config.compat?.lightDomPatches ?? true;
|
|
2106
2143
|
if (buildFlags.slotRelocation && ldp !== false) {
|
|
@@ -2146,10 +2183,11 @@ const serializeCollectionManifest = (config, compilerCtx, buildCtx) => {
|
|
|
2146
2183
|
return collectionManifest;
|
|
2147
2184
|
};
|
|
2148
2185
|
const serializeCollectionDependencies = (compilerCtx) => {
|
|
2149
|
-
|
|
2186
|
+
const collectionDeps = compilerCtx.collections.map((c) => ({
|
|
2150
2187
|
name: c.collectionName,
|
|
2151
2188
|
tags: flatOne(c.moduleFiles.map((m) => m.cmps)).map((cmp) => cmp.tagName).sort()
|
|
2152
|
-
}))
|
|
2189
|
+
}));
|
|
2190
|
+
return sortBy(collectionDeps, (item) => item.name);
|
|
2153
2191
|
};
|
|
2154
2192
|
//#endregion
|
|
2155
2193
|
//#region src/compiler/output-targets/copy/local-copy-tasks.ts
|
|
@@ -2158,8 +2196,10 @@ const getSrcAbsPath = (config, src) => {
|
|
|
2158
2196
|
return join$2(config.srcDir, src);
|
|
2159
2197
|
};
|
|
2160
2198
|
const getDestAbsPath = (src, destAbsPath, destRelPath) => {
|
|
2161
|
-
if (destRelPath)
|
|
2162
|
-
|
|
2199
|
+
if (destRelPath) {
|
|
2200
|
+
if (isAbsolute$1(destRelPath)) return destRelPath;
|
|
2201
|
+
else return join$2(destAbsPath, destRelPath);
|
|
2202
|
+
}
|
|
2163
2203
|
if (isAbsolute$1(src)) throw new Error(`copy task, "dest" property must exist if "src" property is an absolute path: ${src}`);
|
|
2164
2204
|
return destAbsPath;
|
|
2165
2205
|
};
|
|
@@ -2353,6 +2393,7 @@ const setPackageVersionByContent = (pkgVersions, pkgContent) => {
|
|
|
2353
2393
|
if (pkg.name && pkg.version) setPackageVersion(pkgVersions, pkg.name, pkg.version);
|
|
2354
2394
|
} catch {}
|
|
2355
2395
|
};
|
|
2396
|
+
const isNodeModulePath = (p) => normalizePath(p).split("/").includes("node_modules");
|
|
2356
2397
|
const getModuleId = (orgImport) => {
|
|
2357
2398
|
if (orgImport.startsWith("~")) orgImport = orgImport.substring(1);
|
|
2358
2399
|
const splt = orgImport.split("/");
|
|
@@ -2444,6 +2485,54 @@ const createCustomResolverAsync = (sys, inMemoryFs, exts) => {
|
|
|
2444
2485
|
//#endregion
|
|
2445
2486
|
//#region src/compiler/style/style-utils.ts
|
|
2446
2487
|
/**
|
|
2488
|
+
* Wrap CSS content according to the modifiers trailing an `@import` specifier
|
|
2489
|
+
* (`layer(name)`, `supports(condition)`, and/or a media query), mirroring what
|
|
2490
|
+
* `@import url(...) layer(name) supports(condition) (media);` would do natively.
|
|
2491
|
+
*
|
|
2492
|
+
* @param cssText the CSS content to wrap
|
|
2493
|
+
* @param modifiers the raw modifier string following the import specifier, if any
|
|
2494
|
+
* @returns cssText wrapped in @layer/@media/@supports blocks as needed
|
|
2495
|
+
*/
|
|
2496
|
+
const wrapCssWithImportModifiers = (cssText, modifiers) => {
|
|
2497
|
+
if (!modifiers?.trim()) return cssText;
|
|
2498
|
+
let remaining = modifiers.trim();
|
|
2499
|
+
let replacement = cssText;
|
|
2500
|
+
let layerName = "";
|
|
2501
|
+
let supportsCondition = "";
|
|
2502
|
+
const layerMatch = remaining.match(/layer\(([^)]+)\)/);
|
|
2503
|
+
if (layerMatch) {
|
|
2504
|
+
layerName = layerMatch[1].trim();
|
|
2505
|
+
remaining = remaining.replace(/layer\([^)]+\)/, "").trim();
|
|
2506
|
+
}
|
|
2507
|
+
let depth = 0;
|
|
2508
|
+
let startIdx = -1;
|
|
2509
|
+
let endIdx = -1;
|
|
2510
|
+
const supportsIdx = remaining.indexOf("supports(");
|
|
2511
|
+
if (supportsIdx !== -1) {
|
|
2512
|
+
startIdx = supportsIdx + 9;
|
|
2513
|
+
for (let i = startIdx; i < remaining.length; i++) {
|
|
2514
|
+
if (remaining[i] === "(") depth++;
|
|
2515
|
+
if (remaining[i] === ")") {
|
|
2516
|
+
if (depth === 0) {
|
|
2517
|
+
endIdx = i;
|
|
2518
|
+
break;
|
|
2519
|
+
}
|
|
2520
|
+
depth--;
|
|
2521
|
+
}
|
|
2522
|
+
}
|
|
2523
|
+
if (endIdx !== -1) {
|
|
2524
|
+
supportsCondition = remaining.substring(startIdx, endIdx).trim();
|
|
2525
|
+
remaining = remaining.substring(0, supportsIdx) + remaining.substring(endIdx + 1);
|
|
2526
|
+
remaining = remaining.trim();
|
|
2527
|
+
}
|
|
2528
|
+
}
|
|
2529
|
+
const mediaQuery = remaining.trim();
|
|
2530
|
+
if (layerName) replacement = `@layer ${layerName} {\n${replacement}\n}`;
|
|
2531
|
+
if (mediaQuery) replacement = `@media ${mediaQuery} {\n${replacement}\n}`;
|
|
2532
|
+
if (supportsCondition) replacement = `@supports (${supportsCondition}) {\n${replacement}\n}`;
|
|
2533
|
+
return replacement;
|
|
2534
|
+
};
|
|
2535
|
+
/**
|
|
2447
2536
|
* Strip out comments from some CSS
|
|
2448
2537
|
*
|
|
2449
2538
|
* @param input the string we'd like to de-comment
|
|
@@ -2583,7 +2672,8 @@ const getCssImports = async (config, compilerCtx, buildCtx, filePath, styleText)
|
|
|
2583
2672
|
cssImportData.filePath += `.${importeeExt}`;
|
|
2584
2673
|
if (importeeExt === "scss") {
|
|
2585
2674
|
const fileName = "_" + basename$1(cssImportData.filePath);
|
|
2586
|
-
|
|
2675
|
+
const dirPath = dirname$1(cssImportData.filePath);
|
|
2676
|
+
cssImportData.altFilePath = normalizePath(join$2(dirPath, fileName));
|
|
2587
2677
|
}
|
|
2588
2678
|
}
|
|
2589
2679
|
if (cssImportData.filePath !== "") imports.push(cssImportData);
|
|
@@ -2634,44 +2724,7 @@ const isLocalCssImport$1 = (srcImport) => {
|
|
|
2634
2724
|
const replaceImportDeclarations = (styleText, cssImports, isCssEntry) => {
|
|
2635
2725
|
for (const cssImport of cssImports) if (isCssEntry) {
|
|
2636
2726
|
if (typeof cssImport.styleText === "string") {
|
|
2637
|
-
|
|
2638
|
-
if (cssImport.modifiers) {
|
|
2639
|
-
let modifiers = cssImport.modifiers;
|
|
2640
|
-
let layerName = "";
|
|
2641
|
-
let supportsCondition = "";
|
|
2642
|
-
let mediaQuery = "";
|
|
2643
|
-
const layerMatch = modifiers.match(/layer\(([^)]+)\)/);
|
|
2644
|
-
if (layerMatch) {
|
|
2645
|
-
layerName = layerMatch[1].trim();
|
|
2646
|
-
modifiers = modifiers.replace(/layer\([^)]+\)/, "").trim();
|
|
2647
|
-
}
|
|
2648
|
-
let depth = 0;
|
|
2649
|
-
let startIdx = -1;
|
|
2650
|
-
let endIdx = -1;
|
|
2651
|
-
const supportsIdx = modifiers.indexOf("supports(");
|
|
2652
|
-
if (supportsIdx !== -1) {
|
|
2653
|
-
startIdx = supportsIdx + 9;
|
|
2654
|
-
for (let i = startIdx; i < modifiers.length; i++) {
|
|
2655
|
-
if (modifiers[i] === "(") depth++;
|
|
2656
|
-
if (modifiers[i] === ")") {
|
|
2657
|
-
if (depth === 0) {
|
|
2658
|
-
endIdx = i;
|
|
2659
|
-
break;
|
|
2660
|
-
}
|
|
2661
|
-
depth--;
|
|
2662
|
-
}
|
|
2663
|
-
}
|
|
2664
|
-
if (endIdx !== -1) {
|
|
2665
|
-
supportsCondition = modifiers.substring(startIdx, endIdx).trim();
|
|
2666
|
-
modifiers = modifiers.substring(0, supportsIdx) + modifiers.substring(endIdx + 1);
|
|
2667
|
-
modifiers = modifiers.trim();
|
|
2668
|
-
}
|
|
2669
|
-
}
|
|
2670
|
-
mediaQuery = modifiers.trim();
|
|
2671
|
-
if (layerName) replacement = `@layer ${layerName} {\n${replacement}\n}`;
|
|
2672
|
-
if (mediaQuery) replacement = `@media ${mediaQuery} {\n${replacement}\n}`;
|
|
2673
|
-
if (supportsCondition) replacement = `@supports (${supportsCondition}) {\n${replacement}\n}`;
|
|
2674
|
-
}
|
|
2727
|
+
const replacement = wrapCssWithImportModifiers(cssImport.styleText, cssImport.modifiers);
|
|
2675
2728
|
styleText = styleText.replace(cssImport.srcImport, replacement);
|
|
2676
2729
|
}
|
|
2677
2730
|
} else if (typeof cssImport.updatedImport === "string") styleText = styleText.replace(cssImport.srcImport, cssImport.updatedImport);
|
|
@@ -2725,7 +2778,8 @@ const runPluginTransforms = async (config, compilerCtx, buildCtx, id, cmp) => {
|
|
|
2725
2778
|
cache: compilerCtx.cache,
|
|
2726
2779
|
diagnostics: []
|
|
2727
2780
|
};
|
|
2728
|
-
const
|
|
2781
|
+
const resolvedId = await runPluginResolveId(pluginCtx, id);
|
|
2782
|
+
const sourceText = await runPluginLoad(pluginCtx, resolvedId);
|
|
2729
2783
|
if (!isString$1(sourceText)) {
|
|
2730
2784
|
const diagnostic = buildError(buildCtx.diagnostics);
|
|
2731
2785
|
diagnostic.header = `Unable to find "${basename$1(id)}"`;
|
|
@@ -2739,15 +2793,17 @@ const runPluginTransforms = async (config, compilerCtx, buildCtx, id, cmp) => {
|
|
|
2739
2793
|
};
|
|
2740
2794
|
const isRawCssFile = transformResults.id.toLowerCase().endsWith(".css");
|
|
2741
2795
|
const shouldParseCssDocs = cmp != null && config.outputTargets.some(isOutputTargetDocs);
|
|
2742
|
-
if (isRawCssFile)
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2796
|
+
if (isRawCssFile) {
|
|
2797
|
+
if (shouldParseCssDocs && cmp != null) {
|
|
2798
|
+
cmp.styleDocs = cmp.styleDocs || [];
|
|
2799
|
+
const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, id, transformResults.code, cmp.styleDocs);
|
|
2800
|
+
transformResults.code = cssParseResults.styleText;
|
|
2801
|
+
transformResults.dependencies = cssParseResults.imports;
|
|
2802
|
+
} else {
|
|
2803
|
+
const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, id, transformResults.code);
|
|
2804
|
+
transformResults.code = cssParseResults.styleText;
|
|
2805
|
+
transformResults.dependencies = cssParseResults.imports;
|
|
2806
|
+
}
|
|
2751
2807
|
}
|
|
2752
2808
|
for (const plugin of pluginCtx.config?.plugins ?? []) if (isFunction(plugin.transform)) try {
|
|
2753
2809
|
let pluginTransformResults;
|
|
@@ -2755,29 +2811,33 @@ const runPluginTransforms = async (config, compilerCtx, buildCtx, id, cmp) => {
|
|
|
2755
2811
|
if (results != null) {
|
|
2756
2812
|
if (isFunction(results.then)) pluginTransformResults = await results;
|
|
2757
2813
|
else pluginTransformResults = results;
|
|
2758
|
-
if (pluginTransformResults != null)
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2814
|
+
if (pluginTransformResults != null) {
|
|
2815
|
+
if (isString$1(pluginTransformResults)) transformResults.code = pluginTransformResults;
|
|
2816
|
+
else {
|
|
2817
|
+
if (isString$1(pluginTransformResults.code)) transformResults.code = pluginTransformResults.code;
|
|
2818
|
+
if (isString$1(pluginTransformResults.id)) transformResults.id = pluginTransformResults.id;
|
|
2819
|
+
/**
|
|
2820
|
+
* add dependencies from plugin transform results, e.g. transformed sass files
|
|
2821
|
+
*/
|
|
2822
|
+
transformResults.dependencies.push(...getDependencySubset(pluginTransformResults.dependencies, transformResults.dependencies));
|
|
2823
|
+
}
|
|
2766
2824
|
}
|
|
2767
2825
|
}
|
|
2768
2826
|
} catch (e) {
|
|
2769
2827
|
catchError(buildCtx.diagnostics, e);
|
|
2770
2828
|
}
|
|
2771
2829
|
buildCtx.diagnostics.push(...pluginCtx.diagnostics);
|
|
2772
|
-
if (!isRawCssFile)
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2830
|
+
if (!isRawCssFile) {
|
|
2831
|
+
if (shouldParseCssDocs && cmp != null) {
|
|
2832
|
+
cmp.styleDocs = cmp.styleDocs || [];
|
|
2833
|
+
const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, transformResults.id, transformResults.code, cmp.styleDocs);
|
|
2834
|
+
transformResults.code = cssParseResults.styleText;
|
|
2835
|
+
transformResults.dependencies.push(...getDependencySubset(cssParseResults.imports, transformResults.dependencies));
|
|
2836
|
+
} else {
|
|
2837
|
+
const cssParseResults = await parseCssImports(config, compilerCtx, buildCtx, id, transformResults.id, transformResults.code);
|
|
2838
|
+
transformResults.code = cssParseResults.styleText;
|
|
2839
|
+
transformResults.dependencies.push(...getDependencySubset(cssParseResults.imports, transformResults.dependencies));
|
|
2840
|
+
}
|
|
2781
2841
|
}
|
|
2782
2842
|
return transformResults;
|
|
2783
2843
|
};
|
|
@@ -2808,13 +2868,15 @@ const runPluginTransformsEsmImports = async (config, compilerCtx, buildCtx, code
|
|
|
2808
2868
|
if (results != null) {
|
|
2809
2869
|
if (isFunction(results.then)) pluginTransformResults = await results;
|
|
2810
2870
|
else pluginTransformResults = results;
|
|
2811
|
-
if (pluginTransformResults != null)
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2871
|
+
if (pluginTransformResults != null) {
|
|
2872
|
+
if (isString$1(pluginTransformResults)) transformResults.code = pluginTransformResults;
|
|
2873
|
+
else {
|
|
2874
|
+
if (isString$1(pluginTransformResults.code)) transformResults.code = pluginTransformResults.code;
|
|
2875
|
+
if (isString$1(pluginTransformResults.id)) transformResults.id = pluginTransformResults.id;
|
|
2876
|
+
if (Array.isArray(pluginTransformResults.dependencies)) {
|
|
2877
|
+
const imports = pluginTransformResults.dependencies.filter((f) => !transformResults.dependencies.includes(f));
|
|
2878
|
+
transformResults.dependencies.push(...imports);
|
|
2879
|
+
}
|
|
2818
2880
|
}
|
|
2819
2881
|
}
|
|
2820
2882
|
}
|
|
@@ -2860,8 +2922,8 @@ const optimizeCss$1 = async (config, compilerCtx, diagnostics, styleText, filePa
|
|
|
2860
2922
|
};
|
|
2861
2923
|
//#endregion
|
|
2862
2924
|
//#region src/compiler/style/component-global-styles.ts
|
|
2863
|
-
const STENCIL_GLOBALS_RE = /@import\s+(?:url\()?\s*['"]stencil-globals['"]\s*\)
|
|
2864
|
-
const STENCIL_HYDRATE_RE = /@import\s+(?:url\()?\s*['"]stencil-hydrate['"]\s*\)
|
|
2925
|
+
const STENCIL_GLOBALS_RE = /@import\s+(?:url\()?\s*['"]stencil-globals['"]\s*\)?([^;]*);?/g;
|
|
2926
|
+
const STENCIL_HYDRATE_RE = /@import\s+(?:url\()?\s*['"]stencil-hydrate['"]\s*\)?([^;]*);?/g;
|
|
2865
2927
|
const hasStencilGlobalsImport = (css) => css.includes("stencil-globals");
|
|
2866
2928
|
const hasStencilHydrateImport = (css) => css.includes("stencil-hydrate");
|
|
2867
2929
|
/**
|
|
@@ -2884,12 +2946,16 @@ const generateHydrateCss = (config, buildCtx) => {
|
|
|
2884
2946
|
};
|
|
2885
2947
|
/**
|
|
2886
2948
|
* Replace `@import "stencil-hydrate"` in CSS with the generated FOUC-prevention styles.
|
|
2949
|
+
* Supports trailing `layer()`/`supports()`/media modifiers, e.g. `@import "stencil-hydrate" layer(init);`.
|
|
2887
2950
|
* @param css the CSS string to process
|
|
2888
2951
|
* @param config the Stencil configuration
|
|
2889
2952
|
* @param buildCtx the current build context, used to get the list of components in the build
|
|
2890
2953
|
* @returns the CSS string with `@import "stencil-hydrate"` replaced by generated styles
|
|
2891
2954
|
*/
|
|
2892
|
-
const resolveStencilHydrateImport = (css, config, buildCtx) =>
|
|
2955
|
+
const resolveStencilHydrateImport = (css, config, buildCtx) => {
|
|
2956
|
+
const hydrateCss = generateHydrateCss(config, buildCtx);
|
|
2957
|
+
return css.replace(STENCIL_HYDRATE_RE, (_match, modifiers) => wrapCssWithImportModifiers(hydrateCss, modifiers));
|
|
2958
|
+
};
|
|
2893
2959
|
/**
|
|
2894
2960
|
* Collect and build all component-level globalStyle/globalStyleUrl CSS from the current build.
|
|
2895
2961
|
* Results are cached per file path via the existing globalStyleCache.
|
|
@@ -2927,6 +2993,7 @@ const collectAndBuildComponentGlobalStyles = async (config, compilerCtx, buildCt
|
|
|
2927
2993
|
* Replace `@import "stencil-globals"` in CSS with the collected component global styles.
|
|
2928
2994
|
* Also registers component global style files as cssModuleImports of the global stylesheet
|
|
2929
2995
|
* so the build cache is properly invalidated when those files change.
|
|
2996
|
+
* Supports trailing `layer()`/`supports()`/media modifiers, e.g. `@import "stencil-globals" layer(init);`.
|
|
2930
2997
|
*
|
|
2931
2998
|
* @param css the CSS string to process
|
|
2932
2999
|
* @param config the Stencil configuration
|
|
@@ -2943,7 +3010,7 @@ const resolveStencilGlobalsImport = async (css, config, compilerCtx, buildCtx, g
|
|
|
2943
3010
|
for (const p of filePaths) if (!existing.includes(p)) existing.push(p);
|
|
2944
3011
|
compilerCtx.cssModuleImports.set(globalStyleInputPath, existing);
|
|
2945
3012
|
}
|
|
2946
|
-
return css.replace(STENCIL_GLOBALS_RE, collectedCss);
|
|
3013
|
+
return css.replace(STENCIL_GLOBALS_RE, (_match, modifiers) => wrapCssWithImportModifiers(collectedCss, modifiers));
|
|
2947
3014
|
};
|
|
2948
3015
|
//#endregion
|
|
2949
3016
|
//#region src/compiler/style/global-styles.ts
|
|
@@ -3464,7 +3531,8 @@ const getStencilInternalModule = (config, compilerExe, internalModule) => {
|
|
|
3464
3531
|
moduleId: "@stencil/core",
|
|
3465
3532
|
path: "runtime/" + internalModule
|
|
3466
3533
|
}));
|
|
3467
|
-
|
|
3534
|
+
const compilerExeDir = dirname$1(compilerExe);
|
|
3535
|
+
return normalizePath(join$2(compilerExeDir, "..", "runtime", internalModule));
|
|
3468
3536
|
};
|
|
3469
3537
|
const getHydratedFlagHead = (h) => {
|
|
3470
3538
|
let initial;
|
|
@@ -3516,7 +3584,8 @@ const getPackageJsonPath = (resolvedPath, importee) => {
|
|
|
3516
3584
|
for (let i = 0; i < 10; i++) {
|
|
3517
3585
|
currentPath = dirname$1(currentPath);
|
|
3518
3586
|
const aBasename = basename$1(currentPath);
|
|
3519
|
-
const
|
|
3587
|
+
const upDir = dirname$1(currentPath);
|
|
3588
|
+
const bBasename = basename$1(upDir);
|
|
3520
3589
|
if (aBasename === importee && bBasename === "node_modules") return join$2(currentPath, "package.json");
|
|
3521
3590
|
}
|
|
3522
3591
|
return null;
|
|
@@ -3565,7 +3634,7 @@ const FORMAT_TEXT_EXTS = [
|
|
|
3565
3634
|
"vert"
|
|
3566
3635
|
];
|
|
3567
3636
|
const FORMAT_URL_MIME = { svg: "image/svg+xml" };
|
|
3568
|
-
const DATAURL_MAX_IMAGE_SIZE =
|
|
3637
|
+
const DATAURL_MAX_IMAGE_SIZE = 4096;
|
|
3569
3638
|
const formatText = (code, filePath) => {
|
|
3570
3639
|
const varName = createJsVarName(basename$1(filePath));
|
|
3571
3640
|
return `const ${varName} = ${JSON.stringify(code)};export default ${varName};`;
|
|
@@ -3663,6 +3732,7 @@ const parseImportPath = (importPath) => {
|
|
|
3663
3732
|
encapsulation: urlParams.get("encapsulation") || "none",
|
|
3664
3733
|
mode: urlParams.get("mode") || "$"
|
|
3665
3734
|
};
|
|
3735
|
+
else if (urlParams.has("stencil") && parsedPath.basename.endsWith(".css")) parsedPath.data = { encapsulation: "none" };
|
|
3666
3736
|
} else if (parsedPath.basename.endsWith(".css")) parsedPath.data = { encapsulation: "none" };
|
|
3667
3737
|
}
|
|
3668
3738
|
return parsedPath;
|
|
@@ -3902,7 +3972,7 @@ const loaderPlugin = (entries = {}) => {
|
|
|
3902
3972
|
};
|
|
3903
3973
|
//#endregion
|
|
3904
3974
|
//#region src/compiler/bundle/plugin-helper.ts
|
|
3905
|
-
const builtIns = new Set([
|
|
3975
|
+
const builtIns = /* @__PURE__ */ new Set([
|
|
3906
3976
|
"child_process",
|
|
3907
3977
|
"cluster",
|
|
3908
3978
|
"dgram",
|
|
@@ -4059,6 +4129,7 @@ const createModule = (staticSourceFile, staticSourceFileText, emitFilepath) => (
|
|
|
4059
4129
|
hasSignalsImport: false,
|
|
4060
4130
|
htmlAttrNames: [],
|
|
4061
4131
|
htmlParts: [],
|
|
4132
|
+
htmlSlots: [],
|
|
4062
4133
|
htmlTagNames: [],
|
|
4063
4134
|
isCollectionDependency: false,
|
|
4064
4135
|
isLegacy: false,
|
|
@@ -4096,7 +4167,8 @@ const typescriptPlugin = (compilerCtx, bundleOpts, config) => {
|
|
|
4096
4167
|
*/
|
|
4097
4168
|
load(id) {
|
|
4098
4169
|
if (isAbsolute$1(id)) {
|
|
4099
|
-
const
|
|
4170
|
+
const fsFilePath = normalizeFsPath(id);
|
|
4171
|
+
const module = getModule(compilerCtx, fsFilePath);
|
|
4100
4172
|
if (module) {
|
|
4101
4173
|
if (!module.sourceMapFileText) return {
|
|
4102
4174
|
code: module.staticSourceFileText,
|
|
@@ -4278,7 +4350,7 @@ const loadMinifyJsDiagnostics = (sourceText, diagnostics, error) => {
|
|
|
4278
4350
|
}
|
|
4279
4351
|
diagnostics.push(d);
|
|
4280
4352
|
};
|
|
4281
|
-
const MINIFY_CHAR_BREAK = new Set([
|
|
4353
|
+
const MINIFY_CHAR_BREAK = /* @__PURE__ */ new Set([
|
|
4282
4354
|
" ",
|
|
4283
4355
|
"=",
|
|
4284
4356
|
".",
|
|
@@ -4500,16 +4572,18 @@ const workerPlugin = (config, compilerCtx, buildCtx, platform, inlineWorkers) =>
|
|
|
4500
4572
|
const workerEntryPath = getWorkerEntryPath(id);
|
|
4501
4573
|
if (workerEntryPath != null) {
|
|
4502
4574
|
const worker = await getWorker(config, compilerCtx, buildCtx, this, workersMap, workerEntryPath);
|
|
4503
|
-
if (worker)
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4575
|
+
if (worker) {
|
|
4576
|
+
if (inlineWorkers) return {
|
|
4577
|
+
code: getInlineWorkerProxy(workerEntryPath, worker.workerMsgId, worker.exports),
|
|
4578
|
+
map: { mappings: "" },
|
|
4579
|
+
moduleSideEffects: false
|
|
4580
|
+
};
|
|
4581
|
+
else return {
|
|
4582
|
+
code: getWorkerProxy(workerEntryPath, worker.exports),
|
|
4583
|
+
map: { mappings: "" },
|
|
4584
|
+
moduleSideEffects: false
|
|
4585
|
+
};
|
|
4586
|
+
}
|
|
4513
4587
|
}
|
|
4514
4588
|
return null;
|
|
4515
4589
|
}
|
|
@@ -4808,7 +4882,8 @@ ${exportedMethods.map((exportedMethod) => {
|
|
|
4808
4882
|
//#region src/compiler/bundle/bundle-output.ts
|
|
4809
4883
|
const bundleOutput = async (config, compilerCtx, buildCtx, bundleOpts) => {
|
|
4810
4884
|
try {
|
|
4811
|
-
|
|
4885
|
+
const rolldownOptions = getRolldownOptions(config, compilerCtx, buildCtx, bundleOpts);
|
|
4886
|
+
return await rolldown(rolldownOptions);
|
|
4812
4887
|
} catch (e) {
|
|
4813
4888
|
if (!buildCtx.hasError && isRolldownError(e)) loadRolldownDiagnostics(config, compilerCtx, buildCtx, e);
|
|
4814
4889
|
}
|
|
@@ -5433,13 +5508,14 @@ const updateCjsStyleRequires = (transformOpts, tsSourceFile, moduleFile) => {
|
|
|
5433
5508
|
return tsSourceFile;
|
|
5434
5509
|
};
|
|
5435
5510
|
const getStyleImportPath = (transformOpts, tsSourceFile, cmp, style, importPath) => {
|
|
5436
|
-
|
|
5511
|
+
const importData = {
|
|
5437
5512
|
importeePath: importPath,
|
|
5438
5513
|
importerPath: tsSourceFile.fileName,
|
|
5439
5514
|
tag: cmp.tagName,
|
|
5440
5515
|
encapsulation: cmp.encapsulation,
|
|
5441
5516
|
mode: style.modeName
|
|
5442
|
-
}
|
|
5517
|
+
};
|
|
5518
|
+
return serializeImportPath(importData, transformOpts.styleImportData);
|
|
5443
5519
|
};
|
|
5444
5520
|
//#endregion
|
|
5445
5521
|
//#region src/compiler/transformers/add-static-style.ts
|
|
@@ -5479,8 +5555,10 @@ const addStaticStylePropertyToClass = (styleStatements, cmp, buildCtx) => {
|
|
|
5479
5555
|
}
|
|
5480
5556
|
};
|
|
5481
5557
|
const getStyleLiteral = (cmp, buildCtx) => {
|
|
5482
|
-
if (Array.isArray(cmp.styles) && cmp.styles.length > 0)
|
|
5483
|
-
|
|
5558
|
+
if (Array.isArray(cmp.styles) && cmp.styles.length > 0) {
|
|
5559
|
+
if (cmp.styles.length > 1 || cmp.styles.length === 1 && cmp.styles[0].modeName !== "$") return getMultipleModeStyle(cmp, cmp.styles, buildCtx);
|
|
5560
|
+
else return getSingleStyle(cmp, cmp.styles[0], buildCtx);
|
|
5561
|
+
}
|
|
5484
5562
|
return null;
|
|
5485
5563
|
};
|
|
5486
5564
|
const getMultipleModeStyle = (cmp, styles, buildCtx) => {
|
|
@@ -5902,30 +5980,31 @@ const updateStencilCoreImports = (updatedCoreImportPath) => {
|
|
|
5902
5980
|
/**
|
|
5903
5981
|
* A set of imports which we don't want to remove from an output file
|
|
5904
5982
|
*/
|
|
5905
|
-
const KEEP_IMPORTS = new Set([
|
|
5906
|
-
"h",
|
|
5907
|
-
"setMode",
|
|
5908
|
-
"getMode",
|
|
5909
|
-
"setPlatformHelpers",
|
|
5983
|
+
const KEEP_IMPORTS = /* @__PURE__ */ new Set([
|
|
5910
5984
|
"Build",
|
|
5911
5985
|
"Env",
|
|
5912
|
-
"Host",
|
|
5913
5986
|
"Fragment",
|
|
5987
|
+
"Host",
|
|
5988
|
+
"Mixin",
|
|
5989
|
+
"ReactiveControllerHost",
|
|
5990
|
+
"forceUpdate",
|
|
5991
|
+
"forceModeUpdate",
|
|
5914
5992
|
"getAssetPath",
|
|
5915
|
-
"writeTask",
|
|
5916
|
-
"readTask",
|
|
5917
5993
|
"getElement",
|
|
5918
|
-
"
|
|
5919
|
-
"forceUpdate",
|
|
5994
|
+
"getMode",
|
|
5920
5995
|
"getRenderingRef",
|
|
5921
|
-
"
|
|
5996
|
+
"getShadowRoot",
|
|
5997
|
+
"h",
|
|
5998
|
+
"jsx",
|
|
5999
|
+
"jsxs",
|
|
6000
|
+
"readTask",
|
|
6001
|
+
"render",
|
|
5922
6002
|
"setErrorHandler",
|
|
6003
|
+
"setMode",
|
|
6004
|
+
"setPlatformHelpers",
|
|
5923
6005
|
"setTagTransformer",
|
|
5924
6006
|
"transformTag",
|
|
5925
|
-
"
|
|
5926
|
-
"jsx",
|
|
5927
|
-
"jsxs",
|
|
5928
|
-
"render"
|
|
6007
|
+
"writeTask"
|
|
5929
6008
|
]);
|
|
5930
6009
|
//#endregion
|
|
5931
6010
|
//#region src/compiler/app-core/bundle-app-core.ts
|
|
@@ -6109,7 +6188,8 @@ const writeLazyChunk = async (config, compilerCtx, buildCtx, rolldownResult, out
|
|
|
6109
6188
|
};
|
|
6110
6189
|
const writeLazyEntry = async (config, compilerCtx, buildCtx, rolldownResult, outputTargetType, destinations, lazyRuntimeData, sourceTarget, shouldMinify, isBrowserBuild) => {
|
|
6111
6190
|
if (isBrowserBuild && ["loader"].includes(rolldownResult.entryKey)) return;
|
|
6112
|
-
const
|
|
6191
|
+
const inputCode = rolldownResult.code.replace(`["__STENCIL_LAZY_DATA__"]`, `${lazyRuntimeData}`);
|
|
6192
|
+
const { code, sourceMap } = await convertChunk(config, compilerCtx, buildCtx, sourceTarget, shouldMinify, false, isBrowserBuild, inputCode, rolldownResult.map);
|
|
6113
6193
|
await Promise.all(destinations.map((dst) => {
|
|
6114
6194
|
const filePath = join$2(dst, rolldownResult.fileName);
|
|
6115
6195
|
let fileCode = code;
|
|
@@ -6129,7 +6209,8 @@ const writeLazyEntry = async (config, compilerCtx, buildCtx, rolldownResult, out
|
|
|
6129
6209
|
* @returns A stringified representation of the lazy bundles.
|
|
6130
6210
|
*/
|
|
6131
6211
|
const formatLazyBundlesRuntimeMeta = (bundleModules) => {
|
|
6132
|
-
|
|
6212
|
+
const lazyBundles = bundleModules.slice().sort(sortBundleModules).map(formatLazyRuntimeBundle);
|
|
6213
|
+
return stringifyRuntimeData(lazyBundles);
|
|
6133
6214
|
};
|
|
6134
6215
|
/**
|
|
6135
6216
|
* Formats a bundle module into a tuple of bundle ID and component metadata for use at runtime.
|
|
@@ -6305,7 +6386,8 @@ const generateCjs = async (config, compilerCtx, buildCtx, rolldownBuild, outputT
|
|
|
6305
6386
|
if (config.compat.enableImportInjection) esmOpts.dynamicImportInCjs = false;
|
|
6306
6387
|
const results = await generateRolldownOutput(rolldownBuild, esmOpts, config, buildCtx.entryModules);
|
|
6307
6388
|
if (results != null) {
|
|
6308
|
-
|
|
6389
|
+
const destinations = cjsOutputs.map((o) => o.cjsDir).filter((cjsDir) => typeof cjsDir === "string");
|
|
6390
|
+
buildCtx.commonJsComponentBundle = await generateLazyModules(config, compilerCtx, buildCtx, outputTargetType, destinations, results, "es2017", false);
|
|
6309
6391
|
await generateShortcuts$1(compilerCtx, results, cjsOutputs);
|
|
6310
6392
|
}
|
|
6311
6393
|
}
|
|
@@ -6340,7 +6422,8 @@ const generateEsm = async (config, compilerCtx, buildCtx, rolldownBuild, outputT
|
|
|
6340
6422
|
const outputTargetType = esmOutputs[0].type;
|
|
6341
6423
|
const output = await generateRolldownOutput(rolldownBuild, esmOpts, config, buildCtx.entryModules);
|
|
6342
6424
|
if (output != null) {
|
|
6343
|
-
|
|
6425
|
+
const es2017destinations = esmOutputs.map((o) => o.esmDir).filter((esmDir) => typeof esmDir === "string");
|
|
6426
|
+
buildCtx.esmComponentBundle = await generateLazyModules(config, compilerCtx, buildCtx, outputTargetType, es2017destinations, output, "es2017", false);
|
|
6344
6427
|
await generateShortcuts(compilerCtx, outputTargets, output);
|
|
6345
6428
|
}
|
|
6346
6429
|
}
|
|
@@ -6365,7 +6448,7 @@ const generateEsmBrowser = async (config, compilerCtx, buildCtx, rolldownBuild,
|
|
|
6365
6448
|
const esmOutputs = outputTargets.filter((o) => !!o.esmDir && !!o.isBrowserBuild);
|
|
6366
6449
|
if (esmOutputs.length) {
|
|
6367
6450
|
const outputTargetType = esmOutputs[0].type;
|
|
6368
|
-
const
|
|
6451
|
+
const esmOpts = {
|
|
6369
6452
|
banner: generatePreamble(config),
|
|
6370
6453
|
format: "es",
|
|
6371
6454
|
entryFileNames: "[name].js",
|
|
@@ -6373,7 +6456,8 @@ const generateEsmBrowser = async (config, compilerCtx, buildCtx, rolldownBuild,
|
|
|
6373
6456
|
assetFileNames: esmOutputs[0].hashFileNames ? "p-[hash][extname]" : "[name]-[hash][extname]",
|
|
6374
6457
|
sourcemap: config.sourceMap,
|
|
6375
6458
|
plugins: [lazyBundleIdPlugin(buildCtx, config, esmOutputs[0].hashFileNames ?? true, esmOutputs[0].hashedFileNameLength ?? 8, "", true)]
|
|
6376
|
-
}
|
|
6459
|
+
};
|
|
6460
|
+
const output = await generateRolldownOutput(rolldownBuild, esmOpts, config, buildCtx.entryModules);
|
|
6377
6461
|
if (output != null) {
|
|
6378
6462
|
const es2017destinations = esmOutputs.map((o) => o.esmDir).filter((esmDir) => typeof esmDir === "string");
|
|
6379
6463
|
buildCtx.esmBrowserComponentBundle = await generateLazyModules(config, compilerCtx, buildCtx, outputTargetType, es2017destinations, output, "es2017", true);
|
|
@@ -6416,15 +6500,18 @@ const generateLoader = async (compilerCtx, outputTargets) => {
|
|
|
6416
6500
|
await Promise.all(outputTargets.map(async (o) => {
|
|
6417
6501
|
if (!o.loaderDir || !o.esmDir || !o.typesDir) return;
|
|
6418
6502
|
const loaderIndexJs = join$2(o.loaderDir, "index.js");
|
|
6419
|
-
const
|
|
6503
|
+
const esmLoaderPath = join$2(o.esmDir, "loader.js");
|
|
6504
|
+
const relativeEsmLoader = relativeImport(loaderIndexJs, esmLoaderPath);
|
|
6420
6505
|
await compilerCtx.fs.writeFile(loaderIndexJs, `export * from '${relativeEsmLoader}';\n`, { outputTargetType: o.type });
|
|
6421
6506
|
if (o.cjsDir) {
|
|
6422
6507
|
const loaderIndexCjs = join$2(o.loaderDir, "index.cjs");
|
|
6423
|
-
const
|
|
6508
|
+
const cjsLoaderPath = join$2(o.cjsDir, "loader.cjs");
|
|
6509
|
+
const relativeCjsLoader = relativeImport(loaderIndexCjs, cjsLoaderPath);
|
|
6424
6510
|
await compilerCtx.fs.writeFile(loaderIndexCjs, `module.exports = require('${relativeCjsLoader}');\n`, { outputTargetType: o.type });
|
|
6425
6511
|
}
|
|
6426
6512
|
const loaderIndexDts = join$2(o.loaderDir, "index.d.ts");
|
|
6427
|
-
const
|
|
6513
|
+
const loaderDtsPath = join$2(o.typesDir, "loader.d.ts");
|
|
6514
|
+
const relativeDtsPath = relativeImport(loaderIndexDts, loaderDtsPath);
|
|
6428
6515
|
await compilerCtx.fs.writeFile(loaderIndexDts, `export * from '${relativeDtsPath}';\n`, { outputTargetType: o.type });
|
|
6429
6516
|
}));
|
|
6430
6517
|
};
|
|
@@ -6647,7 +6734,8 @@ const canSkipAssetsCopy = (compilerCtx, entryModules, filesChanged) => {
|
|
|
6647
6734
|
entryModules.forEach((entryModule) => {
|
|
6648
6735
|
entryModule.cmps.forEach((cmp) => {
|
|
6649
6736
|
if (cmp.assetsDirs != null) cmp.assetsDirs.forEach((assetsDir) => {
|
|
6650
|
-
|
|
6737
|
+
const assetDirPath = normalizePath(assetsDir.absolutePath);
|
|
6738
|
+
if (changedFileDirPath === assetDirPath) {
|
|
6651
6739
|
shouldSkipAssetsCopy = false;
|
|
6652
6740
|
return;
|
|
6653
6741
|
}
|
|
@@ -6683,7 +6771,8 @@ const outputAssets = async (config, compilerCtx, buildCtx) => {
|
|
|
6683
6771
|
allCopyTasks.push(...copyTasks);
|
|
6684
6772
|
}
|
|
6685
6773
|
for (const wwwTarget of wwwTargets) {
|
|
6686
|
-
const
|
|
6774
|
+
const wwwAssetsDir = join$2(wwwTarget.buildDir, "assets");
|
|
6775
|
+
const copyTasks = getComponentAssetsCopyTasks(config, buildCtx, wwwAssetsDir, false);
|
|
6687
6776
|
allCopyTasks.push(...copyTasks);
|
|
6688
6777
|
}
|
|
6689
6778
|
if (allCopyTasks.length > 0) {
|
|
@@ -6912,6 +7001,7 @@ const generateDocData = async (config, compilerCtx, buildCtx) => {
|
|
|
6912
7001
|
typescriptVersion: versions.typescript
|
|
6913
7002
|
},
|
|
6914
7003
|
components: await getDocsComponents(config, compilerCtx, buildCtx),
|
|
7004
|
+
usage: await generateUsages(compilerCtx, normalizePath(join$2(config.srcDir, "usage"))),
|
|
6915
7005
|
typeLibrary
|
|
6916
7006
|
};
|
|
6917
7007
|
};
|
|
@@ -6934,7 +7024,7 @@ function findSupplementalPublicTypes(outputTargets) {
|
|
|
6934
7024
|
* @returns the derived metadata
|
|
6935
7025
|
*/
|
|
6936
7026
|
const getDocsComponents = async (config, compilerCtx, buildCtx) => {
|
|
6937
|
-
|
|
7027
|
+
const results = await Promise.all(buildCtx.moduleFiles.map(async (moduleFile) => {
|
|
6938
7028
|
const filePath = moduleFile.sourceFilePath;
|
|
6939
7029
|
const dirPath = normalizePath(dirname$1(filePath));
|
|
6940
7030
|
const readmePath = normalizePath(join$2(dirPath, "readme.md"));
|
|
@@ -6962,12 +7052,13 @@ const getDocsComponents = async (config, compilerCtx, buildCtx) => {
|
|
|
6962
7052
|
methods: getDocsMethods(cmp.methods),
|
|
6963
7053
|
events: getDocsEvents(cmp.events),
|
|
6964
7054
|
styles: getDocsStyles(cmp),
|
|
6965
|
-
slots: getDocsSlots(cmp.docs.tags),
|
|
7055
|
+
slots: getDocsSlots(cmp.htmlSlots, cmp.docs.tags),
|
|
6966
7056
|
parts: getDocsParts(cmp.htmlParts, cmp.docs.tags),
|
|
6967
7057
|
customStates: getDocsCustomStates(cmp),
|
|
6968
7058
|
listeners: getDocsListeners(cmp.listeners)
|
|
6969
7059
|
}));
|
|
6970
|
-
}))
|
|
7060
|
+
}));
|
|
7061
|
+
return sortBy(flatOne(results), (cmp) => cmp.tag);
|
|
6971
7062
|
};
|
|
6972
7063
|
const buildDocsDepGraph = (cmp, cmps) => {
|
|
6973
7064
|
const dependencies = {};
|
|
@@ -7154,11 +7245,17 @@ const getDocsDeprecationText = (tags) => {
|
|
|
7154
7245
|
const deprecation = tags.find((t) => t.name === "deprecated");
|
|
7155
7246
|
if (deprecation) return deprecation.text || "";
|
|
7156
7247
|
};
|
|
7157
|
-
const
|
|
7158
|
-
|
|
7248
|
+
const DEFAULT_SLOT_DOCS = "The default slot";
|
|
7249
|
+
const getDocsSlots = (vdom, tags) => {
|
|
7250
|
+
const docsSlots = getNameText("slot", tags).map(([name, docs]) => ({
|
|
7159
7251
|
name,
|
|
7160
7252
|
docs
|
|
7161
|
-
}))
|
|
7253
|
+
}));
|
|
7254
|
+
const vdomSlots = vdom.map((name) => ({
|
|
7255
|
+
name,
|
|
7256
|
+
docs: name === "" ? DEFAULT_SLOT_DOCS : ""
|
|
7257
|
+
}));
|
|
7258
|
+
return sortBy(unique([...docsSlots, ...vdomSlots], (s) => s.name), (a) => a.name);
|
|
7162
7259
|
};
|
|
7163
7260
|
const getDocsParts = (vdom, tags) => {
|
|
7164
7261
|
const docsParts = getNameText("part", tags).map(([name, docs]) => ({
|
|
@@ -7224,7 +7321,7 @@ const cmpMetaToDocsComponent = (cmp, filePath, rootDir = process.cwd()) => {
|
|
|
7224
7321
|
methods: getDocsMethods(cmp.methods ?? []),
|
|
7225
7322
|
events: getDocsEvents(cmp.events ?? []),
|
|
7226
7323
|
styles: getDocsStyles(cmp),
|
|
7227
|
-
slots: getDocsSlots(docs.tags),
|
|
7324
|
+
slots: getDocsSlots(cmp.htmlSlots ?? [], docs.tags),
|
|
7228
7325
|
parts: getDocsParts(cmp.htmlParts ?? [], docs.tags),
|
|
7229
7326
|
customStates: getDocsCustomStates(cmp),
|
|
7230
7327
|
listeners: getDocsListeners(cmp.listeners ?? [])
|
|
@@ -7333,63 +7430,552 @@ const outputCustom = async (config, compilerCtx, buildCtx) => {
|
|
|
7333
7430
|
}));
|
|
7334
7431
|
};
|
|
7335
7432
|
//#endregion
|
|
7336
|
-
//#region src/compiler/docs/
|
|
7337
|
-
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
|
|
7348
|
-
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
|
|
7433
|
+
//#region src/compiler/docs/readme/markdown-usage.ts
|
|
7434
|
+
const usageToMarkdown = (usages) => {
|
|
7435
|
+
const content = [];
|
|
7436
|
+
const merged = mergeUsages(usages);
|
|
7437
|
+
if (merged.length === 0) return content;
|
|
7438
|
+
content.push(`## Usage`);
|
|
7439
|
+
merged.forEach(({ name, text }) => {
|
|
7440
|
+
content.push("");
|
|
7441
|
+
content.push(`### ${toTitleCase(name)}`);
|
|
7442
|
+
content.push("");
|
|
7443
|
+
content.push(text);
|
|
7444
|
+
content.push("");
|
|
7445
|
+
});
|
|
7446
|
+
content.push("");
|
|
7447
|
+
content.push("");
|
|
7448
|
+
return content;
|
|
7352
7449
|
};
|
|
7353
|
-
|
|
7354
|
-
|
|
7355
|
-
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
const
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7450
|
+
const mergeUsages = (usages) => {
|
|
7451
|
+
const keys = Object.keys(usages);
|
|
7452
|
+
const map = /* @__PURE__ */ new Map();
|
|
7453
|
+
keys.forEach((key) => {
|
|
7454
|
+
const usage = usages[key].trim();
|
|
7455
|
+
const array = map.get(usage) || [];
|
|
7456
|
+
array.push(key);
|
|
7457
|
+
map.set(usage, array);
|
|
7458
|
+
});
|
|
7459
|
+
const merged = [];
|
|
7460
|
+
map.forEach((value, key) => {
|
|
7461
|
+
merged.push({
|
|
7462
|
+
name: value.join(" / "),
|
|
7463
|
+
text: key
|
|
7464
|
+
});
|
|
7465
|
+
});
|
|
7466
|
+
return merged;
|
|
7467
|
+
};
|
|
7468
|
+
//#endregion
|
|
7469
|
+
//#region src/compiler/docs/agent-skill/frontmatter.ts
|
|
7470
|
+
/**
|
|
7471
|
+
* Truncate a string to a max length, replacing any trailing content with an ellipsis.
|
|
7472
|
+
* @param text the text to truncate
|
|
7473
|
+
* @param maxLen the max length of the returned string
|
|
7474
|
+
* @returns the truncated string
|
|
7475
|
+
*/
|
|
7476
|
+
const truncate = (text, maxLen) => text.length > maxLen ? `${text.slice(0, maxLen - 1).trimEnd()}…` : text;
|
|
7477
|
+
/**
|
|
7478
|
+
* Extract the first sentence from a block of text, for use as a short summary.
|
|
7479
|
+
* Bounded to the first paragraph (text up to a blank line) so a heading or
|
|
7480
|
+
* short first line doesn't get glued to unrelated content further down.
|
|
7481
|
+
* Falls back to the full (truncated) first paragraph if no sentence-ending
|
|
7482
|
+
* punctuation is found within it.
|
|
7483
|
+
* @param text the text to extract a summary from
|
|
7484
|
+
* @param maxLen the max length of the returned string
|
|
7485
|
+
* @returns the first sentence, or an empty string if `text` is empty
|
|
7486
|
+
*/
|
|
7487
|
+
const firstSentence = (text, maxLen = 200) => {
|
|
7488
|
+
if (!text) return "";
|
|
7489
|
+
const trimmed = text.trim();
|
|
7490
|
+
if (trimmed === "") return "";
|
|
7491
|
+
const firstParagraph = trimmed.split(/\r?\n\s*\r?\n/)[0];
|
|
7492
|
+
const match = firstParagraph.match(/^[\s\S]*?[.!?](?=\s|$)/);
|
|
7493
|
+
const sentence = (match ? match[0] : firstParagraph).trim();
|
|
7494
|
+
return truncate(sentence, maxLen);
|
|
7495
|
+
};
|
|
7496
|
+
/**
|
|
7497
|
+
* Strip a single leading markdown ATX heading (e.g. `# Getting Started`), if
|
|
7498
|
+
* present, so summary extraction starts from the first real paragraph of prose.
|
|
7499
|
+
* @param text the text to strip a leading heading from
|
|
7500
|
+
* @returns the text with any leading heading removed
|
|
7501
|
+
*/
|
|
7502
|
+
const stripLeadingHeading = (text) => text.replace(/^\s*#{1,6}[^\n]*\n+/, "");
|
|
7503
|
+
/**
|
|
7504
|
+
* Sanitize a string into a valid Agent Skill `name` (lowercase, alphanumeric + hyphens).
|
|
7505
|
+
* @param raw the raw string to sanitize, e.g. a project namespace
|
|
7506
|
+
* @returns the kebab-cased name, or 'skill' if `raw` sanitizes to an empty string
|
|
7507
|
+
*/
|
|
7508
|
+
const toSkillName = (raw) => {
|
|
7509
|
+
return raw.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "skill";
|
|
7510
|
+
};
|
|
7511
|
+
/**
|
|
7512
|
+
* Auto-generate the skill's `description` when the user doesn't supply one -
|
|
7513
|
+
* prefers real project-level usage content (see `<srcDir>/usage/*.md`) over a
|
|
7514
|
+
* generic sentence built from the component tag list.
|
|
7515
|
+
* @param components the project's documented components
|
|
7516
|
+
* @param name the skill's (already-sanitized) name
|
|
7517
|
+
* @param projectUsage project-level usage content, from `JsonDocs.usage`
|
|
7518
|
+
* @returns the generated description
|
|
7519
|
+
*/
|
|
7520
|
+
const buildSkillDescription = (components, name, projectUsage) => {
|
|
7521
|
+
if (projectUsage) {
|
|
7522
|
+
const firstEntry = Object.values(projectUsage)[0];
|
|
7523
|
+
const fromProjectUsage = firstEntry ? firstSentence(stripLeadingHeading(firstEntry), 400) : "";
|
|
7524
|
+
if (fromProjectUsage) return fromProjectUsage;
|
|
7525
|
+
}
|
|
7526
|
+
const tags = components.map((cmp) => cmp.tag);
|
|
7527
|
+
const description = `Use when building UI with the ${name} component library. Provides API reference and usage examples for its ${tags.length} component${tags.length === 1 ? "" : "s"}: ${tags.join(", ")}.`;
|
|
7528
|
+
return truncate(description, 800);
|
|
7529
|
+
};
|
|
7530
|
+
/**
|
|
7531
|
+
* Minimal YAML string serializer for the two flat frontmatter fields
|
|
7532
|
+
* (`name`/`description`). Quotes and escapes only when necessary - not a
|
|
7533
|
+
* general-purpose YAML writer.
|
|
7534
|
+
* @param value the string to serialize
|
|
7535
|
+
* @returns the value, quoted/escaped if it contains YAML-significant characters
|
|
7536
|
+
*/
|
|
7537
|
+
const escapeYamlString = (value) => {
|
|
7538
|
+
if (!(value === "" || /[:#"'\n]/.test(value) || /^\s|\s$/.test(value) || /^[-?*&!|>%@`[\]{},]/.test(value))) return value;
|
|
7539
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\r\n|\r|\n/g, "\\n")}"`;
|
|
7540
|
+
};
|
|
7541
|
+
/**
|
|
7542
|
+
* Assemble the top-level `SKILL.md` content: frontmatter, project-level intro
|
|
7543
|
+
* (from `JsonDocs.usage`, if any), and an index of components linking to
|
|
7544
|
+
* their `components/<tag>.md` reference file.
|
|
7545
|
+
* @param docsData the project's generated docs data
|
|
7546
|
+
* @param outputTarget the (already-validated) docs-agent-skill output target
|
|
7547
|
+
* @returns the `SKILL.md` content
|
|
7548
|
+
*/
|
|
7549
|
+
const generateSkillMarkdown = (docsData, outputTarget) => {
|
|
7550
|
+
const name = outputTarget.name;
|
|
7551
|
+
const description = outputTarget.description ?? buildSkillDescription(docsData.components, name, docsData.usage);
|
|
7552
|
+
const lines = [
|
|
7553
|
+
"---",
|
|
7554
|
+
`name: ${escapeYamlString(name)}`,
|
|
7555
|
+
`description: ${escapeYamlString(description)}`,
|
|
7556
|
+
"---",
|
|
7557
|
+
"",
|
|
7558
|
+
`# ${name}`,
|
|
7559
|
+
""
|
|
7560
|
+
];
|
|
7561
|
+
if (docsData.usage) lines.push(...usageToMarkdown(docsData.usage));
|
|
7562
|
+
lines.push("## Components", "");
|
|
7563
|
+
[...docsData.components].sort((a, b) => a.tag.localeCompare(b.tag)).forEach((cmp) => {
|
|
7564
|
+
const summary = firstSentence(cmp.overview);
|
|
7565
|
+
lines.push(`- [${cmp.tag}](components/${cmp.tag}.md)${summary ? ` — ${summary}` : ""}`);
|
|
7566
|
+
});
|
|
7567
|
+
lines.push("");
|
|
7568
|
+
return lines.join("\n");
|
|
7569
|
+
};
|
|
7570
|
+
//#endregion
|
|
7571
|
+
//#region src/compiler/docs/readme/docs-util.ts
|
|
7572
|
+
var MarkdownTable = class {
|
|
7573
|
+
rows = [];
|
|
7574
|
+
addHeader(data) {
|
|
7575
|
+
this.addRow(data, true);
|
|
7364
7576
|
}
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
|
|
7368
|
-
|
|
7369
|
-
|
|
7370
|
-
|
|
7371
|
-
|
|
7372
|
-
|
|
7373
|
-
declaration: { name: className }
|
|
7374
|
-
}, {
|
|
7375
|
-
kind: "custom-element-definition",
|
|
7376
|
-
name: component.tag,
|
|
7377
|
-
declaration: { name: className }
|
|
7378
|
-
}];
|
|
7577
|
+
addRow(data, isHeader = false) {
|
|
7578
|
+
const colData = [];
|
|
7579
|
+
data.forEach((text) => {
|
|
7580
|
+
const col = {
|
|
7581
|
+
text: escapeMarkdownTableColumn(text),
|
|
7582
|
+
width: text.length
|
|
7583
|
+
};
|
|
7584
|
+
colData.push(col);
|
|
7379
7585
|
});
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
declarations,
|
|
7384
|
-
exports
|
|
7586
|
+
this.rows.push({
|
|
7587
|
+
columns: colData,
|
|
7588
|
+
isHeader
|
|
7385
7589
|
});
|
|
7386
7590
|
}
|
|
7387
|
-
|
|
7388
|
-
|
|
7389
|
-
|
|
7390
|
-
};
|
|
7591
|
+
toMarkdown() {
|
|
7592
|
+
return createTable(this.rows);
|
|
7593
|
+
}
|
|
7391
7594
|
};
|
|
7392
|
-
|
|
7595
|
+
const escapeMarkdownTableColumn = (text) => {
|
|
7596
|
+
text = text.replace(/\r?\n/g, " ");
|
|
7597
|
+
text = text.replace(/\|/g, "\\|");
|
|
7598
|
+
return text;
|
|
7599
|
+
};
|
|
7600
|
+
const createTable = (rows) => {
|
|
7601
|
+
const content = [];
|
|
7602
|
+
if (rows.length === 0) return content;
|
|
7603
|
+
normalizeColumCount(rows);
|
|
7604
|
+
normalizeColumnWidth(rows);
|
|
7605
|
+
const th = rows.find((r) => r.isHeader);
|
|
7606
|
+
if (th) {
|
|
7607
|
+
const headerRow = createRow(th);
|
|
7608
|
+
content.push(headerRow);
|
|
7609
|
+
content.push(createBorder(th));
|
|
7610
|
+
}
|
|
7611
|
+
rows.filter((r) => !r.isHeader).forEach((td) => {
|
|
7612
|
+
content.push(createRow(td));
|
|
7613
|
+
});
|
|
7614
|
+
return content;
|
|
7615
|
+
};
|
|
7616
|
+
const createBorder = (th) => {
|
|
7617
|
+
const border = {
|
|
7618
|
+
columns: [],
|
|
7619
|
+
isHeader: false
|
|
7620
|
+
};
|
|
7621
|
+
th.columns.forEach((c) => {
|
|
7622
|
+
const borderCol = {
|
|
7623
|
+
text: "",
|
|
7624
|
+
width: c.width
|
|
7625
|
+
};
|
|
7626
|
+
while (borderCol.text.length < borderCol.width) borderCol.text += "-";
|
|
7627
|
+
border.columns.push(borderCol);
|
|
7628
|
+
});
|
|
7629
|
+
return createRow(border);
|
|
7630
|
+
};
|
|
7631
|
+
const createRow = (row) => {
|
|
7632
|
+
const content = ["| "];
|
|
7633
|
+
row.columns.forEach((c) => {
|
|
7634
|
+
content.push(c.text);
|
|
7635
|
+
content.push(" | ");
|
|
7636
|
+
});
|
|
7637
|
+
return content.join("").trim();
|
|
7638
|
+
};
|
|
7639
|
+
const normalizeColumCount = (rows) => {
|
|
7640
|
+
let columnCount = 0;
|
|
7641
|
+
rows.forEach((r) => {
|
|
7642
|
+
if (r.columns.length > columnCount) columnCount = r.columns.length;
|
|
7643
|
+
});
|
|
7644
|
+
rows.forEach((r) => {
|
|
7645
|
+
while (r.columns.length < columnCount) r.columns.push({
|
|
7646
|
+
text: ``,
|
|
7647
|
+
width: 0
|
|
7648
|
+
});
|
|
7649
|
+
});
|
|
7650
|
+
};
|
|
7651
|
+
const normalizeColumnWidth = (rows) => {
|
|
7652
|
+
const columnCount = rows[0].columns.length;
|
|
7653
|
+
for (let columnIndex = 0; columnIndex < columnCount; columnIndex++) {
|
|
7654
|
+
let longestText = 0;
|
|
7655
|
+
rows.forEach((r) => {
|
|
7656
|
+
const col = r.columns[columnIndex];
|
|
7657
|
+
if (col.text.length > longestText) longestText = col.text.length;
|
|
7658
|
+
});
|
|
7659
|
+
rows.forEach((r) => {
|
|
7660
|
+
const col = r.columns[columnIndex];
|
|
7661
|
+
col.width = longestText;
|
|
7662
|
+
while (col.text.length < longestText) col.text += " ";
|
|
7663
|
+
});
|
|
7664
|
+
}
|
|
7665
|
+
};
|
|
7666
|
+
/**
|
|
7667
|
+
* Checks if a given string is a valid hexadecimal color representation.
|
|
7668
|
+
*
|
|
7669
|
+
* @param str - The string to be checked.
|
|
7670
|
+
* @returns `true` if the string is a valid hex color (e.g., '#FF00AA', '#f0f'), `false` otherwise.
|
|
7671
|
+
*
|
|
7672
|
+
* @example
|
|
7673
|
+
* isHexColor('#FF00AA'); // true
|
|
7674
|
+
* isHexColor('#f0f'); // true
|
|
7675
|
+
* isHexColor('#abcde'); // false (too many characters)
|
|
7676
|
+
* isHexColor('FF00AA'); // false (missing #)
|
|
7677
|
+
*/
|
|
7678
|
+
const isHexColor = (str) => {
|
|
7679
|
+
return /^#([0-9A-Fa-f]{3}){1,2}$/.test(str);
|
|
7680
|
+
};
|
|
7681
|
+
//#endregion
|
|
7682
|
+
//#region src/compiler/docs/readme/markdown-css-props.ts
|
|
7683
|
+
const stylesToMarkdown = (styles) => {
|
|
7684
|
+
const content = [];
|
|
7685
|
+
if (styles.length === 0) return content;
|
|
7686
|
+
content.push(`## CSS Custom Properties`);
|
|
7687
|
+
content.push(``);
|
|
7688
|
+
const table = new MarkdownTable();
|
|
7689
|
+
table.addHeader(["Name", "Description"]);
|
|
7690
|
+
styles.forEach((style) => {
|
|
7691
|
+
table.addRow([`\`${style.name}\``, style.docs]);
|
|
7692
|
+
});
|
|
7693
|
+
content.push(...table.toMarkdown());
|
|
7694
|
+
content.push(``);
|
|
7695
|
+
content.push(``);
|
|
7696
|
+
return content;
|
|
7697
|
+
};
|
|
7698
|
+
//#endregion
|
|
7699
|
+
//#region src/compiler/docs/readme/markdown-events.ts
|
|
7700
|
+
const eventsToMarkdown = (events, cmp, customColumns = []) => {
|
|
7701
|
+
const content = [];
|
|
7702
|
+
if (events.length === 0) return content;
|
|
7703
|
+
content.push(`## Events`);
|
|
7704
|
+
content.push(``);
|
|
7705
|
+
const table = new MarkdownTable();
|
|
7706
|
+
table.addHeader([
|
|
7707
|
+
"Event",
|
|
7708
|
+
"Description",
|
|
7709
|
+
"Type",
|
|
7710
|
+
...customColumns.map((c) => c.header)
|
|
7711
|
+
]);
|
|
7712
|
+
events.forEach((ev) => {
|
|
7713
|
+
table.addRow([
|
|
7714
|
+
`\`${ev.event}\``,
|
|
7715
|
+
getDocsField$2(ev),
|
|
7716
|
+
`\`CustomEvent<${ev.detail}>\``,
|
|
7717
|
+
...customColumns.map((c) => c.content(ev, cmp))
|
|
7718
|
+
]);
|
|
7719
|
+
});
|
|
7720
|
+
content.push(...table.toMarkdown());
|
|
7721
|
+
content.push(``);
|
|
7722
|
+
content.push(``);
|
|
7723
|
+
return content;
|
|
7724
|
+
};
|
|
7725
|
+
const getDocsField$2 = (prop) => {
|
|
7726
|
+
return `${prop.deprecation !== void 0 ? `<span style="color:red">**[DEPRECATED]**</span> ${prop.deprecation}<br/><br/>` : ""}${prop.docs}`;
|
|
7727
|
+
};
|
|
7728
|
+
//#endregion
|
|
7729
|
+
//#region src/compiler/docs/readme/markdown-methods.ts
|
|
7730
|
+
const methodsToMarkdown = (methods) => {
|
|
7731
|
+
const content = [];
|
|
7732
|
+
if (methods.length === 0) return content;
|
|
7733
|
+
content.push(`## Methods`);
|
|
7734
|
+
content.push(``);
|
|
7735
|
+
methods.forEach((method) => {
|
|
7736
|
+
content.push(`### \`${method.signature}\``);
|
|
7737
|
+
content.push(``);
|
|
7738
|
+
content.push(getDocsField$1(method));
|
|
7739
|
+
content.push(``);
|
|
7740
|
+
if (method.parameters.length > 0) {
|
|
7741
|
+
const parmsTable = new MarkdownTable();
|
|
7742
|
+
parmsTable.addHeader([
|
|
7743
|
+
"Name",
|
|
7744
|
+
"Type",
|
|
7745
|
+
"Description"
|
|
7746
|
+
]);
|
|
7747
|
+
method.parameters.forEach(({ name, type, docs }) => {
|
|
7748
|
+
parmsTable.addRow([
|
|
7749
|
+
"`" + name + "`",
|
|
7750
|
+
"`" + type + "`",
|
|
7751
|
+
docs
|
|
7752
|
+
]);
|
|
7753
|
+
});
|
|
7754
|
+
content.push(`#### Parameters`);
|
|
7755
|
+
content.push(``);
|
|
7756
|
+
content.push(...parmsTable.toMarkdown());
|
|
7757
|
+
content.push(``);
|
|
7758
|
+
}
|
|
7759
|
+
if (method.returns) {
|
|
7760
|
+
content.push(`#### Returns`);
|
|
7761
|
+
content.push(``);
|
|
7762
|
+
content.push(`Type: \`${method.returns.type}\``);
|
|
7763
|
+
content.push(``);
|
|
7764
|
+
content.push(method.returns.docs);
|
|
7765
|
+
content.push(``);
|
|
7766
|
+
}
|
|
7767
|
+
});
|
|
7768
|
+
content.push(``);
|
|
7769
|
+
return content;
|
|
7770
|
+
};
|
|
7771
|
+
const getDocsField$1 = (prop) => {
|
|
7772
|
+
return `${prop.deprecation !== void 0 ? `<span style="color:red">**[DEPRECATED]**</span> ${prop.deprecation}<br/><br/>` : ""}${prop.docs}`;
|
|
7773
|
+
};
|
|
7774
|
+
//#endregion
|
|
7775
|
+
//#region src/compiler/docs/readme/markdown-overview.ts
|
|
7776
|
+
/**
|
|
7777
|
+
* Generate an 'Overview' section for a markdown file
|
|
7778
|
+
* @param overview a component-level comment string to place in a markdown file
|
|
7779
|
+
* @returns The generated Overview section. If the provided overview is empty, return an empty list
|
|
7780
|
+
*/
|
|
7781
|
+
const overviewToMarkdown = (overview) => {
|
|
7782
|
+
if (!overview) return [];
|
|
7783
|
+
const content = [];
|
|
7784
|
+
content.push(`## Overview`);
|
|
7785
|
+
content.push("");
|
|
7786
|
+
content.push(`${overview.trim()}`);
|
|
7787
|
+
content.push("");
|
|
7788
|
+
return content;
|
|
7789
|
+
};
|
|
7790
|
+
//#endregion
|
|
7791
|
+
//#region src/compiler/docs/readme/markdown-parts.ts
|
|
7792
|
+
/**
|
|
7793
|
+
* Converts a list of Shadow Parts metadata to a table written in Markdown
|
|
7794
|
+
* @param parts the Shadow parts metadata to convert
|
|
7795
|
+
* @returns a list of strings that make up the Markdown table
|
|
7796
|
+
*/
|
|
7797
|
+
const partsToMarkdown = (parts) => {
|
|
7798
|
+
const content = [];
|
|
7799
|
+
if (parts.length === 0) return content;
|
|
7800
|
+
content.push(`## Shadow Parts`);
|
|
7801
|
+
content.push(``);
|
|
7802
|
+
const table = new MarkdownTable();
|
|
7803
|
+
table.addHeader(["Part", "Description"]);
|
|
7804
|
+
parts.forEach((style) => {
|
|
7805
|
+
table.addRow([style.name === "" ? "" : `\`"${style.name}"\``, style.docs]);
|
|
7806
|
+
});
|
|
7807
|
+
content.push(...table.toMarkdown());
|
|
7808
|
+
content.push(``);
|
|
7809
|
+
content.push(``);
|
|
7810
|
+
return content;
|
|
7811
|
+
};
|
|
7812
|
+
//#endregion
|
|
7813
|
+
//#region src/compiler/docs/readme/markdown-props.ts
|
|
7814
|
+
const propsToMarkdown = (props, cmp, customColumns = []) => {
|
|
7815
|
+
const content = [];
|
|
7816
|
+
if (props.length === 0) return content;
|
|
7817
|
+
content.push(`## Properties`);
|
|
7818
|
+
content.push(``);
|
|
7819
|
+
const table = new MarkdownTable();
|
|
7820
|
+
table.addHeader([
|
|
7821
|
+
"Property",
|
|
7822
|
+
"Attribute",
|
|
7823
|
+
"Description",
|
|
7824
|
+
"Type",
|
|
7825
|
+
"Default",
|
|
7826
|
+
...customColumns.map((c) => c.header)
|
|
7827
|
+
]);
|
|
7828
|
+
props.forEach((prop) => {
|
|
7829
|
+
table.addRow([
|
|
7830
|
+
getPropertyField(prop),
|
|
7831
|
+
getAttributeField(prop),
|
|
7832
|
+
getDocsField(prop),
|
|
7833
|
+
getTypeField(prop),
|
|
7834
|
+
getDefaultValueField(prop),
|
|
7835
|
+
...customColumns.map((c) => c.content(prop, cmp))
|
|
7836
|
+
]);
|
|
7837
|
+
});
|
|
7838
|
+
content.push(...table.toMarkdown());
|
|
7839
|
+
content.push(``);
|
|
7840
|
+
content.push(``);
|
|
7841
|
+
return content;
|
|
7842
|
+
};
|
|
7843
|
+
const getPropertyField = (prop) => {
|
|
7844
|
+
return `\`${prop.name}\`${prop.required ? " _(required)_" : ""}`;
|
|
7845
|
+
};
|
|
7846
|
+
const getAttributeField = (prop) => {
|
|
7847
|
+
return prop.attr ? `\`${prop.attr}\`` : "--";
|
|
7848
|
+
};
|
|
7849
|
+
const getDocsField = (prop) => {
|
|
7850
|
+
return `${prop.deprecation !== void 0 ? `<span style="color:red">**[DEPRECATED]**</span> ${prop.deprecation}<br/><br/>` : ""}${prop.docs}`;
|
|
7851
|
+
};
|
|
7852
|
+
const getTypeField = (prop) => {
|
|
7853
|
+
return prop.type.includes("`") ? `\`\` ${prop.type} \`\`` : `\`${prop.type}\``;
|
|
7854
|
+
};
|
|
7855
|
+
const getDefaultValueField = (prop) => {
|
|
7856
|
+
return prop.default?.includes("`") ? `\`\` ${prop.default} \`\`` : `\`${prop.default}\``;
|
|
7857
|
+
};
|
|
7858
|
+
//#endregion
|
|
7859
|
+
//#region src/compiler/docs/readme/markdown-slots.ts
|
|
7860
|
+
/**
|
|
7861
|
+
* Converts a list of Slots metadata to a table written in Markdown
|
|
7862
|
+
* @param slots the Slots metadata to convert
|
|
7863
|
+
* @returns a list of strings that make up the Markdown table
|
|
7864
|
+
*/
|
|
7865
|
+
const slotsToMarkdown = (slots) => {
|
|
7866
|
+
const content = [];
|
|
7867
|
+
if (slots.length === 0) return content;
|
|
7868
|
+
content.push(`## Slots`);
|
|
7869
|
+
content.push(``);
|
|
7870
|
+
const table = new MarkdownTable();
|
|
7871
|
+
table.addHeader(["Slot", "Description"]);
|
|
7872
|
+
slots.forEach((style) => {
|
|
7873
|
+
table.addRow([style.name === "" ? "" : `\`"${style.name}"\``, style.docs]);
|
|
7874
|
+
});
|
|
7875
|
+
content.push(...table.toMarkdown());
|
|
7876
|
+
content.push(``);
|
|
7877
|
+
content.push(``);
|
|
7878
|
+
return content;
|
|
7879
|
+
};
|
|
7880
|
+
//#endregion
|
|
7881
|
+
//#region src/compiler/docs/agent-skill/markdown-component.ts
|
|
7882
|
+
/**
|
|
7883
|
+
* Generate a single component's skill reference file (`components/<tag>.md`),
|
|
7884
|
+
* reusing the same pure markdown-formatting functions the `docs-readme`
|
|
7885
|
+
* output target uses.
|
|
7886
|
+
* @param cmp the component's docs metadata
|
|
7887
|
+
* @returns the component's markdown content
|
|
7888
|
+
*/
|
|
7889
|
+
const generateComponentSkillMarkdown = (cmp) => {
|
|
7890
|
+
return [
|
|
7891
|
+
`# ${cmp.tag}`,
|
|
7892
|
+
"",
|
|
7893
|
+
...overviewToMarkdown(cmp.overview),
|
|
7894
|
+
...propsToMarkdown(cmp.props),
|
|
7895
|
+
...eventsToMarkdown(cmp.events),
|
|
7896
|
+
...methodsToMarkdown(cmp.methods),
|
|
7897
|
+
...slotsToMarkdown(cmp.slots),
|
|
7898
|
+
...stylesToMarkdown(cmp.styles),
|
|
7899
|
+
...partsToMarkdown(cmp.parts),
|
|
7900
|
+
...usageToMarkdown(cmp.usage)
|
|
7901
|
+
].join("\n");
|
|
7902
|
+
};
|
|
7903
|
+
//#endregion
|
|
7904
|
+
//#region src/compiler/docs/agent-skill/index.ts
|
|
7905
|
+
/**
|
|
7906
|
+
* Generate an Agent Skill (`SKILL.md` + `components/*.md`) describing the project's
|
|
7907
|
+
* component library.
|
|
7908
|
+
* @param compilerCtx the current compiler context
|
|
7909
|
+
* @param docsData the generated docs data
|
|
7910
|
+
* @param outputTargets the output targets configured for the build
|
|
7911
|
+
*/
|
|
7912
|
+
const generateAgentSkillDocs = async (compilerCtx, docsData, outputTargets) => {
|
|
7913
|
+
const skillOutputs = outputTargets.filter(isOutputTargetDocsAgentSkill);
|
|
7914
|
+
if (skillOutputs.length === 0) return;
|
|
7915
|
+
await Promise.all(skillOutputs.map(async (outputTarget) => {
|
|
7916
|
+
const dir = outputTarget.dir;
|
|
7917
|
+
const skillMd = generateSkillMarkdown(docsData, outputTarget);
|
|
7918
|
+
await Promise.all([compilerCtx.fs.writeFile(join$2(dir, "SKILL.md"), skillMd), ...docsData.components.map((cmp) => compilerCtx.fs.writeFile(join$2(dir, "components", `${cmp.tag}.md`), generateComponentSkillMarkdown(cmp)))]);
|
|
7919
|
+
}));
|
|
7920
|
+
};
|
|
7921
|
+
//#endregion
|
|
7922
|
+
//#region src/compiler/docs/cem/index.ts
|
|
7923
|
+
/**
|
|
7924
|
+
* Generate Custom Elements Manifest (custom-elements.json) output
|
|
7925
|
+
* conforming to the Custom Elements Manifest specification.
|
|
7926
|
+
* @see https://github.com/webcomponents/custom-elements-manifest
|
|
7927
|
+
*
|
|
7928
|
+
* @param compilerCtx the current compiler context
|
|
7929
|
+
* @param docsData the generated docs data from Stencil components
|
|
7930
|
+
* @param outputTargets the output targets configured for the build
|
|
7931
|
+
*/
|
|
7932
|
+
const generateCustomElementsManifestDocs = async (compilerCtx, docsData, outputTargets) => {
|
|
7933
|
+
const cemOutputTargets = outputTargets.filter(isOutputTargetDocsCustomElementsManifest);
|
|
7934
|
+
if (cemOutputTargets.length === 0) return;
|
|
7935
|
+
const manifest = generateManifest(docsData);
|
|
7936
|
+
const jsonContent = JSON.stringify(manifest, null, 2);
|
|
7937
|
+
await Promise.all(cemOutputTargets.map((outputTarget) => compilerCtx.fs.writeFile(outputTarget.file, jsonContent)));
|
|
7938
|
+
};
|
|
7939
|
+
/**
|
|
7940
|
+
* Generate the Custom Elements Manifest from Stencil docs data
|
|
7941
|
+
* @param docsData the generated docs data
|
|
7942
|
+
* @returns the Custom Elements Manifest object
|
|
7943
|
+
*/
|
|
7944
|
+
const generateManifest = (docsData) => {
|
|
7945
|
+
const componentsByFile = /* @__PURE__ */ new Map();
|
|
7946
|
+
for (const component of docsData.components) {
|
|
7947
|
+
const filePath = component.filePath;
|
|
7948
|
+
if (!componentsByFile.has(filePath)) componentsByFile.set(filePath, []);
|
|
7949
|
+
componentsByFile.get(filePath).push(component);
|
|
7950
|
+
}
|
|
7951
|
+
const modules = [];
|
|
7952
|
+
for (const [filePath, components] of componentsByFile) {
|
|
7953
|
+
const declarations = components.map((component) => componentToDeclaration(component));
|
|
7954
|
+
const exports = components.flatMap((component) => {
|
|
7955
|
+
const className = dashToPascalCase(component.tag);
|
|
7956
|
+
return [{
|
|
7957
|
+
kind: "js",
|
|
7958
|
+
name: className,
|
|
7959
|
+
declaration: { name: className }
|
|
7960
|
+
}, {
|
|
7961
|
+
kind: "custom-element-definition",
|
|
7962
|
+
name: component.tag,
|
|
7963
|
+
declaration: { name: className }
|
|
7964
|
+
}];
|
|
7965
|
+
});
|
|
7966
|
+
modules.push({
|
|
7967
|
+
kind: "javascript-module",
|
|
7968
|
+
path: filePath,
|
|
7969
|
+
declarations,
|
|
7970
|
+
exports
|
|
7971
|
+
});
|
|
7972
|
+
}
|
|
7973
|
+
return {
|
|
7974
|
+
schemaVersion: "2.1.0",
|
|
7975
|
+
modules
|
|
7976
|
+
};
|
|
7977
|
+
};
|
|
7978
|
+
/**
|
|
7393
7979
|
* Convert Stencil's ComponentCompilerTypeReferences to CEM TypeReference array
|
|
7394
7980
|
* @param references Stencil's type references map
|
|
7395
7981
|
* @returns CEM TypeReference array
|
|
@@ -7570,141 +8156,13 @@ export default _default;
|
|
|
7570
8156
|
deprecation: cmp.deprecation
|
|
7571
8157
|
}))
|
|
7572
8158
|
};
|
|
7573
|
-
const jsonContent = JSON.stringify(json, null, 2);
|
|
7574
|
-
await Promise.all(jsonOutputTargets.map((jsonOutput) => {
|
|
7575
|
-
return writeDocsOutput(compilerCtx, jsonOutput, jsonContent, typesContent);
|
|
7576
|
-
}));
|
|
7577
|
-
};
|
|
7578
|
-
const writeDocsOutput = async (compilerCtx, jsonOutput, jsonContent, typesContent) => {
|
|
7579
|
-
return Promise.all([compilerCtx.fs.writeFile(jsonOutput.file, jsonContent), jsonOutput.typesFile ? compilerCtx.fs.writeFile(jsonOutput.typesFile, typesContent) : Promise.resolve()]);
|
|
7580
|
-
};
|
|
7581
|
-
//#endregion
|
|
7582
|
-
//#region src/compiler/docs/readme/docs-util.ts
|
|
7583
|
-
var MarkdownTable = class {
|
|
7584
|
-
rows = [];
|
|
7585
|
-
addHeader(data) {
|
|
7586
|
-
this.addRow(data, true);
|
|
7587
|
-
}
|
|
7588
|
-
addRow(data, isHeader = false) {
|
|
7589
|
-
const colData = [];
|
|
7590
|
-
data.forEach((text) => {
|
|
7591
|
-
const col = {
|
|
7592
|
-
text: escapeMarkdownTableColumn(text),
|
|
7593
|
-
width: text.length
|
|
7594
|
-
};
|
|
7595
|
-
colData.push(col);
|
|
7596
|
-
});
|
|
7597
|
-
this.rows.push({
|
|
7598
|
-
columns: colData,
|
|
7599
|
-
isHeader
|
|
7600
|
-
});
|
|
7601
|
-
}
|
|
7602
|
-
toMarkdown() {
|
|
7603
|
-
return createTable(this.rows);
|
|
7604
|
-
}
|
|
7605
|
-
};
|
|
7606
|
-
const escapeMarkdownTableColumn = (text) => {
|
|
7607
|
-
text = text.replace(/\r?\n/g, " ");
|
|
7608
|
-
text = text.replace(/\|/g, "\\|");
|
|
7609
|
-
return text;
|
|
7610
|
-
};
|
|
7611
|
-
const createTable = (rows) => {
|
|
7612
|
-
const content = [];
|
|
7613
|
-
if (rows.length === 0) return content;
|
|
7614
|
-
normalizeColumCount(rows);
|
|
7615
|
-
normalizeColumnWidth(rows);
|
|
7616
|
-
const th = rows.find((r) => r.isHeader);
|
|
7617
|
-
if (th) {
|
|
7618
|
-
const headerRow = createRow(th);
|
|
7619
|
-
content.push(headerRow);
|
|
7620
|
-
content.push(createBorder(th));
|
|
7621
|
-
}
|
|
7622
|
-
rows.filter((r) => !r.isHeader).forEach((td) => {
|
|
7623
|
-
content.push(createRow(td));
|
|
7624
|
-
});
|
|
7625
|
-
return content;
|
|
7626
|
-
};
|
|
7627
|
-
const createBorder = (th) => {
|
|
7628
|
-
const border = {
|
|
7629
|
-
columns: [],
|
|
7630
|
-
isHeader: false
|
|
7631
|
-
};
|
|
7632
|
-
th.columns.forEach((c) => {
|
|
7633
|
-
const borderCol = {
|
|
7634
|
-
text: "",
|
|
7635
|
-
width: c.width
|
|
7636
|
-
};
|
|
7637
|
-
while (borderCol.text.length < borderCol.width) borderCol.text += "-";
|
|
7638
|
-
border.columns.push(borderCol);
|
|
7639
|
-
});
|
|
7640
|
-
return createRow(border);
|
|
7641
|
-
};
|
|
7642
|
-
const createRow = (row) => {
|
|
7643
|
-
const content = ["| "];
|
|
7644
|
-
row.columns.forEach((c) => {
|
|
7645
|
-
content.push(c.text);
|
|
7646
|
-
content.push(" | ");
|
|
7647
|
-
});
|
|
7648
|
-
return content.join("").trim();
|
|
7649
|
-
};
|
|
7650
|
-
const normalizeColumCount = (rows) => {
|
|
7651
|
-
let columnCount = 0;
|
|
7652
|
-
rows.forEach((r) => {
|
|
7653
|
-
if (r.columns.length > columnCount) columnCount = r.columns.length;
|
|
7654
|
-
});
|
|
7655
|
-
rows.forEach((r) => {
|
|
7656
|
-
while (r.columns.length < columnCount) r.columns.push({
|
|
7657
|
-
text: ``,
|
|
7658
|
-
width: 0
|
|
7659
|
-
});
|
|
7660
|
-
});
|
|
7661
|
-
};
|
|
7662
|
-
const normalizeColumnWidth = (rows) => {
|
|
7663
|
-
const columnCount = rows[0].columns.length;
|
|
7664
|
-
for (let columnIndex = 0; columnIndex < columnCount; columnIndex++) {
|
|
7665
|
-
let longestText = 0;
|
|
7666
|
-
rows.forEach((r) => {
|
|
7667
|
-
const col = r.columns[columnIndex];
|
|
7668
|
-
if (col.text.length > longestText) longestText = col.text.length;
|
|
7669
|
-
});
|
|
7670
|
-
rows.forEach((r) => {
|
|
7671
|
-
const col = r.columns[columnIndex];
|
|
7672
|
-
col.width = longestText;
|
|
7673
|
-
while (col.text.length < longestText) col.text += " ";
|
|
7674
|
-
});
|
|
7675
|
-
}
|
|
7676
|
-
};
|
|
7677
|
-
/**
|
|
7678
|
-
* Checks if a given string is a valid hexadecimal color representation.
|
|
7679
|
-
*
|
|
7680
|
-
* @param str - The string to be checked.
|
|
7681
|
-
* @returns `true` if the string is a valid hex color (e.g., '#FF00AA', '#f0f'), `false` otherwise.
|
|
7682
|
-
*
|
|
7683
|
-
* @example
|
|
7684
|
-
* isHexColor('#FF00AA'); // true
|
|
7685
|
-
* isHexColor('#f0f'); // true
|
|
7686
|
-
* isHexColor('#abcde'); // false (too many characters)
|
|
7687
|
-
* isHexColor('FF00AA'); // false (missing #)
|
|
7688
|
-
*/
|
|
7689
|
-
const isHexColor = (str) => {
|
|
7690
|
-
return /^#([0-9A-Fa-f]{3}){1,2}$/.test(str);
|
|
7691
|
-
};
|
|
7692
|
-
//#endregion
|
|
7693
|
-
//#region src/compiler/docs/readme/markdown-css-props.ts
|
|
7694
|
-
const stylesToMarkdown = (styles) => {
|
|
7695
|
-
const content = [];
|
|
7696
|
-
if (styles.length === 0) return content;
|
|
7697
|
-
content.push(`## CSS Custom Properties`);
|
|
7698
|
-
content.push(``);
|
|
7699
|
-
const table = new MarkdownTable();
|
|
7700
|
-
table.addHeader(["Name", "Description"]);
|
|
7701
|
-
styles.forEach((style) => {
|
|
7702
|
-
table.addRow([`\`${style.name}\``, style.docs]);
|
|
7703
|
-
});
|
|
7704
|
-
content.push(...table.toMarkdown());
|
|
7705
|
-
content.push(``);
|
|
7706
|
-
content.push(``);
|
|
7707
|
-
return content;
|
|
8159
|
+
const jsonContent = JSON.stringify(json, null, 2);
|
|
8160
|
+
await Promise.all(jsonOutputTargets.map((jsonOutput) => {
|
|
8161
|
+
return writeDocsOutput(compilerCtx, jsonOutput, jsonContent, typesContent);
|
|
8162
|
+
}));
|
|
8163
|
+
};
|
|
8164
|
+
const writeDocsOutput = async (compilerCtx, jsonOutput, jsonContent, typesContent) => {
|
|
8165
|
+
return Promise.all([compilerCtx.fs.writeFile(jsonOutput.file, jsonContent), jsonOutput.typesFile ? compilerCtx.fs.writeFile(jsonOutput.typesFile, typesContent) : Promise.resolve()]);
|
|
7708
8166
|
};
|
|
7709
8167
|
//#endregion
|
|
7710
8168
|
//#region src/compiler/docs/readme/markdown-custom-states.ts
|
|
@@ -7778,220 +8236,6 @@ const getCmpLink = (from, to, cmps) => {
|
|
|
7778
8236
|
return to;
|
|
7779
8237
|
};
|
|
7780
8238
|
//#endregion
|
|
7781
|
-
//#region src/compiler/docs/readme/markdown-events.ts
|
|
7782
|
-
const eventsToMarkdown = (events) => {
|
|
7783
|
-
const content = [];
|
|
7784
|
-
if (events.length === 0) return content;
|
|
7785
|
-
content.push(`## Events`);
|
|
7786
|
-
content.push(``);
|
|
7787
|
-
const table = new MarkdownTable();
|
|
7788
|
-
table.addHeader([
|
|
7789
|
-
"Event",
|
|
7790
|
-
"Description",
|
|
7791
|
-
"Type"
|
|
7792
|
-
]);
|
|
7793
|
-
events.forEach((ev) => {
|
|
7794
|
-
table.addRow([
|
|
7795
|
-
`\`${ev.event}\``,
|
|
7796
|
-
getDocsField$2(ev),
|
|
7797
|
-
`\`CustomEvent<${ev.detail}>\``
|
|
7798
|
-
]);
|
|
7799
|
-
});
|
|
7800
|
-
content.push(...table.toMarkdown());
|
|
7801
|
-
content.push(``);
|
|
7802
|
-
content.push(``);
|
|
7803
|
-
return content;
|
|
7804
|
-
};
|
|
7805
|
-
const getDocsField$2 = (prop) => {
|
|
7806
|
-
return `${prop.deprecation !== void 0 ? `<span style="color:red">**[DEPRECATED]**</span> ${prop.deprecation}<br/><br/>` : ""}${prop.docs}`;
|
|
7807
|
-
};
|
|
7808
|
-
//#endregion
|
|
7809
|
-
//#region src/compiler/docs/readme/markdown-methods.ts
|
|
7810
|
-
const methodsToMarkdown = (methods) => {
|
|
7811
|
-
const content = [];
|
|
7812
|
-
if (methods.length === 0) return content;
|
|
7813
|
-
content.push(`## Methods`);
|
|
7814
|
-
content.push(``);
|
|
7815
|
-
methods.forEach((method) => {
|
|
7816
|
-
content.push(`### \`${method.signature}\``);
|
|
7817
|
-
content.push(``);
|
|
7818
|
-
content.push(getDocsField$1(method));
|
|
7819
|
-
content.push(``);
|
|
7820
|
-
if (method.parameters.length > 0) {
|
|
7821
|
-
const parmsTable = new MarkdownTable();
|
|
7822
|
-
parmsTable.addHeader([
|
|
7823
|
-
"Name",
|
|
7824
|
-
"Type",
|
|
7825
|
-
"Description"
|
|
7826
|
-
]);
|
|
7827
|
-
method.parameters.forEach(({ name, type, docs }) => {
|
|
7828
|
-
parmsTable.addRow([
|
|
7829
|
-
"`" + name + "`",
|
|
7830
|
-
"`" + type + "`",
|
|
7831
|
-
docs
|
|
7832
|
-
]);
|
|
7833
|
-
});
|
|
7834
|
-
content.push(`#### Parameters`);
|
|
7835
|
-
content.push(``);
|
|
7836
|
-
content.push(...parmsTable.toMarkdown());
|
|
7837
|
-
content.push(``);
|
|
7838
|
-
}
|
|
7839
|
-
if (method.returns) {
|
|
7840
|
-
content.push(`#### Returns`);
|
|
7841
|
-
content.push(``);
|
|
7842
|
-
content.push(`Type: \`${method.returns.type}\``);
|
|
7843
|
-
content.push(``);
|
|
7844
|
-
content.push(method.returns.docs);
|
|
7845
|
-
content.push(``);
|
|
7846
|
-
}
|
|
7847
|
-
});
|
|
7848
|
-
content.push(``);
|
|
7849
|
-
return content;
|
|
7850
|
-
};
|
|
7851
|
-
const getDocsField$1 = (prop) => {
|
|
7852
|
-
return `${prop.deprecation !== void 0 ? `<span style="color:red">**[DEPRECATED]**</span> ${prop.deprecation}<br/><br/>` : ""}${prop.docs}`;
|
|
7853
|
-
};
|
|
7854
|
-
//#endregion
|
|
7855
|
-
//#region src/compiler/docs/readme/markdown-overview.ts
|
|
7856
|
-
/**
|
|
7857
|
-
* Generate an 'Overview' section for a markdown file
|
|
7858
|
-
* @param overview a component-level comment string to place in a markdown file
|
|
7859
|
-
* @returns The generated Overview section. If the provided overview is empty, return an empty list
|
|
7860
|
-
*/
|
|
7861
|
-
const overviewToMarkdown = (overview) => {
|
|
7862
|
-
if (!overview) return [];
|
|
7863
|
-
const content = [];
|
|
7864
|
-
content.push(`## Overview`);
|
|
7865
|
-
content.push("");
|
|
7866
|
-
content.push(`${overview.trim()}`);
|
|
7867
|
-
content.push("");
|
|
7868
|
-
return content;
|
|
7869
|
-
};
|
|
7870
|
-
//#endregion
|
|
7871
|
-
//#region src/compiler/docs/readme/markdown-parts.ts
|
|
7872
|
-
/**
|
|
7873
|
-
* Converts a list of Shadow Parts metadata to a table written in Markdown
|
|
7874
|
-
* @param parts the Shadow parts metadata to convert
|
|
7875
|
-
* @returns a list of strings that make up the Markdown table
|
|
7876
|
-
*/
|
|
7877
|
-
const partsToMarkdown = (parts) => {
|
|
7878
|
-
const content = [];
|
|
7879
|
-
if (parts.length === 0) return content;
|
|
7880
|
-
content.push(`## Shadow Parts`);
|
|
7881
|
-
content.push(``);
|
|
7882
|
-
const table = new MarkdownTable();
|
|
7883
|
-
table.addHeader(["Part", "Description"]);
|
|
7884
|
-
parts.forEach((style) => {
|
|
7885
|
-
table.addRow([style.name === "" ? "" : `\`"${style.name}"\``, style.docs]);
|
|
7886
|
-
});
|
|
7887
|
-
content.push(...table.toMarkdown());
|
|
7888
|
-
content.push(``);
|
|
7889
|
-
content.push(``);
|
|
7890
|
-
return content;
|
|
7891
|
-
};
|
|
7892
|
-
//#endregion
|
|
7893
|
-
//#region src/compiler/docs/readme/markdown-props.ts
|
|
7894
|
-
const propsToMarkdown = (props) => {
|
|
7895
|
-
const content = [];
|
|
7896
|
-
if (props.length === 0) return content;
|
|
7897
|
-
content.push(`## Properties`);
|
|
7898
|
-
content.push(``);
|
|
7899
|
-
const table = new MarkdownTable();
|
|
7900
|
-
table.addHeader([
|
|
7901
|
-
"Property",
|
|
7902
|
-
"Attribute",
|
|
7903
|
-
"Description",
|
|
7904
|
-
"Type",
|
|
7905
|
-
"Default"
|
|
7906
|
-
]);
|
|
7907
|
-
props.forEach((prop) => {
|
|
7908
|
-
table.addRow([
|
|
7909
|
-
getPropertyField(prop),
|
|
7910
|
-
getAttributeField(prop),
|
|
7911
|
-
getDocsField(prop),
|
|
7912
|
-
getTypeField(prop),
|
|
7913
|
-
getDefaultValueField(prop)
|
|
7914
|
-
]);
|
|
7915
|
-
});
|
|
7916
|
-
content.push(...table.toMarkdown());
|
|
7917
|
-
content.push(``);
|
|
7918
|
-
content.push(``);
|
|
7919
|
-
return content;
|
|
7920
|
-
};
|
|
7921
|
-
const getPropertyField = (prop) => {
|
|
7922
|
-
return `\`${prop.name}\`${prop.required ? " _(required)_" : ""}`;
|
|
7923
|
-
};
|
|
7924
|
-
const getAttributeField = (prop) => {
|
|
7925
|
-
return prop.attr ? `\`${prop.attr}\`` : "--";
|
|
7926
|
-
};
|
|
7927
|
-
const getDocsField = (prop) => {
|
|
7928
|
-
return `${prop.deprecation !== void 0 ? `<span style="color:red">**[DEPRECATED]**</span> ${prop.deprecation}<br/><br/>` : ""}${prop.docs}`;
|
|
7929
|
-
};
|
|
7930
|
-
const getTypeField = (prop) => {
|
|
7931
|
-
return prop.type.includes("`") ? `\`\` ${prop.type} \`\`` : `\`${prop.type}\``;
|
|
7932
|
-
};
|
|
7933
|
-
const getDefaultValueField = (prop) => {
|
|
7934
|
-
return prop.default?.includes("`") ? `\`\` ${prop.default} \`\`` : `\`${prop.default}\``;
|
|
7935
|
-
};
|
|
7936
|
-
//#endregion
|
|
7937
|
-
//#region src/compiler/docs/readme/markdown-slots.ts
|
|
7938
|
-
/**
|
|
7939
|
-
* Converts a list of Slots metadata to a table written in Markdown
|
|
7940
|
-
* @param slots the Slots metadata to convert
|
|
7941
|
-
* @returns a list of strings that make up the Markdown table
|
|
7942
|
-
*/
|
|
7943
|
-
const slotsToMarkdown = (slots) => {
|
|
7944
|
-
const content = [];
|
|
7945
|
-
if (slots.length === 0) return content;
|
|
7946
|
-
content.push(`## Slots`);
|
|
7947
|
-
content.push(``);
|
|
7948
|
-
const table = new MarkdownTable();
|
|
7949
|
-
table.addHeader(["Slot", "Description"]);
|
|
7950
|
-
slots.forEach((style) => {
|
|
7951
|
-
table.addRow([style.name === "" ? "" : `\`"${style.name}"\``, style.docs]);
|
|
7952
|
-
});
|
|
7953
|
-
content.push(...table.toMarkdown());
|
|
7954
|
-
content.push(``);
|
|
7955
|
-
content.push(``);
|
|
7956
|
-
return content;
|
|
7957
|
-
};
|
|
7958
|
-
//#endregion
|
|
7959
|
-
//#region src/compiler/docs/readme/markdown-usage.ts
|
|
7960
|
-
const usageToMarkdown = (usages) => {
|
|
7961
|
-
const content = [];
|
|
7962
|
-
const merged = mergeUsages(usages);
|
|
7963
|
-
if (merged.length === 0) return content;
|
|
7964
|
-
content.push(`## Usage`);
|
|
7965
|
-
merged.forEach(({ name, text }) => {
|
|
7966
|
-
content.push("");
|
|
7967
|
-
content.push(`### ${toTitleCase(name)}`);
|
|
7968
|
-
content.push("");
|
|
7969
|
-
content.push(text);
|
|
7970
|
-
content.push("");
|
|
7971
|
-
});
|
|
7972
|
-
content.push("");
|
|
7973
|
-
content.push("");
|
|
7974
|
-
return content;
|
|
7975
|
-
};
|
|
7976
|
-
const mergeUsages = (usages) => {
|
|
7977
|
-
const keys = Object.keys(usages);
|
|
7978
|
-
const map = /* @__PURE__ */ new Map();
|
|
7979
|
-
keys.forEach((key) => {
|
|
7980
|
-
const usage = usages[key].trim();
|
|
7981
|
-
const array = map.get(usage) || [];
|
|
7982
|
-
array.push(key);
|
|
7983
|
-
map.set(usage, array);
|
|
7984
|
-
});
|
|
7985
|
-
const merged = [];
|
|
7986
|
-
map.forEach((value, key) => {
|
|
7987
|
-
merged.push({
|
|
7988
|
-
name: value.join(" / "),
|
|
7989
|
-
text: key
|
|
7990
|
-
});
|
|
7991
|
-
});
|
|
7992
|
-
return merged;
|
|
7993
|
-
};
|
|
7994
|
-
//#endregion
|
|
7995
8239
|
//#region src/compiler/docs/readme/output-docs.ts
|
|
7996
8240
|
/**
|
|
7997
8241
|
* Generate a README for a given component and write it to disk.
|
|
@@ -8017,7 +8261,8 @@ const generateReadme = async (config, compilerCtx, readmeOutputs, docsData, cmps
|
|
|
8017
8261
|
if (readmeOutput.dir) {
|
|
8018
8262
|
const relativeReadmePath = relative$1(config.srcDir, docsData.readmePath);
|
|
8019
8263
|
const readmeOutputPath = join$2(readmeOutput.dir, relativeReadmePath);
|
|
8020
|
-
const
|
|
8264
|
+
const currentReadmeContent = await resolveUserContent(compilerCtx, readmeOutput, readmeOutputPath, config, userContent);
|
|
8265
|
+
const readmeContent = generateMarkdown(currentReadmeContent, docsData, cmps, readmeOutput, config);
|
|
8021
8266
|
if ((await compilerCtx.fs.readFile(readmeOutputPath))?.replace(/\r/g, "") === readmeContent.replace(/\r/g, "")) return;
|
|
8022
8267
|
await compilerCtx.fs.writeFile(readmeOutputPath, readmeContent);
|
|
8023
8268
|
if (isUpdate) config.logger.info(`updated readme docs: ${docsData.tag}`);
|
|
@@ -8046,7 +8291,8 @@ const generateMergedReadme = async (config, compilerCtx, readmeOutputs, cmps, al
|
|
|
8046
8291
|
if (readmeOutput.dir) {
|
|
8047
8292
|
const relativeReadmePath = relative$1(config.srcDir, primaryCmp.readmePath);
|
|
8048
8293
|
const readmeOutputPath = join$2(readmeOutput.dir, relativeReadmePath);
|
|
8049
|
-
const
|
|
8294
|
+
const currentReadmeContent = await resolveUserContent(compilerCtx, readmeOutput, readmeOutputPath, config, userContent);
|
|
8295
|
+
const readmeContent = generateMergedMarkdown(currentReadmeContent, cmps, allCmps, readmeOutput, config);
|
|
8050
8296
|
if ((await compilerCtx.fs.readFile(readmeOutputPath))?.replace(/\r/g, "") === readmeContent.replace(/\r/g, "")) return;
|
|
8051
8297
|
await compilerCtx.fs.writeFile(readmeOutputPath, readmeContent);
|
|
8052
8298
|
const tags = cmps.map((c) => c.tag).join(", ");
|
|
@@ -8102,8 +8348,8 @@ const generateComponentBody = (cmp, cmps, readmeOutput, config) => {
|
|
|
8102
8348
|
...getDocsDeprecation(cmp),
|
|
8103
8349
|
...overviewToMarkdown(cmp.overview),
|
|
8104
8350
|
...usageToMarkdown(cmp.usage),
|
|
8105
|
-
...propsToMarkdown(cmp.props),
|
|
8106
|
-
...eventsToMarkdown(cmp.events),
|
|
8351
|
+
...propsToMarkdown(cmp.props, cmp, readmeOutput.customColumns?.props),
|
|
8352
|
+
...eventsToMarkdown(cmp.events, cmp, readmeOutput.customColumns?.events),
|
|
8107
8353
|
...methodsToMarkdown(cmp.methods),
|
|
8108
8354
|
...slotsToMarkdown(cmp.slots),
|
|
8109
8355
|
...partsToMarkdown(cmp.parts),
|
|
@@ -8303,14 +8549,15 @@ const serializeAttribute = (prop) => {
|
|
|
8303
8549
|
* @param buildCtx the build context for the current Stencil task run
|
|
8304
8550
|
*/
|
|
8305
8551
|
const outputDocs = async (config, compilerCtx, buildCtx) => {
|
|
8306
|
-
const docsOutputTargets = filterActiveTargets(config.outputTargets.filter((o) => isOutputTargetDocsReadme(o) || isOutputTargetDocsJson(o) || isOutputTargetDocsCustom(o) || isOutputTargetDocsVscode(o) || isOutputTargetDocsCustomElementsManifest(o)), config.devMode);
|
|
8552
|
+
const docsOutputTargets = filterActiveTargets(config.outputTargets.filter((o) => isOutputTargetDocsReadme(o) || isOutputTargetDocsJson(o) || isOutputTargetDocsCustom(o) || isOutputTargetDocsVscode(o) || isOutputTargetDocsCustomElementsManifest(o) || isOutputTargetDocsAgentSkill(o)), config.devMode);
|
|
8307
8553
|
if (docsOutputTargets.length === 0) return;
|
|
8308
8554
|
await buildCtx.stylesPromise;
|
|
8309
8555
|
const docsData = await generateDocData(config, compilerCtx, buildCtx);
|
|
8310
|
-
if (config.outputTargets.every((target) => target.type === "docs-readme" || target.type === "docs-json" || target.type === "docs-custom" || target.type === "docs-vscode" || target.type === "docs-custom-elements-manifest")) await Promise.all(docsData.components.map(async (component) => {
|
|
8556
|
+
if (config.outputTargets.every((target) => target.type === "docs-readme" || target.type === "docs-json" || target.type === "docs-custom" || target.type === "docs-vscode" || target.type === "docs-custom-elements-manifest" || target.type === "docs-agent-skill")) await Promise.all(docsData.components.map(async (component) => {
|
|
8311
8557
|
if (component.styles.length === 0) {
|
|
8312
8558
|
const readmeDir = docsOutputTargets.find(isOutputTargetDocsReadme)?.dir || config.srcDir;
|
|
8313
|
-
const
|
|
8559
|
+
const readmePath = normalizePath(readmeDir) === normalizePath(config.srcDir) ? component.readmePath : join$2(readmeDir, component.readmePath.replace(config.srcDir, ""));
|
|
8560
|
+
const existingCssProps = await extractExistingCssProps(compilerCtx, readmePath);
|
|
8314
8561
|
if (existingCssProps) component.styles = existingCssProps;
|
|
8315
8562
|
}
|
|
8316
8563
|
}));
|
|
@@ -8319,7 +8566,8 @@ const outputDocs = async (config, compilerCtx, buildCtx) => {
|
|
|
8319
8566
|
generateJsonDocs(config, compilerCtx, docsData, docsOutputTargets),
|
|
8320
8567
|
generateVscodeDocs(compilerCtx, docsData, docsOutputTargets),
|
|
8321
8568
|
generateCustomDocs(config, docsData, docsOutputTargets),
|
|
8322
|
-
generateCustomElementsManifestDocs(compilerCtx, docsData, docsOutputTargets)
|
|
8569
|
+
generateCustomElementsManifestDocs(compilerCtx, docsData, docsOutputTargets),
|
|
8570
|
+
generateAgentSkillDocs(compilerCtx, docsData, docsOutputTargets)
|
|
8323
8571
|
]);
|
|
8324
8572
|
};
|
|
8325
8573
|
//#endregion
|
|
@@ -8353,7 +8601,8 @@ const outputGlobalStyle = async (config, compilerCtx, buildCtx) => {
|
|
|
8353
8601
|
const primaryPath = join$2(outputTarget.dir, outputTarget.fileName);
|
|
8354
8602
|
writePromises.push(compilerCtx.fs.writeFile(primaryPath, css, { outputTargetType: outputTarget.type }));
|
|
8355
8603
|
if (outputTarget.copyToLoaderBrowser && loaderBundleTargets.length > 0) for (const loaderTarget of loaderBundleTargets) {
|
|
8356
|
-
const
|
|
8604
|
+
const browserDir = join$2(loaderTarget.buildDir, namespace);
|
|
8605
|
+
const compatPath = join$2(browserDir, outputTarget.fileName);
|
|
8357
8606
|
writePromises.push(compilerCtx.fs.writeFile(compatPath, css));
|
|
8358
8607
|
}
|
|
8359
8608
|
for (const wwwTarget of wwwTargets) {
|
|
@@ -8403,7 +8652,8 @@ const generateStandaloneTypesOutput = async (config, compilerCtx, buildCtx, type
|
|
|
8403
8652
|
...components.map((component) => {
|
|
8404
8653
|
const exportName = dashToPascalCase(component.tagName);
|
|
8405
8654
|
const importName = component.componentClassName;
|
|
8406
|
-
const
|
|
8655
|
+
const componentSourceRelPath = relative$1(config.srcDir, component.sourceFilePath).replace(/\.tsx$/, "");
|
|
8656
|
+
const componentDTSPath = join$2(componentsTypeDirectoryRelPath, componentSourceRelPath);
|
|
8407
8657
|
const defineFunctionExportName = `defineCustomElement${exportName}`;
|
|
8408
8658
|
const localComponentTypeDefFilePath = `./${component.tagName}`;
|
|
8409
8659
|
return [`export { ${importName} as ${exportName} } from '${componentDTSPath.startsWith(".") ? componentDTSPath : "./" + componentDTSPath}';`, `export { defineCustomElement as ${defineFunctionExportName} } from '${localComponentTypeDefFilePath}';`].join("\n");
|
|
@@ -8474,8 +8724,9 @@ const generateCustomElementType = (componentsDtsRelPath, cmp) => {
|
|
|
8474
8724
|
const tagNameAsPascal = dashToPascalCase(cmp.tagName);
|
|
8475
8725
|
return [
|
|
8476
8726
|
`import type { Components, JSX } from "${componentsDtsRelPath}";`,
|
|
8727
|
+
`import type { HTMLStencilElement } from "@stencil/core/runtime";`,
|
|
8477
8728
|
``,
|
|
8478
|
-
`interface ${tagNameAsPascal} extends Components.${tagNameAsPascal},
|
|
8729
|
+
`interface ${tagNameAsPascal} extends Components.${tagNameAsPascal}, HTMLStencilElement {}`,
|
|
8479
8730
|
`export const ${tagNameAsPascal}: {`,
|
|
8480
8731
|
` prototype: ${tagNameAsPascal};`,
|
|
8481
8732
|
` new (): ${tagNameAsPascal};`,
|
|
@@ -8500,7 +8751,7 @@ const relDts = (fromPath, dtsPath) => {
|
|
|
8500
8751
|
};
|
|
8501
8752
|
//#endregion
|
|
8502
8753
|
//#region src/compiler/types/constants.ts
|
|
8503
|
-
const HTML_ELEMENT_METHODS = new Set([
|
|
8754
|
+
const HTML_ELEMENT_METHODS = /* @__PURE__ */ new Set([
|
|
8504
8755
|
"attachInternals",
|
|
8505
8756
|
"blur",
|
|
8506
8757
|
"click",
|
|
@@ -8593,7 +8844,9 @@ const HTML_ELEMENT_METHODS = new Set([
|
|
|
8593
8844
|
* @returns the updated type declaration file contents
|
|
8594
8845
|
*/
|
|
8595
8846
|
const updateStencilTypesImports = (typesDir, dtsFilePath, dtsContent) => {
|
|
8596
|
-
|
|
8847
|
+
const dir = dirname$1(dtsFilePath);
|
|
8848
|
+
const relPath = relative$1(dir, typesDir);
|
|
8849
|
+
let coreDtsPath = join$2(relPath, CORE_FILENAME);
|
|
8597
8850
|
if (!coreDtsPath.startsWith(".")) coreDtsPath = `./${coreDtsPath}`;
|
|
8598
8851
|
coreDtsPath = normalizePath(coreDtsPath);
|
|
8599
8852
|
if (dtsContent.includes("@stencil/core")) {
|
|
@@ -8731,7 +8984,8 @@ const CORE_DTS = `${CORE_FILENAME}.d.ts`;
|
|
|
8731
8984
|
* @returns additional types information to add event listener method overloads for component's html element type
|
|
8732
8985
|
*/
|
|
8733
8986
|
const generateEventListenerTypes = (cmp, typeImportData) => {
|
|
8734
|
-
const
|
|
8987
|
+
const tagName = cmp.tagName.toLowerCase();
|
|
8988
|
+
const tagNameAsPascal = dashToPascalCase(tagName);
|
|
8735
8989
|
const htmlElementName = `HTML${tagNameAsPascal}Element`;
|
|
8736
8990
|
const cmpEventInterface = `${tagNameAsPascal}CustomEvent`;
|
|
8737
8991
|
const htmlElementEventMapName = `${htmlElementName}EventMap`;
|
|
@@ -8797,9 +9051,11 @@ const getEventGenericType = (cmpEvent, typeImportData, componentSourcePath) => {
|
|
|
8797
9051
|
*/
|
|
8798
9052
|
const generateEventTypes = (cmpMeta, typeImportData, cmpClassName) => {
|
|
8799
9053
|
return cmpMeta.events.map((cmpEvent) => {
|
|
9054
|
+
const name = `on${toTitleCase(cmpEvent.name)}`;
|
|
9055
|
+
const cmpEventDetailInterface = `${cmpClassName}CustomEvent`;
|
|
8800
9056
|
return {
|
|
8801
|
-
name
|
|
8802
|
-
type: getEventType$1(cmpEvent,
|
|
9057
|
+
name,
|
|
9058
|
+
type: getEventType$1(cmpEvent, cmpEventDetailInterface, typeImportData, cmpMeta.sourceFilePath),
|
|
8803
9059
|
optional: false,
|
|
8804
9060
|
required: false,
|
|
8805
9061
|
internal: cmpEvent.internal,
|
|
@@ -9210,6 +9466,12 @@ const updateImportReferenceFactory = (typeCounts, filePath, config) => {
|
|
|
9210
9466
|
//#endregion
|
|
9211
9467
|
//#region src/compiler/types/generate-app-types.ts
|
|
9212
9468
|
/**
|
|
9469
|
+
* Above this many required props on a single component, the generated `OneOf<>` required-prop
|
|
9470
|
+
* check is skipped entirely (falling back to unchecked optional `attr:`/`prop:` variants) rather
|
|
9471
|
+
* than risking exponential failure in the TS checker - see the comment at its usage site.
|
|
9472
|
+
*/
|
|
9473
|
+
const MAX_ONE_OF_REQUIRED_PROPS = 8;
|
|
9474
|
+
/**
|
|
9213
9475
|
* Generates and writes a `components.d.ts` file to disk. This file may be written to the `src` directory of a project,
|
|
9214
9476
|
* or be written to a directory that is meant to be distributed.
|
|
9215
9477
|
* @param config the Stencil configuration associated with the project being compiled
|
|
@@ -9273,20 +9535,26 @@ const generateComponentTypesFile = (config, buildCtx, areTypesInternal) => {
|
|
|
9273
9535
|
const typeData = typeImportData[filePath];
|
|
9274
9536
|
let importFilePath = filePath;
|
|
9275
9537
|
if (isAbsolute$1(filePath)) importFilePath = normalizePath("./" + relative$1(config.srcDir, filePath)).replace(/\.(tsx|ts)$/, "");
|
|
9276
|
-
const
|
|
9277
|
-
if (
|
|
9278
|
-
const
|
|
9279
|
-
|
|
9280
|
-
|
|
9281
|
-
} else if (hasDefaultImport) {
|
|
9282
|
-
const defaultImport = typeData.find((td) => td.isDefault);
|
|
9283
|
-
const namedPart = typeData.filter((td) => !td.isDefault).sort(sortImportNames).map((td) => {
|
|
9538
|
+
const defaultImports = typeData.filter((td) => td.isDefault);
|
|
9539
|
+
if (defaultImports.length > 0) {
|
|
9540
|
+
const [defaultImport, ...additionalDefaultImports] = defaultImports;
|
|
9541
|
+
const namedImports = typeData.filter((td) => !td.isDefault);
|
|
9542
|
+
const namedPart = namedImports.sort(sortImportNames).map((td) => {
|
|
9284
9543
|
if (td.originalName === "") return `${td.localName}`;
|
|
9285
9544
|
else if (td.originalName === td.importName) return `${td.originalName}`;
|
|
9286
9545
|
else return `${td.originalName} as ${td.importName}`;
|
|
9287
9546
|
}).join(`, `);
|
|
9288
|
-
|
|
9289
|
-
|
|
9547
|
+
if (namedImports.length > 0) {
|
|
9548
|
+
imports.push(`import ${defaultImport.importName}, { ${namedPart} } from "${importFilePath}";`);
|
|
9549
|
+
exports.push(`export { default as ${defaultImport.importName}, ${namedPart} } from "${importFilePath}";`);
|
|
9550
|
+
} else {
|
|
9551
|
+
imports.push(`import ${defaultImport.importName} from "${importFilePath}";`);
|
|
9552
|
+
exports.push(`export { default as ${defaultImport.importName} } from "${importFilePath}";`);
|
|
9553
|
+
}
|
|
9554
|
+
additionalDefaultImports.forEach((td) => {
|
|
9555
|
+
imports.push(`import ${td.importName} from "${importFilePath}";`);
|
|
9556
|
+
exports.push(`export { default as ${td.importName} } from "${importFilePath}";`);
|
|
9557
|
+
});
|
|
9290
9558
|
} else {
|
|
9291
9559
|
const namedPart = typeData.sort(sortImportNames).map((td) => {
|
|
9292
9560
|
if (td.originalName === "") return `${td.localName}`;
|
|
@@ -9309,8 +9577,8 @@ const generateComponentTypesFile = (config, buildCtx, areTypesInternal) => {
|
|
|
9309
9577
|
c.push(` }`);
|
|
9310
9578
|
c.push(`}`);
|
|
9311
9579
|
c.push(`declare namespace LocalJSX {`);
|
|
9312
|
-
if (modules.some((m) => m.requiredProps)) {
|
|
9313
|
-
c.push(` type OneOf<K extends string, PropT, AttrT = PropT> = { [P in K]: PropT } & { [P in \`attr:\${K}\`
|
|
9580
|
+
if (modules.some((m) => m.requiredProps && m.requiredProps.length > 0 && m.requiredProps.length <= MAX_ONE_OF_REQUIRED_PROPS)) {
|
|
9581
|
+
c.push(` type OneOf<K extends string, PropT, AttrT = PropT> = { [P in K]: PropT } & { [P in \`attr:\${K}\`]?: never } | { [P in \`attr:\${K}\`]: AttrT } & { [P in K]?: never };`);
|
|
9314
9582
|
c.push(``);
|
|
9315
9583
|
}
|
|
9316
9584
|
c.push(...modules.map((m) => {
|
|
@@ -9327,7 +9595,7 @@ const generateComponentTypesFile = (config, buildCtx, areTypesInternal) => {
|
|
|
9327
9595
|
c.push(...modules.map((m) => {
|
|
9328
9596
|
if (m.explicitAttributes) {
|
|
9329
9597
|
const baseOptional = `Omit<${m.tagNameAsPascal}, keyof ${m.tagNameAsPascal}Attributes> & { [K in keyof ${m.tagNameAsPascal} & keyof ${m.tagNameAsPascal}Attributes]?: ${m.tagNameAsPascal}[K] } & { [K in keyof ${m.tagNameAsPascal} & keyof ${m.tagNameAsPascal}Attributes as \`attr:\${K}\`]?: ${m.tagNameAsPascal}Attributes[K] } & { [K in keyof ${m.tagNameAsPascal} & keyof ${m.tagNameAsPascal}Attributes as \`prop:\${K}\`]?: ${m.tagNameAsPascal}[K] }`;
|
|
9330
|
-
if (m.requiredProps && m.requiredProps.length > 0) {
|
|
9598
|
+
if (m.requiredProps && m.requiredProps.length > 0 && m.requiredProps.length <= MAX_ONE_OF_REQUIRED_PROPS) {
|
|
9331
9599
|
const requiredUnions = m.requiredProps.map((prop) => {
|
|
9332
9600
|
return `OneOf<"${prop.name}", ${m.tagNameAsPascal}["${prop.name}"], ${m.tagNameAsPascal}Attributes["${prop.name}"]>`;
|
|
9333
9601
|
}).join(" & ");
|
|
@@ -9506,7 +9774,8 @@ const outputTypes = async (config, compilerCtx, buildCtx) => {
|
|
|
9506
9774
|
* @returns a path to the build directory for that output target
|
|
9507
9775
|
*/
|
|
9508
9776
|
const getAbsoluteBuildDir = (outputTarget) => {
|
|
9509
|
-
|
|
9777
|
+
const relativeBuildDir = relative$1(outputTarget.dir, outputTarget.buildDir);
|
|
9778
|
+
return join$2("/", relativeBuildDir) + "/";
|
|
9510
9779
|
};
|
|
9511
9780
|
//#endregion
|
|
9512
9781
|
//#region src/compiler/html/add-script-attr.ts
|
|
@@ -9526,7 +9795,8 @@ const addScriptDataAttribute = (config, doc, outputTarget) => {
|
|
|
9526
9795
|
//#region src/compiler/html/inject-module-preloads.ts
|
|
9527
9796
|
const optimizeCriticalPath = (doc, criticalBundlers, outputTarget) => {
|
|
9528
9797
|
const buildDir = getAbsoluteBuildDir(outputTarget);
|
|
9529
|
-
|
|
9798
|
+
const paths = criticalBundlers.map((path) => join$2(buildDir, path));
|
|
9799
|
+
injectModulePreloads(doc, paths);
|
|
9530
9800
|
};
|
|
9531
9801
|
const injectModulePreloads = (doc, paths) => {
|
|
9532
9802
|
const existingLinks = Array.from(doc.querySelectorAll("link[rel=modulepreload]")).map((link) => link.getAttribute("href"));
|
|
@@ -9656,7 +9926,8 @@ const updateIndexHtmlServiceWorker = async (config, buildCtx, doc, outputTarget)
|
|
|
9656
9926
|
else if (serviceWorker) await injectRegisterServiceWorker(buildCtx, outputTarget, doc);
|
|
9657
9927
|
};
|
|
9658
9928
|
const injectRegisterServiceWorker = async (buildCtx, outputTarget, doc) => {
|
|
9659
|
-
const
|
|
9929
|
+
const swUrl = generateServiceWorkerUrl(outputTarget, outputTarget.serviceWorker);
|
|
9930
|
+
const serviceWorker = getRegisterSwScript(doc, buildCtx, swUrl);
|
|
9660
9931
|
doc.body.appendChild(serviceWorker);
|
|
9661
9932
|
};
|
|
9662
9933
|
const injectUnregisterServiceWorker = (doc) => {
|
|
@@ -9826,7 +10097,7 @@ function readModulePaths(code) {
|
|
|
9826
10097
|
function isImportOrExportDecl(stmt) {
|
|
9827
10098
|
return ts.isExportDeclaration(stmt) || ts.isImportDeclaration(stmt);
|
|
9828
10099
|
}
|
|
9829
|
-
const MAX_JS_INLINE_SIZE =
|
|
10100
|
+
const MAX_JS_INLINE_SIZE = 1024;
|
|
9830
10101
|
//#endregion
|
|
9831
10102
|
//#region src/compiler/html/inline-style-sheets.ts
|
|
9832
10103
|
const inlineStyleSheets = (compilerCtx, doc, maxSize, outputTarget) => {
|
|
@@ -9928,7 +10199,10 @@ const generateWww = async (config, compilerCtx, buildCtx, criticalPath, outputTa
|
|
|
9928
10199
|
}
|
|
9929
10200
|
if (!skipHtml) {
|
|
9930
10201
|
if (buildCtx.indexDoc && outputTarget.indexHtml) await generateIndexHtml(config, compilerCtx, buildCtx, criticalPath, outputTarget, globalStylesMap);
|
|
9931
|
-
for (const [relPath, doc] of buildCtx.htmlDocs)
|
|
10202
|
+
for (const [relPath, doc] of buildCtx.htmlDocs) {
|
|
10203
|
+
const destPath = join$2(outputTarget.appDir, relPath);
|
|
10204
|
+
await generateHtmlFile(config, compilerCtx, buildCtx, doc, destPath, outputTarget, globalStylesMap);
|
|
10205
|
+
}
|
|
9932
10206
|
}
|
|
9933
10207
|
await generateHostConfig(compilerCtx, outputTarget);
|
|
9934
10208
|
};
|
|
@@ -10013,24 +10287,26 @@ const generateIndexHtml = async (config, compilerCtx, buildCtx, criticalPath, ou
|
|
|
10013
10287
|
*/
|
|
10014
10288
|
const generateHtmlFile = async (config, compilerCtx, buildCtx, doc, destPath, outputTarget, globalStylesMap) => {
|
|
10015
10289
|
try {
|
|
10016
|
-
|
|
10290
|
+
const cloned = cloneDocument(doc);
|
|
10291
|
+
await processHtmlDoc(config, compilerCtx, buildCtx, cloned, destPath, outputTarget, globalStylesMap);
|
|
10017
10292
|
} catch (e) {
|
|
10018
10293
|
catchError(buildCtx.diagnostics, e);
|
|
10019
10294
|
}
|
|
10020
10295
|
};
|
|
10021
|
-
const MAX_CSS_INLINE_SIZE =
|
|
10296
|
+
const MAX_CSS_INLINE_SIZE = 3072;
|
|
10022
10297
|
//#endregion
|
|
10023
10298
|
//#region src/compiler/transformers/component-ssr/ssr-runtime-cmp-meta.ts
|
|
10024
10299
|
const addHydrateRuntimeCmpMeta = (classMembers, cmp, buildCtx) => {
|
|
10025
10300
|
const compactMeta = formatComponentRuntimeMeta(cmp, true);
|
|
10026
|
-
const
|
|
10301
|
+
const cmpMeta = {
|
|
10027
10302
|
$flags$: compactMeta[0],
|
|
10028
10303
|
$tagName$: compactMeta[1],
|
|
10029
10304
|
$members$: compactMeta[2],
|
|
10030
10305
|
$listeners$: compactMeta[3],
|
|
10031
10306
|
$lazyBundleId$: fakeBundleIds(cmp),
|
|
10032
10307
|
$attrsToReflect$: getHydrateAttrsToReflect(cmp)
|
|
10033
|
-
}
|
|
10308
|
+
};
|
|
10309
|
+
const staticMember = createStaticGetter("cmpMeta", convertValueToLiteral(cmpMeta));
|
|
10034
10310
|
addStaticStyleGetterWithinClass(classMembers, cmp, buildCtx);
|
|
10035
10311
|
classMembers.push(staticMember);
|
|
10036
10312
|
};
|
|
@@ -10156,7 +10432,7 @@ const getSsrBuildConditionals = (config, cmps) => {
|
|
|
10156
10432
|
*/
|
|
10157
10433
|
const bundleSsrFactory = async (config, compilerCtx, buildCtx, appFactoryEntryCode) => {
|
|
10158
10434
|
try {
|
|
10159
|
-
|
|
10435
|
+
const bundleOpts = {
|
|
10160
10436
|
id: "ssr",
|
|
10161
10437
|
platform: "ssr",
|
|
10162
10438
|
conditionals: getSsrBuildConditionals(config, buildCtx.components),
|
|
@@ -10164,7 +10440,8 @@ const bundleSsrFactory = async (config, compilerCtx, buildCtx, appFactoryEntryCo
|
|
|
10164
10440
|
codeSplitting: false,
|
|
10165
10441
|
inputs: { "@stencil/core/runtime/server/ssr-factory": "@stencil/core/runtime/server/ssr-factory" },
|
|
10166
10442
|
loader: { "@stencil/core/runtime/server/ssr-factory": appFactoryEntryCode }
|
|
10167
|
-
}
|
|
10443
|
+
};
|
|
10444
|
+
return await bundleOutput(config, compilerCtx, buildCtx, bundleOpts);
|
|
10168
10445
|
} catch (e) {
|
|
10169
10446
|
if (!buildCtx.hasError && isRolldownError(e)) loadRolldownDiagnostics(config, compilerCtx, buildCtx, e);
|
|
10170
10447
|
}
|
|
@@ -10358,7 +10635,8 @@ const SSR_FACTORY_OUTRO = `
|
|
|
10358
10635
|
* @returns The updated component metadata array.
|
|
10359
10636
|
*/
|
|
10360
10637
|
const updateSsrComponents = async (cmps) => {
|
|
10361
|
-
|
|
10638
|
+
const ssrCmps = await Promise.all(cmps.map(updateSsrComponent));
|
|
10639
|
+
return sortBy(ssrCmps, (c) => c.cmp.componentClassName);
|
|
10362
10640
|
};
|
|
10363
10641
|
const updateSsrComponent = async (cmp) => {
|
|
10364
10642
|
const cmpData = {
|
|
@@ -10478,7 +10756,8 @@ const writeSsrOutput = async (config, compilerCtx, buildCtx, outputTarget, rolld
|
|
|
10478
10756
|
}));
|
|
10479
10757
|
};
|
|
10480
10758
|
const copySsrRunnerDts = async (config, compilerCtx, hydrateAppDirPath) => {
|
|
10481
|
-
const
|
|
10759
|
+
const packageDir = join$2(config.sys.getCompilerExecutingPath(), "..", "..");
|
|
10760
|
+
const srcSsrDir = join$2(packageDir, "runtime", "server", "runner.d.mts");
|
|
10482
10761
|
const runnerDtsDestPath = join$2(hydrateAppDirPath, "index.d.ts");
|
|
10483
10762
|
await compilerCtx.fs.copyFile(srcSsrDir, runnerDtsDestPath);
|
|
10484
10763
|
};
|
|
@@ -10495,11 +10774,12 @@ const copySsrRunnerDts = async (config, compilerCtx, hydrateAppDirPath) => {
|
|
|
10495
10774
|
*/
|
|
10496
10775
|
const buildSsrAppFor = async (format, rolldownBuild, config, compilerCtx, buildCtx, outputTargets) => {
|
|
10497
10776
|
const file = format === "esm" ? "index.js" : "index.cjs";
|
|
10498
|
-
|
|
10777
|
+
const rolldownOutput = await rolldownBuild.generate({
|
|
10499
10778
|
banner: generatePreamble(config),
|
|
10500
10779
|
format,
|
|
10501
10780
|
file
|
|
10502
|
-
})
|
|
10781
|
+
});
|
|
10782
|
+
await writeSsrOutputs(config, compilerCtx, buildCtx, outputTargets, rolldownOutput);
|
|
10503
10783
|
};
|
|
10504
10784
|
/**
|
|
10505
10785
|
* Generate and build the SSR app and then write it to disk
|
|
@@ -10514,7 +10794,7 @@ const generateSsrApp = async (config, compilerCtx, buildCtx, outputTargets) => {
|
|
|
10514
10794
|
const packageDir = join$2(config.sys.getCompilerExecutingPath(), "..", "..");
|
|
10515
10795
|
const input = join$2(packageDir, "runtime", "server", "runner.mjs");
|
|
10516
10796
|
const appData = join$2(packageDir, "runtime", "app-data", "index.js");
|
|
10517
|
-
const
|
|
10797
|
+
const rolldownOptions = {
|
|
10518
10798
|
...config.rolldownConfig,
|
|
10519
10799
|
external: ["node:stream"],
|
|
10520
10800
|
input,
|
|
@@ -10549,7 +10829,8 @@ const generateSsrApp = async (config, compilerCtx, buildCtx, outputTargets) => {
|
|
|
10549
10829
|
treeshake: false,
|
|
10550
10830
|
onwarn: createOnWarnFn(buildCtx.diagnostics),
|
|
10551
10831
|
checks: { pluginTimings: config.logLevel === "debug" }
|
|
10552
|
-
}
|
|
10832
|
+
};
|
|
10833
|
+
const rolldownAppBuild = await rolldown(rolldownOptions);
|
|
10553
10834
|
const buildPromises = [buildSsrAppFor("esm", rolldownAppBuild, config, compilerCtx, buildCtx, outputTargets)];
|
|
10554
10835
|
if (outputTargets.some((o) => o.cjs)) buildPromises.push(buildSsrAppFor("cjs", rolldownAppBuild, config, compilerCtx, buildCtx, outputTargets));
|
|
10555
10836
|
await Promise.all(buildPromises);
|
|
@@ -10559,7 +10840,8 @@ const generateSsrApp = async (config, compilerCtx, buildCtx, outputTargets) => {
|
|
|
10559
10840
|
};
|
|
10560
10841
|
const generateSsrFactory = async (config, compilerCtx, buildCtx) => {
|
|
10561
10842
|
if (!buildCtx.hasError) try {
|
|
10562
|
-
const
|
|
10843
|
+
const appFactoryEntryCode = await generateSsrFactoryEntry(buildCtx);
|
|
10844
|
+
const rolldownFactoryBuild = await bundleSsrFactory(config, compilerCtx, buildCtx, appFactoryEntryCode);
|
|
10563
10845
|
if (rolldownFactoryBuild != null) {
|
|
10564
10846
|
const rolldownOutput = await rolldownFactoryBuild.generate({
|
|
10565
10847
|
format: "cjs",
|
|
@@ -10648,7 +10930,7 @@ const generateSsrWasmApp = async (config, compilerCtx, buildCtx, outputTargets)
|
|
|
10648
10930
|
const packageDir = join$2(config.sys.getCompilerExecutingPath(), "..", "..");
|
|
10649
10931
|
const input = join$2(packageDir, "runtime", "server", "runner.mjs");
|
|
10650
10932
|
const appData = join$2(packageDir, "runtime", "app-data", "index.js");
|
|
10651
|
-
const
|
|
10933
|
+
const rolldownOptions = {
|
|
10652
10934
|
...config.rolldownConfig,
|
|
10653
10935
|
external: [],
|
|
10654
10936
|
input,
|
|
@@ -10679,7 +10961,8 @@ const generateSsrWasmApp = async (config, compilerCtx, buildCtx, outputTargets)
|
|
|
10679
10961
|
transform: { target: "es2020" },
|
|
10680
10962
|
onwarn: createOnWarnFn(buildCtx.diagnostics),
|
|
10681
10963
|
checks: { pluginTimings: config.logLevel === "debug" }
|
|
10682
|
-
}
|
|
10964
|
+
};
|
|
10965
|
+
const rolldownOutput = await (await rolldown(rolldownOptions)).generate({
|
|
10683
10966
|
banner: generatePreamble(config) + SSR_WASM_TIMER_POLYFILL,
|
|
10684
10967
|
outro: SSR_WASM_OUTRO,
|
|
10685
10968
|
format: "iife",
|
|
@@ -10912,7 +11195,8 @@ const createComponentMetadataProxy = (compilerMeta) => {
|
|
|
10912
11195
|
* @returns the generated call expression
|
|
10913
11196
|
*/
|
|
10914
11197
|
const createClassMetadataProxy = (compilerMeta, clazz) => {
|
|
10915
|
-
const
|
|
11198
|
+
const compactMeta = formatComponentRuntimeMeta(compilerMeta, true);
|
|
11199
|
+
const literalMeta = convertValueToLiteral(compactMeta);
|
|
10916
11200
|
return ts.factory.createCallExpression(ts.factory.createIdentifier(PROXY_CUSTOM_ELEMENT), [], [clazz, literalMeta]);
|
|
10917
11201
|
};
|
|
10918
11202
|
//#endregion
|
|
@@ -10947,7 +11231,8 @@ const proxyCustomElement = (compilerCtx, transformOpts) => {
|
|
|
10947
11231
|
for (const [stmtIndex, stmt] of tsSourceFile.statements.entries()) if (ts.isVariableStatement(stmt)) for (const [declarationIndex, declaration] of stmt.declarationList.declarations.entries()) {
|
|
10948
11232
|
if (declaration.name.getText() !== principalComponent.componentClassName) continue;
|
|
10949
11233
|
if (!ts.isClassExpression(declaration.initializer)) continue;
|
|
10950
|
-
const
|
|
11234
|
+
const renamedClassExpression = ts.factory.updateClassExpression(declaration.initializer, ts.getModifiers(declaration.initializer), ts.factory.createIdentifier(principalComponent.componentClassName), declaration.initializer.typeParameters, declaration.initializer.heritageClauses, declaration.initializer.members);
|
|
11235
|
+
const proxyCreationCall = createClassMetadataProxy(principalComponent, renamedClassExpression);
|
|
10951
11236
|
ts.addSyntheticLeadingComment(proxyCreationCall, ts.SyntaxKind.MultiLineCommentTrivia, "@__PURE__", false);
|
|
10952
11237
|
const proxiedComponentDeclaration = ts.factory.updateVariableDeclaration(declaration, declaration.name, declaration.exclamationToken, declaration.type, proxyCreationCall);
|
|
10953
11238
|
const updatedDeclarationList = ts.factory.updateVariableDeclarationList(stmt.declarationList, [
|
|
@@ -11111,11 +11396,12 @@ function createStatesAddCall(memberName, stateName) {
|
|
|
11111
11396
|
const updateNativeConstructor = (classMembers, moduleFile, cmp, classNode) => {
|
|
11112
11397
|
if (cmp.isPlain) return;
|
|
11113
11398
|
const cstrMethodArgs = [ts.factory.createParameterDeclaration(void 0, void 0, ts.factory.createIdentifier("registerHost"))];
|
|
11114
|
-
|
|
11399
|
+
const nativeCstrStatements = [
|
|
11115
11400
|
...nativeInit(cmp),
|
|
11116
11401
|
...addCreateEvents(moduleFile, cmp),
|
|
11117
11402
|
...createNativeAttachInternalsBinding(cmp)
|
|
11118
|
-
]
|
|
11403
|
+
];
|
|
11404
|
+
updateConstructor(classNode, classMembers, nativeCstrStatements, cstrMethodArgs, cmp.doesExtend);
|
|
11119
11405
|
};
|
|
11120
11406
|
/**
|
|
11121
11407
|
* Generates a series of expression statements used to help initialize a Stencil component
|
|
@@ -11169,8 +11455,10 @@ const addNativeComponentMeta = (classMembers, cmp) => {
|
|
|
11169
11455
|
//#endregion
|
|
11170
11456
|
//#region src/compiler/transformers/component-native/native-static-style.ts
|
|
11171
11457
|
const addNativeStaticStyle = (classMembers, cmp, buildCtx) => {
|
|
11172
|
-
if (Array.isArray(cmp.styles) && cmp.styles.length > 0)
|
|
11173
|
-
|
|
11458
|
+
if (Array.isArray(cmp.styles) && cmp.styles.length > 0) {
|
|
11459
|
+
if (cmp.styles.length > 1 || cmp.styles.length === 1 && cmp.styles[0].modeName !== "$") addMultipleModeStyleGetter(classMembers, cmp, cmp.styles, buildCtx);
|
|
11460
|
+
else addSingleStyleGetter(classMembers, cmp, cmp.styles[0], buildCtx);
|
|
11461
|
+
}
|
|
11174
11462
|
};
|
|
11175
11463
|
const addMultipleModeStyleGetter = (classMembers, cmp, styles, buildCtx) => {
|
|
11176
11464
|
const styleModes = [];
|
|
@@ -11309,7 +11597,8 @@ const updateNativeHostComponentHeritageClauses = (classNode, moduleFile) => {
|
|
|
11309
11597
|
*/
|
|
11310
11598
|
const updateNativeBaseClass = (node, moduleFile) => {
|
|
11311
11599
|
const withHeritageClauses = updateNativeHostComponentHeritageClauses(node, moduleFile);
|
|
11312
|
-
const
|
|
11600
|
+
const members = removeStaticMetaProperties(withHeritageClauses);
|
|
11601
|
+
const membersWithCtor = updateConstructor(withHeritageClauses, members, [], void 0, false);
|
|
11313
11602
|
return ts.factory.updateClassDeclaration(withHeritageClauses, withHeritageClauses.modifiers, withHeritageClauses.name, withHeritageClauses.typeParameters, withHeritageClauses.heritageClauses, membersWithCtor);
|
|
11314
11603
|
};
|
|
11315
11604
|
/**
|
|
@@ -11417,9 +11706,11 @@ const generateLoaderModule = (components, outputTarget, relativeAssetPath) => {
|
|
|
11417
11706
|
const autoStart = typeof autoLoaderConfig === "object" ? autoLoaderConfig.autoStart !== false : true;
|
|
11418
11707
|
const tagsList = components.map((cmp) => `'${cmp.tagName}'`).join(", ");
|
|
11419
11708
|
const switchCases = components.map((cmp) => ` case '${cmp.tagName}': module = await import('./${cmp.tagName}.js'); break;`).join("\n");
|
|
11709
|
+
const assetPathImport = relativeAssetPath ? `import { setAssetPath } from '${STENCIL_INTERNAL_STANDALONE_CLIENT_PLATFORM_ID}';\n` : "";
|
|
11710
|
+
const assetPathInit = relativeAssetPath ? `setAssetPath(new URL('${relativeAssetPath}', String(import.meta.url)).href);\n` : "";
|
|
11420
11711
|
return `
|
|
11421
11712
|
import { transformTag, getRegistry } from '${STENCIL_INTERNAL_STANDALONE_CLIENT_PLATFORM_ID}';
|
|
11422
|
-
${
|
|
11713
|
+
${assetPathImport}${assetPathInit}
|
|
11423
11714
|
|
|
11424
11715
|
/**
|
|
11425
11716
|
* Tag names built at compile time.
|
|
@@ -11453,13 +11744,13 @@ let observer;
|
|
|
11453
11744
|
/**
|
|
11454
11745
|
* Scan a root element for undefined custom elements and load them.
|
|
11455
11746
|
*
|
|
11456
|
-
* Before any modules are imported we do
|
|
11457
|
-
* Stencil lifecycle ordering (componentWillLoad top-down,
|
|
11458
|
-
* bottom-up) regardless of
|
|
11747
|
+
* Before any modules are imported we do 3 things to guarantee the documented
|
|
11748
|
+
* Stencil lifecycle ordering (connectedCallback/componentWillLoad top-down,
|
|
11749
|
+
* componentDidLoad bottom-up) regardless of which tag's chunk happens to resolve first:
|
|
11459
11750
|
*
|
|
11460
|
-
* 1. Pre-mark every not-yet-upgraded Stencil element with empty \`s-p\`/\`s-rc\`
|
|
11461
|
-
* arrays so the runtime's connectedCallback ancestor walk can always find a
|
|
11462
|
-
*
|
|
11751
|
+
* 1. Pre-mark every not-yet-upgraded Stencil element with empty \`s-p\`/\`s-rc\`/\`s-pc\`
|
|
11752
|
+
* arrays so the runtime's connectedCallback ancestor walk can always find a parent
|
|
11753
|
+
* element even before it has been upgraded (see \`connected-callback.ts\`).
|
|
11463
11754
|
*
|
|
11464
11755
|
* 2. For every child Stencil element, push a Promise into its nearest Stencil
|
|
11465
11756
|
* ancestor's \`s-p\` array. That Promise resolves only after the child's full
|
|
@@ -11468,6 +11759,15 @@ let observer;
|
|
|
11468
11759
|
* descendants are ready - even when a descendant's module loads *after* the
|
|
11469
11760
|
* ancestor has already started rendering.
|
|
11470
11761
|
*
|
|
11762
|
+
* 3. Likewise, push a Promise into the ancestor's \`s-pc\` array that resolves once the
|
|
11763
|
+
* child's real \`connectedCallback\` has fired (\`s-fc\`). Without this, an ancestor
|
|
11764
|
+
* whose own module resolves before an unconnected child's would check \`s-pc\` (see
|
|
11765
|
+
* \`scheduleUpdate\` in \`update-component.ts\`) before that child ever got a chance to
|
|
11766
|
+
* register itself via \`attachToAncestor\` - since a not-yet-defined child doesn't
|
|
11767
|
+
* connect (and self-register) until its own module import resolves. Pre-registering
|
|
11768
|
+
* here means the ancestor's \`componentWillLoad\` always waits for it, however long
|
|
11769
|
+
* that import takes.
|
|
11770
|
+
*
|
|
11471
11771
|
* @param root - The root element to scan
|
|
11472
11772
|
*/
|
|
11473
11773
|
async function load(root) {
|
|
@@ -11480,6 +11780,7 @@ async function load(root) {
|
|
|
11480
11780
|
if (lookup[rootTag]) {
|
|
11481
11781
|
if (!root['s-p']) root['s-p'] = [];
|
|
11482
11782
|
if (!root['s-rc']) root['s-rc'] = [];
|
|
11783
|
+
if (!root['s-pc']) root['s-pc'] = [];
|
|
11483
11784
|
if (!defined.has(rootTag)) pending.add(rootTag);
|
|
11484
11785
|
elements.push(root);
|
|
11485
11786
|
}
|
|
@@ -11491,6 +11792,7 @@ async function load(root) {
|
|
|
11491
11792
|
if (lookup[tag]) {
|
|
11492
11793
|
if (!el['s-p']) el['s-p'] = [];
|
|
11493
11794
|
if (!el['s-rc']) el['s-rc'] = [];
|
|
11795
|
+
if (!el['s-pc']) el['s-pc'] = [];
|
|
11494
11796
|
if (!defined.has(tag)) pending.add(tag);
|
|
11495
11797
|
elements.push(el);
|
|
11496
11798
|
}
|
|
@@ -11513,6 +11815,11 @@ async function load(root) {
|
|
|
11513
11815
|
ancestor['s-p'].push(
|
|
11514
11816
|
reg.whenDefined(tag).then(() => el['s-rp'])
|
|
11515
11817
|
);
|
|
11818
|
+
// Same idea, but resolving once the child's real connectedCallback has fired
|
|
11819
|
+
// rather than once its full initial lifecycle has completed.
|
|
11820
|
+
ancestor['s-pc'].push(
|
|
11821
|
+
reg.whenDefined(tag).then(() => el['s-fc'])
|
|
11822
|
+
);
|
|
11516
11823
|
break;
|
|
11517
11824
|
}
|
|
11518
11825
|
ancestor = ancestor.parentElement;
|
|
@@ -12045,11 +12352,12 @@ const getTypescriptPathFromUrl = (config, tsExecutingUrl, url) => {
|
|
|
12045
12352
|
const tsBaseUrl = new URL("..", tsExecutingUrl).href;
|
|
12046
12353
|
if (url.startsWith(tsBaseUrl)) {
|
|
12047
12354
|
const tsFilePath = url.replace(tsBaseUrl, "/");
|
|
12048
|
-
|
|
12355
|
+
const tsNodePath = config.sys.getLocalModulePath({
|
|
12049
12356
|
rootDir: config.rootDir,
|
|
12050
12357
|
moduleId: "@stencil/core",
|
|
12051
12358
|
path: tsFilePath
|
|
12052
|
-
})
|
|
12359
|
+
});
|
|
12360
|
+
return normalizePath(tsNodePath);
|
|
12053
12361
|
}
|
|
12054
12362
|
return url;
|
|
12055
12363
|
};
|
|
@@ -12092,9 +12400,25 @@ const tsResolveModuleNamePackageJsonPath = (config, compilerCtx, moduleName, con
|
|
|
12092
12400
|
};
|
|
12093
12401
|
//#endregion
|
|
12094
12402
|
//#region src/compiler/transformers/static-to-meta/vdom.ts
|
|
12095
|
-
|
|
12403
|
+
/**
|
|
12404
|
+
* Attempt to resolve an expression to a statically-known string value.
|
|
12405
|
+
* Handles plain string literals directly. For anything else, falls back to the type checker.
|
|
12406
|
+
*
|
|
12407
|
+
* @param expr the expression to resolve
|
|
12408
|
+
* @param typeChecker the type checker for the program being compiled, if available
|
|
12409
|
+
* @returns the statically-known string value, or `undefined` if it can't be determined
|
|
12410
|
+
*/
|
|
12411
|
+
const resolveStaticStringValue = (expr, typeChecker) => {
|
|
12412
|
+
if (ts.isStringLiteralLike(expr)) return expr.text;
|
|
12413
|
+
if (typeChecker) {
|
|
12414
|
+
const type = typeChecker.getTypeAtLocation(expr);
|
|
12415
|
+
if (type.isStringLiteral()) return type.value;
|
|
12416
|
+
}
|
|
12417
|
+
};
|
|
12418
|
+
const gatherVdomMeta = (m, args, typeChecker) => {
|
|
12096
12419
|
m.hasVdomRender = true;
|
|
12097
12420
|
const hTag = args[0];
|
|
12421
|
+
const isSlotTag = ts.isStringLiteral(hTag) && hTag.text === "slot";
|
|
12098
12422
|
if (!ts.isStringLiteral(hTag) && (!ts.isIdentifier(hTag) || hTag.text !== "Host")) m.hasVdomFunctional = true;
|
|
12099
12423
|
if (args.length > 1) {
|
|
12100
12424
|
const objectLiteral = args[1];
|
|
@@ -12107,32 +12431,46 @@ const gatherVdomMeta = (m, args) => {
|
|
|
12107
12431
|
m.hasVdomRef = true;
|
|
12108
12432
|
m.hasVdomStyle = true;
|
|
12109
12433
|
m.hasVdomXlink = true;
|
|
12110
|
-
} else if (ts.isObjectLiteralExpression(objectLiteral))
|
|
12111
|
-
|
|
12112
|
-
|
|
12113
|
-
|
|
12114
|
-
m.
|
|
12115
|
-
|
|
12116
|
-
|
|
12117
|
-
|
|
12118
|
-
|
|
12119
|
-
m.hasVdomXlink = true;
|
|
12120
|
-
} else if (prop.name && prop.name.text && prop.name.text.length > 0) {
|
|
12121
|
-
const attrName = prop.name.text;
|
|
12122
|
-
if (attrName === "key") m.hasVdomKey = true;
|
|
12123
|
-
else if (attrName === "ref") m.hasVdomRef = true;
|
|
12124
|
-
else if (attrName === "class" || attrName === "className") m.hasVdomClass = true;
|
|
12125
|
-
else if (attrName === "style") m.hasVdomStyle = true;
|
|
12126
|
-
else if (/^on(-|[A-Z])/.test(attrName)) m.hasVdomListener = true;
|
|
12127
|
-
else if (attrName.startsWith("xlink")) {
|
|
12128
|
-
m.hasVdomXlink = true;
|
|
12434
|
+
} else if (ts.isObjectLiteralExpression(objectLiteral)) {
|
|
12435
|
+
let slotName;
|
|
12436
|
+
let hasDynamicSlotName = false;
|
|
12437
|
+
objectLiteral.properties.forEach((prop) => {
|
|
12438
|
+
m.hasVdomAttribute = true;
|
|
12439
|
+
if (ts.isSpreadAssignment(prop) || ts.isComputedPropertyName(prop.name)) {
|
|
12440
|
+
m.hasVdomClass = true;
|
|
12441
|
+
m.hasVdomKey = true;
|
|
12442
|
+
m.hasVdomListener = true;
|
|
12129
12443
|
m.hasVdomPropOrAttr = true;
|
|
12130
|
-
|
|
12131
|
-
|
|
12132
|
-
|
|
12133
|
-
|
|
12134
|
-
|
|
12135
|
-
|
|
12444
|
+
m.hasVdomRef = true;
|
|
12445
|
+
m.hasVdomStyle = true;
|
|
12446
|
+
m.hasVdomXlink = true;
|
|
12447
|
+
hasDynamicSlotName = isSlotTag || hasDynamicSlotName;
|
|
12448
|
+
} else if (prop.name && prop.name.text && prop.name.text.length > 0) {
|
|
12449
|
+
const attrName = prop.name.text;
|
|
12450
|
+
if (attrName === "key") m.hasVdomKey = true;
|
|
12451
|
+
else if (attrName === "ref") m.hasVdomRef = true;
|
|
12452
|
+
else if (attrName === "class" || attrName === "className") m.hasVdomClass = true;
|
|
12453
|
+
else if (attrName === "style") m.hasVdomStyle = true;
|
|
12454
|
+
else if (/^on(-|[A-Z])/.test(attrName)) m.hasVdomListener = true;
|
|
12455
|
+
else if (attrName.startsWith("xlink")) {
|
|
12456
|
+
m.hasVdomXlink = true;
|
|
12457
|
+
m.hasVdomPropOrAttr = true;
|
|
12458
|
+
} else m.hasVdomPropOrAttr = true;
|
|
12459
|
+
if (attrName === "part" && ts.isPropertyAssignment(prop)) {
|
|
12460
|
+
const partValue = resolveStaticStringValue(prop.initializer, typeChecker);
|
|
12461
|
+
if (partValue !== void 0) m.htmlParts.push(...partValue.split(" ").filter((part) => part.length > 0));
|
|
12462
|
+
}
|
|
12463
|
+
if (isSlotTag && attrName === "name" && ts.isPropertyAssignment(prop)) {
|
|
12464
|
+
const resolvedSlotName = resolveStaticStringValue(prop.initializer, typeChecker);
|
|
12465
|
+
if (resolvedSlotName !== void 0) slotName = resolvedSlotName;
|
|
12466
|
+
else hasDynamicSlotName = true;
|
|
12467
|
+
}
|
|
12468
|
+
m.htmlAttrNames.push(attrName);
|
|
12469
|
+
}
|
|
12470
|
+
});
|
|
12471
|
+
if (isSlotTag && !hasDynamicSlotName) m.htmlSlots.push(slotName ?? "");
|
|
12472
|
+
} else if (isSlotTag) m.htmlSlots.push("");
|
|
12473
|
+
} else if (isSlotTag) m.htmlSlots.push("");
|
|
12136
12474
|
if (!m.hasVdomText) for (let i = 2; i < args.length; i++) {
|
|
12137
12475
|
const arg = args[i];
|
|
12138
12476
|
if (!ts.isCallExpression(arg) || !ts.isIdentifier(arg.expression) || arg.expression.text !== "h") {
|
|
@@ -12170,10 +12508,10 @@ const visitCallExpressionArgs = (m, callExpressionName, args, typeChecker) => {
|
|
|
12170
12508
|
const fnName = callExpressionName.escapedText;
|
|
12171
12509
|
if (fnName === "h" || fnName === "__stencil_h" || fnName === "createElement") {
|
|
12172
12510
|
visitCallExpressionArg(m, args[0], typeChecker);
|
|
12173
|
-
if (fnName === "h" || fnName === "__stencil_h") gatherVdomMeta(m, args);
|
|
12511
|
+
if (fnName === "h" || fnName === "__stencil_h") gatherVdomMeta(m, args, typeChecker);
|
|
12174
12512
|
} else if (fnName === "jsx" || fnName === "jsxs" || fnName === "_jsx" || fnName === "_jsxs") {
|
|
12175
12513
|
visitCallExpressionArg(m, args[0], typeChecker);
|
|
12176
|
-
gatherVdomMeta(m, args);
|
|
12514
|
+
gatherVdomMeta(m, args, typeChecker);
|
|
12177
12515
|
if (args.length > 2 && args[2]) m.hasVdomKey = true;
|
|
12178
12516
|
} else if (args.length > 1 && fnName === "createElementNS") visitCallExpressionArg(m, args[1], typeChecker);
|
|
12179
12517
|
else if (fnName === "require" && args.length > 0 && m.originalImports) {
|
|
@@ -12229,7 +12567,8 @@ const resolveFunctionalComponentDep = (m, identifier, typeChecker) => {
|
|
|
12229
12567
|
* @returns the updated typescript class declaration
|
|
12230
12568
|
*/
|
|
12231
12569
|
const addComponentMetaStatic = (cmpNode, cmpMeta) => {
|
|
12232
|
-
const
|
|
12570
|
+
const publicCompilerMeta = getPublicCompilerMeta(cmpMeta);
|
|
12571
|
+
const cmpMetaStaticProp = createStaticGetter("COMPILER_META", convertValueToLiteral(publicCompilerMeta));
|
|
12233
12572
|
const classMembers = [...cmpNode.members, cmpMetaStaticProp];
|
|
12234
12573
|
return ts.factory.updateClassDeclaration(cmpNode, retrieveModifierLike(cmpNode), cmpNode.name, cmpNode.typeParameters, cmpNode.heritageClauses, classMembers);
|
|
12235
12574
|
};
|
|
@@ -12277,7 +12616,7 @@ const setComponentBuildConditionals = (cmpMeta) => {
|
|
|
12277
12616
|
cmpMeta.hasStyle = true;
|
|
12278
12617
|
cmpMeta.hasMode = cmpMeta.styles.some((s) => s.modeName !== "$");
|
|
12279
12618
|
}
|
|
12280
|
-
cmpMeta.hasLifecycle = cmpMeta.hasComponentWillLoadFn || cmpMeta.hasComponentDidLoadFn || cmpMeta.hasComponentShouldUpdateFn || cmpMeta.hasComponentWillUpdateFn || cmpMeta.hasComponentDidUpdateFn || cmpMeta.hasComponentWillRenderFn || cmpMeta.hasComponentDidRenderFn;
|
|
12619
|
+
cmpMeta.hasLifecycle = cmpMeta.hasComponentWillLoadFn || cmpMeta.hasComponentDidLoadFn || cmpMeta.hasComponentShouldUpdateFn || cmpMeta.hasComponentWillUpdateFn || cmpMeta.hasComponentDidUpdateFn || cmpMeta.hasComponentWillRenderFn || cmpMeta.hasComponentDidRenderFn || cmpMeta.hasConnectedCallbackFn || cmpMeta.hasDisconnectedCallbackFn;
|
|
12281
12620
|
cmpMeta.isPlain = !cmpMeta.hasMember && !cmpMeta.hasStyle && !cmpMeta.hasLifecycle && !cmpMeta.hasListener && !cmpMeta.hasVdomRender;
|
|
12282
12621
|
if (cmpMeta.patches) {
|
|
12283
12622
|
cmpMeta.hasPatchAll = !!cmpMeta.patches.all;
|
|
@@ -12405,7 +12744,8 @@ const getDecoratorParameter = (arg, typeChecker, diagnostics, errorNode) => {
|
|
|
12405
12744
|
*/
|
|
12406
12745
|
const resolveVariableValue = (node, typeChecker, diagnostics, errorNode) => {
|
|
12407
12746
|
if (ts.isIdentifier(node)) {
|
|
12408
|
-
|
|
12747
|
+
let symbol = typeChecker.getSymbolAtLocation(node);
|
|
12748
|
+
if (symbol && symbol.flags & ts.SymbolFlags.Alias) symbol = typeChecker.getAliasedSymbol(symbol);
|
|
12409
12749
|
if (!symbol || !symbol.valueDeclaration) {
|
|
12410
12750
|
const err = buildError(diagnostics);
|
|
12411
12751
|
err.messageText = `resolveVar() cannot resolve the value of "${node.text}" at compile time. Only const variables and object properties with string literal values are supported.`;
|
|
@@ -12605,8 +12945,10 @@ function parseCustomStatesFromDecorator(decorator, typeChecker) {
|
|
|
12605
12945
|
//#region src/compiler/transformers/decorators-to-static/style-to-static.ts
|
|
12606
12946
|
const styleToStatic = (newMembers, componentOptions) => {
|
|
12607
12947
|
const defaultModeStyles = [];
|
|
12608
|
-
if (componentOptions.styleUrls)
|
|
12609
|
-
|
|
12948
|
+
if (componentOptions.styleUrls) {
|
|
12949
|
+
if (Array.isArray(componentOptions.styleUrls)) defaultModeStyles.push(...normalizeStyleUrl(componentOptions.styleUrls));
|
|
12950
|
+
else defaultModeStyles.push(...normalizeStyleUrl(componentOptions.styleUrls["$"]));
|
|
12951
|
+
}
|
|
12610
12952
|
if (componentOptions.styleUrl) defaultModeStyles.push(...normalizeStyleUrl(componentOptions.styleUrl));
|
|
12611
12953
|
let styleUrls = {};
|
|
12612
12954
|
if (componentOptions.styleUrls && !Array.isArray(componentOptions.styleUrls)) styleUrls = normalizeStyleUrls(componentOptions.styleUrls);
|
|
@@ -12614,7 +12956,8 @@ const styleToStatic = (newMembers, componentOptions) => {
|
|
|
12614
12956
|
if (Object.keys(styleUrls).length > 0) {
|
|
12615
12957
|
const originalStyleUrls = convertValueToLiteral(styleUrls);
|
|
12616
12958
|
newMembers.push(createStaticGetter("originalStyleUrls", originalStyleUrls));
|
|
12617
|
-
const
|
|
12959
|
+
const norlizedStyleExt = normalizeExtension(styleUrls);
|
|
12960
|
+
const normalizedStyleExp = convertValueToLiteral(norlizedStyleExt);
|
|
12618
12961
|
newMembers.push(createStaticGetter("styleUrls", normalizedStyleExp));
|
|
12619
12962
|
}
|
|
12620
12963
|
if (componentOptions.globalStyleUrl) newMembers.push(createStaticGetter("originalGlobalStyleUrl", convertValueToLiteral(componentOptions.globalStyleUrl)));
|
|
@@ -12643,7 +12986,10 @@ const normalizeExtension = (styleUrls) => {
|
|
|
12643
12986
|
return compilerStyleUrls;
|
|
12644
12987
|
};
|
|
12645
12988
|
const useCss = (stylePath) => {
|
|
12646
|
-
|
|
12989
|
+
const sourceFileDir = dirname$1(stylePath);
|
|
12990
|
+
const sourceFileExt = extname(stylePath);
|
|
12991
|
+
const sourceFileName = basename$1(stylePath, sourceFileExt);
|
|
12992
|
+
return join$2(sourceFileDir, sourceFileName + ".css");
|
|
12647
12993
|
};
|
|
12648
12994
|
const normalizeStyleUrls = (styleUrls) => {
|
|
12649
12995
|
const compilerStyleUrls = {};
|
|
@@ -12793,6 +13139,13 @@ const validateComponent = (config, diagnostics, typeChecker, componentOptions, c
|
|
|
12793
13139
|
}
|
|
12794
13140
|
}
|
|
12795
13141
|
}
|
|
13142
|
+
const modeError = validateComponentModes(config.modes, componentOptions);
|
|
13143
|
+
if (modeError) {
|
|
13144
|
+
const err = buildError(diagnostics);
|
|
13145
|
+
err.messageText = modeError.message;
|
|
13146
|
+
augmentDiagnosticWithNode(err, findTagNode(modeError.propName, componentDecorator));
|
|
13147
|
+
return false;
|
|
13148
|
+
}
|
|
12796
13149
|
const constructor = cmpNode.members.find(ts.isConstructorDeclaration);
|
|
12797
13150
|
if (constructor && constructor.parameters.length > 0) {
|
|
12798
13151
|
const err = buildError(diagnostics);
|
|
@@ -12830,7 +13183,8 @@ const validateComponent = (config, diagnostics, typeChecker, componentOptions, c
|
|
|
12830
13183
|
err.messageText = `To allow efficient bundling, modules using @Component() can only have a single export which is the component class itself.
|
|
12831
13184
|
Any other exports should be moved to a separate file.
|
|
12832
13185
|
For further information check out: https://stenciljs.com/docs/module-bundling`;
|
|
12833
|
-
|
|
13186
|
+
const errorNode = symbol.valueDeclaration ? symbol.valueDeclaration : symbol.declarations[0];
|
|
13187
|
+
augmentDiagnosticWithNode(err, errorNode);
|
|
12834
13188
|
});
|
|
12835
13189
|
if (nonTypeExports.length > 0) return false;
|
|
12836
13190
|
}
|
|
@@ -13007,7 +13361,7 @@ const validateEventName = (config, diagnostics, node, eventName) => {
|
|
|
13007
13361
|
augmentDiagnosticWithNode(warn, node);
|
|
13008
13362
|
return;
|
|
13009
13363
|
}
|
|
13010
|
-
if (!config.
|
|
13364
|
+
if (!config.compat?.suppressEventNameWarnings && DOM_EVENT_NAMES.has(eventName.toLowerCase())) {
|
|
13011
13365
|
const diagnostic = buildWarn(diagnostics);
|
|
13012
13366
|
diagnostic.messageText = `The event name conflicts with the "${eventName}" native DOM event name.`;
|
|
13013
13367
|
augmentDiagnosticWithNode(diagnostic, node);
|
|
@@ -13306,7 +13660,8 @@ var ImportAliasMap = class extends Map {
|
|
|
13306
13660
|
//#endregion
|
|
13307
13661
|
//#region src/compiler/transformers/decorators-to-static/listen-decorator.ts
|
|
13308
13662
|
const listenDecoratorsToStatic = (diagnostics, typeChecker, decoratedMembers, newMembers, decoratorName) => {
|
|
13309
|
-
const
|
|
13663
|
+
const listeners = decoratedMembers.filter(ts.isMethodDeclaration).map((method) => parseListenDecorators(diagnostics, typeChecker, method, decoratorName));
|
|
13664
|
+
const flatListeners = flatOne(listeners);
|
|
13310
13665
|
if (flatListeners.length > 0) newMembers.push(createStaticGetter("listeners", convertValueToLiteral(flatListeners)));
|
|
13311
13666
|
};
|
|
13312
13667
|
const parseListenDecorators = (diagnostics, typeChecker, method, decoratorName) => {
|
|
@@ -13340,7 +13695,7 @@ const parseListener = (eventName, opts = {}, methodName) => {
|
|
|
13340
13695
|
passive: typeof opts.passive === "boolean" ? opts.passive : PASSIVE_TRUE_DEFAULTS.has(rawEventName.toLowerCase())
|
|
13341
13696
|
};
|
|
13342
13697
|
};
|
|
13343
|
-
const PASSIVE_TRUE_DEFAULTS = new Set([
|
|
13698
|
+
const PASSIVE_TRUE_DEFAULTS = /* @__PURE__ */ new Set([
|
|
13344
13699
|
"dragstart",
|
|
13345
13700
|
"drag",
|
|
13346
13701
|
"dragend",
|
|
@@ -13389,7 +13744,7 @@ const PASSIVE_TRUE_DEFAULTS = new Set([
|
|
|
13389
13744
|
* @param node the TypeScript AST node at which the class member is defined
|
|
13390
13745
|
*/
|
|
13391
13746
|
const validatePublicName = (config, diagnostics, memberName, decorator, memberType, node) => {
|
|
13392
|
-
if (config.
|
|
13747
|
+
if (config.compat?.suppressPublicNameWarnings) return;
|
|
13393
13748
|
if (RESERVED_PUBLIC_MEMBERS.has(memberName.toLowerCase())) {
|
|
13394
13749
|
const warn = buildWarn(diagnostics);
|
|
13395
13750
|
warn.messageText = [
|
|
@@ -13800,7 +14155,8 @@ const parsePropDecorator = (config, diagnostics, typeChecker, program, prop, dec
|
|
|
13800
14155
|
const returnExpression = (prop.body?.statements.find((st) => ts.isReturnStatement(st))).expression;
|
|
13801
14156
|
if (returnExpression && ts.isLiteralExpression(returnExpression)) propMeta.defaultValue = returnExpression.getText();
|
|
13802
14157
|
else if (returnExpression && ts.isPropertyAccessExpression(returnExpression)) {
|
|
13803
|
-
const
|
|
14158
|
+
const nameToFind = returnExpression.name.getText();
|
|
14159
|
+
const foundProp = findGetProp(nameToFind, newMembers);
|
|
13804
14160
|
if (foundProp && foundProp.initializer) {
|
|
13805
14161
|
propMeta.defaultValue = resolveInitializerText(foundProp.initializer, typeChecker);
|
|
13806
14162
|
if (propMeta.type === "unknown") {
|
|
@@ -14088,8 +14444,10 @@ const serializeDecoratorsToStatic = (typeChecker, decoratedProps, newMembers, de
|
|
|
14088
14444
|
return [];
|
|
14089
14445
|
});
|
|
14090
14446
|
const serializers = decoratedProps.filter(ts.isMethodDeclaration).flatMap((method) => parseSerializeDecorator(typeChecker, method, decoratorName, props));
|
|
14091
|
-
if (serializers.length > 0)
|
|
14092
|
-
|
|
14447
|
+
if (serializers.length > 0) {
|
|
14448
|
+
if (translateType === "PropSerialize") newMembers.push(createStaticGetter("serializers", convertValueToLiteral(serializers)));
|
|
14449
|
+
else newMembers.push(createStaticGetter("deserializers", convertValueToLiteral(serializers)));
|
|
14450
|
+
}
|
|
14093
14451
|
return serializers;
|
|
14094
14452
|
};
|
|
14095
14453
|
const parseSerializeDecorator = (typeChecker, method, decoratorName, props) => {
|
|
@@ -14145,7 +14503,8 @@ const stateDecoratorToStatic = (prop, typeChecker, decoratorName) => {
|
|
|
14145
14503
|
//#endregion
|
|
14146
14504
|
//#region src/compiler/transformers/decorators-to-static/watch-decorator.ts
|
|
14147
14505
|
const watchDecoratorsToStatic = (typeChecker, decoratedProps, newMembers, decoratorName) => {
|
|
14148
|
-
const
|
|
14506
|
+
const watchers = decoratedProps.filter(ts.isMethodDeclaration).map((method) => parseWatchDecorator(typeChecker, method, decoratorName));
|
|
14507
|
+
const flatWatchers = flatOne(watchers);
|
|
14149
14508
|
if (flatWatchers.length > 0) newMembers.push(createStaticGetter("watchers", convertValueToLiteral(flatWatchers)));
|
|
14150
14509
|
};
|
|
14151
14510
|
const parseWatchDecorator = (typeChecker, method, decoratorName) => {
|
|
@@ -14266,19 +14625,21 @@ const removeStencilMethodDecorators = (classMembers, diagnostics, importAliasMap
|
|
|
14266
14625
|
return classMembers.map((member) => {
|
|
14267
14626
|
const currentDecorators = retrieveTsDecorators(member);
|
|
14268
14627
|
const newDecorators = filterDecorators(currentDecorators, MEMBER_DECORATORS_TO_REMOVE.map((decorator) => importAliasMap.get(decorator)));
|
|
14269
|
-
if (currentDecorators !== newDecorators)
|
|
14270
|
-
|
|
14271
|
-
|
|
14272
|
-
|
|
14273
|
-
|
|
14274
|
-
|
|
14275
|
-
|
|
14276
|
-
|
|
14277
|
-
|
|
14278
|
-
|
|
14279
|
-
|
|
14280
|
-
|
|
14281
|
-
|
|
14628
|
+
if (currentDecorators !== newDecorators) {
|
|
14629
|
+
if (ts.isMethodDeclaration(member)) return ts.factory.updateMethodDeclaration(member, [...newDecorators ?? [], ...retrieveTsModifiers(member) ?? []], member.asteriskToken, member.name, member.questionToken, member.typeParameters, member.parameters, member.type, member.body);
|
|
14630
|
+
else if (ts.isGetAccessor(member)) return ts.factory.updateGetAccessorDeclaration(member, [...newDecorators ?? [], ...retrieveTsModifiers(member) ?? []], member.name, member.parameters, member.type, member.body);
|
|
14631
|
+
else if (ts.isSetAccessor(member)) {
|
|
14632
|
+
const err = buildError(diagnostics);
|
|
14633
|
+
err.messageText = "A get accessor should be decorated before a set accessor";
|
|
14634
|
+
augmentDiagnosticWithNode(err, member);
|
|
14635
|
+
} else if (ts.isPropertyDeclaration(member)) {
|
|
14636
|
+
const modifiers = retrieveTsModifiers(member);
|
|
14637
|
+
return ts.factory.updatePropertyDeclaration(member, [...newDecorators ?? [], ...modifiers ?? []], member.name, member.questionToken, member.type, member.initializer);
|
|
14638
|
+
} else {
|
|
14639
|
+
const err = buildError(diagnostics);
|
|
14640
|
+
err.messageText = "Unknown class member encountered!";
|
|
14641
|
+
augmentDiagnosticWithNode(err, member);
|
|
14642
|
+
}
|
|
14282
14643
|
}
|
|
14283
14644
|
return member;
|
|
14284
14645
|
});
|
|
@@ -14423,15 +14784,80 @@ const parseStaticWatchers = (staticMembers) => {
|
|
|
14423
14784
|
});
|
|
14424
14785
|
};
|
|
14425
14786
|
//#endregion
|
|
14426
|
-
//#region src/compiler/transformers/static-to-meta/class-extension.ts
|
|
14787
|
+
//#region src/compiler/transformers/static-to-meta/class-extension/shared.ts
|
|
14788
|
+
/**
|
|
14789
|
+
* Walks the AST looking for a class declaration, optionally by name - descends
|
|
14790
|
+
* into a mixin factory's wrapping function (arrow function or `function`
|
|
14791
|
+
* declaration) body too, since a mixin factory's class is always nested one
|
|
14792
|
+
* level inside it (e.g. `const Foo = (Base) => class extends Base {}`).
|
|
14793
|
+
* @param node the node to search from
|
|
14794
|
+
* @param name if given, only matches a class declaration with this name
|
|
14795
|
+
* @returns the found class declaration, or `undefined`
|
|
14796
|
+
*/
|
|
14797
|
+
function findClassWalk(node, name) {
|
|
14798
|
+
if (!node) return void 0;
|
|
14799
|
+
if (ts.isClassDeclaration(node)) {
|
|
14800
|
+
if (!name || node.name?.text === name) return node;
|
|
14801
|
+
} else if (ts.isVariableDeclaration(node) && (!name || name === node.name?.text) && node.initializer && ts.isArrowFunction(node.initializer)) {
|
|
14802
|
+
let found;
|
|
14803
|
+
ts.forEachChild(node.initializer.body, (child) => {
|
|
14804
|
+
if (found) return;
|
|
14805
|
+
if (ts.isClassDeclaration(child)) found = child;
|
|
14806
|
+
});
|
|
14807
|
+
return found;
|
|
14808
|
+
}
|
|
14809
|
+
let found;
|
|
14810
|
+
ts.forEachChild(node, (child) => {
|
|
14811
|
+
if (found) return;
|
|
14812
|
+
const result = findClassWalk(child, name);
|
|
14813
|
+
if (result) found = result;
|
|
14814
|
+
});
|
|
14815
|
+
return found;
|
|
14816
|
+
}
|
|
14817
|
+
/**
|
|
14818
|
+
* Matches a top-level class/function/variable declaration by name - the three
|
|
14819
|
+
* shapes a mixin or base-class export can take (a plain class, a mixin
|
|
14820
|
+
* factory function declaration, or a mixin factory assigned to a `const`).
|
|
14821
|
+
* @param name the declaration name to match
|
|
14822
|
+
* @returns a predicate usable with `Array.prototype.find` over a source file's statements
|
|
14823
|
+
*/
|
|
14824
|
+
function matchesNamedDeclaration(name) {
|
|
14825
|
+
return function(stmt) {
|
|
14826
|
+
if (ts.isClassDeclaration(stmt) && stmt.name?.text === name) return true;
|
|
14827
|
+
if (ts.isFunctionDeclaration(stmt) && stmt.name?.text === name) return true;
|
|
14828
|
+
if (ts.isVariableStatement(stmt)) {
|
|
14829
|
+
for (const decl of stmt.declarationList.declarations) if (ts.isIdentifier(decl.name) && decl.name.text === name) return true;
|
|
14830
|
+
}
|
|
14831
|
+
return false;
|
|
14832
|
+
};
|
|
14833
|
+
}
|
|
14834
|
+
/**
|
|
14835
|
+
* Finds a re-export of `className` in `sourceFile` - `export { X } from './y'` or
|
|
14836
|
+
* `export { X as Y } from './y'` - as used by barrel entry points (e.g. `@stencil/core`'s own
|
|
14837
|
+
* public `index.d.mts`, which re-exports its runtime API from `./declarations/stencil-public-runtime`
|
|
14838
|
+
* rather than declaring it directly).
|
|
14839
|
+
* @param sourceFile the (barrel) source file to scan
|
|
14840
|
+
* @param className the exported name to look for
|
|
14841
|
+
* @returns the module specifier and the name to look for in that module (the local name, before
|
|
14842
|
+
* any `as` aliasing), or `undefined` if no matching re-export is found
|
|
14843
|
+
*/
|
|
14844
|
+
function findReExport(sourceFile, className) {
|
|
14845
|
+
for (const stmt of sourceFile.statements) {
|
|
14846
|
+
if (!ts.isExportDeclaration(stmt) || !stmt.moduleSpecifier || !ts.isStringLiteral(stmt.moduleSpecifier) || !stmt.exportClause || !ts.isNamedExports(stmt.exportClause)) continue;
|
|
14847
|
+
for (const element of stmt.exportClause.elements) if (element.name.text === className) return {
|
|
14848
|
+
moduleSpecifier: stmt.moduleSpecifier.text,
|
|
14849
|
+
localName: element.propertyName?.text ?? element.name.text
|
|
14850
|
+
};
|
|
14851
|
+
}
|
|
14852
|
+
}
|
|
14427
14853
|
/**
|
|
14428
|
-
*
|
|
14429
|
-
*
|
|
14430
|
-
*
|
|
14854
|
+
* Filters `dedupeMembers` down to entries not already present in `staticMembers`
|
|
14855
|
+
* (by name, or `methodName` for change handlers) - used so an extending
|
|
14856
|
+
* class's own members win over inherited ones.
|
|
14431
14857
|
*
|
|
14432
|
-
* @param dedupeMembers the
|
|
14433
|
-
* @param staticMembers the
|
|
14434
|
-
* @returns
|
|
14858
|
+
* @param dedupeMembers the members to filter
|
|
14859
|
+
* @param staticMembers the members to filter against
|
|
14860
|
+
* @returns the filtered `dedupeMembers` array
|
|
14435
14861
|
*/
|
|
14436
14862
|
const deDupeMembers = (dedupeMembers, staticMembers) => {
|
|
14437
14863
|
return dedupeMembers.filter((s) => !staticMembers.some((d) => {
|
|
@@ -14439,22 +14865,62 @@ const deDupeMembers = (dedupeMembers, staticMembers) => {
|
|
|
14439
14865
|
return d.name === s.name;
|
|
14440
14866
|
}));
|
|
14441
14867
|
};
|
|
14868
|
+
const ensureRelativeSpecifier = (specifier) => {
|
|
14869
|
+
return specifier.startsWith(".") ? specifier : `./${specifier}`;
|
|
14870
|
+
};
|
|
14871
|
+
/**
|
|
14872
|
+
* Re-anchors inherited members' complex-type references - recorded relative
|
|
14873
|
+
* to the file declaring them - so they resolve from the extending
|
|
14874
|
+
* component's file instead. Consumers like `components.d.ts` generation
|
|
14875
|
+
* always resolve a reference against the component, not the declaring class,
|
|
14876
|
+
* so an inherited reference from a different directory would otherwise
|
|
14877
|
+
* produce a broken import.
|
|
14878
|
+
*
|
|
14879
|
+
* `import` refs get their relative path rewritten; `local` refs (a type
|
|
14880
|
+
* declared in the extended class's own file) become `import` refs pointing
|
|
14881
|
+
* at that file. Also applies to `node_modules`-published collections:
|
|
14882
|
+
* `dist/types/` mirrors `dist/collection/` 1:1, so the same math works after
|
|
14883
|
+
* swapping one for the other (type-only declarations don't survive
|
|
14884
|
+
* compilation to `.js`, so a reference has to point at the `.d.ts` tree).
|
|
14885
|
+
*
|
|
14886
|
+
* @param members inherited members whose type references should be re-anchored
|
|
14887
|
+
* @param extendedClassFileName absolute path of the file declaring the extended class
|
|
14888
|
+
* @param cmpSourceFilePath absolute path of the extending component's source file
|
|
14889
|
+
* @returns the same members, with their type references re-anchored
|
|
14890
|
+
*/
|
|
14891
|
+
const reanchorInheritedTypeReferences = (members, extendedClassFileName, cmpSourceFilePath) => {
|
|
14892
|
+
const extendedClassDir = dirname$1(normalizePath(extendedClassFileName, false));
|
|
14893
|
+
const cmpDir = dirname$1(normalizePath(cmpSourceFilePath, false));
|
|
14894
|
+
if (extendedClassDir === cmpDir) return members;
|
|
14895
|
+
const isCollectionModule = isNodeModulePath(extendedClassFileName);
|
|
14896
|
+
const toDeclarationPath = (path) => isCollectionModule ? path.replace("/collection/", "/types/") : path;
|
|
14897
|
+
members.forEach((member) => {
|
|
14898
|
+
const references = member.complexType?.references;
|
|
14899
|
+
if (!references) return;
|
|
14900
|
+
Object.values(references).forEach((reference) => {
|
|
14901
|
+
if (reference.location === "import" && reference.path?.startsWith(".")) {
|
|
14902
|
+
const typeModulePath = toDeclarationPath(join$2(extendedClassDir, reference.path));
|
|
14903
|
+
reference.path = ensureRelativeSpecifier(relative$1(cmpDir, typeModulePath));
|
|
14904
|
+
} else if (reference.location === "local") {
|
|
14905
|
+
const extendedClassModule = toDeclarationPath(normalizePath(extendedClassFileName, false).replace(/\.(tsx|ts|js)$/, ""));
|
|
14906
|
+
reference.location = "import";
|
|
14907
|
+
reference.path = ensureRelativeSpecifier(relative$1(cmpDir, extendedClassModule));
|
|
14908
|
+
}
|
|
14909
|
+
});
|
|
14910
|
+
});
|
|
14911
|
+
return members;
|
|
14912
|
+
};
|
|
14913
|
+
//#endregion
|
|
14914
|
+
//#region src/compiler/transformers/static-to-meta/class-extension/compiler-ctx-merge.ts
|
|
14442
14915
|
/**
|
|
14443
|
-
*
|
|
14444
|
-
*
|
|
14445
|
-
*
|
|
14446
|
-
*
|
|
14447
|
-
*
|
|
14448
|
-
*
|
|
14449
|
-
* This helper creates a self-contained mini TypeScript program for the single
|
|
14450
|
-
* file and runs the decorator→static transformer on it, returning the
|
|
14451
|
-
* transformed source file. Prop types may be under-resolved (external imports
|
|
14452
|
-
* are not available in the mini program) and will fall back to `any`, which is
|
|
14453
|
-
* acceptable for the purpose of walking the inheritance chain.
|
|
14454
|
-
*
|
|
14916
|
+
* Converts a disk-fetched parent source file (still decorator syntax) to
|
|
14917
|
+
* static-getter form via a throwaway single-file program - `parseStatic*`
|
|
14918
|
+
* only understands the static-getter form {@link convertDecoratorsToStatic}
|
|
14919
|
+
* produces. Cross-file imports can't resolve in this mini program, so prop
|
|
14920
|
+
* types may fall back to `any`, which is fine for just walking the chain.
|
|
14455
14921
|
* @param sourceFile the raw (decorator-syntax) source file from disk
|
|
14456
14922
|
* @param config the current Stencil validated config
|
|
14457
|
-
* @param target the script target to
|
|
14923
|
+
* @param target the script target to convert decorators with
|
|
14458
14924
|
* @returns the source file with decorators converted to static getters
|
|
14459
14925
|
*/
|
|
14460
14926
|
function convertDiskSourceFileDecorators(sourceFile, config, target = ts.ScriptTarget.ESNext) {
|
|
@@ -14475,26 +14941,24 @@ function convertDiskSourceFileDecorators(sourceFile, config, target = ts.ScriptT
|
|
|
14475
14941
|
return ts.createSourceFile(sourceFile.fileName, printed, target, true);
|
|
14476
14942
|
}
|
|
14477
14943
|
/**
|
|
14478
|
-
*
|
|
14479
|
-
*
|
|
14480
|
-
*
|
|
14481
|
-
*
|
|
14482
|
-
*
|
|
14483
|
-
*
|
|
14484
|
-
*
|
|
14485
|
-
* @param
|
|
14486
|
-
* @param
|
|
14487
|
-
* @param
|
|
14488
|
-
* @param
|
|
14489
|
-
* @param
|
|
14490
|
-
* @param
|
|
14491
|
-
* @param
|
|
14492
|
-
* @param
|
|
14493
|
-
* @
|
|
14494
|
-
* @param targetScriptTarget - the script target to use when converting decorators to static (if needed)
|
|
14495
|
-
* @returns the found class declaration or undefined
|
|
14944
|
+
* Resolves an `extends` target through a module specifier: resolves the
|
|
14945
|
+
* module, finds the named class/mixin-factory export, and adds it (and its
|
|
14946
|
+
* own ancestors) to `dependentClasses`. Follows one level of re-export (barrel file) when the
|
|
14947
|
+
* declaration isn't found directly in the resolved module.
|
|
14948
|
+
* @param compilerCtx the current compiler context
|
|
14949
|
+
* @param buildCtx the current build context
|
|
14950
|
+
* @param classDeclaration the current class being analyzed
|
|
14951
|
+
* @param currentSource the source file of the current class
|
|
14952
|
+
* @param moduleSpecifier the module path to resolve
|
|
14953
|
+
* @param className the name of the class to find in the resolved module
|
|
14954
|
+
* @param dependentClasses the array to add found classes to
|
|
14955
|
+
* @param typeChecker the TypeScript type checker
|
|
14956
|
+
* @param ogModule the original module file of the class declaration
|
|
14957
|
+
* @param targetScriptTarget the script target to convert decorators with, if needed
|
|
14958
|
+
* @param barrelHopsRemaining re-export hops still allowed before giving up
|
|
14959
|
+
* @returns the found class declaration, or `undefined`
|
|
14496
14960
|
*/
|
|
14497
|
-
function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, currentSource, moduleSpecifier, className, dependentClasses, typeChecker, ogModule, targetScriptTarget = ts.ScriptTarget.ESNext) {
|
|
14961
|
+
function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, currentSource, moduleSpecifier, className, dependentClasses, typeChecker, ogModule, targetScriptTarget = ts.ScriptTarget.ESNext, barrelHopsRemaining = 1) {
|
|
14498
14962
|
let keepLooking = true;
|
|
14499
14963
|
const foundFile = tsResolveModuleName(buildCtx.config, compilerCtx, moduleSpecifier, currentSource.fileName);
|
|
14500
14964
|
if (!foundFile?.resolvedModule || !className) return;
|
|
@@ -14503,7 +14967,7 @@ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration,
|
|
|
14503
14967
|
foundSource = tsGetSourceFile(buildCtx.config, foundFile);
|
|
14504
14968
|
if (!foundSource) {
|
|
14505
14969
|
const err = buildWarn(buildCtx.diagnostics);
|
|
14506
|
-
err.messageText = `Unable to resolve import "${moduleSpecifier}" from "${currentSource.fileName}".
|
|
14970
|
+
err.messageText = `Unable to resolve import "${moduleSpecifier}" from "${currentSource.fileName}".
|
|
14507
14971
|
This can happen when trying to resolve .js files and "allowJs" is not set to "true" in your tsconfig.json.`;
|
|
14508
14972
|
if (!buildCtx.config._isTesting) augmentDiagnosticWithNode(err, classDeclaration);
|
|
14509
14973
|
return;
|
|
@@ -14512,8 +14976,10 @@ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration,
|
|
|
14512
14976
|
}
|
|
14513
14977
|
const matchedStatement = foundSource.statements.find(matchesNamedDeclaration(className));
|
|
14514
14978
|
if (!matchedStatement) {
|
|
14979
|
+
const reExport = barrelHopsRemaining > 0 ? findReExport(foundSource, className) : void 0;
|
|
14980
|
+
if (reExport) return resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, foundSource, reExport.moduleSpecifier, reExport.localName, dependentClasses, typeChecker, ogModule, targetScriptTarget, barrelHopsRemaining - 1);
|
|
14515
14981
|
const err = buildWarn(buildCtx.diagnostics);
|
|
14516
|
-
err.messageText = `Unable to find "${className}" in the imported module "${moduleSpecifier}".
|
|
14982
|
+
err.messageText = `Unable to find "${className}" in the imported module "${moduleSpecifier}".
|
|
14517
14983
|
Please import class / mixin-factory declarations directly and not via barrel files.`;
|
|
14518
14984
|
if (!buildCtx.config._isTesting) augmentDiagnosticWithNode(err, classDeclaration);
|
|
14519
14985
|
return;
|
|
@@ -14533,71 +14999,20 @@ function resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration,
|
|
|
14533
14999
|
}
|
|
14534
15000
|
return foundClassDeclaration;
|
|
14535
15001
|
}
|
|
14536
|
-
/**
|
|
14537
|
-
* A recursive function that walks the AST to find a class declaration.
|
|
14538
|
-
* @param node the current AST node
|
|
14539
|
-
* @param depth the current depth in the AST
|
|
14540
|
-
* @param name optional name of the class to find
|
|
14541
|
-
* @returns the found class declaration or undefined
|
|
14542
|
-
*/
|
|
14543
|
-
function findClassWalk(node, name, depth = 0) {
|
|
14544
|
-
if (!node) return void 0;
|
|
14545
|
-
if (node && ts.isClassDeclaration(node)) {
|
|
14546
|
-
if (!name || node.name?.text === name) return node;
|
|
14547
|
-
} else if (node && ts.isVariableDeclaration(node) && (!name || name === (node.name?.text || node.name?.escapedText)) && node.initializer && ts.isArrowFunction(node.initializer)) {
|
|
14548
|
-
let found;
|
|
14549
|
-
ts.forEachChild(node.initializer.body, (child) => {
|
|
14550
|
-
if (found) return;
|
|
14551
|
-
if (ts.isClassDeclaration(child)) found = child;
|
|
14552
|
-
});
|
|
14553
|
-
return found;
|
|
14554
|
-
}
|
|
14555
|
-
let found;
|
|
14556
|
-
ts.forEachChild(node, (child) => {
|
|
14557
|
-
if (found) return;
|
|
14558
|
-
const result = findClassWalk(child, name, depth + 1);
|
|
14559
|
-
if (result) found = result;
|
|
14560
|
-
});
|
|
14561
|
-
return found;
|
|
14562
|
-
}
|
|
14563
|
-
/**
|
|
14564
|
-
* A function that checks if a statement matches a named declaration.
|
|
14565
|
-
* @param name the name to match
|
|
14566
|
-
* @returns a function that checks if a statement is a named declaration
|
|
14567
|
-
*/
|
|
14568
|
-
function matchesNamedDeclaration(name) {
|
|
14569
|
-
return function(stmt) {
|
|
14570
|
-
if (ts.isClassDeclaration(stmt) && stmt.name?.text === name) return true;
|
|
14571
|
-
if (ts.isFunctionDeclaration(stmt) && stmt.name?.text === name) return true;
|
|
14572
|
-
if (ts.isVariableStatement(stmt)) {
|
|
14573
|
-
for (const decl of stmt.declarationList.declarations) if (ts.isIdentifier(decl.name) && decl.name.text === name) return true;
|
|
14574
|
-
}
|
|
14575
|
-
return false;
|
|
14576
|
-
};
|
|
14577
|
-
}
|
|
14578
|
-
/**
|
|
14579
|
-
* Helper function to convert a .d.ts declaration file path to its corresponding
|
|
14580
|
-
* .js source file path and get the source file from the compiler context.
|
|
14581
|
-
* This is needed because in external projects the extended class may only be found as a .d.ts declaration.
|
|
14582
|
-
* *
|
|
14583
|
-
* @param declarationSourceFile the path to the .d.ts declaration file
|
|
14584
|
-
* @param compilerCtx the current compiler context
|
|
14585
|
-
* @returns the corresponding .js source file
|
|
14586
|
-
*/
|
|
14587
15002
|
function convertDtsToJs(declarationSourceFile, compilerCtx) {
|
|
14588
15003
|
const jsPath = normalizePath(declarationSourceFile.replace(/\.d\.ts$/, ".js").replace("/types/", "/collection/"));
|
|
14589
15004
|
return compilerCtx.moduleMap.get(jsPath)?.staticSourceFile;
|
|
14590
15005
|
}
|
|
14591
15006
|
/**
|
|
14592
|
-
*
|
|
14593
|
-
*
|
|
15007
|
+
* Recursively walks a class's heritage clauses to build a flat list of every
|
|
15008
|
+
* class it extends from (and their own ancestors in turn).
|
|
14594
15009
|
* @param compilerCtx the current compiler context
|
|
14595
15010
|
* @param classDeclaration a class declaration to analyze
|
|
14596
|
-
* @param dependentClasses
|
|
15011
|
+
* @param dependentClasses the flat array to accumulate found classes into
|
|
14597
15012
|
* @param typeChecker the TypeScript type checker
|
|
14598
15013
|
* @param buildCtx the current build context
|
|
14599
15014
|
* @param ogModule the original module file of the class declaration
|
|
14600
|
-
* @returns
|
|
15015
|
+
* @returns `dependentClasses`, mutated in place
|
|
14601
15016
|
*/
|
|
14602
15017
|
function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeChecker, buildCtx, ogModule) {
|
|
14603
15018
|
const hasHeritageClauses = classDeclaration.heritageClauses;
|
|
@@ -14614,10 +15029,10 @@ function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeC
|
|
|
14614
15029
|
});
|
|
14615
15030
|
classIdentifiers.forEach((extendee) => {
|
|
14616
15031
|
try {
|
|
14617
|
-
|
|
14618
|
-
|
|
14619
|
-
let source =
|
|
14620
|
-
let declarations =
|
|
15032
|
+
let symbol = typeChecker?.getSymbolAtLocation(extendee);
|
|
15033
|
+
if (symbol && symbol.flags & ts.SymbolFlags.Alias) symbol = typeChecker.getAliasedSymbol(symbol);
|
|
15034
|
+
let source = symbol?.declarations?.[0].getSourceFile();
|
|
15035
|
+
let declarations = symbol?.declarations;
|
|
14621
15036
|
if (source.fileName.endsWith(".d.ts")) {
|
|
14622
15037
|
source = convertDtsToJs(source.fileName, compilerCtx);
|
|
14623
15038
|
declarations = [...source.statements];
|
|
@@ -14689,7 +15104,8 @@ function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeC
|
|
|
14689
15104
|
if (statement.importClause?.namedBindings && ts.isNamedImports(statement.importClause?.namedBindings)) statement.importClause?.namedBindings.elements.forEach((element) => {
|
|
14690
15105
|
if (element.name.getText() === extendee.getText()) {
|
|
14691
15106
|
const className = element.propertyName?.getText() || element.name.getText();
|
|
14692
|
-
|
|
15107
|
+
const moduleSpecifier = statement.moduleSpecifier.getText().replaceAll(/['"]/g, "");
|
|
15108
|
+
resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, currentSource, moduleSpecifier, className, dependentClasses, typeChecker, ogModule, targetScriptTarget);
|
|
14693
15109
|
}
|
|
14694
15110
|
});
|
|
14695
15111
|
});
|
|
@@ -14698,17 +15114,15 @@ function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeC
|
|
|
14698
15114
|
return dependentClasses;
|
|
14699
15115
|
}
|
|
14700
15116
|
/**
|
|
14701
|
-
*
|
|
14702
|
-
*
|
|
14703
|
-
*
|
|
14704
|
-
*
|
|
14705
|
-
* @param
|
|
14706
|
-
* @param
|
|
14707
|
-
* @param
|
|
14708
|
-
* @param
|
|
14709
|
-
* @
|
|
14710
|
-
* @param moduleFile - the module file of the extending class
|
|
14711
|
-
* @returns an object containing merged metadata from extended classes
|
|
15117
|
+
* Analyzes a class's heritage clauses to find any extended classes, then
|
|
15118
|
+
* merges their static members into the extending class's own metadata.
|
|
15119
|
+
* @param compilerCtx the current compiler context
|
|
15120
|
+
* @param typeChecker the TypeScript type checker
|
|
15121
|
+
* @param buildCtx the current build context
|
|
15122
|
+
* @param cmpNode the extending class declaration
|
|
15123
|
+
* @param staticMembers the static members of the extending class
|
|
15124
|
+
* @param moduleFile the module file of the extending class
|
|
15125
|
+
* @returns the merged metadata from `cmpNode` and every class it extends
|
|
14712
15126
|
*/
|
|
14713
15127
|
function mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, staticMembers, moduleFile) {
|
|
14714
15128
|
const tree = buildExtendsTree(compilerCtx, cmpNode, [], typeChecker, buildCtx, moduleFile);
|
|
@@ -14725,10 +15139,10 @@ function mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, sta
|
|
|
14725
15139
|
let deserializers = parseStaticSerializers(staticMembers, "deserializers");
|
|
14726
15140
|
tree.forEach((extendedClass) => {
|
|
14727
15141
|
const extendedStaticMembers = extendedClass.classNode.members.filter(isStaticGetter);
|
|
14728
|
-
const mixinProps = parseStaticProps(extendedStaticMembers) ?? [];
|
|
15142
|
+
const mixinProps = reanchorInheritedTypeReferences(parseStaticProps(extendedStaticMembers) ?? [], extendedClass.fileName, moduleFile.sourceFilePath);
|
|
14729
15143
|
const mixinStates = parseStaticStates(extendedStaticMembers) ?? [];
|
|
14730
|
-
const mixinMethods = parseStaticMethods(extendedStaticMembers) ?? [];
|
|
14731
|
-
const mixinEvents = parseStaticEvents(extendedStaticMembers) ?? [];
|
|
15144
|
+
const mixinMethods = reanchorInheritedTypeReferences(parseStaticMethods(extendedStaticMembers) ?? [], extendedClass.fileName, moduleFile.sourceFilePath);
|
|
15145
|
+
const mixinEvents = reanchorInheritedTypeReferences(parseStaticEvents(extendedStaticMembers) ?? [], extendedClass.fileName, moduleFile.sourceFilePath);
|
|
14732
15146
|
const isMixin = mixinProps.length > 0 || mixinStates.length > 0 || mixinMethods.length > 0 || mixinEvents.length > 0;
|
|
14733
15147
|
const module = compilerCtx.moduleMap.get(extendedClass.fileName);
|
|
14734
15148
|
if (module) {
|
|
@@ -14770,6 +15184,8 @@ function mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, sta
|
|
|
14770
15184
|
deserializers
|
|
14771
15185
|
};
|
|
14772
15186
|
}
|
|
15187
|
+
//#endregion
|
|
15188
|
+
//#region src/compiler/transformers/static-to-meta/class-extension/extract-inherited-meta.ts
|
|
14773
15189
|
const EMPTY_DOCS = {
|
|
14774
15190
|
text: "",
|
|
14775
15191
|
tags: []
|
|
@@ -14805,19 +15221,14 @@ function extractDecoratorOptions(node) {
|
|
|
14805
15221
|
return result;
|
|
14806
15222
|
}
|
|
14807
15223
|
/**
|
|
14808
|
-
*
|
|
14809
|
-
*
|
|
14810
|
-
*
|
|
14811
|
-
*
|
|
14812
|
-
* @param
|
|
14813
|
-
* @
|
|
14814
|
-
* @param fileName virtual filename used to determine script kind
|
|
14815
|
-
* @returns extracted metadata, or null if the named class is not found
|
|
15224
|
+
* Same as {@link extractInheritedMeta}, but takes an already-parsed class
|
|
15225
|
+
* declaration directly - used for ancestors reached via `findClassWalk`
|
|
15226
|
+
* (e.g. a mixin factory's nested class, or a same-file ancestor), where
|
|
15227
|
+
* there's no standalone source text to re-parse.
|
|
15228
|
+
* @param classDecl the class declaration to extract metadata from
|
|
15229
|
+
* @returns extracted metadata
|
|
14816
15230
|
*/
|
|
14817
|
-
function
|
|
14818
|
-
const scriptKind = fileName.endsWith(".tsx") || fileName.endsWith(".ts") ? ts.ScriptKind.TSX : ts.ScriptKind.JS;
|
|
14819
|
-
const classDecl = ts.createSourceFile(fileName, code, ts.ScriptTarget.ESNext, true, scriptKind).statements.filter(ts.isClassDeclaration).find((c) => c.name?.text === className);
|
|
14820
|
-
if (!classDecl) return null;
|
|
15231
|
+
function extractInheritedMetaFromClass(classDecl) {
|
|
14821
15232
|
const methodNames = classDecl.members.filter(ts.isMethodDeclaration).map((m) => ts.isIdentifier(m.name) ? m.name.text : "").filter(Boolean);
|
|
14822
15233
|
const staticMembers = classDecl.members.filter(isStaticGetter);
|
|
14823
15234
|
if (staticMembers.some((m) => ts.isGetAccessorDeclaration(m) && ts.isIdentifier(m.name) && [
|
|
@@ -14917,11 +15328,68 @@ function extractInheritedMeta(code, className, fileName = "__stencil_parent__.ts
|
|
|
14917
15328
|
methodNames
|
|
14918
15329
|
};
|
|
14919
15330
|
}
|
|
14920
|
-
|
|
15331
|
+
//#endregion
|
|
15332
|
+
//#region src/compiler/transformers/static-to-meta/class-extension/resolve-import-merge.ts
|
|
15333
|
+
/**
|
|
15334
|
+
* Same purpose as `convertDiskSourceFileDecorators` in compiler-ctx-merge.ts,
|
|
15335
|
+
* but serves the already-parsed in-memory source directly instead of
|
|
15336
|
+
* re-reading it from disk - the parent source here comes from a
|
|
15337
|
+
* caller-supplied `resolveImport` callback and isn't guaranteed to
|
|
15338
|
+
* correspond to a real file on disk.
|
|
15339
|
+
* @param sourceFile the raw (decorator-syntax) parent source file, already parsed
|
|
15340
|
+
* @param config the current Stencil validated config
|
|
15341
|
+
* @returns the source converted to static-getter form, or `null` if the mini-program transform fails
|
|
15342
|
+
*/
|
|
15343
|
+
function convertInMemorySourceDecorators(sourceFile, config) {
|
|
15344
|
+
const compilerOptions = {
|
|
15345
|
+
...config.tsCompilerOptions,
|
|
15346
|
+
experimentalDecorators: true,
|
|
15347
|
+
noLib: true,
|
|
15348
|
+
noResolve: true,
|
|
15349
|
+
isolatedModules: false,
|
|
15350
|
+
target: sourceFile.languageVersion
|
|
15351
|
+
};
|
|
15352
|
+
const compilerHost = {
|
|
15353
|
+
getSourceFile: (fileName) => fileName === sourceFile.fileName ? sourceFile : void 0,
|
|
15354
|
+
writeFile: () => {},
|
|
15355
|
+
getDefaultLibFileName: () => "lib.d.ts",
|
|
15356
|
+
useCaseSensitiveFileNames: () => false,
|
|
15357
|
+
getCanonicalFileName: (fileName) => fileName,
|
|
15358
|
+
getCurrentDirectory: () => "",
|
|
15359
|
+
getNewLine: () => "\n",
|
|
15360
|
+
fileExists: (fileName) => fileName === sourceFile.fileName,
|
|
15361
|
+
readFile: () => "",
|
|
15362
|
+
directoryExists: () => true,
|
|
15363
|
+
getDirectories: () => []
|
|
15364
|
+
};
|
|
15365
|
+
try {
|
|
15366
|
+
const program = ts.createProgram([sourceFile.fileName], compilerOptions, compilerHost);
|
|
15367
|
+
const typeChecker = program.getTypeChecker();
|
|
15368
|
+
const ownSourceFile = program.getSourceFile(sourceFile.fileName) ?? sourceFile;
|
|
15369
|
+
const result = ts.transform(ownSourceFile, [convertDecoratorsToStatic(config, [], typeChecker, program)]);
|
|
15370
|
+
const printed = ts.createPrinter({ removeComments: false }).printFile(result.transformed[0]);
|
|
15371
|
+
const scriptKind = sourceFile.fileName.endsWith(".tsx") || sourceFile.fileName.endsWith(".ts") ? ts.ScriptKind.TSX : ts.ScriptKind.JS;
|
|
15372
|
+
return ts.createSourceFile(sourceFile.fileName, printed, sourceFile.languageVersion, true, scriptKind);
|
|
15373
|
+
} catch {
|
|
15374
|
+
return null;
|
|
15375
|
+
}
|
|
15376
|
+
}
|
|
15377
|
+
/**
|
|
15378
|
+
* Reads the name(s) a class declaration extends from - either a single
|
|
15379
|
+
* identifier (`extends Foo`) or, for the mixin composition pattern, each
|
|
15380
|
+
* mixin factory argument (`extends Mixin(A, B)` > `['A', 'B']`).
|
|
15381
|
+
*
|
|
15382
|
+
* @param node the class declaration to inspect
|
|
15383
|
+
* @returns the extended identifier names, or an empty array if the class
|
|
15384
|
+
* doesn't extend anything recognizable
|
|
15385
|
+
*/
|
|
15386
|
+
function getExtendsClassNames(node) {
|
|
14921
15387
|
const heritage = node.heritageClauses?.find((h) => h.token === ts.SyntaxKind.ExtendsKeyword);
|
|
14922
|
-
if (!heritage?.types.length) return
|
|
15388
|
+
if (!heritage?.types.length) return [];
|
|
14923
15389
|
const expr = heritage.types[0].expression;
|
|
14924
|
-
|
|
15390
|
+
if (ts.isIdentifier(expr)) return [expr.text];
|
|
15391
|
+
if (ts.isCallExpression(expr) && expr.expression.getText() === "Mixin") return expr.arguments.filter(ts.isIdentifier).map((id) => id.text);
|
|
15392
|
+
return [];
|
|
14925
15393
|
}
|
|
14926
15394
|
function findImportSpecifier(sf, localName) {
|
|
14927
15395
|
for (const stmt of sf.statements) {
|
|
@@ -14937,17 +15405,208 @@ function findImportSpecifier(sf, localName) {
|
|
|
14937
15405
|
return null;
|
|
14938
15406
|
}
|
|
14939
15407
|
/**
|
|
15408
|
+
* A single-file mini-program (see `convertInMemorySourceDecorators`) can
|
|
15409
|
+
* never load an imported module's own `SourceFile`, so a type that's
|
|
15410
|
+
* genuinely imported still ends up classified `location: 'global'`
|
|
15411
|
+
*
|
|
15412
|
+
* This reclassifies those cases using the same syntactic import lookup used
|
|
15413
|
+
* to walk the extends chain: if the type name matches something imported in
|
|
15414
|
+
* the file that declares it, it's an import, not a global, regardless of
|
|
15415
|
+
* whether the mini-program could load that file - downstream consumers
|
|
15416
|
+
* (e.g. `@stencil/unplugin`'s own type expansion) resolve `path` themselves.
|
|
15417
|
+
*
|
|
15418
|
+
* @param members inherited members whose type references should be reclassified
|
|
15419
|
+
* @param declaringSf the source file that declares these members
|
|
15420
|
+
* @param declaringPath the resolved absolute path of `declaringSf`
|
|
15421
|
+
* @param resolveImport callback used to resolve a canonical id for the reclassified reference
|
|
15422
|
+
* @returns the same members, with `global` references reclassified where possible
|
|
15423
|
+
*/
|
|
15424
|
+
function reclassifyGlobalTypeReferences(members, declaringSf, declaringPath, resolveImport) {
|
|
15425
|
+
members.forEach((member) => {
|
|
15426
|
+
const references = member.complexType?.references;
|
|
15427
|
+
if (!references) return;
|
|
15428
|
+
Object.entries(references).forEach(([typeName, reference]) => {
|
|
15429
|
+
if (reference.location !== "global") return;
|
|
15430
|
+
const specifier = findImportSpecifier(declaringSf, typeName);
|
|
15431
|
+
if (!specifier) return;
|
|
15432
|
+
const resolved = resolveImport(specifier, declaringPath);
|
|
15433
|
+
reference.location = "import";
|
|
15434
|
+
reference.path = specifier;
|
|
15435
|
+
reference.id = `${resolved?.path ?? specifier}::${typeName}`;
|
|
15436
|
+
});
|
|
15437
|
+
});
|
|
15438
|
+
return members;
|
|
15439
|
+
}
|
|
15440
|
+
/**
|
|
15441
|
+
* Looks for `name` as a direct top-level declaration in `sf`; if not found, follows one level of
|
|
15442
|
+
* re-export (barrel file) via `resolveImport` - matching `compiler-ctx-merge.ts`'s equivalent
|
|
15443
|
+
* one-hop fallback (see `findReExport` in `shared.ts` for why it's capped at one hop).
|
|
15444
|
+
*
|
|
15445
|
+
* @param sf the source file to search
|
|
15446
|
+
* @param path the resolved absolute path of `sf`
|
|
15447
|
+
* @param name the declaration name to find
|
|
15448
|
+
* @param resolveImport callback used to follow a re-export's module specifier
|
|
15449
|
+
* @returns the matched statement and the source file/path it was actually found in (which may
|
|
15450
|
+
* differ from `sf`/`path` if resolved through a re-export), or `undefined`
|
|
15451
|
+
*/
|
|
15452
|
+
function findDeclarationOrReExport(sf, path, name, resolveImport) {
|
|
15453
|
+
const direct = sf.statements.find(matchesNamedDeclaration(name));
|
|
15454
|
+
if (direct) return {
|
|
15455
|
+
statement: direct,
|
|
15456
|
+
sourceFile: sf,
|
|
15457
|
+
path
|
|
15458
|
+
};
|
|
15459
|
+
const reExport = findReExport(sf, name);
|
|
15460
|
+
if (!reExport) return void 0;
|
|
15461
|
+
const resolved = resolveImport(reExport.moduleSpecifier, path);
|
|
15462
|
+
if (!resolved) return void 0;
|
|
15463
|
+
const { code, path: resolvedPath } = resolved;
|
|
15464
|
+
const isTs = resolvedPath.endsWith(".tsx") || resolvedPath.endsWith(".ts");
|
|
15465
|
+
const reExportSf = ts.createSourceFile(resolvedPath, code, ts.ScriptTarget.ESNext, true, isTs ? ts.ScriptKind.TSX : ts.ScriptKind.JS);
|
|
15466
|
+
const statement = reExportSf.statements.find(matchesNamedDeclaration(reExport.localName));
|
|
15467
|
+
if (!statement) return void 0;
|
|
15468
|
+
return {
|
|
15469
|
+
statement,
|
|
15470
|
+
sourceFile: reExportSf,
|
|
15471
|
+
path: resolvedPath
|
|
15472
|
+
};
|
|
15473
|
+
}
|
|
15474
|
+
/**
|
|
15475
|
+
* Recursively resolves a class's `extends` heritage into a flat, deduplicated
|
|
15476
|
+
* list of ancestor classes, using `resolveImport` (and same-file lookups)
|
|
15477
|
+
* instead of a TypeChecker - the `resolveImport`-callback equivalent of
|
|
15478
|
+
* `compiler-ctx-merge.ts`'s `buildExtendsTree`. Handles both a plain
|
|
15479
|
+
* `extends Foo` and `extends Mixin(A, B, ...)`, resolving each mixin
|
|
15480
|
+
* argument independently.
|
|
15481
|
+
*
|
|
15482
|
+
* A found ancestor that's wrapped in a mixin factory function (rather than a
|
|
15483
|
+
* plain class) stops that branch's recursion - the factory's own `extends`
|
|
15484
|
+
* target is a dynamic parameter (e.g. `Base`), not a statically resolvable
|
|
15485
|
+
* name.
|
|
15486
|
+
* @param classNode the class declaration whose heritage should be walked
|
|
15487
|
+
* @param sf the source file containing `classNode` (for import/statement lookups)
|
|
15488
|
+
* @param path the resolved absolute path of `sf`
|
|
15489
|
+
* @param resolveImport callback that resolves an import specifier to source code
|
|
15490
|
+
* @param visited cycle guard, keyed by `resolvedPath::name`
|
|
15491
|
+
* @param ancestors the flat array to accumulate found ancestors into
|
|
15492
|
+
* @param rootClassDeclaration the top-level component class, used to anchor any "not found" warning
|
|
15493
|
+
* @param buildCtx used to surface a warning when an imported extends/mixin target can't be found -
|
|
15494
|
+
* omit to resolve silently (e.g. from tests that don't care about diagnostics)
|
|
15495
|
+
*/
|
|
15496
|
+
function resolveAncestors(classNode, sf, path, resolveImport, visited, ancestors, rootClassDeclaration, buildCtx) {
|
|
15497
|
+
const parentNames = getExtendsClassNames(classNode);
|
|
15498
|
+
for (const parentName of parentNames) {
|
|
15499
|
+
let foundClass;
|
|
15500
|
+
let foundSf = sf;
|
|
15501
|
+
let foundPath = path;
|
|
15502
|
+
let keepLooking = true;
|
|
15503
|
+
const sameFileStatement = sf.statements.find(matchesNamedDeclaration(parentName));
|
|
15504
|
+
if (sameFileStatement) {
|
|
15505
|
+
if (ts.isClassDeclaration(sameFileStatement)) foundClass = sameFileStatement;
|
|
15506
|
+
else {
|
|
15507
|
+
foundClass = findClassWalk(sameFileStatement);
|
|
15508
|
+
keepLooking = false;
|
|
15509
|
+
}
|
|
15510
|
+
} else {
|
|
15511
|
+
const specifier = findImportSpecifier(sf, parentName);
|
|
15512
|
+
if (!specifier) continue;
|
|
15513
|
+
const resolved = resolveImport(specifier, path);
|
|
15514
|
+
if (!resolved) continue;
|
|
15515
|
+
const { code, path: resolvedPath } = resolved;
|
|
15516
|
+
const visitKey = `${resolvedPath}::${parentName}`;
|
|
15517
|
+
if (visited.has(visitKey)) continue;
|
|
15518
|
+
visited.add(visitKey);
|
|
15519
|
+
const isTs = resolvedPath.endsWith(".tsx") || resolvedPath.endsWith(".ts");
|
|
15520
|
+
const found = findDeclarationOrReExport(ts.createSourceFile(resolvedPath, code, ts.ScriptTarget.ESNext, true, isTs ? ts.ScriptKind.TSX : ts.ScriptKind.JS), resolvedPath, parentName, resolveImport);
|
|
15521
|
+
if (!found) {
|
|
15522
|
+
if (buildCtx) {
|
|
15523
|
+
const err = buildWarn(buildCtx.diagnostics);
|
|
15524
|
+
err.messageText = `Unable to find "${parentName}" in the imported module "${specifier}".
|
|
15525
|
+
Please import class / mixin-factory declarations directly and not via barrel files.`;
|
|
15526
|
+
if (!buildCtx.config._isTesting) augmentDiagnosticWithNode(err, rootClassDeclaration);
|
|
15527
|
+
}
|
|
15528
|
+
continue;
|
|
15529
|
+
}
|
|
15530
|
+
foundSf = found.sourceFile;
|
|
15531
|
+
foundPath = found.path;
|
|
15532
|
+
if (ts.isClassDeclaration(found.statement)) foundClass = found.statement;
|
|
15533
|
+
else {
|
|
15534
|
+
foundClass = findClassWalk(found.statement);
|
|
15535
|
+
keepLooking = false;
|
|
15536
|
+
}
|
|
15537
|
+
}
|
|
15538
|
+
if (!foundClass || ancestors.some((a) => a.classNode === foundClass)) continue;
|
|
15539
|
+
ancestors.push({
|
|
15540
|
+
classNode: foundClass,
|
|
15541
|
+
sourceFile: foundSf,
|
|
15542
|
+
path: foundPath
|
|
15543
|
+
});
|
|
15544
|
+
if (keepLooking) resolveAncestors(foundClass, foundSf, foundPath, resolveImport, visited, ancestors, rootClassDeclaration, buildCtx);
|
|
15545
|
+
}
|
|
15546
|
+
}
|
|
15547
|
+
/**
|
|
15548
|
+
* Extracts Stencil member metadata for a single resolved ancestor - static
|
|
15549
|
+
* getter form, or decorator syntax run through a throwaway single-file
|
|
15550
|
+
* program so real `complexType` info is computed, falling back to the
|
|
15551
|
+
* type-blind `extractInheritedMetaFromClass` walk if that program fails.
|
|
15552
|
+
* @param ancestor the resolved ancestor to extract metadata from
|
|
15553
|
+
* @param cmpSourceFile the extending component's source file (re-anchor target)
|
|
15554
|
+
* @param resolveImport callback that resolves an import specifier to source code
|
|
15555
|
+
* @param config used to compute real `complexType` info via a mini `ts.Program`
|
|
15556
|
+
* @returns the ancestor's metadata
|
|
15557
|
+
*/
|
|
15558
|
+
function extractAncestorMeta(ancestor, cmpSourceFile, resolveImport, config) {
|
|
15559
|
+
const { classNode, sourceFile: parentSf, path: resolvedPath } = ancestor;
|
|
15560
|
+
const className = classNode.name?.text;
|
|
15561
|
+
const parentStaticMembers = classNode.members.filter(isStaticGetter);
|
|
15562
|
+
let resolvedClassNode = classNode;
|
|
15563
|
+
let resolvedStaticMembers = parentStaticMembers;
|
|
15564
|
+
let hasUsableStaticMembers = parentStaticMembers.some((m) => ts.isGetAccessorDeclaration(m) && ts.isIdentifier(m.name) && [
|
|
15565
|
+
"properties",
|
|
15566
|
+
"states",
|
|
15567
|
+
"events",
|
|
15568
|
+
"listeners",
|
|
15569
|
+
"watchers",
|
|
15570
|
+
"methods"
|
|
15571
|
+
].includes(m.name.text));
|
|
15572
|
+
if (!hasUsableStaticMembers && className) {
|
|
15573
|
+
const converted = convertInMemorySourceDecorators(parentSf, config);
|
|
15574
|
+
const convertedClass = converted && findClassWalk(converted, className);
|
|
15575
|
+
if (convertedClass) {
|
|
15576
|
+
resolvedClassNode = convertedClass;
|
|
15577
|
+
resolvedStaticMembers = convertedClass.members.filter(isStaticGetter);
|
|
15578
|
+
hasUsableStaticMembers = true;
|
|
15579
|
+
}
|
|
15580
|
+
}
|
|
15581
|
+
if (!hasUsableStaticMembers) return extractInheritedMetaFromClass(classNode);
|
|
15582
|
+
return {
|
|
15583
|
+
properties: reanchorInheritedTypeReferences(reclassifyGlobalTypeReferences(parseStaticProps(resolvedStaticMembers) ?? [], parentSf, resolvedPath, resolveImport), resolvedPath, cmpSourceFile.fileName),
|
|
15584
|
+
states: parseStaticStates(resolvedStaticMembers) ?? [],
|
|
15585
|
+
methods: reanchorInheritedTypeReferences(reclassifyGlobalTypeReferences(parseStaticMethods(resolvedStaticMembers) ?? [], parentSf, resolvedPath, resolveImport), resolvedPath, cmpSourceFile.fileName),
|
|
15586
|
+
events: reanchorInheritedTypeReferences(reclassifyGlobalTypeReferences(parseStaticEvents(resolvedStaticMembers) ?? [], parentSf, resolvedPath, resolveImport), resolvedPath, cmpSourceFile.fileName),
|
|
15587
|
+
listeners: parseStaticListeners(resolvedStaticMembers) ?? [],
|
|
15588
|
+
watchers: parseStaticWatchers(resolvedStaticMembers) ?? [],
|
|
15589
|
+
methodNames: resolvedClassNode.members.filter(ts.isMethodDeclaration).map((m) => ts.isIdentifier(m.name) ? m.name.text : "").filter(Boolean)
|
|
15590
|
+
};
|
|
15591
|
+
}
|
|
15592
|
+
/**
|
|
14940
15593
|
* Resolves the inheritance chain for a component using a caller-supplied
|
|
14941
|
-
* `resolveImport` callback instead of the full compiler infrastructure
|
|
14942
|
-
*
|
|
15594
|
+
* `resolveImport` callback instead of the full compiler infrastructure -
|
|
15595
|
+
* safe to call from `transpileSync`/`transpileAsync` (no TypeChecker needed).
|
|
15596
|
+
* Handles both a plain `extends Foo` and the mixin composition pattern
|
|
15597
|
+
* (`extends Mixin(A, B, ...)`).
|
|
14943
15598
|
*
|
|
14944
15599
|
* @param cmpNode the component's class declaration
|
|
14945
15600
|
* @param staticMembers static getter members already parsed from the component
|
|
14946
15601
|
* @param sourceFile the source file containing the component (for import resolution)
|
|
14947
15602
|
* @param resolveImport callback that resolves an import specifier to source code
|
|
15603
|
+
* @param config used to compute real `complexType` info for decorator-syntax
|
|
15604
|
+
* parent classes via a mini `ts.Program`
|
|
15605
|
+
* @param buildCtx used to surface a warning when an imported extends/mixin target can't be
|
|
15606
|
+
* found - optional so existing (non-diagnostic-checking) callers aren't forced to supply one
|
|
14948
15607
|
* @returns merged metadata including all inherited members
|
|
14949
15608
|
*/
|
|
14950
|
-
function mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, sourceFile, resolveImport) {
|
|
15609
|
+
function mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, sourceFile, resolveImport, config, buildCtx) {
|
|
14951
15610
|
let doesExtend = false;
|
|
14952
15611
|
let properties = parseStaticProps(staticMembers);
|
|
14953
15612
|
let states = parseStaticStates(staticMembers);
|
|
@@ -14958,42 +15617,10 @@ function mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, sourceF
|
|
|
14958
15617
|
let classMethods = cmpNode.members.filter(ts.isMethodDeclaration).map((m) => ts.isIdentifier(m.name) ? m.name.text : "").filter(Boolean);
|
|
14959
15618
|
const serializers = [];
|
|
14960
15619
|
const deserializers = [];
|
|
14961
|
-
|
|
14962
|
-
|
|
14963
|
-
|
|
14964
|
-
|
|
14965
|
-
while (true) {
|
|
14966
|
-
const parentClassName = getExtendsClassName(currentNode);
|
|
14967
|
-
if (!parentClassName) break;
|
|
14968
|
-
const specifier = findImportSpecifier(currentSf, parentClassName);
|
|
14969
|
-
if (!specifier) break;
|
|
14970
|
-
const resolved = resolveImport(specifier, currentPath);
|
|
14971
|
-
if (!resolved) break;
|
|
14972
|
-
const { code, path: resolvedPath } = resolved;
|
|
14973
|
-
if (visited.has(resolvedPath)) break;
|
|
14974
|
-
visited.add(resolvedPath);
|
|
14975
|
-
const isTs = resolvedPath.endsWith(".tsx") || resolvedPath.endsWith(".ts");
|
|
14976
|
-
const parentSf = ts.createSourceFile(resolvedPath, code, ts.ScriptTarget.ESNext, true, isTs ? ts.ScriptKind.TSX : ts.ScriptKind.JS);
|
|
14977
|
-
const parentClass = parentSf.statements.filter(ts.isClassDeclaration).find((c) => c.name?.text === parentClassName);
|
|
14978
|
-
if (!parentClass) break;
|
|
14979
|
-
const parentStaticMembers = parentClass.members.filter(isStaticGetter);
|
|
14980
|
-
const parentMeta = parentStaticMembers.some((m) => ts.isGetAccessorDeclaration(m) && ts.isIdentifier(m.name) && [
|
|
14981
|
-
"properties",
|
|
14982
|
-
"states",
|
|
14983
|
-
"events",
|
|
14984
|
-
"listeners",
|
|
14985
|
-
"watchers",
|
|
14986
|
-
"methods"
|
|
14987
|
-
].includes(m.name.text)) ? {
|
|
14988
|
-
properties: parseStaticProps(parentStaticMembers),
|
|
14989
|
-
states: parseStaticStates(parentStaticMembers),
|
|
14990
|
-
methods: parseStaticMethods(parentStaticMembers),
|
|
14991
|
-
events: parseStaticEvents(parentStaticMembers),
|
|
14992
|
-
listeners: parseStaticListeners(parentStaticMembers),
|
|
14993
|
-
watchers: parseStaticWatchers(parentStaticMembers),
|
|
14994
|
-
methodNames: parentClass.members.filter(ts.isMethodDeclaration).map((m) => ts.isIdentifier(m.name) ? m.name.text : "").filter(Boolean)
|
|
14995
|
-
} : extractInheritedMeta(code, parentClassName, resolvedPath);
|
|
14996
|
-
if (!parentMeta) break;
|
|
15620
|
+
const ancestors = [];
|
|
15621
|
+
resolveAncestors(cmpNode, sourceFile, sourceFile.fileName, resolveImport, /* @__PURE__ */ new Set(), ancestors, cmpNode, buildCtx);
|
|
15622
|
+
ancestors.forEach((ancestor) => {
|
|
15623
|
+
const parentMeta = extractAncestorMeta(ancestor, sourceFile, resolveImport, config);
|
|
14997
15624
|
doesExtend = true;
|
|
14998
15625
|
const mixinPropsExcludingStates = parentMeta.properties.filter((mp) => !states.some((s) => s.name === mp.name));
|
|
14999
15626
|
const mixinStatesExcludingProps = parentMeta.states.filter((ms) => !properties.some((p) => p.name === ms.name));
|
|
@@ -15004,10 +15631,7 @@ function mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, sourceF
|
|
|
15004
15631
|
listeners = [...deDupeMembers(parentMeta.listeners, listeners), ...listeners];
|
|
15005
15632
|
watchers = [...deDupeMembers(parentMeta.watchers, watchers), ...watchers];
|
|
15006
15633
|
classMethods = [...classMethods, ...parentMeta.methodNames];
|
|
15007
|
-
|
|
15008
|
-
currentSf = parentSf;
|
|
15009
|
-
currentPath = resolvedPath;
|
|
15010
|
-
}
|
|
15634
|
+
});
|
|
15011
15635
|
return {
|
|
15012
15636
|
doesExtend,
|
|
15013
15637
|
properties,
|
|
@@ -15125,9 +15749,7 @@ const parseStaticPatches = (encapsulation, staticMembers) => {
|
|
|
15125
15749
|
case "clone":
|
|
15126
15750
|
result.clone = true;
|
|
15127
15751
|
break;
|
|
15128
|
-
case "insert":
|
|
15129
|
-
result.insert = true;
|
|
15130
|
-
break;
|
|
15752
|
+
case "insert": result.insert = true;
|
|
15131
15753
|
}
|
|
15132
15754
|
return Object.keys(result).length > 0 ? result : null;
|
|
15133
15755
|
};
|
|
@@ -15291,8 +15913,9 @@ const parseStaticComponentMeta = (compilerCtx, typeChecker, cmpNode, moduleFile,
|
|
|
15291
15913
|
const staticMembers = cmpNode.members.filter(isStaticGetter);
|
|
15292
15914
|
const tagName = getComponentTagName(staticMembers);
|
|
15293
15915
|
if (tagName == null) return cmpNode;
|
|
15294
|
-
const { doesExtend, properties, states, methods, listeners, events, watchers, classMethods, serializers, deserializers } = transformOpts?.resolveImport ? mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, moduleFile.staticSourceFile, transformOpts.resolveImport) : mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, staticMembers, moduleFile);
|
|
15295
|
-
const
|
|
15916
|
+
const { doesExtend, properties, states, methods, listeners, events, watchers, classMethods, serializers, deserializers } = transformOpts?.resolveImport ? mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, moduleFile.staticSourceFile, transformOpts.resolveImport, buildCtx.config, buildCtx) : mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, staticMembers, moduleFile);
|
|
15917
|
+
const symbol = typeChecker ? typeChecker.getSymbolAtLocation(cmpNode.name) : void 0;
|
|
15918
|
+
const docs = serializeSymbol(typeChecker, symbol);
|
|
15296
15919
|
const isCollectionDependency = moduleFile.isCollectionDependency;
|
|
15297
15920
|
const encapsulation = parseStaticEncapsulation(staticMembers);
|
|
15298
15921
|
const cmp = {
|
|
@@ -15380,6 +16003,7 @@ const parseStaticComponentMeta = (compilerCtx, typeChecker, cmpNode, moduleFile,
|
|
|
15380
16003
|
htmlAttrNames: [],
|
|
15381
16004
|
htmlTagNames: [],
|
|
15382
16005
|
htmlParts: [],
|
|
16006
|
+
htmlSlots: [],
|
|
15383
16007
|
isUpdateable: false,
|
|
15384
16008
|
potentialCmpRefs: [],
|
|
15385
16009
|
dependents: [],
|
|
@@ -15402,9 +16026,11 @@ const parseStaticComponentMeta = (compilerCtx, typeChecker, cmpNode, moduleFile,
|
|
|
15402
16026
|
cmp.hasModernPropertyDecls = detectModernPropDeclarations(cmpNode) || doesExtend;
|
|
15403
16027
|
cmp.htmlAttrNames = unique(cmp.htmlAttrNames);
|
|
15404
16028
|
cmp.htmlTagNames = unique(cmp.htmlTagNames);
|
|
16029
|
+
cmp.htmlSlots = unique(cmp.htmlSlots);
|
|
15405
16030
|
cmp.hasSlot = cmp.hasSlot || cmp.htmlTagNames.includes("slot");
|
|
15406
16031
|
cmp.potentialCmpRefs = unique(cmp.potentialCmpRefs);
|
|
15407
16032
|
setComponentBuildConditionals(cmp);
|
|
16033
|
+
if (cmp.isPlain && cmpNode.heritageClauses?.some((c) => c.token === ts.SyntaxKind.ExtendsKeyword)) cmp.isPlain = false;
|
|
15408
16034
|
if (transformOpts && transformOpts.componentMetadata === "compilerstatic") cmpNode = addComponentMetaStatic(cmpNode, cmp);
|
|
15409
16035
|
const foundIndex = moduleFile.cmps.findIndex((c) => c.tagName === cmp.tagName && c.sourceFilePath === cmp.sourceFilePath);
|
|
15410
16036
|
if (foundIndex > -1) moduleFile.cmps[foundIndex] = cmp;
|
|
@@ -15412,22 +16038,32 @@ const parseStaticComponentMeta = (compilerCtx, typeChecker, cmpNode, moduleFile,
|
|
|
15412
16038
|
compilerCtx.nodeMap.set(cmpNode, cmp);
|
|
15413
16039
|
return cmpNode;
|
|
15414
16040
|
};
|
|
16041
|
+
/**
|
|
16042
|
+
* Check whether a class declaration is a Stencil component, i.e. it's
|
|
16043
|
+
* decorated with `@Component({ tag: ... })`.
|
|
16044
|
+
* @param classNode the class declaration to check
|
|
16045
|
+
* @returns whether `classNode` is a Stencil component class
|
|
16046
|
+
*/
|
|
16047
|
+
const isStencilComponentClass = (classNode) => {
|
|
16048
|
+
const decorator = ts.getDecorators(classNode)?.[0];
|
|
16049
|
+
return decorator != null && ts.isCallExpression(decorator.expression) && decorator.expression.arguments.length === 1 && ts.isObjectLiteralExpression(decorator.expression.arguments[0]) && decorator.expression.arguments[0].properties.some((prop) => ts.isPropertyAssignment(prop) && prop.name.getText() === "tag");
|
|
16050
|
+
};
|
|
15415
16051
|
const validateComponentMembers = (node, buildCtx) => {
|
|
15416
16052
|
/**
|
|
15417
16053
|
* validate if:
|
|
15418
16054
|
*/
|
|
15419
|
-
if (ts.isGetAccessorDeclaration(node) && ts.isIdentifier(node.name) && typeof node.name.escapedText === "string" && BLACKLISTED_COMPONENT_METHODS.includes(node.name.escapedText) && node.parent && ts.isClassDeclaration(node.parent)) {
|
|
16055
|
+
if (ts.isGetAccessorDeclaration(node) && ts.isIdentifier(node.name) && typeof node.name.escapedText === "string" && BLACKLISTED_COMPONENT_METHODS.includes(node.name.escapedText) && node.parent && ts.isClassDeclaration(node.parent) && isStencilComponentClass(node.parent)) {
|
|
15420
16056
|
const propName = node.name.escapedText;
|
|
15421
|
-
const
|
|
15422
|
-
|
|
15423
|
-
|
|
15424
|
-
|
|
15425
|
-
|
|
15426
|
-
|
|
15427
|
-
|
|
15428
|
-
|
|
15429
|
-
|
|
15430
|
-
|
|
16057
|
+
const componentName = node.parent.name.getText();
|
|
16058
|
+
const err = buildWarn(buildCtx.diagnostics);
|
|
16059
|
+
err.messageText = `The component "${componentName}" has a getter called "${propName}". This getter is reserved for use by Stencil components and should not be defined by the user.`;
|
|
16060
|
+
augmentDiagnosticWithNode(err, node);
|
|
16061
|
+
}
|
|
16062
|
+
if (ts.isMethodDeclaration(node) && ts.isIdentifier(node.name) && node.name.escapedText === "componentShouldUpdate" && node.parameters.length > 1 && node.parent && ts.isClassDeclaration(node.parent) && isStencilComponentClass(node.parent)) {
|
|
16063
|
+
const componentName = node.parent.name.getText();
|
|
16064
|
+
const err = buildWarn(buildCtx.diagnostics);
|
|
16065
|
+
err.messageText = `The component "${componentName}" defines "componentShouldUpdate" with ${node.parameters.length} parameters. As of Stencil v5, "componentShouldUpdate" is called once per render with a single "changes" argument (a map of prop/state names to "{ newVal, oldVal }") instead of once per prop with "(newVal, oldVal, propName)". This method will still compile, but any extra parameters will be "undefined" at runtime.`;
|
|
16066
|
+
augmentDiagnosticWithNode(err, node);
|
|
15431
16067
|
}
|
|
15432
16068
|
};
|
|
15433
16069
|
const parseVirtualProps = (docs) => {
|
|
@@ -15470,7 +16106,7 @@ const parseModuleImport = (config, compilerCtx, buildCtx, moduleFile, dirPath, i
|
|
|
15470
16106
|
importPath = normalizePath(importPath);
|
|
15471
16107
|
moduleFile.localImports.push(importPath);
|
|
15472
16108
|
} else if (importPath.startsWith(".")) {
|
|
15473
|
-
importPath = normalizePath(
|
|
16109
|
+
importPath = normalizePath(join$2(dirPath, importPath));
|
|
15474
16110
|
moduleFile.localImports.push(importPath);
|
|
15475
16111
|
} else addExternalImport(config, compilerCtx, buildCtx, moduleFile, moduleFile.sourceFilePath, importPath, resolveCollections, !importNode.importClause);
|
|
15476
16112
|
}
|
|
@@ -15536,7 +16172,8 @@ const updateModule = (config, compilerCtx, buildCtx, tsSourceFile, sourceFileTex
|
|
|
15536
16172
|
const prevModuleFile = getModule(compilerCtx, sourceFilePath);
|
|
15537
16173
|
if (prevModuleFile && prevModuleFile.staticSourceFileText === sourceFileText) return prevModuleFile;
|
|
15538
16174
|
const srcDirPath = dirname$1(sourceFilePath);
|
|
15539
|
-
|
|
16175
|
+
const emitFileName = basename$1(emitFilePath);
|
|
16176
|
+
emitFilePath = normalizePath(join$2(srcDirPath, emitFileName));
|
|
15540
16177
|
const moduleFile = createModule(tsSourceFile, sourceFileText, emitFilePath);
|
|
15541
16178
|
if (emitFilePath.endsWith(".js.map")) {
|
|
15542
16179
|
moduleFile.sourceMapPath = emitFilePath;
|
|
@@ -15588,15 +16225,18 @@ const updateModule = (config, compilerCtx, buildCtx, tsSourceFile, sourceFileTex
|
|
|
15588
16225
|
//#region src/compiler/transformers/collection/parse-collection-components.ts
|
|
15589
16226
|
const parseCollectionComponents = (config, compilerCtx, buildCtx, collectionDir, collectionManifest, collection) => {
|
|
15590
16227
|
if (collectionManifest.mixins) collectionManifest.mixins.forEach((mixinPath) => {
|
|
15591
|
-
|
|
16228
|
+
const fullPath = join$2(collectionDir, mixinPath);
|
|
16229
|
+
transpileCollectionModule(config, compilerCtx, buildCtx, collection, fullPath);
|
|
15592
16230
|
});
|
|
15593
16231
|
if (collectionManifest.entries) collectionManifest.entries.forEach((entryPath) => {
|
|
15594
|
-
|
|
16232
|
+
const componentPath = join$2(collectionDir, entryPath);
|
|
16233
|
+
transpileCollectionModule(config, compilerCtx, buildCtx, collection, componentPath);
|
|
15595
16234
|
});
|
|
15596
16235
|
};
|
|
15597
16236
|
const transpileCollectionModule = (config, compilerCtx, buildCtx, collection, inputFileName) => {
|
|
15598
16237
|
const sourceText = compilerCtx.fs.readFileSync(inputFileName);
|
|
15599
|
-
|
|
16238
|
+
const sourceFile = ts.createSourceFile(inputFileName, sourceText, ts.ScriptTarget.ES2017, true, ts.ScriptKind.JS);
|
|
16239
|
+
return updateModule(config, compilerCtx, buildCtx, sourceFile, sourceText, inputFileName, void 0, collection);
|
|
15600
16240
|
};
|
|
15601
16241
|
//#endregion
|
|
15602
16242
|
//#region src/compiler/transformers/collection/parse-collection-manifest.ts
|
|
@@ -15626,7 +16266,8 @@ const parseCollectionDependencies = (collectionManifest) => {
|
|
|
15626
16266
|
};
|
|
15627
16267
|
const parseGlobal = (config, compilerCtx, buildCtx, collectionDir, collectionManifest, collection) => {
|
|
15628
16268
|
if (typeof collectionManifest.global !== "string") return;
|
|
15629
|
-
|
|
16269
|
+
const sourceFilePath = normalizePath(join$2(collectionDir, collectionManifest.global));
|
|
16270
|
+
collection.global = transpileCollectionModule(config, compilerCtx, buildCtx, collection, sourceFilePath);
|
|
15630
16271
|
};
|
|
15631
16272
|
const parseBundles = (collectionManifest) => {
|
|
15632
16273
|
if (invalidArrayData(collectionManifest.bundles)) return [];
|
|
@@ -15644,12 +16285,14 @@ const parseCollection = (config, compilerCtx, buildCtx, moduleId, pkgJsonFilePat
|
|
|
15644
16285
|
let collection = compilerCtx.collections.find((c) => c.collectionName === collectionName);
|
|
15645
16286
|
if (collection != null) return collection;
|
|
15646
16287
|
const collectionPackageRootDir = dirname$1(pkgJsonFilePath);
|
|
15647
|
-
const
|
|
16288
|
+
const collectionManifestPath = pkgData.collection ?? pkgData.collection;
|
|
16289
|
+
const collectionFilePath = join$2(collectionPackageRootDir, collectionManifestPath);
|
|
15648
16290
|
const relPath = relative$1(config.rootDir, collectionFilePath);
|
|
15649
16291
|
config.logger.debug(`load collection: ${collectionName}, ${relPath}`);
|
|
15650
16292
|
const collectionJsonStr = compilerCtx.fs.readFileSync(collectionFilePath);
|
|
15651
16293
|
if (!collectionJsonStr) return null;
|
|
15652
|
-
|
|
16294
|
+
const collectionDir = normalizePath(dirname$1(collectionFilePath));
|
|
16295
|
+
collection = parseCollectionManifest(config, compilerCtx, buildCtx, collectionName, collectionDir, collectionJsonStr);
|
|
15653
16296
|
collection.moduleId = moduleId;
|
|
15654
16297
|
if (pkgData.module && pkgData.module !== pkgData.main) collection.hasExports = true;
|
|
15655
16298
|
collection.moduleDir = collectionPackageRootDir;
|
|
@@ -15693,7 +16336,8 @@ const resolveAndIngestCollection = (config, compilerCtx, buildCtx, containingFil
|
|
|
15693
16336
|
})) return;
|
|
15694
16337
|
buildCtx.collections.push(collection);
|
|
15695
16338
|
if (Array.isArray(collection.dependencies)) collection.dependencies.forEach((dependencyModuleId) => {
|
|
15696
|
-
|
|
16339
|
+
const resolveFromDir = dirname$1(pkgJsonFilePath);
|
|
16340
|
+
resolveAndIngestCollection(config, compilerCtx, buildCtx, resolveFromDir, dependencyModuleId, resolveCollections);
|
|
15697
16341
|
});
|
|
15698
16342
|
};
|
|
15699
16343
|
/**
|
|
@@ -16019,6 +16663,18 @@ const validateUniqueTagNames = (config, buildCtx, cmp) => {
|
|
|
16019
16663
|
//#endregion
|
|
16020
16664
|
//#region src/compiler/transpile/run-program.ts
|
|
16021
16665
|
/**
|
|
16666
|
+
* In dev mode, downgrade unused-variable diagnostics to warnings so they don't fail the build
|
|
16667
|
+
* while a component is mid-edit.
|
|
16668
|
+
*
|
|
16669
|
+
* @param config - the validated Stencil configuration
|
|
16670
|
+
* @param diags - the diagnostics to relax in place
|
|
16671
|
+
*/
|
|
16672
|
+
const applyDevModeRelaxation = (config, diags) => {
|
|
16673
|
+
if (config.devMode) diags.forEach((diag) => {
|
|
16674
|
+
if (diag.code === "6133" || diag.code === "6192") diag.level = "warn";
|
|
16675
|
+
});
|
|
16676
|
+
};
|
|
16677
|
+
/**
|
|
16022
16678
|
* Run the TypeScript program to transpile source files.
|
|
16023
16679
|
*
|
|
16024
16680
|
* @param config - the validated Stencil configuration
|
|
@@ -16039,6 +16695,21 @@ const runTsProgram = async (config, compilerCtx, buildCtx, tsBuilder) => {
|
|
|
16039
16695
|
const tsTypeChecker = tsProgram.getTypeChecker();
|
|
16040
16696
|
const typesOutputTarget = config.outputTargets.filter(isOutputTargetTypes);
|
|
16041
16697
|
const emittedDts = [];
|
|
16698
|
+
if (buildCtx.isRebuild && buildCtx.hasScriptChanges && config.validateTypes) {
|
|
16699
|
+
const emitBuilder = tsBuilder;
|
|
16700
|
+
let affected = emitBuilder.getSemanticDiagnosticsOfNextAffectedFile?.();
|
|
16701
|
+
while (affected) {
|
|
16702
|
+
if ("fileName" in affected.affected) {
|
|
16703
|
+
const fileName = normalizePath(affected.affected.fileName);
|
|
16704
|
+
if (!fileName.includes("node_modules") && !fileName.endsWith(".d.ts") && fileName.startsWith(normalizePath(config.srcDir))) {
|
|
16705
|
+
const tsSemantic = loadTypeScriptDiagnostics(affected.result);
|
|
16706
|
+
applyDevModeRelaxation(config, tsSemantic);
|
|
16707
|
+
buildCtx.diagnostics.push(...tsSemantic);
|
|
16708
|
+
}
|
|
16709
|
+
}
|
|
16710
|
+
affected = emitBuilder.getSemanticDiagnosticsOfNextAffectedFile?.();
|
|
16711
|
+
}
|
|
16712
|
+
}
|
|
16042
16713
|
const emitCallback = (emitFilePath, data, _w, _e, tsSourceFiles) => {
|
|
16043
16714
|
if (emitFilePath.includes("e2e.") || emitFilePath.includes("spec.") || emitFilePath.endsWith("e2e.d.ts") || emitFilePath.endsWith("spec.d.ts")) return;
|
|
16044
16715
|
if (emitFilePath.endsWith(".js") || emitFilePath.endsWith("js.map")) updateModule(config, compilerCtx, buildCtx, tsSourceFiles[0], data, emitFilePath, tsTypeChecker, null);
|
|
@@ -16087,7 +16758,8 @@ const runTsProgram = async (config, compilerCtx, buildCtx, tsBuilder) => {
|
|
|
16087
16758
|
const changedmodules = Array.from(compilerCtx.changedModules.keys());
|
|
16088
16759
|
buildCtx.debug("Transpiled modules: " + JSON.stringify(changedmodules, null, "\n"));
|
|
16089
16760
|
buildCtx.moduleFiles = Array.from(compilerCtx.moduleMap.values());
|
|
16090
|
-
const
|
|
16761
|
+
const allComponents = getComponentsFromModules(buildCtx.moduleFiles);
|
|
16762
|
+
const { components: filteredComponents, excludedComponents } = filterExcludedComponents(allComponents, config);
|
|
16091
16763
|
buildCtx.components = filteredComponents;
|
|
16092
16764
|
if (excludedComponents.length > 0 && typesOutputTarget.length > 0) excludedComponents.forEach((cmp) => {
|
|
16093
16765
|
const srcPath = normalizePath(cmp.sourceFilePath);
|
|
@@ -16126,36 +16798,15 @@ const validateTypesAfterGeneration = async (config, compilerCtx, buildCtx, tsBui
|
|
|
16126
16798
|
needsRebuild: true
|
|
16127
16799
|
};
|
|
16128
16800
|
}
|
|
16129
|
-
if (config.validateTypes) {
|
|
16130
|
-
const
|
|
16131
|
-
|
|
16132
|
-
|
|
16133
|
-
|
|
16134
|
-
|
|
16135
|
-
|
|
16136
|
-
|
|
16137
|
-
|
|
16138
|
-
while (affected) {
|
|
16139
|
-
if ("fileName" in affected.affected) {
|
|
16140
|
-
const fileName = normalizePath(affected.affected.fileName);
|
|
16141
|
-
if (!fileName.includes("node_modules") && !fileName.endsWith(".d.ts") && fileName.startsWith(normalizePath(config.srcDir))) {
|
|
16142
|
-
const tsSemantic = loadTypeScriptDiagnostics(affected.result);
|
|
16143
|
-
applyDevModeRelaxation(tsSemantic);
|
|
16144
|
-
buildCtx.diagnostics.push(...tsSemantic);
|
|
16145
|
-
}
|
|
16146
|
-
}
|
|
16147
|
-
affected = emitBuilder.getSemanticDiagnosticsOfNextAffectedFile?.();
|
|
16148
|
-
}
|
|
16149
|
-
} else {
|
|
16150
|
-
const sourceFiles = tsProgram.getSourceFiles().filter((sf) => {
|
|
16151
|
-
const fileName = normalizePath(sf.fileName);
|
|
16152
|
-
return !fileName.includes("node_modules") && !fileName.endsWith(".d.ts") && fileName.startsWith(normalizePath(config.srcDir));
|
|
16153
|
-
});
|
|
16154
|
-
for (const sourceFile of sourceFiles) {
|
|
16155
|
-
const tsSemantic = loadTypeScriptDiagnostics(tsProgram.getSemanticDiagnostics(sourceFile));
|
|
16156
|
-
applyDevModeRelaxation(tsSemantic);
|
|
16157
|
-
buildCtx.diagnostics.push(...tsSemantic);
|
|
16158
|
-
}
|
|
16801
|
+
if (config.validateTypes && !buildCtx.isRebuild) {
|
|
16802
|
+
const sourceFiles = tsProgram.getSourceFiles().filter((sf) => {
|
|
16803
|
+
const fileName = normalizePath(sf.fileName);
|
|
16804
|
+
return !fileName.includes("node_modules") && !fileName.endsWith(".d.ts") && fileName.startsWith(normalizePath(config.srcDir));
|
|
16805
|
+
});
|
|
16806
|
+
for (const sourceFile of sourceFiles) {
|
|
16807
|
+
const tsSemantic = loadTypeScriptDiagnostics(tsProgram.getSemanticDiagnostics(sourceFile));
|
|
16808
|
+
applyDevModeRelaxation(config, tsSemantic);
|
|
16809
|
+
buildCtx.diagnostics.push(...tsSemantic);
|
|
16159
16810
|
}
|
|
16160
16811
|
}
|
|
16161
16812
|
const hasTypesChanged = await generateAppTypes(config, compilerCtx, buildCtx, "src");
|
|
@@ -16263,7 +16914,10 @@ const getComponentsUpdated = (compilerCtx, buildCtx) => {
|
|
|
16263
16914
|
const changedScriptFiles = [];
|
|
16264
16915
|
const checkedFiles = /* @__PURE__ */ new Set();
|
|
16265
16916
|
const allModuleFiles = buildCtx.moduleFiles.filter((m) => m.localImports && m.localImports.length > 0);
|
|
16266
|
-
while (filesToLookForImporters.length > 0)
|
|
16917
|
+
while (filesToLookForImporters.length > 0) {
|
|
16918
|
+
const scriptFile = filesToLookForImporters.shift();
|
|
16919
|
+
addTsFileImporters(allModuleFiles, filesToLookForImporters, checkedFiles, changedScriptFiles, scriptFile);
|
|
16920
|
+
}
|
|
16267
16921
|
const tags = changedScriptFiles.reduce((acc, changedTsFile) => {
|
|
16268
16922
|
const moduleFile = compilerCtx.moduleMap.get(changedTsFile);
|
|
16269
16923
|
if (moduleFile != null) moduleFile.cmps.forEach((cmp) => {
|
|
@@ -16448,43 +17102,47 @@ function generateBuildStats(config, buildCtx) {
|
|
|
16448
17102
|
const buildResults = buildCtx.buildResults;
|
|
16449
17103
|
try {
|
|
16450
17104
|
if (buildResults.hasError) return err({ diagnostics: buildResults.diagnostics });
|
|
16451
|
-
else
|
|
16452
|
-
|
|
16453
|
-
|
|
16454
|
-
|
|
16455
|
-
|
|
16456
|
-
|
|
16457
|
-
|
|
16458
|
-
|
|
16459
|
-
|
|
16460
|
-
|
|
16461
|
-
|
|
16462
|
-
|
|
16463
|
-
|
|
16464
|
-
|
|
16465
|
-
|
|
16466
|
-
|
|
16467
|
-
|
|
16468
|
-
|
|
16469
|
-
|
|
16470
|
-
|
|
16471
|
-
|
|
16472
|
-
|
|
16473
|
-
|
|
16474
|
-
|
|
16475
|
-
|
|
16476
|
-
|
|
16477
|
-
|
|
16478
|
-
|
|
16479
|
-
|
|
16480
|
-
|
|
17105
|
+
else {
|
|
17106
|
+
const stats = {
|
|
17107
|
+
timestamp: buildResults.timestamp,
|
|
17108
|
+
compiler: {
|
|
17109
|
+
name: config.sys.name,
|
|
17110
|
+
version: config.sys.version
|
|
17111
|
+
},
|
|
17112
|
+
app: {
|
|
17113
|
+
namespace: config.namespace,
|
|
17114
|
+
fsNamespace: config.fsNamespace,
|
|
17115
|
+
components: Object.keys(buildResults.componentGraph ?? {}).length,
|
|
17116
|
+
entries: Object.keys(buildResults.componentGraph ?? {}).length,
|
|
17117
|
+
bundles: buildResults.outputs.reduce((total, en) => total + en.files.length, 0),
|
|
17118
|
+
outputs: getAppOutputs(config, buildResults)
|
|
17119
|
+
},
|
|
17120
|
+
options: {
|
|
17121
|
+
minifyJs: !!config.minifyJs,
|
|
17122
|
+
minifyCss: !!config.minifyCss
|
|
17123
|
+
},
|
|
17124
|
+
formats: {
|
|
17125
|
+
esmBrowser: sanitizeBundlesForStats(buildCtx.esmBrowserComponentBundle),
|
|
17126
|
+
esm: sanitizeBundlesForStats(buildCtx.esmComponentBundle),
|
|
17127
|
+
commonjs: sanitizeBundlesForStats(buildCtx.commonJsComponentBundle)
|
|
17128
|
+
},
|
|
17129
|
+
components: getComponentsFileMap(config, buildCtx),
|
|
17130
|
+
entries: buildCtx.entryModules,
|
|
17131
|
+
componentGraph: buildResults.componentGraph ?? {},
|
|
17132
|
+
sourceGraph: getSourceGraph(config, buildCtx),
|
|
17133
|
+
rolldownResults: buildCtx.rolldownResults ?? { modules: [] },
|
|
17134
|
+
collections: getCollections(config, buildCtx)
|
|
17135
|
+
};
|
|
17136
|
+
return ok(stats);
|
|
17137
|
+
}
|
|
16481
17138
|
} catch (e) {
|
|
16482
|
-
|
|
17139
|
+
const diagnostic = {
|
|
16483
17140
|
level: `error`,
|
|
16484
17141
|
lines: [],
|
|
16485
17142
|
messageText: `Generate Build Stats Error: ` + e,
|
|
16486
17143
|
type: `build`
|
|
16487
|
-
}
|
|
17144
|
+
};
|
|
17145
|
+
return err({ diagnostics: [diagnostic] });
|
|
16488
17146
|
}
|
|
16489
17147
|
}
|
|
16490
17148
|
/**
|
|
@@ -16660,10 +17318,13 @@ const buildDone = async (config, compilerCtx, buildCtx, aborted) => {
|
|
|
16660
17318
|
*/
|
|
16661
17319
|
const logHmr = (logger, hmr) => {
|
|
16662
17320
|
if (hmr.componentsUpdated) cleanupUpdateMsg(logger, `updated component`, hmr.componentsUpdated);
|
|
16663
|
-
if (hmr.inlineStylesUpdated)
|
|
16664
|
-
|
|
16665
|
-
|
|
16666
|
-
|
|
17321
|
+
if (hmr.inlineStylesUpdated) {
|
|
17322
|
+
const inlineStyles = hmr.inlineStylesUpdated.map((s) => s.styleTag).reduce((arr, v) => {
|
|
17323
|
+
if (!arr.includes(v)) arr.push(v);
|
|
17324
|
+
return arr;
|
|
17325
|
+
}, []);
|
|
17326
|
+
cleanupUpdateMsg(logger, `updated style`, inlineStyles);
|
|
17327
|
+
}
|
|
16667
17328
|
if (hmr.externalStylesUpdated) cleanupUpdateMsg(logger, `updated stylesheet`, hmr.externalStylesUpdated);
|
|
16668
17329
|
if (hmr.imagesUpdated) cleanupUpdateMsg(logger, `updated image`, hmr.imagesUpdated);
|
|
16669
17330
|
};
|
|
@@ -16760,7 +17421,7 @@ const getPackageJsonRecommendations = (config, compilerCtx) => {
|
|
|
16760
17421
|
* @returns an empty Promise
|
|
16761
17422
|
*/
|
|
16762
17423
|
const validateBuildPackageJson = async (config, compilerCtx, buildCtx) => {
|
|
16763
|
-
if (config.watch || buildCtx.packageJson == null) return;
|
|
17424
|
+
if (config.watch || config.devMode || buildCtx.packageJson == null) return;
|
|
16764
17425
|
validatePackageJson(config, compilerCtx, buildCtx);
|
|
16765
17426
|
const stencilCollectionOutputTargets = config.outputTargets.filter(isOutputTargetCollection);
|
|
16766
17427
|
await Promise.all(stencilCollectionOutputTargets.map((stencilCollectionOT) => validateCollectionFields(config, compilerCtx, buildCtx, stencilCollectionOT)));
|
|
@@ -16900,26 +17561,30 @@ const validateCollectionFields = async (config, compilerCtx, buildCtx, outputTar
|
|
|
16900
17561
|
* @param outputTarget the collection output target to validate against
|
|
16901
17562
|
*/
|
|
16902
17563
|
const validatePackageFiles = async (config, compilerCtx, buildCtx, outputTarget) => {
|
|
16903
|
-
if (!
|
|
16904
|
-
|
|
16905
|
-
|
|
16906
|
-
|
|
16907
|
-
|
|
16908
|
-
|
|
16909
|
-
|
|
16910
|
-
|
|
16911
|
-
|
|
16912
|
-
|
|
16913
|
-
|
|
16914
|
-
|
|
16915
|
-
|
|
16916
|
-
await Promise.all(buildCtx.packageJson.files.map(async (pkgFile) => {
|
|
16917
|
-
if (!isGlob(pkgFile)) {
|
|
16918
|
-
const absPath = join$2(dirname$1(config.packageJsonFilePath), pkgFile);
|
|
16919
|
-
if (!await compilerCtx.fs.access(absPath)) packageJsonError(config, compilerCtx, buildCtx, `Unable to find "${pkgFile}" within the package.json "files" array.`, `"${pkgFile}"`);
|
|
16920
|
-
}
|
|
16921
|
-
}));
|
|
17564
|
+
if (!Array.isArray(buildCtx.packageJson.files)) return;
|
|
17565
|
+
const actualDistDir = normalizePath(relative$1(config.rootDir, outputTarget.dir));
|
|
17566
|
+
if (!buildCtx.packageJson.files.some((userPath) => {
|
|
17567
|
+
const normalizedUserPath = normalizePath(userPath).replace(/\/$/, "").replace(/^\.\//, "");
|
|
17568
|
+
const normalizedDistDir = actualDistDir.replace(/\/$/, "").replace(/^\.\//, "");
|
|
17569
|
+
if (normalizedUserPath === normalizedDistDir) return true;
|
|
17570
|
+
const userPathWithSlash = normalizedUserPath + "/";
|
|
17571
|
+
if (normalizedDistDir.startsWith(userPathWithSlash)) return true;
|
|
17572
|
+
return false;
|
|
17573
|
+
})) {
|
|
17574
|
+
const msg = `package.json "files" array must contain the distribution directory "${actualDistDir}/" when generating a distribution.`;
|
|
17575
|
+
packageJsonWarn(config, compilerCtx, buildCtx, msg, `"files"`);
|
|
17576
|
+
return;
|
|
16922
17577
|
}
|
|
17578
|
+
await Promise.all(buildCtx.packageJson.files.map(async (pkgFile) => {
|
|
17579
|
+
if (!isGlob(pkgFile)) {
|
|
17580
|
+
const packageJsonDir = dirname$1(config.packageJsonFilePath);
|
|
17581
|
+
const absPath = join$2(packageJsonDir, pkgFile);
|
|
17582
|
+
if (!await compilerCtx.fs.access(absPath)) {
|
|
17583
|
+
const msg = `Unable to find "${pkgFile}" within the package.json "files" array.`;
|
|
17584
|
+
packageJsonError(config, compilerCtx, buildCtx, msg, `"${pkgFile}"`);
|
|
17585
|
+
}
|
|
17586
|
+
}
|
|
17587
|
+
}));
|
|
16923
17588
|
};
|
|
16924
17589
|
/**
|
|
16925
17590
|
* Check that the `collection` field is set correctly in `package.json` for the
|
|
@@ -16932,7 +17597,10 @@ const validatePackageFiles = async (config, compilerCtx, buildCtx, outputTarget)
|
|
|
16932
17597
|
const validateCollectionField = (config, compilerCtx, buildCtx, outputTarget) => {
|
|
16933
17598
|
if (outputTarget.dir) {
|
|
16934
17599
|
const collectionRel = normalizePath(join$2(relative$1(config.rootDir, outputTarget.dir), COLLECTION_MANIFEST_FILE_NAME), false);
|
|
16935
|
-
if (!buildCtx.packageJson.collection || normalizePath(buildCtx.packageJson.collection, false) !== collectionRel)
|
|
17600
|
+
if (!buildCtx.packageJson.collection || normalizePath(buildCtx.packageJson.collection, false) !== collectionRel) {
|
|
17601
|
+
const msg = `package.json "collection" property should be set to ${collectionRel} when generating a distribution bundle.`;
|
|
17602
|
+
packageJsonWarn(config, compilerCtx, buildCtx, msg, `"collection"`);
|
|
17603
|
+
}
|
|
16936
17604
|
}
|
|
16937
17605
|
};
|
|
16938
17606
|
/**
|
|
@@ -16976,7 +17644,8 @@ const validateManifestJson = (config, compilerCtx, buildCtx) => {
|
|
|
16976
17644
|
try {
|
|
16977
17645
|
const manifestContent = await compilerCtx.fs.readFile(manifestFilePath);
|
|
16978
17646
|
if (manifestContent) try {
|
|
16979
|
-
|
|
17647
|
+
const manifestData = JSON.parse(manifestContent);
|
|
17648
|
+
await validateManifestJsonData(compilerCtx, buildCtx, manifestFilePath, manifestData);
|
|
16980
17649
|
} catch (e) {
|
|
16981
17650
|
const err = buildError(buildCtx.diagnostics);
|
|
16982
17651
|
err.header = `Invalid manifest.json: ${e}`;
|
|
@@ -16997,7 +17666,8 @@ const validateManifestJsonIcon = async (compilerCtx, buildCtx, manifestFilePath,
|
|
|
16997
17666
|
return;
|
|
16998
17667
|
}
|
|
16999
17668
|
if (iconSrc.startsWith("/")) iconSrc = iconSrc.slice(1);
|
|
17000
|
-
const
|
|
17669
|
+
const manifestDir = dirname$1(manifestFilePath);
|
|
17670
|
+
const iconPath = join$2(manifestDir, iconSrc);
|
|
17001
17671
|
if (!await compilerCtx.fs.access(iconPath)) {
|
|
17002
17672
|
const msg = `Unable to find manifest icon "${manifestIcon.src}"`;
|
|
17003
17673
|
buildJsonFileError(compilerCtx, buildCtx.diagnostics, manifestFilePath, msg, `"${manifestIcon.src}"`);
|
|
@@ -17059,11 +17729,18 @@ const generateRootExport = (config, buildCtx, loaderBundle, standalone, types) =
|
|
|
17059
17729
|
if (!(currentImport && isValidRootExport(config, currentImport, loaderBundle, standalone))) {
|
|
17060
17730
|
const primaryDir = loaderBundle?.dir ?? standalone?.dir;
|
|
17061
17731
|
if (primaryDir) {
|
|
17062
|
-
|
|
17063
|
-
|
|
17732
|
+
const importPath = normalizePath(relative$1(config.rootDir, join$2(primaryDir, "index.js")));
|
|
17733
|
+
execSync(`npm pkg set "exports[.][import]"="${importPath}"`);
|
|
17734
|
+
if (loaderBundle?.cjs) {
|
|
17735
|
+
const requirePath = normalizePath(relative$1(config.rootDir, join$2(loaderBundle.dir, "index.cjs")));
|
|
17736
|
+
execSync(`npm pkg set "exports[.][require]"="${requirePath}"`);
|
|
17737
|
+
}
|
|
17064
17738
|
}
|
|
17065
17739
|
}
|
|
17066
|
-
if (types?.dir)
|
|
17740
|
+
if (types?.dir) {
|
|
17741
|
+
const typesPath = normalizePath(relative$1(config.rootDir, join$2(types.dir, "index.d.ts")));
|
|
17742
|
+
execSync(`npm pkg set "exports[.][types]"="${typesPath}"`);
|
|
17743
|
+
}
|
|
17067
17744
|
};
|
|
17068
17745
|
/**
|
|
17069
17746
|
* Check if the current root export import path is valid
|
|
@@ -17108,12 +17785,17 @@ const ensureRelativePrefix = (path) => {
|
|
|
17108
17785
|
*/
|
|
17109
17786
|
const generateLoaderExport = (config, loaderBundle, types) => {
|
|
17110
17787
|
const esmDir = join$2(loaderBundle.dir, "esm");
|
|
17111
|
-
|
|
17788
|
+
const esmLoaderPath = ensureRelativePrefix(normalizePath(relative$1(config.rootDir, join$2(esmDir, "loader.js"))));
|
|
17789
|
+
execSync(`npm pkg set "exports[./loader][import]"="${esmLoaderPath}"`);
|
|
17112
17790
|
if (loaderBundle.cjs) {
|
|
17113
17791
|
const cjsDir = join$2(loaderBundle.dir, "cjs");
|
|
17114
|
-
|
|
17792
|
+
const cjsLoaderPath = ensureRelativePrefix(normalizePath(relative$1(config.rootDir, join$2(cjsDir, "loader.cjs"))));
|
|
17793
|
+
execSync(`npm pkg set "exports[./loader][require]"="${cjsLoaderPath}"`);
|
|
17794
|
+
}
|
|
17795
|
+
if (types?.dir) {
|
|
17796
|
+
const typesPath = ensureRelativePrefix(normalizePath(relative$1(config.rootDir, join$2(types.dir, "loader.d.ts"))));
|
|
17797
|
+
execSync(`npm pkg set "exports[./loader][types]"="${typesPath}"`);
|
|
17115
17798
|
}
|
|
17116
|
-
if (types?.dir) execSync(`npm pkg set "exports[./loader][types]"="${ensureRelativePrefix(normalizePath(relative$1(config.rootDir, join$2(types.dir, "loader.d.ts"))))}"`);
|
|
17117
17799
|
};
|
|
17118
17800
|
/**
|
|
17119
17801
|
* Generate per-component exports for standalone output.
|
|
@@ -17307,8 +17989,10 @@ const compilerRequest = async (config, compilerCtx, data) => {
|
|
|
17307
17989
|
return results;
|
|
17308
17990
|
}
|
|
17309
17991
|
} catch (e) {
|
|
17310
|
-
if (e)
|
|
17311
|
-
|
|
17992
|
+
if (e) {
|
|
17993
|
+
if (e instanceof Error && e.stack) results.content = `/*\n${e.stack}\n*/`;
|
|
17994
|
+
else results.content = `/*\n${e}\n*/`;
|
|
17995
|
+
}
|
|
17312
17996
|
results.status = 500;
|
|
17313
17997
|
}
|
|
17314
17998
|
return results;
|
|
@@ -17725,7 +18409,8 @@ const createWatchBuild = async (config, compilerCtx) => {
|
|
|
17725
18409
|
filesAdded.forEach((f) => currentlyBuildingFiles.add(f));
|
|
17726
18410
|
filesUpdated.forEach((f) => currentlyBuildingFiles.add(f));
|
|
17727
18411
|
filesDeleted.forEach((f) => currentlyBuildingFiles.add(f));
|
|
17728
|
-
|
|
18412
|
+
const tsBuilder = incrementalCompiler.rebuild();
|
|
18413
|
+
await onBuild(tsBuilder);
|
|
17729
18414
|
} finally {
|
|
17730
18415
|
currentlyBuildingFiles.clear();
|
|
17731
18416
|
isBuilding = false;
|
|
@@ -17765,7 +18450,7 @@ const createWatchBuild = async (config, compilerCtx) => {
|
|
|
17765
18450
|
if (!compilerCtx.fs.accessSync(key)) compilerCtx.moduleMap.delete(key);
|
|
17766
18451
|
}
|
|
17767
18452
|
});
|
|
17768
|
-
new Set([...filesUpdated, ...filesAdded]).forEach((filePath) => {
|
|
18453
|
+
(/* @__PURE__ */ new Set([...filesUpdated, ...filesAdded])).forEach((filePath) => {
|
|
17769
18454
|
compilerCtx.addWatchFile(filePath);
|
|
17770
18455
|
});
|
|
17771
18456
|
dirsAdded.clear();
|
|
@@ -17778,7 +18463,8 @@ const createWatchBuild = async (config, compilerCtx) => {
|
|
|
17778
18463
|
const result = await build(config, compilerCtx, buildCtx, tsBuilder);
|
|
17779
18464
|
if (result === null) {
|
|
17780
18465
|
incrementalCompiler.refreshRootNames();
|
|
17781
|
-
|
|
18466
|
+
const freshTsBuilder = incrementalCompiler.rebuild();
|
|
18467
|
+
await onBuild(freshTsBuilder);
|
|
17782
18468
|
return;
|
|
17783
18469
|
}
|
|
17784
18470
|
if (!result.hasError) isRebuild = true;
|
|
@@ -17806,7 +18492,8 @@ const createWatchBuild = async (config, compilerCtx) => {
|
|
|
17806
18492
|
...(config.watchExternalDirs || []).map((dir) => watchFiles(compilerCtx, dir))
|
|
17807
18493
|
]);
|
|
17808
18494
|
incrementalCompiler = new IncrementalCompiler(config);
|
|
17809
|
-
|
|
18495
|
+
const tsBuilder = incrementalCompiler.rebuild();
|
|
18496
|
+
await onBuild(tsBuilder);
|
|
17810
18497
|
return watchWaiter;
|
|
17811
18498
|
};
|
|
17812
18499
|
/**
|
|
@@ -17849,9 +18536,7 @@ const createWatchBuild = async (config, compilerCtx) => {
|
|
|
17849
18536
|
case "fileUpdate":
|
|
17850
18537
|
filesUpdated.add(filePath);
|
|
17851
18538
|
break;
|
|
17852
|
-
case "fileDelete":
|
|
17853
|
-
filesDeleted.add(filePath);
|
|
17854
|
-
break;
|
|
18539
|
+
case "fileDelete": filesDeleted.add(filePath);
|
|
17855
18540
|
}
|
|
17856
18541
|
if (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) tsFilesToInvalidate.add(filePath);
|
|
17857
18542
|
config.logger.debug(`WATCH_BUILD::fs_event_change - type=${eventKind}, path=${filePath}, time=${(/* @__PURE__ */ new Date()).getTime()}`);
|
|
@@ -18116,7 +18801,7 @@ var Cache = class {
|
|
|
18116
18801
|
}
|
|
18117
18802
|
};
|
|
18118
18803
|
const MAX_FAILED = 100;
|
|
18119
|
-
const ONE_DAY =
|
|
18804
|
+
const ONE_DAY = 864e5;
|
|
18120
18805
|
const ONE_WEEK = ONE_DAY * 7;
|
|
18121
18806
|
const EXP_STORAGE_KEY = `last_clear_expired_cache`;
|
|
18122
18807
|
const CACHE_DIR_README = `# Stencil Cache Directory
|
|
@@ -18275,6 +18960,9 @@ const validateDocs$1 = (config, diagnostics, userOutputs) => {
|
|
|
18275
18960
|
userOutputs.filter(isOutputTargetDocsCustomElementsManifest).forEach((cemOutput) => {
|
|
18276
18961
|
docsOutputs.push(validateCustomElementsManifestOutputTarget(config, cemOutput));
|
|
18277
18962
|
});
|
|
18963
|
+
userOutputs.filter(isOutputTargetDocsAgentSkill).forEach((agentSkillOutput) => {
|
|
18964
|
+
docsOutputs.push(validateAgentSkillOutputTarget(config, agentSkillOutput));
|
|
18965
|
+
});
|
|
18278
18966
|
return docsOutputs;
|
|
18279
18967
|
};
|
|
18280
18968
|
const validateReadmeOutputTarget = (config, outputTarget) => {
|
|
@@ -18314,6 +19002,13 @@ const validateVScodeDocsOutputTarget = (config, diagnostics, outputTarget) => {
|
|
|
18314
19002
|
if (!isBoolean$1(outputTarget.skipInDev)) outputTarget.skipInDev = !config._docsFlag;
|
|
18315
19003
|
return outputTarget;
|
|
18316
19004
|
};
|
|
19005
|
+
const DEFAULT_AGENT_SKILL_DIR = "dist/skill";
|
|
19006
|
+
const validateAgentSkillOutputTarget = (config, outputTarget) => {
|
|
19007
|
+
outputTarget.dir = getAbsolutePath(config, outputTarget.dir || DEFAULT_AGENT_SKILL_DIR);
|
|
19008
|
+
outputTarget.name = toSkillName(outputTarget.name || config.fsNamespace);
|
|
19009
|
+
if (!isBoolean$1(outputTarget.skipInDev)) outputTarget.skipInDev = !config._docsFlag;
|
|
19010
|
+
return outputTarget;
|
|
19011
|
+
};
|
|
18317
19012
|
const validateCustomElementsManifestOutputTarget = (config, outputTarget) => {
|
|
18318
19013
|
if (!isString$1(outputTarget.file)) outputTarget.file = "custom-elements.json";
|
|
18319
19014
|
if (!isAbsolute$1(outputTarget.file)) outputTarget.file = join$2(config.rootDir, outputTarget.file);
|
|
@@ -18342,9 +19037,10 @@ const validateGlobalStyle = (config, userOutputs) => {
|
|
|
18342
19037
|
const input = isString$1(outputTarget.input) ? getAbsolutePath(config, outputTarget.input) : config.globalStyle ?? void 0;
|
|
18343
19038
|
let fileName;
|
|
18344
19039
|
if (isString$1(outputTarget.fileName)) fileName = outputTarget.fileName;
|
|
18345
|
-
else if (input)
|
|
18346
|
-
|
|
18347
|
-
|
|
19040
|
+
else if (input) {
|
|
19041
|
+
if (isString$1(outputTarget.input)) fileName = basename(input);
|
|
19042
|
+
else fileName = `${config.fsNamespace}.css`;
|
|
19043
|
+
} else fileName = `${config.fsNamespace}.css`;
|
|
18348
19044
|
const validInjectValues = [
|
|
18349
19045
|
"none",
|
|
18350
19046
|
"client",
|
|
@@ -18367,9 +19063,10 @@ const validateGlobalStyle = (config, userOutputs) => {
|
|
|
18367
19063
|
//#region src/compiler/config/outputs/validate-lazy.ts
|
|
18368
19064
|
const validateLazy = (config, userOutputs) => {
|
|
18369
19065
|
return userOutputs.filter(isOutputTargetDistLazy).map((o) => {
|
|
19066
|
+
const dir = getAbsolutePath(config, o.dir || join$2("dist", config.fsNamespace));
|
|
18370
19067
|
return {
|
|
18371
19068
|
type: DIST_LAZY,
|
|
18372
|
-
esmDir:
|
|
19069
|
+
esmDir: dir,
|
|
18373
19070
|
isBrowserBuild: true,
|
|
18374
19071
|
empty: isBoolean$1(o.empty) ? o.empty : true
|
|
18375
19072
|
};
|
|
@@ -18433,7 +19130,8 @@ const validateLoaderBundle = (config, diagnostics, userOutputs) => {
|
|
|
18433
19130
|
if (!config.devMode || !loaderBundleOutput.skipInDev) {
|
|
18434
19131
|
const esmDir = join$2(loaderBundleOutput.dir, "esm");
|
|
18435
19132
|
const cjsDir = loaderBundleOutput.cjs ? join$2(loaderBundleOutput.dir, "cjs") : void 0;
|
|
18436
|
-
const
|
|
19133
|
+
const typesOutput = userOutputs.find(isOutputTargetTypes);
|
|
19134
|
+
const typesDir = getAbsolutePath(config, typesOutput?.dir ?? "dist/types");
|
|
18437
19135
|
outputs.push({
|
|
18438
19136
|
type: DIST_LAZY,
|
|
18439
19137
|
esmDir,
|
|
@@ -19245,6 +19943,8 @@ const validateConfig = (userConfig = {}, bootstrapConfig) => {
|
|
|
19245
19943
|
const ldp = validatedConfig.compat.lightDomPatches;
|
|
19246
19944
|
if (ldp === void 0) validatedConfig.compat.lightDomPatches = true;
|
|
19247
19945
|
else if (typeof ldp !== "boolean" && typeof ldp !== "object") validatedConfig.compat.lightDomPatches = true;
|
|
19946
|
+
validatedConfig.compat.suppressPublicNameWarnings = !!validatedConfig.compat.suppressPublicNameWarnings;
|
|
19947
|
+
validatedConfig.compat.suppressEventNameWarnings = !!validatedConfig.compat.suppressEventNameWarnings;
|
|
19248
19948
|
setBooleanConfig(validatedConfig, "watch", false);
|
|
19249
19949
|
setBooleanConfig(validatedConfig, "profile", validatedConfig.devMode);
|
|
19250
19950
|
setBooleanConfig(validatedConfig, "writeLog", false);
|
|
@@ -19252,8 +19952,6 @@ const validateConfig = (userConfig = {}, bootstrapConfig) => {
|
|
|
19252
19952
|
setBooleanConfig(validatedConfig, "autoprefixCss", false);
|
|
19253
19953
|
setBooleanConfig(validatedConfig, "validateTypes", !validatedConfig._isTesting);
|
|
19254
19954
|
setBooleanConfig(validatedConfig, "allowInlineScripts", true);
|
|
19255
|
-
setBooleanConfig(validatedConfig, "suppressReservedPublicNameWarnings", false);
|
|
19256
|
-
setBooleanConfig(validatedConfig, "suppressReservedEventNameWarnings", false);
|
|
19257
19955
|
if (!isString$1(validatedConfig.taskQueue)) validatedConfig.taskQueue = "async";
|
|
19258
19956
|
if (!validatedConfig.env) validatedConfig.env = {};
|
|
19259
19957
|
validateOutputTargets(validatedConfig, diagnostics);
|
|
@@ -19263,6 +19961,7 @@ const validateConfig = (userConfig = {}, bootstrapConfig) => {
|
|
|
19263
19961
|
else validatedConfig.bundles = [];
|
|
19264
19962
|
if (!Array.isArray(validatedConfig.excludeComponents)) validatedConfig.excludeComponents = [];
|
|
19265
19963
|
if (!Array.isArray(validatedConfig.collections)) validatedConfig.collections = [];
|
|
19964
|
+
if (!Array.isArray(validatedConfig.modes)) validatedConfig.modes = [];
|
|
19266
19965
|
validateWorkers(validatedConfig);
|
|
19267
19966
|
setBooleanConfig(validatedConfig, "devInspector", validatedConfig.devMode);
|
|
19268
19967
|
setBooleanConfig(validatedConfig, "enableCache", true);
|
|
@@ -20205,7 +20904,8 @@ const autoprefixCss = async (cssText, opts, filePath, minify = false) => {
|
|
|
20205
20904
|
diagnostics: []
|
|
20206
20905
|
};
|
|
20207
20906
|
try {
|
|
20208
|
-
const
|
|
20907
|
+
const browserTargets = opts != null && typeof opts === "object" && Array.isArray(opts.targets) ? opts.targets : DEFAULT_BROWSER_TARGETS;
|
|
20908
|
+
const targets = getTargets(browserTargets);
|
|
20209
20909
|
output.output = transform({
|
|
20210
20910
|
filename: filePath ?? "style.css",
|
|
20211
20911
|
code: Buffer.from(cssText),
|
|
@@ -20489,7 +21189,8 @@ const parseCss = (css, filePath) => {
|
|
|
20489
21189
|
};
|
|
20490
21190
|
const atquery = (name) => {
|
|
20491
21191
|
const pos = position();
|
|
20492
|
-
const
|
|
21192
|
+
const regex = new RegExp("^@" + name + " *([^{]+)");
|
|
21193
|
+
const m = match(regex);
|
|
20493
21194
|
if (!m) return null;
|
|
20494
21195
|
const media = trim(m[1]);
|
|
20495
21196
|
if (!open()) return error(`@${name} missing '{'`);
|
|
@@ -20508,7 +21209,8 @@ const parseCss = (css, filePath) => {
|
|
|
20508
21209
|
*/
|
|
20509
21210
|
const nestedAtQuery = (name) => {
|
|
20510
21211
|
const pos = position();
|
|
20511
|
-
const
|
|
21212
|
+
const regex = new RegExp("^@" + name + " *([^{]+)");
|
|
21213
|
+
const m = match(regex);
|
|
20512
21214
|
if (!m) return null;
|
|
20513
21215
|
const media = trim(m[1]);
|
|
20514
21216
|
const decls = declarations();
|
|
@@ -20766,8 +21468,10 @@ const serializeCssVisitNode = (opts, node, index, len) => {
|
|
|
20766
21468
|
const nodeType = node.type;
|
|
20767
21469
|
if (nodeType === 4) return serializeCssDeclaration(node, index, len);
|
|
20768
21470
|
if (nodeType === 14) return serializeCssRule(opts, node);
|
|
20769
|
-
if (nodeType === 1)
|
|
20770
|
-
|
|
21471
|
+
if (nodeType === 1) {
|
|
21472
|
+
if (node.comment?.[0] === "!") return `/*${node.comment}*/`;
|
|
21473
|
+
else return "";
|
|
21474
|
+
}
|
|
20771
21475
|
if (nodeType === 10) return serializeCssMedia(opts, node);
|
|
20772
21476
|
if (nodeType === 11) return serializeCssContainer(opts, node);
|
|
20773
21477
|
if (nodeType === 8) return serializeCssKeyframes(opts, node);
|
|
@@ -20999,7 +21703,8 @@ const crawlAnchorsForNextUrls = (prerenderConfig, diagnostics, baseUrl, currentU
|
|
|
20999
21703
|
return standardFilterAnchor(diagnostics, anchor, currentUrl);
|
|
21000
21704
|
}).map((anchor) => {
|
|
21001
21705
|
if (typeof prerenderConfig.normalizeUrl === "function") try {
|
|
21002
|
-
|
|
21706
|
+
const userNormalizedUrl = prerenderConfig.normalizeUrl(anchor.href, currentUrl);
|
|
21707
|
+
return standardNormalizeUrl(diagnostics, userNormalizedUrl.href, currentUrl);
|
|
21003
21708
|
} catch (e) {
|
|
21004
21709
|
catchError(diagnostics, e);
|
|
21005
21710
|
}
|
|
@@ -21101,7 +21806,7 @@ const extname$1 = (str) => {
|
|
|
21101
21806
|
const parts = str.split(".");
|
|
21102
21807
|
return parts[parts.length - 1].toLowerCase();
|
|
21103
21808
|
};
|
|
21104
|
-
const SKIP_EXT = new Set([
|
|
21809
|
+
const SKIP_EXT = /* @__PURE__ */ new Set([
|
|
21105
21810
|
"zip",
|
|
21106
21811
|
"rar",
|
|
21107
21812
|
"tar",
|
|
@@ -21145,8 +21850,10 @@ const getPrerenderConfig = async (diagnostics, prerenderConfigPath) => {
|
|
|
21145
21850
|
const results = await nodeRequire(prerenderConfigPath);
|
|
21146
21851
|
diagnostics.push(...results.diagnostics);
|
|
21147
21852
|
const mod = results.module?.default ?? results.module;
|
|
21148
|
-
if (mod != null && typeof mod === "object")
|
|
21149
|
-
|
|
21853
|
+
if (mod != null && typeof mod === "object") {
|
|
21854
|
+
if (mod.config != null && typeof mod.config === "object") Object.assign(prerenderConfig, mod.config);
|
|
21855
|
+
else Object.assign(prerenderConfig, mod);
|
|
21856
|
+
}
|
|
21150
21857
|
}
|
|
21151
21858
|
return prerenderConfig;
|
|
21152
21859
|
};
|
|
@@ -21203,7 +21910,8 @@ const optimizeJs = async (inputOpts) => {
|
|
|
21203
21910
|
sourceMap: null
|
|
21204
21911
|
};
|
|
21205
21912
|
try {
|
|
21206
|
-
const
|
|
21913
|
+
const prettyOutput = !!inputOpts.pretty;
|
|
21914
|
+
const minifyOpts = getTerserOptions({}, "latest", prettyOutput);
|
|
21207
21915
|
const minifyResults = await minifyJs(inputOpts.input, minifyOpts);
|
|
21208
21916
|
if (minifyResults.diagnostics.length > 0) result.diagnostics.push(...minifyResults.diagnostics);
|
|
21209
21917
|
else {
|
|
@@ -21309,7 +22017,9 @@ s&&((s['data-opts']=s['data-opts']||{}).exclude=__EXCLUDE__);
|
|
|
21309
22017
|
const addModulePreloads = (doc, hydrateOpts, hydrateResults, componentGraph) => {
|
|
21310
22018
|
if (!componentGraph) return false;
|
|
21311
22019
|
const staticComponents = hydrateOpts.staticComponents || [];
|
|
21312
|
-
|
|
22020
|
+
const cmpTags = hydrateResults.components.filter((cmp) => !staticComponents.includes(cmp.tag));
|
|
22021
|
+
const modulePreloads = unique(flatOne(cmpTags.map((cmp) => getScopeId(cmp.tag, cmp.mode)).map((scopeId) => componentGraph.get(scopeId) || [])));
|
|
22022
|
+
injectModulePreloads(doc, modulePreloads);
|
|
21313
22023
|
return true;
|
|
21314
22024
|
};
|
|
21315
22025
|
const removeModulePreloads = (doc) => {
|
|
@@ -21418,14 +22128,16 @@ const hashPageStateAstAssets = async (sys, hydrateOpts, appDir, currentUrl, page
|
|
|
21418
22128
|
};
|
|
21419
22129
|
const getAttrUrls = (attrName, attrValue) => {
|
|
21420
22130
|
const srcValues = [];
|
|
21421
|
-
if (isString$1(attrValue))
|
|
21422
|
-
|
|
21423
|
-
|
|
21424
|
-
|
|
21425
|
-
|
|
22131
|
+
if (isString$1(attrValue)) {
|
|
22132
|
+
if (attrName.toLowerCase() === "srcset") attrValue.split(",").map((a) => a.trim()).filter((a) => a.length > 0).forEach((src) => {
|
|
22133
|
+
const spaceSplt = src.split(" ");
|
|
22134
|
+
if (spaceSplt[0].length > 0) srcValues.push({
|
|
22135
|
+
src: spaceSplt[0],
|
|
22136
|
+
descriptor: spaceSplt[1]
|
|
22137
|
+
});
|
|
21426
22138
|
});
|
|
21427
|
-
|
|
21428
|
-
|
|
22139
|
+
else srcValues.push({ src: attrValue });
|
|
22140
|
+
}
|
|
21429
22141
|
return srcValues;
|
|
21430
22142
|
};
|
|
21431
22143
|
const setAttrUrls = (url, descriptor) => {
|
|
@@ -21550,10 +22262,12 @@ const prerenderWorker = async (sys, prerenderRequest) => {
|
|
|
21550
22262
|
[s.id]: JSON.parse(s.content),
|
|
21551
22263
|
components: hydrateResults.components.map((c) => c.tag)
|
|
21552
22264
|
};
|
|
21553
|
-
const
|
|
22265
|
+
const dataFileName = `${s.id}.json`;
|
|
22266
|
+
const dataFilePath = join$2(pageDir, dataFileName);
|
|
21554
22267
|
await sys.writeFile(dataFilePath, JSON.stringify(data));
|
|
21555
22268
|
} else {
|
|
21556
|
-
const
|
|
22269
|
+
const contentFileName = `${s.id}.txt`;
|
|
22270
|
+
const contentFilePath = join$2(pageDir, contentFileName);
|
|
21557
22271
|
await sys.writeFile(contentFilePath, s.content);
|
|
21558
22272
|
}
|
|
21559
22273
|
}));
|
|
@@ -21661,7 +22375,8 @@ const transformCssToEsm = async (input) => {
|
|
|
21661
22375
|
* @returns transformed ESM output
|
|
21662
22376
|
*/
|
|
21663
22377
|
const transformCssToEsmSync = (input) => {
|
|
21664
|
-
|
|
22378
|
+
const results = transformCssToEsmModule(input);
|
|
22379
|
+
return generateTransformCssToEsm(input, results);
|
|
21665
22380
|
};
|
|
21666
22381
|
/**
|
|
21667
22382
|
* Performs the actual transformation from CSS to ESM
|
|
@@ -21681,7 +22396,7 @@ const transformCssToEsmModule = (input) => {
|
|
|
21681
22396
|
};
|
|
21682
22397
|
if (input.docs) parseStyleDocs(results.styleDocs, input.input, input.mode);
|
|
21683
22398
|
try {
|
|
21684
|
-
const varNames = new Set([results.defaultVarName]);
|
|
22399
|
+
const varNames = /* @__PURE__ */ new Set([results.defaultVarName]);
|
|
21685
22400
|
if (isString$1(input.tag) && input.encapsulation === "scoped") {
|
|
21686
22401
|
const scopeId = getScopeId(input.tag, input.mode);
|
|
21687
22402
|
results.styleText = scopeCss(results.styleText, scopeId, false);
|
|
@@ -21716,7 +22431,7 @@ const transformCssToEsmModule = (input) => {
|
|
|
21716
22431
|
*/
|
|
21717
22432
|
const generateTransformCssToEsm = (input, results) => {
|
|
21718
22433
|
const s = new MagicString("");
|
|
21719
|
-
results.styleText = results.styleText.replace(
|
|
22434
|
+
results.styleText = results.styleText.replace(/\\/g, "\\\\").replace(/\n/g, " ").replace(/\r/g, " ").replace(/\t/g, " ").replace(/\u000c/g, "\\\\f").replace(/\u0008/g, "\\\\b").replace(/\u000b/g, "\\\\v").replace(/\0/g, "\\\\0").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
21720
22435
|
if (input.addTagTransformers) results.styleText = addTagTransformToCssString(results.styleText, input.tags);
|
|
21721
22436
|
results.styleText = stripCssComments(results.styleText);
|
|
21722
22437
|
if (input.module === "cjs") {
|
|
@@ -21758,7 +22473,7 @@ const getCssToEsmImports = (varNames, cssText, filePath, modeName) => {
|
|
|
21758
22473
|
const cssImports = [];
|
|
21759
22474
|
if (!cssText.includes("@import")) return cssImports;
|
|
21760
22475
|
cssText = stripCssComments(cssText);
|
|
21761
|
-
const dir = path
|
|
22476
|
+
const dir = path.dirname(filePath);
|
|
21762
22477
|
let r;
|
|
21763
22478
|
while (r = CSS_IMPORT_RE.exec(cssText)) {
|
|
21764
22479
|
const cssImportData = {
|
|
@@ -21772,7 +22487,7 @@ const getCssToEsmImports = (varNames, cssText, filePath, modeName) => {
|
|
|
21772
22487
|
else if (isCssNodeModule(cssImportData.url)) {
|
|
21773
22488
|
cssImportData.filePath = cssImportData.url.substring(1);
|
|
21774
22489
|
cssImportData.isNodeModule = true;
|
|
21775
|
-
} else if (path
|
|
22490
|
+
} else if (path.isAbsolute(cssImportData.url)) cssImportData.filePath = normalizePath(cssImportData.url);
|
|
21776
22491
|
else cssImportData.filePath = normalizePath(resolve$2(dir, cssImportData.url));
|
|
21777
22492
|
cssImportData.varName = createCssVarName(cssImportData.filePath, modeName);
|
|
21778
22493
|
if (varNames.has(cssImportData.varName)) cssImportData.varName += varNames.size;
|
|
@@ -21815,7 +22530,7 @@ const isLocalCssImport = (srcImport) => {
|
|
|
21815
22530
|
* @returns an appropriate Css var name
|
|
21816
22531
|
*/
|
|
21817
22532
|
const createCssVarName = (filePath, modeName) => {
|
|
21818
|
-
let varName = path
|
|
22533
|
+
let varName = path.basename(filePath);
|
|
21819
22534
|
if (modeName && modeName !== "$" && !varName.includes(modeName)) varName = modeName + "-" + varName;
|
|
21820
22535
|
return createJsVarName(varName);
|
|
21821
22536
|
};
|
|
@@ -22001,9 +22716,10 @@ const getTsConfigPath = async (config, sys) => {
|
|
|
22001
22716
|
path: "",
|
|
22002
22717
|
content: ""
|
|
22003
22718
|
};
|
|
22004
|
-
if (isString$1(config.tsconfig))
|
|
22005
|
-
|
|
22006
|
-
|
|
22719
|
+
if (isString$1(config.tsconfig)) {
|
|
22720
|
+
if (!isAbsolute$1(config.tsconfig)) tsconfig.path = join$2(config.rootDir, config.tsconfig);
|
|
22721
|
+
else tsconfig.path = config.tsconfig;
|
|
22722
|
+
} else tsconfig.path = join$2(config.rootDir, "tsconfig.json");
|
|
22007
22723
|
tsconfig.content = await sys.readFile(tsconfig.path);
|
|
22008
22724
|
if (!isString$1(tsconfig.content)) {
|
|
22009
22725
|
tsconfig.path = join$2(config.rootDir, "tsconfig.json");
|
|
@@ -22191,7 +22907,7 @@ const getWriteFilePathFromUrlPath = (manager, inputHref) => {
|
|
|
22191
22907
|
const inputPathParts = inputPathname.split("/");
|
|
22192
22908
|
const isPrerrenderRoot = basePathname === inputPathname;
|
|
22193
22909
|
let fileName;
|
|
22194
|
-
if (isPrerrenderRoot) fileName = path
|
|
22910
|
+
if (isPrerrenderRoot) fileName = path.basename(manager.outputTarget.indexHtml);
|
|
22195
22911
|
else fileName = "index.html";
|
|
22196
22912
|
const pathParts = [];
|
|
22197
22913
|
for (let i = 0; i < inputPathParts.length; i++) {
|
|
@@ -22248,13 +22964,15 @@ const addUrlToPendingQueue = (manager, queueUrl, fromUrl) => {
|
|
|
22248
22964
|
};
|
|
22249
22965
|
const drainPrerenderQueue = (results, manager) => {
|
|
22250
22966
|
const nextUrl = manager.urlsPending.values().next();
|
|
22251
|
-
if (!nextUrl.done)
|
|
22252
|
-
|
|
22253
|
-
|
|
22254
|
-
|
|
22255
|
-
|
|
22256
|
-
|
|
22257
|
-
|
|
22967
|
+
if (!nextUrl.done) {
|
|
22968
|
+
if (manager.urlsProcessing.size > manager.maxConcurrency) setTimeout(() => drainPrerenderQueue(results, manager));
|
|
22969
|
+
else {
|
|
22970
|
+
const url = nextUrl.value;
|
|
22971
|
+
manager.urlsPending.delete(url);
|
|
22972
|
+
manager.urlsProcessing.add(url);
|
|
22973
|
+
prerenderUrl(results, manager, url);
|
|
22974
|
+
if (manager.urlsProcessing.size < manager.maxConcurrency) manager.config.sys.nextTick(() => drainPrerenderQueue(results, manager));
|
|
22975
|
+
}
|
|
22258
22976
|
}
|
|
22259
22977
|
if (manager.urlsProcessing.size === 0 && manager.urlsPending.size === 0) {
|
|
22260
22978
|
if (isFunction(manager.resolve)) {
|
|
@@ -22554,7 +23272,8 @@ const runPrerenderOutputTarget = async (workerCtx, results, diagnostics, config,
|
|
|
22554
23272
|
if (debugDiagnostics.length > 0) config.logger.printDiagnostics(debugDiagnostics);
|
|
22555
23273
|
}
|
|
22556
23274
|
const duration = timeSpan.duration();
|
|
22557
|
-
|
|
23275
|
+
const sitemapResults = await generateSitemapXml(manager);
|
|
23276
|
+
await generateRobotsTxt(manager, sitemapResults);
|
|
22558
23277
|
const prerenderBuildErrors = prerenderDiagnostics.filter((d) => d.level === "error");
|
|
22559
23278
|
const prerenderRuntimeErrors = prerenderDiagnostics.filter((d) => d.type === "runtime");
|
|
22560
23279
|
if (prerenderBuildErrors.length > 0) {
|
|
@@ -22765,7 +23484,8 @@ const createSystem = (c) => {
|
|
|
22765
23484
|
const itemStat = statSync(oldPath);
|
|
22766
23485
|
if (!itemStat.error && !results.error) {
|
|
22767
23486
|
if (itemStat.isFile) {
|
|
22768
|
-
const
|
|
23487
|
+
const newFileParentDir = dirname$1(newPath);
|
|
23488
|
+
const createDirResults = createDirSync(newFileParentDir, { recursive: true });
|
|
22769
23489
|
const fileContent = items.get(oldPath).data;
|
|
22770
23490
|
const writeResults = writeFileSync(newPath, fileContent);
|
|
22771
23491
|
results.newDirs.push(...createDirResults.newDirs);
|
|
@@ -22787,7 +23507,10 @@ const createSystem = (c) => {
|
|
|
22787
23507
|
isDirectory: true,
|
|
22788
23508
|
isFile: false
|
|
22789
23509
|
});
|
|
22790
|
-
for (const oldDirItemChildPath of oldDirItemChildPaths)
|
|
23510
|
+
for (const oldDirItemChildPath of oldDirItemChildPaths) {
|
|
23511
|
+
const newDirItemChildPath = oldDirItemChildPath.replace(oldPath, newPath);
|
|
23512
|
+
renameNewRecursiveSync(oldDirItemChildPath, newDirItemChildPath, results);
|
|
23513
|
+
}
|
|
22791
23514
|
}
|
|
22792
23515
|
}
|
|
22793
23516
|
};
|
|
@@ -23019,7 +23742,7 @@ const createSystem = (c) => {
|
|
|
23019
23742
|
isSymbolicLink,
|
|
23020
23743
|
nextTick,
|
|
23021
23744
|
normalizePath: normalize,
|
|
23022
|
-
platformPath: path
|
|
23745
|
+
platformPath: path,
|
|
23023
23746
|
readDir,
|
|
23024
23747
|
readDirSync,
|
|
23025
23748
|
readFile,
|
|
@@ -23177,13 +23900,13 @@ const getTranspileConfigOpt = (value, validValues, defaultValue) => {
|
|
|
23177
23900
|
if (validValues.has(value)) return value;
|
|
23178
23901
|
return defaultValue;
|
|
23179
23902
|
};
|
|
23180
|
-
const VALID_EXPORT = new Set(["customelement", "module"]);
|
|
23181
|
-
const VALID_METADATA = new Set(["compilerstatic", null]);
|
|
23182
|
-
const VALID_MODULE = new Set(["cjs", "esm"]);
|
|
23183
|
-
const VALID_PROXY = new Set(["defineproperty", null]);
|
|
23184
|
-
const VALID_STYLE = new Set(["static"]);
|
|
23185
|
-
const VALID_STYLE_IMPORT_DATA = new Set(["queryparams"]);
|
|
23186
|
-
const VALID_TARGET = new Set([
|
|
23903
|
+
const VALID_EXPORT = /* @__PURE__ */ new Set(["customelement", "module"]);
|
|
23904
|
+
const VALID_METADATA = /* @__PURE__ */ new Set(["compilerstatic", null]);
|
|
23905
|
+
const VALID_MODULE = /* @__PURE__ */ new Set(["cjs", "esm"]);
|
|
23906
|
+
const VALID_PROXY = /* @__PURE__ */ new Set(["defineproperty", null]);
|
|
23907
|
+
const VALID_STYLE = /* @__PURE__ */ new Set(["static"]);
|
|
23908
|
+
const VALID_STYLE_IMPORT_DATA = /* @__PURE__ */ new Set(["queryparams"]);
|
|
23909
|
+
const VALID_TARGET = /* @__PURE__ */ new Set([
|
|
23187
23910
|
"latest",
|
|
23188
23911
|
"esnext",
|
|
23189
23912
|
"es2020",
|
|
@@ -23343,8 +24066,10 @@ const transpile = async (code, opts = {}) => {
|
|
|
23343
24066
|
patchTypescript(validatedConfig, null);
|
|
23344
24067
|
transpileCode(validatedConfig, compileOpts, transformOpts, results);
|
|
23345
24068
|
} else if (results.inputFileExtension === "d.ts") results.code = "";
|
|
23346
|
-
else if (results.inputFileExtension === "css")
|
|
23347
|
-
|
|
24069
|
+
else if (results.inputFileExtension === "css") {
|
|
24070
|
+
const transformInput = getTranspileCssConfig(opts, importData, results);
|
|
24071
|
+
await transpileCss(transformInput, results);
|
|
24072
|
+
} else if (results.inputFileExtension === "json") transpileJson(results);
|
|
23348
24073
|
} catch (e) {
|
|
23349
24074
|
catchError(results.diagnostics, e);
|
|
23350
24075
|
}
|
|
@@ -23368,8 +24093,10 @@ const transpileSync = (code, opts = {}) => {
|
|
|
23368
24093
|
patchTypescript(validatedConfig, null);
|
|
23369
24094
|
transpileCode(validatedConfig, compileOpts, transformOpts, results);
|
|
23370
24095
|
} else if (results.inputFileExtension === "d.ts") results.code = "";
|
|
23371
|
-
else if (results.inputFileExtension === "css")
|
|
23372
|
-
|
|
24096
|
+
else if (results.inputFileExtension === "css") {
|
|
24097
|
+
const transformInput = getTranspileCssConfig(opts, importData, results);
|
|
24098
|
+
transpileCssSync(transformInput, results);
|
|
24099
|
+
} else if (results.inputFileExtension === "json") transpileJson(results);
|
|
23373
24100
|
} catch (e) {
|
|
23374
24101
|
catchError(results.diagnostics, e);
|
|
23375
24102
|
}
|