@stencil/core 5.0.0-alpha.16 → 5.0.0-alpha.17

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.
@@ -1,8 +1,8 @@
1
1
  import { n as __require } from "./chunk-z9aeyW2b.mjs";
2
- import { O as HYDRATED_CSS, f as scopeCss } from "./client-DI9mAOBd.mjs";
2
+ import { O as HYDRATED_CSS, f as scopeCss } from "./client-CgXNkftm.mjs";
3
3
  import { $ as VALID_CONFIG_OUTPUT_TARGETS, C as ASSETS, D as COLLECTION_MANIFEST_FILE_NAME, E as COLLECTION_APP_DATA_FILE_NAME, F as DOCS_README, J as STANDALONE, L as EVENT_FLAGS, O as COPY, P as DOCS_JSON, Q as TYPES, R as GENERATED_DTS, T as COLLECTION, U as LOADER_BUNDLE, X as STYLE_EXT, Y as STATS, _ as sortBy, a as fromEntries, b as toTitleCase, d as isNumber$1, et as WATCH_FLAGS, 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, u as isIterable, x as unique, y as toDashCase, z as GLOBAL_STYLE } from "./regular-expression-CFVJOTUh.mjs";
4
4
  import { $ as loadTypeScriptDiagnostics, A as isOutputTargetCollection, B as isOutputTargetGlobalStyle, Ct as formatComponentRuntimeMeta, E as getComponentsDtsSrcFilePath, Et as byteSize, F as isOutputTargetDocsCustom, G as isOutputTargetStats, H as isOutputTargetSsr, I as isOutputTargetDocsCustomElementsManifest, J as isValidConfigOutputTarget, K as isOutputTargetTypes, L as isOutputTargetDocsJson, M as isOutputTargetCustom, N as isOutputTargetDistLazy, O as getComponentsFromModules, P as isOutputTargetDocs, Q as loadTypeScriptDiagnostic, R as isOutputTargetDocsReadme, S as ok, St as isGlob, T as filterExcludedComponents, Tt as stringifyRuntimeData, U as isOutputTargetSsrWasm, V as isOutputTargetLoaderBundle, W as isOutputTargetStandalone, Y as relativeImport, Z as augmentDiagnosticWithNode, _ as getSourceMappingUrlForEndOfFile, _t as catchError, a as getTextDocs, at as relative$1, b as err, ct as isRolldownError, d as isTsxFile, dt as normalizeDiagnostics, et as join$2, f as parsePackageJson, ft as splitLineBreaks, g as getInlineSourceMappingUrlLinker, gt as buildWarn, h as isRemoteUrl, ht as buildJsonFileError, i as generatePreamble, it as normalizePath, j as isOutputTargetCopy, k as isOutputTargetAssets, lt as loadRolldownDiagnostics, m as readPackageJson, mt as buildError, n as addDocBlock, nt as normalizeFsPath, o as hasDependency, ot as resolve$2, p as readOnlyArrayHasStringMember, q as isOutputTargetWww, r as createJsVarName, rt as normalizeFsPathQuery, s as isDtsFile, st as createOnWarnFn, t as validateComponentTag, u as isTsFile, vt as hasError, w as filterActiveTargets, x as map, xt as isRootPath, y as rolldownToStencilSourceMap, yt as hasWarning, z as isOutputTargetDocsVscode } from "./validation-ByxKj8bC.mjs";
5
- import { i as CustomElementsExportBehaviorOptions, o as buildEvents, r as createNodeLogger, t as createNodeSys } from "./node-BdyxhldJ.mjs";
5
+ import { i as CustomElementsExportBehaviorOptions, o as buildEvents, r as createNodeLogger, t as createNodeSys } from "./node-jFf98r0u.mjs";
6
6
  import ts, { default as ts$1 } from "typescript";
7
7
  import { readFileSync } from "node:fs";
8
8
  import { basename, dirname, isAbsolute, join, resolve } from "node:path";
@@ -28,9 +28,9 @@ import { createJiti } from "jiti";
28
28
  import * as process$1 from "process";
29
29
  import { dataToEsm } from "@rollup/pluginutils";
30
30
  //#region src/version.ts
31
- const version = "5.0.0-alpha.16";
32
- const buildId = "1782306279";
33
- const vermoji = "🐹";
31
+ const version = "5.0.0-alpha.17";
32
+ const buildId = "1783170414";
33
+ const vermoji = "🎨";
34
34
  /**
35
35
  * Get the installed version of a tool/dependency.
36
36
  * Handles packages with exports maps that point to subdirectories.
@@ -1738,16 +1738,6 @@ const isInternal = (jsDocs) => {
1738
1738
  return !!(jsDocs && jsDocs.tags.some((s) => s.name === "internal"));
1739
1739
  };
1740
1740
  /**
1741
- * Check if a class element is a method with a specific name.
1742
- *
1743
- * @param member - the class element to check
1744
- * @param methodName - the method name to match
1745
- * @returns true if the member is a method with the specified name
1746
- */
1747
- const isMethod = (member, methodName) => {
1748
- return ts.isMethodDeclaration(member) && member.name && member.name.escapedText === methodName;
1749
- };
1750
- /**
1751
1741
  * Create an ESM import statement.
1752
1742
  *
1753
1743
  * @param importFnNames - the names to import
@@ -3094,6 +3084,7 @@ const removeCollectionImports = (compilerCtx) => {
3094
3084
  //#region src/compiler/bundle/entry-alias-ids.ts
3095
3085
  const STENCIL_CORE_ID = "@stencil/core";
3096
3086
  const STENCIL_INTERNAL_ID = "@stencil/core/runtime";
3087
+ const STENCIL_APP_DATA_ID = "@stencil/core/app-data";
3097
3088
  const STENCIL_APP_GLOBALS_ID = "@stencil/core/app-globals";
3098
3089
  const STENCIL_SSR_FACTORY_ID = "@stencil/core/runtime/server/ssr-factory";
3099
3090
  const STENCIL_INTERNAL_STANDALONE_CLIENT_PLATFORM_ID = "@stencil/core/runtime/client/standalone";
@@ -7194,6 +7185,51 @@ const getDocsCustomStates = (cmpMeta) => {
7194
7185
  docs: state.docs || ""
7195
7186
  })), (state) => state.name);
7196
7187
  };
7188
+ /**
7189
+ * Convert a single {@link d.ComponentCompilerMeta} to a {@link d.JsonDocsComponent}
7190
+ * without reading any files from disk (readme/usage are left empty).
7191
+ *
7192
+ * Useful for single-file transpilation contexts (e.g. `transpileSync`) when a
7193
+ * full build context is not available.
7194
+ * @param cmp the component metadata to convert
7195
+ * @param filePath absolute path to the component source file
7196
+ * @param rootDir project root used to make `filePath` relative (defaults to `process.cwd()`)
7197
+ * @returns a {@link d.JsonDocsComponent} with empty readme/usage
7198
+ */
7199
+ const cmpMetaToDocsComponent = (cmp, filePath, rootDir = process.cwd()) => {
7200
+ const normalizedFilePath = normalizePath(filePath);
7201
+ const dirPath = normalizePath(dirname$1(normalizedFilePath));
7202
+ const docs = cmp.docs ?? {
7203
+ text: "",
7204
+ tags: []
7205
+ };
7206
+ return {
7207
+ dirPath,
7208
+ filePath: normalizePath(relative$1(rootDir, normalizedFilePath), false),
7209
+ fileName: basename$1(normalizedFilePath),
7210
+ readmePath: normalizePath(join$2(dirPath, "readme.md")),
7211
+ usagesDir: normalizePath(join$2(dirPath, "usage")),
7212
+ tag: cmp.tagName,
7213
+ readme: "",
7214
+ overview: docs.text,
7215
+ usage: {},
7216
+ docs: docs.text,
7217
+ docsTags: docs.tags,
7218
+ encapsulation: getDocsEncapsulation(cmp),
7219
+ dependents: cmp.directDependents ?? [],
7220
+ dependencies: cmp.directDependencies ?? [],
7221
+ dependencyGraph: {},
7222
+ deprecation: getDocsDeprecationText(docs.tags),
7223
+ props: getDocsProperties(cmp),
7224
+ methods: getDocsMethods(cmp.methods ?? []),
7225
+ events: getDocsEvents(cmp.events ?? []),
7226
+ styles: getDocsStyles(cmp),
7227
+ slots: getDocsSlots(docs.tags),
7228
+ parts: getDocsParts(cmp.htmlParts ?? [], docs.tags),
7229
+ customStates: getDocsCustomStates(cmp),
7230
+ listeners: getDocsListeners(cmp.listeners ?? [])
7231
+ };
7232
+ };
7197
7233
  const getNameText = (name, tags) => {
7198
7234
  return tags.filter((tag) => tag.name === name && tag.text).map(({ text }) => {
7199
7235
  const [namePart, ...rest] = (" " + text).split(" - ");
@@ -7367,6 +7403,19 @@ const convertTypeReferences = (references) => {
7367
7403
  }));
7368
7404
  };
7369
7405
  /**
7406
+ * Converts Stencil docsTags to CEM Tag objects, skipping `@deprecated` which
7407
+ * is already conveyed by the dedicated `deprecated` CEM field.
7408
+ * @param docsTags the Stencil docsTags array
7409
+ * @returns CEM Tag array or undefined if no tags remain
7410
+ */
7411
+ const toTags = (docsTags) => {
7412
+ const tags = docsTags.filter((t) => t.name !== "deprecated").map((t) => ({
7413
+ name: t.name,
7414
+ ...t.text && { text: t.text }
7415
+ }));
7416
+ return tags.length > 0 ? tags : void 0;
7417
+ };
7418
+ /**
7370
7419
  * Create a CEM Type object from a type string and optional references
7371
7420
  * @param text the type string
7372
7421
  * @param references Stencil's type references map
@@ -7392,7 +7441,8 @@ const componentToDeclaration = (component) => {
7392
7441
  ...prop.type && { type: createType(prop.type, prop.complexType?.references) },
7393
7442
  ...prop.default !== void 0 && { default: prop.default },
7394
7443
  fieldName: prop.name,
7395
- ...prop.deprecation !== void 0 && { deprecated: prop.deprecation || true }
7444
+ ...prop.deprecation !== void 0 && { deprecated: prop.deprecation || true },
7445
+ ...toTags(prop.docsTags) && { tags: toTags(prop.docsTags) }
7396
7446
  }));
7397
7447
  const members = [...component.props.map((prop) => ({
7398
7448
  kind: "field",
@@ -7403,7 +7453,8 @@ const componentToDeclaration = (component) => {
7403
7453
  ...prop.deprecation !== void 0 && { deprecated: prop.deprecation || true },
7404
7454
  ...!prop.mutable && { readonly: true },
7405
7455
  ...prop.attr && { attribute: prop.attr },
7406
- ...prop.reflectToAttr && { reflects: true }
7456
+ ...prop.reflectToAttr && { reflects: true },
7457
+ ...toTags(prop.docsTags) && { tags: toTags(prop.docsTags) }
7407
7458
  })), ...component.methods.map((method) => ({
7408
7459
  kind: "method",
7409
7460
  name: method.name,
@@ -7417,13 +7468,15 @@ const componentToDeclaration = (component) => {
7417
7468
  ...method.returns && { return: {
7418
7469
  ...method.returns.type && { type: createType(method.returns.type, method.complexType?.references) },
7419
7470
  ...method.returns.docs && { description: method.returns.docs }
7420
- } }
7471
+ } },
7472
+ ...toTags(method.docsTags) && { tags: toTags(method.docsTags) }
7421
7473
  }))];
7422
7474
  const events = component.events.map((event) => ({
7423
7475
  name: event.event,
7424
7476
  ...event.docs && { description: event.docs },
7425
7477
  type: createType(event.detail ? `CustomEvent<${event.detail}>` : "CustomEvent", event.complexType?.references),
7426
- ...event.deprecation !== void 0 && { deprecated: event.deprecation || true }
7478
+ ...event.deprecation !== void 0 && { deprecated: event.deprecation || true },
7479
+ ...toTags(event.docsTags) && { tags: toTags(event.docsTags) }
7427
7480
  }));
7428
7481
  const slots = component.slots.map((slot) => ({
7429
7482
  name: slot.name,
@@ -7448,13 +7501,14 @@ const componentToDeclaration = (component) => {
7448
7501
  name: className,
7449
7502
  ...component.docs && { description: component.docs },
7450
7503
  ...component.deprecation !== void 0 && { deprecated: component.deprecation || true },
7504
+ ...toTags(component.docsTags) && { tags: toTags(component.docsTags) },
7451
7505
  ...attributes.length > 0 && { attributes },
7452
7506
  ...members.length > 0 && { members },
7453
7507
  ...events.length > 0 && { events },
7454
7508
  ...slots.length > 0 && { slots },
7455
7509
  ...cssParts.length > 0 && { cssParts },
7456
7510
  ...cssProperties.length > 0 && { cssProperties },
7457
- ...component.customStates.length > 0 && { customStates: component.customStates.map((state) => ({
7511
+ ...component.customStates.length > 0 && { cssStates: component.customStates.map((state) => ({
7458
7512
  name: state.name,
7459
7513
  initialValue: state.initialValue,
7460
7514
  ...state.docs && { description: state.docs }
@@ -11198,17 +11252,24 @@ const updateNativeComponentClass = (transformOpts, classNode, moduleFile, cmp, b
11198
11252
  return updateComponentClass(transformOpts, withHeritageClauses, withHeritageClauses.heritageClauses, members);
11199
11253
  };
11200
11254
  /**
11201
- * Updates classes that are extended by Stencil components:
11202
- * - extend `HTMLElement` if necessary
11203
- * - ensure the constructor has a `super()` call
11204
- * - remove static metadata properties
11255
+ * Transforms a Stencil superclass (a base class that Stencil components extend)
11256
+ * in the **full build** path, where `compilerCtx.moduleMap` is populated and the
11257
+ * module is flagged with `isExtended = true`.
11258
+ *
11259
+ * For the stateless transpile / unplugin path, use {@link updateNativeBaseClass}
11260
+ * instead — it preserves the `ClassDeclaration` form so derived components can
11261
+ * still import the base class by name.
11262
+ *
11263
+ * - Adds `extends HTMLElement` if necessary
11264
+ * - Ensures the constructor has a `super()` call
11265
+ * - Removes static metadata properties
11205
11266
  *
11206
11267
  * @param node the class node to update
11207
11268
  * @param moduleFile the module file containing the class
11208
11269
  * @param transformOpts transformation options
11209
11270
  * @returns the updated class node
11210
11271
  */
11211
- const updateNativeExtendedClass = (node, moduleFile, transformOpts) => {
11272
+ const updateNativeSuperClass = (node, moduleFile, transformOpts) => {
11212
11273
  let withHeritageClauses = updateNativeHostComponentHeritageClauses(node, moduleFile);
11213
11274
  const ctor = withHeritageClauses.members.find(ts.isConstructorDeclaration);
11214
11275
  if (!foundSuper(ctor?.body?.statements)) {
@@ -11232,6 +11293,26 @@ const updateNativeHostComponentHeritageClauses = (classNode, moduleFile) => {
11232
11293
  return ts.factory.updateClassDeclaration(classNode, classNode.modifiers, classNode.name, classNode.typeParameters, [heritageClause], classNode.members);
11233
11294
  };
11234
11295
  /**
11296
+ * Transforms a Stencil superclass (a base class that Stencil components extend)
11297
+ * in the **stateless transpile / unplugin** path, where `compilerCtx.moduleMap`
11298
+ * is not populated.
11299
+ *
11300
+ * For the full build path, use {@link updateNativeSuperClass} instead.
11301
+ *
11302
+ * Unlike `updateNativeSuperClass` this function keeps the class as a
11303
+ * `ClassDeclaration` so the `export` modifier is preserved — derived
11304
+ * components still need to import the base class by name.
11305
+ *
11306
+ * @param node the base class declaration
11307
+ * @param moduleFile the module file (used to register the HTMLElement import)
11308
+ * @returns the updated class declaration
11309
+ */
11310
+ const updateNativeBaseClass = (node, moduleFile) => {
11311
+ const withHeritageClauses = updateNativeHostComponentHeritageClauses(node, moduleFile);
11312
+ const membersWithCtor = updateConstructor(withHeritageClauses, removeStaticMetaProperties(withHeritageClauses), [], void 0, false);
11313
+ return ts.factory.updateClassDeclaration(withHeritageClauses, withHeritageClauses.modifiers, withHeritageClauses.name, withHeritageClauses.typeParameters, withHeritageClauses.heritageClauses, membersWithCtor);
11314
+ };
11315
+ /**
11235
11316
  * Perform various modifications to the class members of a Stencil component
11236
11317
  * which are necessary for it to be a 'native' web component.
11237
11318
  *
@@ -11261,6 +11342,15 @@ const updateNativeHostComponentMembers = (transformOpts, classNode, moduleFile,
11261
11342
  };
11262
11343
  //#endregion
11263
11344
  //#region src/compiler/transformers/component-native/tranform-to-native-component.ts
11345
+ const STENCIL_META_GETTER_NAMES = [
11346
+ "properties",
11347
+ "states",
11348
+ "events",
11349
+ "listeners",
11350
+ "watchers",
11351
+ "methods"
11352
+ ];
11353
+ const isStencilBaseClass = (node) => node.members.some((m) => isStaticGetter(m) && ts.isGetAccessorDeclaration(m) && ts.isIdentifier(m.name) && STENCIL_META_GETTER_NAMES.includes(m.name.text));
11264
11354
  /**
11265
11355
  * A function that returns a transformation factory. The returned factory
11266
11356
  * performs a series of transformations on Stencil components, in order to
@@ -11292,7 +11382,8 @@ const nativeComponentTransform = (compilerCtx, transformOpts, buildCtx) => {
11292
11382
  if (ts.isClassDeclaration(node)) {
11293
11383
  const cmp = getComponentMeta(compilerCtx, tsSourceFile, node);
11294
11384
  if (cmp != null) return updateNativeComponentClass(transformOpts, node, moduleFile, cmp, buildCtx);
11295
- else if (compilerCtx.moduleMap.get(tsSourceFile.fileName)?.isExtended) return updateNativeExtendedClass(node, moduleFile, transformOpts);
11385
+ else if (compilerCtx.moduleMap.get(tsSourceFile.fileName)?.isExtended) return updateNativeSuperClass(node, moduleFile, transformOpts);
11386
+ else if (moduleFile && (isStencilBaseClass(node) || transformOpts.transformAsBaseClass)) return updateNativeBaseClass(node, moduleFile);
11296
11387
  }
11297
11388
  return ts.visitEachChild(node, visitNode, transformCtx);
11298
11389
  };
@@ -14594,8 +14685,7 @@ function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeC
14594
14685
  if (keepLooking) buildExtendsTree(compilerCtx, foundClassDeclaration, dependentClasses, typeChecker, buildCtx, ogModule);
14595
14686
  return;
14596
14687
  }
14597
- const importStatements = currentSource.statements.filter(ts.isImportDeclaration);
14598
- importStatements.forEach((statement) => {
14688
+ currentSource.statements.filter(ts.isImportDeclaration).forEach((statement) => {
14599
14689
  if (statement.importClause?.namedBindings && ts.isNamedImports(statement.importClause?.namedBindings)) statement.importClause?.namedBindings.elements.forEach((element) => {
14600
14690
  if (element.name.getText() === extendee.getText()) {
14601
14691
  const className = element.propertyName?.getText() || element.name.getText();
@@ -14603,11 +14693,6 @@ function buildExtendsTree(compilerCtx, classDeclaration, dependentClasses, typeC
14603
14693
  }
14604
14694
  });
14605
14695
  });
14606
- if (!importStatements.length) currentSource.statements.filter(ts.isVariableStatement).forEach((statement) => {
14607
- statement.declarationList.declarations.forEach((declaration) => {
14608
- if (declaration.initializer && ts.isCallExpression(declaration.initializer) && ts.isIdentifier(declaration.initializer.expression) && declaration.initializer.expression.escapedText === "require" && declaration.initializer.arguments.length === 1 && ts.isStringLiteral(declaration.initializer.arguments[0])) resolveAndProcessExtendedClass(compilerCtx, buildCtx, classDeclaration, currentSource, declaration.initializer.arguments[0].text.replaceAll(/['"]/g, ""), extendee.getText(), dependentClasses, typeChecker, ogModule, targetScriptTarget);
14609
- });
14610
- });
14611
14696
  }
14612
14697
  });
14613
14698
  return dependentClasses;
@@ -14635,7 +14720,7 @@ function mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, sta
14635
14720
  let listeners = parseStaticListeners(staticMembers);
14636
14721
  let events = parseStaticEvents(staticMembers);
14637
14722
  let watchers = parseStaticWatchers(staticMembers);
14638
- let classMethods = cmpNode.members.filter(ts.isMethodDeclaration);
14723
+ let classMethods = cmpNode.members.filter(ts.isMethodDeclaration).map((m) => ts.isIdentifier(m.name) ? m.name.text : "").filter(Boolean);
14639
14724
  let serializers = parseStaticSerializers(staticMembers, "serializers");
14640
14725
  let deserializers = parseStaticSerializers(staticMembers, "deserializers");
14641
14726
  tree.forEach((extendedClass) => {
@@ -14668,7 +14753,7 @@ function mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, sta
14668
14753
  watchers = [...deDupeMembers(parseStaticWatchers(extendedStaticMembers) ?? [], watchers), ...watchers];
14669
14754
  serializers = [...deDupeMembers(parseStaticSerializers(extendedStaticMembers, "serializers") ?? [], serializers), ...serializers];
14670
14755
  deserializers = [...deDupeMembers(parseStaticSerializers(extendedStaticMembers, "deserializers") ?? [], deserializers), ...deserializers];
14671
- classMethods = [...classMethods, ...extendedClass.classNode.members.filter(ts.isMethodDeclaration) ?? []];
14756
+ classMethods = [...classMethods, ...extendedClass.classNode.members.filter(ts.isMethodDeclaration).map((m) => ts.isIdentifier(m.name) ? m.name.text : "").filter(Boolean)];
14672
14757
  if (isMixin) hasMixin = true;
14673
14758
  });
14674
14759
  return {
@@ -14685,23 +14770,274 @@ function mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, sta
14685
14770
  deserializers
14686
14771
  };
14687
14772
  }
14773
+ const EMPTY_DOCS = {
14774
+ text: "",
14775
+ tags: []
14776
+ };
14777
+ const EMPTY_PROP_COMPLEX_TYPE = {
14778
+ original: "any",
14779
+ resolved: "any",
14780
+ references: {}
14781
+ };
14782
+ const EMPTY_EVENT_COMPLEX_TYPE = {
14783
+ original: "any",
14784
+ resolved: "any",
14785
+ references: {}
14786
+ };
14787
+ const EMPTY_METHOD_COMPLEX_TYPE = {
14788
+ signature: "() => void",
14789
+ parameters: [],
14790
+ references: {},
14791
+ return: "void"
14792
+ };
14793
+ function extractDecoratorOptions(node) {
14794
+ if (!node || !ts.isObjectLiteralExpression(node)) return {};
14795
+ const result = {};
14796
+ for (const prop of node.properties) {
14797
+ if (!ts.isPropertyAssignment(prop) || !ts.isIdentifier(prop.name)) continue;
14798
+ const key = prop.name.text;
14799
+ const val = prop.initializer;
14800
+ if (ts.isStringLiteral(val)) result[key] = val.text;
14801
+ else if (val.kind === ts.SyntaxKind.TrueKeyword) result[key] = true;
14802
+ else if (val.kind === ts.SyntaxKind.FalseKeyword) result[key] = false;
14803
+ else if (ts.isNumericLiteral(val)) result[key] = Number(val.text);
14804
+ }
14805
+ return result;
14806
+ }
14807
+ /**
14808
+ * Extract Stencil member metadata from source text using parse-only TypeScript
14809
+ * (no Program, no TypeChecker). Handles both decorator syntax (.tsx source files)
14810
+ * and compiled static getter syntax (.js collection files).
14811
+ *
14812
+ * @param code source text to parse
14813
+ * @param className name of the class to extract metadata from
14814
+ * @param fileName virtual filename used to determine script kind
14815
+ * @returns extracted metadata, or null if the named class is not found
14816
+ */
14817
+ function extractInheritedMeta(code, className, fileName = "__stencil_parent__.tsx") {
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;
14821
+ const methodNames = classDecl.members.filter(ts.isMethodDeclaration).map((m) => ts.isIdentifier(m.name) ? m.name.text : "").filter(Boolean);
14822
+ const staticMembers = classDecl.members.filter(isStaticGetter);
14823
+ if (staticMembers.some((m) => ts.isGetAccessorDeclaration(m) && ts.isIdentifier(m.name) && [
14824
+ "properties",
14825
+ "states",
14826
+ "events",
14827
+ "listeners",
14828
+ "watchers",
14829
+ "methods"
14830
+ ].includes(m.name.text))) return {
14831
+ properties: parseStaticProps(staticMembers),
14832
+ states: parseStaticStates(staticMembers),
14833
+ methods: parseStaticMethods(staticMembers),
14834
+ events: parseStaticEvents(staticMembers),
14835
+ listeners: parseStaticListeners(staticMembers),
14836
+ watchers: parseStaticWatchers(staticMembers),
14837
+ methodNames
14838
+ };
14839
+ const properties = [];
14840
+ const states = [];
14841
+ const methods = [];
14842
+ const events = [];
14843
+ const listeners = [];
14844
+ const watchers = [];
14845
+ for (const member of classDecl.members) {
14846
+ if (!ts.isPropertyDeclaration(member) && !ts.isMethodDeclaration(member)) continue;
14847
+ if (!ts.isIdentifier(member.name)) continue;
14848
+ const memberName = member.name.text;
14849
+ const decorators = ts.getDecorators?.(member) ?? [];
14850
+ for (const dec of decorators) {
14851
+ if (!ts.isCallExpression(dec.expression) || !ts.isIdentifier(dec.expression.expression)) continue;
14852
+ const decName = dec.expression.expression.text;
14853
+ const args = dec.expression.arguments;
14854
+ if (decName === "Prop" && ts.isPropertyDeclaration(member)) {
14855
+ const opts = extractDecoratorOptions(args[0]);
14856
+ properties.push({
14857
+ name: memberName,
14858
+ attribute: typeof opts.attribute === "string" ? opts.attribute.toLowerCase() : toDashCase(memberName),
14859
+ reflect: !!opts.reflect,
14860
+ mutable: !!opts.mutable,
14861
+ required: false,
14862
+ optional: !!member.questionToken,
14863
+ type: "any",
14864
+ complexType: EMPTY_PROP_COMPLEX_TYPE,
14865
+ docs: EMPTY_DOCS,
14866
+ internal: false,
14867
+ getter: false,
14868
+ setter: false
14869
+ });
14870
+ } else if (decName === "State" && ts.isPropertyDeclaration(member)) states.push({ name: memberName });
14871
+ else if (decName === "Event" && ts.isPropertyDeclaration(member)) {
14872
+ const opts = extractDecoratorOptions(args[0]);
14873
+ events.push({
14874
+ name: typeof opts.eventName === "string" ? opts.eventName : memberName,
14875
+ method: memberName,
14876
+ bubbles: opts.bubbles !== false,
14877
+ cancelable: opts.cancelable !== false,
14878
+ composed: !!opts.composed,
14879
+ docs: EMPTY_DOCS,
14880
+ complexType: EMPTY_EVENT_COMPLEX_TYPE,
14881
+ internal: false
14882
+ });
14883
+ } else if (decName === "Method" && ts.isMethodDeclaration(member)) methods.push({
14884
+ name: memberName,
14885
+ docs: EMPTY_DOCS,
14886
+ complexType: EMPTY_METHOD_COMPLEX_TYPE,
14887
+ internal: false
14888
+ });
14889
+ else if (decName === "Watch" && ts.isMethodDeclaration(member)) {
14890
+ const propName = ts.isStringLiteral(args[0]) ? args[0].text : null;
14891
+ if (propName) watchers.push({
14892
+ propName,
14893
+ methodName: memberName
14894
+ });
14895
+ } else if (decName === "Listen" && ts.isMethodDeclaration(member)) {
14896
+ const eventName = ts.isStringLiteral(args[0]) ? args[0].text : null;
14897
+ if (eventName) {
14898
+ const listenOpts = extractDecoratorOptions(args[1]);
14899
+ listeners.push({
14900
+ name: eventName,
14901
+ method: memberName,
14902
+ capture: !!listenOpts.capture,
14903
+ passive: !!listenOpts.passive,
14904
+ target: typeof listenOpts.target === "string" ? listenOpts.target : void 0
14905
+ });
14906
+ }
14907
+ }
14908
+ }
14909
+ }
14910
+ return {
14911
+ properties,
14912
+ states,
14913
+ methods,
14914
+ events,
14915
+ listeners,
14916
+ watchers,
14917
+ methodNames
14918
+ };
14919
+ }
14920
+ function getExtendsClassName(node) {
14921
+ const heritage = node.heritageClauses?.find((h) => h.token === ts.SyntaxKind.ExtendsKeyword);
14922
+ if (!heritage?.types.length) return null;
14923
+ const expr = heritage.types[0].expression;
14924
+ return ts.isIdentifier(expr) ? expr.text : null;
14925
+ }
14926
+ function findImportSpecifier(sf, localName) {
14927
+ for (const stmt of sf.statements) {
14928
+ if (!ts.isImportDeclaration(stmt) || !ts.isStringLiteral(stmt.moduleSpecifier)) continue;
14929
+ const clause = stmt.importClause;
14930
+ if (!clause) continue;
14931
+ if (clause.name?.text === localName) return stmt.moduleSpecifier.text;
14932
+ const bindings = clause.namedBindings;
14933
+ if (bindings && ts.isNamedImports(bindings)) {
14934
+ for (const el of bindings.elements) if (el.name.text === localName) return stmt.moduleSpecifier.text;
14935
+ }
14936
+ }
14937
+ return null;
14938
+ }
14939
+ /**
14940
+ * Resolves the inheritance chain for a component using a caller-supplied
14941
+ * `resolveImport` callback instead of the full compiler infrastructure.
14942
+ * Safe to call from `transpileSync`/`transpileAsync` (no TypeChecker needed).
14943
+ *
14944
+ * @param cmpNode the component's class declaration
14945
+ * @param staticMembers static getter members already parsed from the component
14946
+ * @param sourceFile the source file containing the component (for import resolution)
14947
+ * @param resolveImport callback that resolves an import specifier to source code
14948
+ * @returns merged metadata including all inherited members
14949
+ */
14950
+ function mergeExtendedClassMetaWithResolveImport(cmpNode, staticMembers, sourceFile, resolveImport) {
14951
+ let doesExtend = false;
14952
+ let properties = parseStaticProps(staticMembers);
14953
+ let states = parseStaticStates(staticMembers);
14954
+ let methods = parseStaticMethods(staticMembers);
14955
+ let listeners = parseStaticListeners(staticMembers);
14956
+ let events = parseStaticEvents(staticMembers);
14957
+ let watchers = parseStaticWatchers(staticMembers);
14958
+ let classMethods = cmpNode.members.filter(ts.isMethodDeclaration).map((m) => ts.isIdentifier(m.name) ? m.name.text : "").filter(Boolean);
14959
+ const serializers = [];
14960
+ const deserializers = [];
14961
+ let currentNode = cmpNode;
14962
+ let currentSf = sourceFile;
14963
+ let currentPath = sourceFile.fileName;
14964
+ const visited = /* @__PURE__ */ new Set();
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;
14997
+ doesExtend = true;
14998
+ const mixinPropsExcludingStates = parentMeta.properties.filter((mp) => !states.some((s) => s.name === mp.name));
14999
+ const mixinStatesExcludingProps = parentMeta.states.filter((ms) => !properties.some((p) => p.name === ms.name));
15000
+ properties = [...deDupeMembers(mixinPropsExcludingStates, properties), ...properties];
15001
+ states = [...deDupeMembers(mixinStatesExcludingProps, states), ...states];
15002
+ methods = [...deDupeMembers(parentMeta.methods, methods), ...methods];
15003
+ events = [...deDupeMembers(parentMeta.events, events), ...events];
15004
+ listeners = [...deDupeMembers(parentMeta.listeners, listeners), ...listeners];
15005
+ watchers = [...deDupeMembers(parentMeta.watchers, watchers), ...watchers];
15006
+ classMethods = [...classMethods, ...parentMeta.methodNames];
15007
+ currentNode = parentClass;
15008
+ currentSf = parentSf;
15009
+ currentPath = resolvedPath;
15010
+ }
15011
+ return {
15012
+ doesExtend,
15013
+ properties,
15014
+ states,
15015
+ methods,
15016
+ listeners,
15017
+ events,
15018
+ watchers,
15019
+ classMethods,
15020
+ serializers,
15021
+ deserializers
15022
+ };
15023
+ }
14688
15024
  //#endregion
14689
15025
  //#region src/compiler/transformers/static-to-meta/class-methods.ts
14690
15026
  const parseClassMethods = (classMethods, cmpMeta) => {
14691
15027
  if (!classMethods?.length) return;
14692
- const hasHostData = classMethods.some((m) => isMethod(m, "hostData"));
14693
- cmpMeta.hasAttributeChangedCallbackFn = classMethods.some((m) => isMethod(m, "attributeChangedCallback"));
14694
- cmpMeta.hasConnectedCallbackFn = classMethods.some((m) => isMethod(m, "connectedCallback"));
14695
- cmpMeta.hasDisconnectedCallbackFn = classMethods.some((m) => isMethod(m, "disconnectedCallback"));
14696
- cmpMeta.hasComponentWillLoadFn = classMethods.some((m) => isMethod(m, "componentWillLoad"));
14697
- cmpMeta.hasComponentWillUpdateFn = classMethods.some((m) => isMethod(m, "componentWillUpdate"));
14698
- cmpMeta.hasComponentWillRenderFn = classMethods.some((m) => isMethod(m, "componentWillRender"));
14699
- cmpMeta.hasComponentDidRenderFn = classMethods.some((m) => isMethod(m, "componentDidRender"));
14700
- cmpMeta.hasComponentDidLoadFn = classMethods.some((m) => isMethod(m, "componentDidLoad"));
14701
- cmpMeta.hasComponentShouldUpdateFn = classMethods.some((m) => isMethod(m, "componentShouldUpdate"));
14702
- cmpMeta.hasComponentDidUpdateFn = classMethods.some((m) => isMethod(m, "componentDidUpdate"));
15028
+ const hasHostData = classMethods.includes("hostData");
15029
+ cmpMeta.hasAttributeChangedCallbackFn = classMethods.includes("attributeChangedCallback");
15030
+ cmpMeta.hasConnectedCallbackFn = classMethods.includes("connectedCallback");
15031
+ cmpMeta.hasDisconnectedCallbackFn = classMethods.includes("disconnectedCallback");
15032
+ cmpMeta.hasComponentWillLoadFn = classMethods.includes("componentWillLoad");
15033
+ cmpMeta.hasComponentWillUpdateFn = classMethods.includes("componentWillUpdate");
15034
+ cmpMeta.hasComponentWillRenderFn = classMethods.includes("componentWillRender");
15035
+ cmpMeta.hasComponentDidRenderFn = classMethods.includes("componentDidRender");
15036
+ cmpMeta.hasComponentDidLoadFn = classMethods.includes("componentDidLoad");
15037
+ cmpMeta.hasComponentShouldUpdateFn = classMethods.includes("componentShouldUpdate");
15038
+ cmpMeta.hasComponentDidUpdateFn = classMethods.includes("componentDidUpdate");
14703
15039
  cmpMeta.hasLifecycle = cmpMeta.hasComponentWillLoadFn || cmpMeta.hasComponentDidLoadFn || cmpMeta.hasComponentWillUpdateFn || cmpMeta.hasComponentDidUpdateFn;
14704
- cmpMeta.hasRenderFn = classMethods.some((m) => isMethod(m, "render")) || hasHostData;
15040
+ cmpMeta.hasRenderFn = classMethods.includes("render") || hasHostData;
14705
15041
  cmpMeta.hasVdomRender = cmpMeta.hasVdomRender || hasHostData;
14706
15042
  };
14707
15043
  //#endregion
@@ -14955,7 +15291,7 @@ const parseStaticComponentMeta = (compilerCtx, typeChecker, cmpNode, moduleFile,
14955
15291
  const staticMembers = cmpNode.members.filter(isStaticGetter);
14956
15292
  const tagName = getComponentTagName(staticMembers);
14957
15293
  if (tagName == null) return cmpNode;
14958
- const { doesExtend, properties, states, methods, listeners, events, watchers, classMethods, serializers, deserializers } = mergeExtendedClassMeta(compilerCtx, typeChecker, buildCtx, cmpNode, staticMembers, moduleFile);
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);
14959
15295
  const docs = serializeSymbol(typeChecker, typeChecker ? typeChecker.getSymbolAtLocation(cmpNode.name) : void 0);
14960
15296
  const isCollectionDependency = moduleFile.isCollectionDependency;
14961
15297
  const encapsulation = parseStaticEncapsulation(staticMembers);
@@ -22792,7 +23128,9 @@ const getTranspileConfig = (input) => {
22792
23128
  style: compileOpts.style,
22793
23129
  styleImportData: compileOpts.styleImportData,
22794
23130
  target: compileOpts.target,
22795
- extraFiles: input.extraFiles
23131
+ resolveImport: input.resolveImport,
23132
+ transformAsBaseClass: input.transformAsBaseClass,
23133
+ buildOverrides: input.buildOverrides
22796
23134
  };
22797
23135
  return {
22798
23136
  compileOpts,
@@ -22920,21 +23258,8 @@ const transpileModule = (config, input, transformOpts) => {
22920
23258
  if (tsCompilerOptions.jsx != null && !isAutomaticRuntime && !isString$1(tsCompilerOptions.jsxFragmentFactory)) tsCompilerOptions.jsxFragmentFactory = "Fragment";
22921
23259
  if (tsCompilerOptions.paths && !isString$1(tsCompilerOptions.baseUrl)) tsCompilerOptions.baseUrl = ".";
22922
23260
  const sourceFile = ts.createSourceFile(sourceFilePath, input, tsCompilerOptions.target);
22923
- const extraSourceFiles = /* @__PURE__ */ new Map();
22924
- if (transformOpts.extraFiles) {
22925
- const currentDir = normalizePath(transformOpts.currentDirectory || process.cwd());
22926
- for (const [filePath, text] of Object.entries(transformOpts.extraFiles)) {
22927
- const resolvedPath = normalizePath(filePath.startsWith("/") ? filePath : join$2(currentDir, filePath));
22928
- extraSourceFiles.set(resolvedPath, ts.createSourceFile(resolvedPath, text, tsCompilerOptions.target));
22929
- }
22930
- tsCompilerOptions.noResolve = false;
22931
- }
22932
- const compilerHost = {
22933
- getSourceFile: (fileName) => {
22934
- const normalized = normalizePath(fileName);
22935
- if (normalized === normalizePath(sourceFilePath)) return sourceFile;
22936
- return extraSourceFiles.get(normalized);
22937
- },
23261
+ const program = ts.createProgram([sourceFilePath], tsCompilerOptions, {
23262
+ getSourceFile: (fileName) => normalizePath(fileName) === normalizePath(sourceFilePath) ? sourceFile : void 0,
22938
23263
  writeFile: (name, text) => {
22939
23264
  if (name.endsWith(".js.map") || name.endsWith(".mjs.map")) results.map = text;
22940
23265
  else if (name.endsWith(".js") || name.endsWith(".mjs")) results.code = text;
@@ -22944,45 +23269,12 @@ const transpileModule = (config, input, transformOpts) => {
22944
23269
  getCanonicalFileName: (fileName) => fileName,
22945
23270
  getCurrentDirectory: () => transformOpts.currentDirectory || process.cwd(),
22946
23271
  getNewLine: () => ts.sys.newLine || "\n",
22947
- fileExists: (fileName) => {
22948
- const normalized = normalizePath(fileName);
22949
- return normalized === normalizePath(sourceFilePath) || extraSourceFiles.has(normalized);
22950
- },
23272
+ fileExists: (fileName) => normalizePath(fileName) === normalizePath(sourceFilePath),
22951
23273
  readFile: () => "",
22952
23274
  directoryExists: () => true,
22953
23275
  getDirectories: () => []
22954
- };
22955
- const program = ts.createProgram([sourceFilePath, ...extraSourceFiles.keys()], tsCompilerOptions, compilerHost);
23276
+ });
22956
23277
  const typeChecker = program.getTypeChecker();
22957
- if (extraSourceFiles.size > 0) {
22958
- const miniCompilerHost = {
22959
- getSourceFile: (fileName) => extraSourceFiles.get(normalizePath(fileName)),
22960
- writeFile: () => {},
22961
- getDefaultLibFileName: () => "lib.d.ts",
22962
- useCaseSensitiveFileNames: () => false,
22963
- getCanonicalFileName: (f) => f,
22964
- getCurrentDirectory: () => transformOpts.currentDirectory || process.cwd(),
22965
- getNewLine: () => ts.sys.newLine || "\n",
22966
- fileExists: (f) => extraSourceFiles.has(normalizePath(f)),
22967
- readFile: () => "",
22968
- directoryExists: () => true,
22969
- getDirectories: () => []
22970
- };
22971
- const miniProgram = ts.createProgram([...extraSourceFiles.keys()], {
22972
- ...tsCompilerOptions,
22973
- noResolve: true
22974
- }, miniCompilerHost);
22975
- const miniTypeChecker = miniProgram.getTypeChecker();
22976
- const decoratorConverter = convertDecoratorsToStatic(config, buildCtx.diagnostics, miniTypeChecker, miniProgram);
22977
- for (const [resolvedPath, rawSource] of extraSourceFiles) {
22978
- const transformResult = ts.transform(rawSource, [decoratorConverter], tsCompilerOptions);
22979
- const processedSource = transformResult.transformed[0];
22980
- transformResult.dispose();
22981
- const moduleFile = getModuleLegacy(compilerCtx, resolvedPath);
22982
- moduleFile.staticSourceFile = processedSource;
22983
- moduleFile.staticSourceFileText = processedSource.getFullText?.() ?? rawSource.text;
22984
- }
22985
- }
22986
23278
  const transformers = {
22987
23279
  before: [
22988
23280
  convertDecoratorsToStatic(config, buildCtx.diagnostics, typeChecker, program),
@@ -22998,8 +23290,11 @@ const transpileModule = (config, input, transformOpts) => {
22998
23290
  }
22999
23291
  if (transformOpts.componentExport === "customelement" || transformOpts.componentExport === "module") transformers.after.push(nativeComponentTransform(compilerCtx, transformOpts, buildCtx));
23000
23292
  else transformers.after.push(lazyComponentTransform(compilerCtx, transformOpts, buildCtx));
23001
- const emitTarget = extraSourceFiles.size > 0 ? program.getSourceFile(sourceFilePath) : void 0;
23002
- program.emit(emitTarget, void 0, void 0, false, transformers);
23293
+ program.emit(void 0, void 0, void 0, false, transformers);
23294
+ if (transformOpts.buildOverrides && results.code) {
23295
+ const mutations = Object.entries(transformOpts.buildOverrides).filter(([, v]) => v !== void 0).map(([k, v]) => `__stencilBUILD.${k}=${v};`).join("");
23296
+ if (mutations) results.code = `import{BUILD as __stencilBUILD}from"${STENCIL_APP_DATA_ID}";\n${mutations}\n` + results.code;
23297
+ }
23003
23298
  const tsDiagnostics = [...program.getSyntacticDiagnostics()];
23004
23299
  if (config.validateTypes) tsDiagnostics.push(...program.getOptionsDiagnostics());
23005
23300
  buildCtx.diagnostics.push(...loadTypeScriptDiagnostics(tsDiagnostics));
@@ -23097,7 +23392,11 @@ const transpileCode = (config, transpileOpts, transformOpts, results) => {
23097
23392
  if (moduleFile) {
23098
23393
  results.outputFilePath = moduleFile.jsFilePath;
23099
23394
  moduleFile.cmps.forEach((cmp) => {
23100
- results.data.push(getPublicCompilerMeta(cmp));
23395
+ results.data.push({
23396
+ ...getPublicCompilerMeta(cmp),
23397
+ docs: cmp.docs,
23398
+ styleDocs: cmp.styleDocs
23399
+ });
23101
23400
  });
23102
23401
  moduleFile.originalImports.forEach((originalImport) => {
23103
23402
  results.imports.push({ path: originalImport });
@@ -23134,4 +23433,4 @@ const shouldTranspileModule = (ext) => [
23134
23433
  "js"
23135
23434
  ].includes(ext);
23136
23435
  //#endregion
23137
- export { getBuildFeatures as _, createPrerenderer as a, version as b, createWorkerContext as c, nodeRequire as d, optimizeCss as f, BuildContext as g, Cache as h, createSystem as i, createWorkerMessageHandler as l, validateConfig as m, transpile as n, loadConfig as o, createInMemoryFs as p, transpileSync as r, createCompiler as s, ts$1 as t, optimizeJs as u, buildId as v, versions as x, vermoji as y };
23436
+ export { version as C, vermoji as S, cmpMetaToDocsComponent as _, createPrerenderer as a, getBuildFeatures as b, createWorkerContext as c, nodeRequire as d, optimizeCss as f, generateManifest as g, Cache as h, createSystem as i, createWorkerMessageHandler as l, validateConfig as m, transpile as n, loadConfig as o, createInMemoryFs as p, transpileSync as r, createCompiler as s, ts$1 as t, optimizeJs as u, BuildContext as v, versions as w, buildId as x, getScopeId as y };