@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.
Files changed (44) hide show
  1. package/dist/app-data/index.d.ts +1 -1
  2. package/dist/{client-CvcvHKz4.mjs → client-D1MsT-Rp.mjs} +373 -238
  3. package/dist/compiler/index.d.mts +2 -3
  4. package/dist/compiler/index.mjs +3 -3
  5. package/dist/compiler/utils/index.d.mts +272 -2
  6. package/dist/compiler/utils/index.mjs +4 -3
  7. package/dist/{compiler-D43Ied7R.mjs → compiler-BbS9TDF_.mjs} +1845 -1118
  8. package/dist/declarations/stencil-ext-modules.d.ts +5 -5
  9. package/dist/declarations/stencil-public-compiler.d.ts +108 -40
  10. package/dist/declarations/stencil-public-docs.d.ts +9 -0
  11. package/dist/declarations/stencil-public-runtime.d.ts +81 -6
  12. package/dist/fragment-Di1hWOC8.mjs +4 -0
  13. package/dist/{index-F3IidHM1.d.mts → index-BHj3EBl2.d.mts} +395 -312
  14. package/dist/{index-xAkMgLX_.d.ts → index-D2PAsXxx.d.ts} +133 -9
  15. package/dist/index-VK8okIiF.d.mts +108 -0
  16. package/dist/index.d.mts +4 -0
  17. package/dist/index.mjs +91 -2
  18. package/dist/jsx-runtime.mjs +2 -1
  19. package/dist/{node-DKVq_Ud0.mjs → node-BQR4L-TG.mjs} +60 -58
  20. package/dist/reactive-controller-BdCpSAQP.d.mts +13 -0
  21. package/dist/{regular-expression-CFVJOTUh.mjs → regular-expression-XqU5zmPp.mjs} +20 -3
  22. package/dist/{chunk-z9aeyW2b.mjs → rolldown-runtime-BhDjJH2R.mjs} +1 -1
  23. package/dist/runtime/client/lazy.js +411 -165
  24. package/dist/runtime/client/runtime.d.ts +136 -9
  25. package/dist/runtime/client/runtime.js +411 -165
  26. package/dist/runtime/index.d.ts +5 -3
  27. package/dist/runtime/index.js +410 -163
  28. package/dist/runtime/server/index.d.mts +80 -8
  29. package/dist/runtime/server/index.mjs +333 -158
  30. package/dist/runtime/server/runner.d.mts +3 -0
  31. package/dist/runtime/server/runner.mjs +232 -308
  32. package/dist/signals/index.d.ts +2 -0
  33. package/dist/sys/node/index.d.mts +1 -2
  34. package/dist/sys/node/index.mjs +1 -1
  35. package/dist/sys/node/worker.d.mts +1 -1
  36. package/dist/sys/node/worker.mjs +6 -3
  37. package/dist/testing/index.d.mts +4 -9
  38. package/dist/testing/index.mjs +74 -56
  39. package/dist/util-BIa-iHnt.mjs +724 -0
  40. package/dist/validation-Dd3g77T5.mjs +778 -0
  41. package/package.json +27 -27
  42. package/dist/index-3fu7WQs4.d.mts +0 -205
  43. package/dist/validation-ByxKj8bC.mjs +0 -1458
  44. /package/{LICENSE.md → LICENSE} +0 -0
@@ -0,0 +1,724 @@
1
+ import { $ as TYPES, B as GLOBAL_STYLE, C as ASSETS, F as DOCS_JSON, I as DOCS_README, J as SSR_WASM, L as DOCS_VSCODE, M as DOCS_AGENT_SKILL, N as DOCS_CUSTOM, O as COPY, P as DOCS_CUSTOM_ELEMENTS_MANIFEST, T as COLLECTION, W as LOADER_BUNDLE, X as STATS, Y as STANDALONE, _ as sortBy, et as VALID_CONFIG_OUTPUT_TARGETS, i as flatOne, j as DIST_LAZY, k as CUSTOM, n as dashToPascalCase, p as isString, r as escapeWithPattern, y as toDashCase, z as GENERATED_DTS } from "./regular-expression-XqU5zmPp.mjs";
2
+ import nodePath, { basename, dirname, relative } from "node:path";
3
+ import picomatch from "picomatch";
4
+ //#region src/utils/is-glob.ts
5
+ /**
6
+ * Check if a string is a glob pattern (e.g. 'src/*.js' or something like that)
7
+ *
8
+ * @param str a string to check
9
+ * @returns whether the string is a glob pattern or not
10
+ */
11
+ const isGlob = (str) => {
12
+ const chars = {
13
+ "{": "}",
14
+ "(": ")",
15
+ "[": "]"
16
+ };
17
+ const regex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/;
18
+ if (str === "") return false;
19
+ let match;
20
+ while (match = regex.exec(str)) {
21
+ if (match[2]) return true;
22
+ let idx = match.index + match[0].length;
23
+ const open = match[1];
24
+ const close = open ? chars[open] : null;
25
+ if (open && close) {
26
+ const n = str.indexOf(close, idx);
27
+ if (n !== -1) idx = n + 1;
28
+ }
29
+ str = str.slice(idx);
30
+ }
31
+ return false;
32
+ };
33
+ //#endregion
34
+ //#region src/utils/message-utils.ts
35
+ /**
36
+ * Builds a template `Diagnostic` entity for a build error. The created `Diagnostic` is returned, and have little
37
+ * detail attached to it regarding the specifics of the error - it is the responsibility of the caller of this method
38
+ * to attach the specifics of the error message.
39
+ *
40
+ * The created `Diagnostic` is pushed to the `diagnostics` argument as a side effect of calling this method.
41
+ *
42
+ * @param diagnostics the existing diagnostics that the created template `Diagnostic` should be added to
43
+ * @returns the created `Diagnostic`
44
+ */
45
+ const buildError = (diagnostics) => {
46
+ const diagnostic = {
47
+ level: "error",
48
+ type: "build",
49
+ header: "Build Error",
50
+ messageText: "build error",
51
+ relFilePath: void 0,
52
+ absFilePath: void 0,
53
+ lines: []
54
+ };
55
+ if (diagnostics) diagnostics.push(diagnostic);
56
+ return diagnostic;
57
+ };
58
+ /**
59
+ * Builds a template `Diagnostic` entity for a build warning. The created `Diagnostic` is returned, and have little
60
+ * detail attached to it regarding the specifics of the warning - it is the responsibility of the caller of this method
61
+ * to attach the specifics of the warning message.
62
+ *
63
+ * The created `Diagnostic` is pushed to the `diagnostics` argument as a side effect of calling this method.
64
+ *
65
+ * @param diagnostics the existing diagnostics that the created template `Diagnostic` should be added to
66
+ * @returns the created `Diagnostic`
67
+ */
68
+ const buildWarn = (diagnostics) => {
69
+ const diagnostic = {
70
+ level: "warn",
71
+ type: "build",
72
+ header: "Build Warn",
73
+ messageText: "build warn",
74
+ lines: []
75
+ };
76
+ diagnostics.push(diagnostic);
77
+ return diagnostic;
78
+ };
79
+ /**
80
+ * Create a diagnostic message suited for representing an error in a JSON
81
+ * file. This includes information about the exact lines in the JSON file which
82
+ * caused the error and the path to the file.
83
+ *
84
+ * @param compilerCtx the current compiler context
85
+ * @param diagnostics a list of diagnostics used as a return param
86
+ * @param jsonFilePath the path to the JSON file where the error occurred
87
+ * @param msg the error message
88
+ * @param jsonField the key for the field which caused the error, used for finding
89
+ * the error line in the original JSON file. Only root-level keys (with minimal
90
+ * indentation, typically 2 spaces) are highlighted to avoid matching nested keys.
91
+ * @returns a reference to the newly-created diagnostic
92
+ */
93
+ const buildJsonFileError = (compilerCtx, diagnostics, jsonFilePath, msg, jsonField) => {
94
+ const err = buildError(diagnostics);
95
+ err.messageText = msg;
96
+ err.absFilePath = jsonFilePath;
97
+ if (typeof jsonField === "string") try {
98
+ const lines = compilerCtx.fs.readFileSync(jsonFilePath).replace(/\r/g, "\n").split("\n");
99
+ let bestMatch = null;
100
+ const ROOT_LEVEL_INDENTATION = 2;
101
+ for (let i = 0; i < lines.length; i++) {
102
+ const txtLine = lines[i];
103
+ const txtIndex = txtLine.indexOf(jsonField);
104
+ if (txtIndex > -1) {
105
+ const indentation = txtLine.search(/\S/);
106
+ if (indentation === ROOT_LEVEL_INDENTATION) {
107
+ bestMatch = {
108
+ lineIndex: i,
109
+ charIndex: txtIndex,
110
+ indentation
111
+ };
112
+ break;
113
+ } else if (bestMatch === null || indentation < bestMatch.indentation) bestMatch = {
114
+ lineIndex: i,
115
+ charIndex: txtIndex,
116
+ indentation
117
+ };
118
+ }
119
+ }
120
+ if (bestMatch !== null && bestMatch.indentation === ROOT_LEVEL_INDENTATION) {
121
+ const i = bestMatch.lineIndex;
122
+ const txtIndex = bestMatch.charIndex;
123
+ const txtLine = lines[i];
124
+ const warnLine = {
125
+ lineIndex: i,
126
+ lineNumber: i + 1,
127
+ text: txtLine,
128
+ errorCharStart: txtIndex,
129
+ errorLength: jsonField.length
130
+ };
131
+ err.lineNumber = warnLine.lineNumber;
132
+ err.columnNumber = txtIndex + 1;
133
+ err.lines.push(warnLine);
134
+ if (i > 0) {
135
+ const beforeWarnLine = {
136
+ lineIndex: warnLine.lineIndex - 1,
137
+ lineNumber: warnLine.lineNumber - 1,
138
+ text: lines[i - 1],
139
+ errorCharStart: -1,
140
+ errorLength: -1
141
+ };
142
+ err.lines.unshift(beforeWarnLine);
143
+ }
144
+ if (i < lines.length - 1) {
145
+ const afterWarnLine = {
146
+ lineIndex: warnLine.lineIndex + 1,
147
+ lineNumber: warnLine.lineNumber + 1,
148
+ text: lines[i + 1],
149
+ errorCharStart: -1,
150
+ errorLength: -1
151
+ };
152
+ err.lines.push(afterWarnLine);
153
+ }
154
+ }
155
+ } catch {}
156
+ return err;
157
+ };
158
+ /**
159
+ * Builds a diagnostic from an `Error`, appends it to the `diagnostics` parameter, and returns the created diagnostic
160
+ * @param diagnostics the series of diagnostics the newly created diagnostics should be added to
161
+ * @param err the error to derive information from in generating the diagnostic
162
+ * @param msg an optional message to use in place of `err` to generate the diagnostic
163
+ * @returns the generated diagnostic
164
+ */
165
+ const catchError = (diagnostics, err, msg) => {
166
+ const diagnostic = {
167
+ level: "error",
168
+ type: "build",
169
+ header: "Build Error",
170
+ messageText: "build error",
171
+ lines: []
172
+ };
173
+ if (isString(msg)) diagnostic.messageText = msg.length ? msg : "UNKNOWN ERROR";
174
+ else if (err != null) {
175
+ if (err.stack != null) diagnostic.messageText = err.stack.toString();
176
+ else if (err.message != null) diagnostic.messageText = err.message.length ? err.message : "UNKNOWN ERROR";
177
+ else diagnostic.messageText = err.toString();
178
+ }
179
+ if (diagnostics != null && !shouldIgnoreError(diagnostic.messageText)) diagnostics.push(diagnostic);
180
+ return diagnostic;
181
+ };
182
+ /**
183
+ * Determine if the provided diagnostics have any build errors
184
+ * @param diagnostics the diagnostics to inspect
185
+ * @returns true if any of the diagnostics in the list provided are errors that did not occur at runtime. false
186
+ * otherwise.
187
+ */
188
+ const hasError = (diagnostics) => {
189
+ if (diagnostics == null || diagnostics.length === 0) return false;
190
+ return diagnostics.some((d) => d.level === "error" && d.type !== "runtime");
191
+ };
192
+ /**
193
+ * Determine if the provided diagnostics have any warnings
194
+ * @param diagnostics the diagnostics to inspect
195
+ * @returns true if any of the diagnostics in the list provided are warnings. false otherwise.
196
+ */
197
+ const hasWarning = (diagnostics) => {
198
+ if (diagnostics == null || diagnostics.length === 0) return false;
199
+ return diagnostics.some((d) => d.level === "warn");
200
+ };
201
+ const shouldIgnoreError = (msg) => {
202
+ return msg === TASK_CANCELED_MSG;
203
+ };
204
+ const TASK_CANCELED_MSG = `task canceled`;
205
+ //#endregion
206
+ //#region src/utils/path.ts
207
+ /**
208
+ * Convert Windows backslash paths to slash paths: foo\\bar ➔ foo/bar
209
+ * Forward-slash paths can be used in Windows as long as they're not
210
+ * extended-length paths and don't contain any non-ascii characters.
211
+ * This was created since the path methods in Node.js outputs \\ paths on Windows.
212
+ * @param path the Windows-based path to convert
213
+ * @param relativize whether or not a relative path should have `./` prepended
214
+ * @returns the converted path
215
+ */
216
+ const normalizePath = (path, relativize = true) => {
217
+ if (typeof path !== "string") throw new Error(`invalid path to normalize`);
218
+ path = normalizeSlashes(path.trim());
219
+ const components = pathComponents(path, getRootLength(path));
220
+ const reducedComponents = reducePathComponents(components);
221
+ const rootPart = reducedComponents[0];
222
+ const secondPart = reducedComponents[1];
223
+ const normalized = rootPart + reducedComponents.slice(1).join("/");
224
+ if (normalized === "") return ".";
225
+ if (rootPart === "" && secondPart && path.includes("/") && !secondPart.startsWith(".") && !secondPart.startsWith("@") && relativize) return "./" + normalized;
226
+ return normalized;
227
+ };
228
+ const normalizeSlashes = (path) => path.replace(backslashRegExp, "/");
229
+ const altDirectorySeparator = "\\";
230
+ const urlSchemeSeparator = "://";
231
+ const backslashRegExp = /\\/g;
232
+ const reducePathComponents = (components) => {
233
+ if (!Array.isArray(components) || components.length === 0) return [];
234
+ const reduced = [components[0]];
235
+ for (let i = 1; i < components.length; i++) {
236
+ const component = components[i];
237
+ if (!component) continue;
238
+ if (component === ".") continue;
239
+ if (component === "..") {
240
+ if (reduced.length > 1) {
241
+ if (reduced[reduced.length - 1] !== "..") {
242
+ reduced.pop();
243
+ continue;
244
+ }
245
+ } else if (reduced[0]) continue;
246
+ }
247
+ reduced.push(component);
248
+ }
249
+ return reduced;
250
+ };
251
+ const getRootLength = (path) => {
252
+ const rootLength = getEncodedRootLength(path);
253
+ return rootLength < 0 ? ~rootLength : rootLength;
254
+ };
255
+ const getEncodedRootLength = (path) => {
256
+ if (!path) return 0;
257
+ const ch0 = path.charCodeAt(0);
258
+ if (ch0 === 47 || ch0 === 92) {
259
+ if (path.charCodeAt(1) !== ch0) return 1;
260
+ const p1 = path.indexOf(ch0 === 47 ? "/" : altDirectorySeparator, 2);
261
+ if (p1 < 0) return path.length;
262
+ return p1 + 1;
263
+ }
264
+ if (isVolumeCharacter(ch0) && path.charCodeAt(1) === 58) {
265
+ const ch2 = path.charCodeAt(2);
266
+ if (ch2 === 47 || ch2 === 92) return 3;
267
+ if (path.length === 2) return 2;
268
+ }
269
+ const schemeEnd = path.indexOf(urlSchemeSeparator);
270
+ if (schemeEnd !== -1) {
271
+ const authorityStart = schemeEnd + 3;
272
+ const authorityEnd = path.indexOf("/", authorityStart);
273
+ if (authorityEnd !== -1) {
274
+ const scheme = path.slice(0, schemeEnd);
275
+ const authority = path.slice(authorityStart, authorityEnd);
276
+ if (scheme === "file" && (authority === "" || authority === "localhost") && isVolumeCharacter(path.charCodeAt(authorityEnd + 1))) {
277
+ const volumeSeparatorEnd = getFileUrlVolumeSeparatorEnd(path, authorityEnd + 2);
278
+ if (volumeSeparatorEnd !== -1) {
279
+ if (path.charCodeAt(volumeSeparatorEnd) === 47) return ~(volumeSeparatorEnd + 1);
280
+ if (volumeSeparatorEnd === path.length) return ~volumeSeparatorEnd;
281
+ }
282
+ }
283
+ return ~(authorityEnd + 1);
284
+ }
285
+ return ~path.length;
286
+ }
287
+ return 0;
288
+ };
289
+ const isVolumeCharacter = (charCode) => charCode >= 97 && charCode <= 122 || charCode >= 65 && charCode <= 90;
290
+ const getFileUrlVolumeSeparatorEnd = (url, start) => {
291
+ const ch0 = url.charCodeAt(start);
292
+ if (ch0 === 58) return start + 1;
293
+ if (ch0 === 37 && url.charCodeAt(start + 1) === 51) {
294
+ const ch2 = url.charCodeAt(start + 2);
295
+ if (ch2 === 97 || ch2 === 65) return start + 3;
296
+ }
297
+ return -1;
298
+ };
299
+ const pathComponents = (path, rootLength) => {
300
+ const root = path.substring(0, rootLength);
301
+ const rest = path.substring(rootLength).split("/");
302
+ const restLen = rest.length;
303
+ if (restLen > 0 && !rest[restLen - 1]) rest.pop();
304
+ return [root, ...rest];
305
+ };
306
+ /**
307
+ * Same as normalizePath(), expect it'll also strip any query strings
308
+ * from the path name. So /dir/file.css?tag=cmp-a becomes /dir/file.css
309
+ * @param p the path to normalize
310
+ * @returns the normalized path, sans any query strings
311
+ */
312
+ const normalizeFsPath = (p) => normalizePath(p.split("?")[0].replace(/\0/g, ""));
313
+ const normalizeFsPathQuery = (importPath) => {
314
+ const pathParts = importPath.split("?");
315
+ const filePath = normalizePath(pathParts[0]);
316
+ const filePathParts = filePath.split(".");
317
+ const ext = filePathParts.length > 1 ? filePathParts.pop().toLowerCase() : null;
318
+ const params = pathParts.length > 1 ? new URLSearchParams(pathParts[1]) : null;
319
+ return {
320
+ filePath,
321
+ ext,
322
+ format: params ? params.get("format") : null
323
+ };
324
+ };
325
+ /**
326
+ * A wrapped version of node.js' {@link path.relative} which adds our custom
327
+ * normalization logic. This solves the relative path between `from` and `to`!
328
+ *
329
+ * The calculation of the returned path follows that of Node's logic, with one exception - if the calculated path
330
+ * results in an empty string, a string of length one with a period (`'.'`) is returned.
331
+ *
332
+ * @throws the underlying node.js function can throw if either path is not a
333
+ * string
334
+ * @param from the path where relative resolution starts
335
+ * @param to the destination path
336
+ * @returns the resolved relative path
337
+ */
338
+ function relative$1(from, to) {
339
+ /**
340
+ * When normalizing, we should _not_ attempt to relativize the path returned by the native Node `relative` method.
341
+ * When finding the relative path between `from` and `to`, Node does not prepend './' to a non-zero length calculated
342
+ * path. However, our algorithm does differ from that of Node's, as described in this function's JSDoc when a zero
343
+ * length string is encountered.
344
+ */
345
+ return normalizePath(nodePath.relative(from, to), false);
346
+ }
347
+ /**
348
+ * A wrapped version of node.js' {@link path.join} which adds our custom
349
+ * normalization logic. This joins all the arguments (path fragments) into a
350
+ * single path.
351
+ *
352
+ * The calculation of the returned path follows that of Node's logic, with one exception - any trailing slashes will
353
+ * be removed from the calculated path.
354
+ *
355
+ * @throws the underlying node function will throw if any argument is not a
356
+ * string
357
+ * @param paths the paths to join together
358
+ * @returns a joined path!
359
+ */
360
+ function join$1(...paths) {
361
+ /**
362
+ * When normalizing, we should _not_ attempt to relativize the path returned by the native Node `join` method. When
363
+ * calculating the path from each of the string-based parts, Node does not prepend './' to any calculated path.
364
+ *
365
+ * Note that our algorithm does differ from Node's, as described in this function's JSDoc regarding trailing
366
+ * slashes.
367
+ */
368
+ return normalizePath(nodePath.join(...paths), false);
369
+ }
370
+ /**
371
+ * A wrapped version of node.js' {@link path.resolve} which adds our custom
372
+ * normalization logic. This resolves a path to a given (relative or absolute)
373
+ * path.
374
+ *
375
+ * @throws the underlying node function will throw if any argument is not a
376
+ * string
377
+ * @param paths a path or path fragments to resolve
378
+ * @returns a resolved path!
379
+ */
380
+ function resolve$1(...paths) {
381
+ /**
382
+ * When normalizing, we should _not_ attempt to relativize the path returned by the native Node `resolve` method. When
383
+ * calculating the path from each of the string-based parts, Node does not prepend './' to the calculated path.
384
+ */
385
+ return normalizePath(nodePath.resolve(...paths), false);
386
+ }
387
+ /**
388
+ * A wrapped version of node.js' {@link path.normalize} which adds our custom
389
+ * normalization logic. This normalizes a path, de-duping repeated segment
390
+ * separators and resolving `'..'` segments.
391
+ *
392
+ * @throws the underlying node function will throw if the argument is not a
393
+ * string
394
+ * @param toNormalize a path to normalize
395
+ * @returns a normalized path!
396
+ */
397
+ function normalize(toNormalize) {
398
+ /**
399
+ * When normalizing, we should _not_ attempt to relativize the path returned by the native Node `normalize` method.
400
+ * When calculating the path from each of the string-based parts, Node does not prepend './' to the calculated path.
401
+ */
402
+ return normalizePath(nodePath.normalize(toNormalize), false);
403
+ }
404
+ //#endregion
405
+ //#region src/utils/output-target.ts
406
+ /**
407
+ * Checks if a component tag name matches any of the exclude patterns.
408
+ * Supports glob patterns using minimatch.
409
+ *
410
+ * @param tagName The component's tag name to check
411
+ * @param excludePatterns Array of patterns to match against (supports globs)
412
+ * @returns true if the component should be excluded, false otherwise
413
+ */
414
+ const shouldExcludeComponent = (tagName, excludePatterns) => {
415
+ if (!excludePatterns || excludePatterns.length === 0) return false;
416
+ return excludePatterns.some((pattern) => {
417
+ if (isGlob(pattern)) return picomatch.isMatch(tagName, pattern);
418
+ return pattern === tagName;
419
+ });
420
+ };
421
+ /**
422
+ * Filters out components that match the excludeComponents patterns from the config.
423
+ * Only applies filtering to production builds (when devMode is false) - dev builds include all components.
424
+ *
425
+ * @param components Array of component metadata
426
+ * @param config The validated Stencil configuration
427
+ * @returns Object containing filtered components and excluded components
428
+ */
429
+ const filterExcludedComponents = (components, config) => {
430
+ if (config.devMode) return {
431
+ components,
432
+ excludedComponents: []
433
+ };
434
+ const excludePatterns = config.excludeComponents;
435
+ if (!excludePatterns || excludePatterns.length === 0) return {
436
+ components,
437
+ excludedComponents: []
438
+ };
439
+ const excludedComponents = [];
440
+ const excludedTags = [];
441
+ const filtered = components.filter((cmp) => {
442
+ const shouldExclude = shouldExcludeComponent(cmp.tagName, excludePatterns);
443
+ if (shouldExclude) {
444
+ excludedComponents.push(cmp);
445
+ excludedTags.push(cmp.tagName);
446
+ config.logger.debug(`Excluding component from build: ${cmp.tagName}`);
447
+ }
448
+ return !shouldExclude;
449
+ });
450
+ if (excludedTags.length > 0) {
451
+ const tagList = excludedTags.join(", ");
452
+ config.logger.info(`Excluding ${excludedTags.length} component${excludedTags.length === 1 ? "" : "s"} from production build: ${tagList}`);
453
+ }
454
+ return {
455
+ components: filtered,
456
+ excludedComponents
457
+ };
458
+ };
459
+ const relativeImport = (pathFrom, pathTo, ext, addPrefix = true) => {
460
+ let relativePath = relative(dirname(pathFrom), dirname(pathTo));
461
+ if (addPrefix) {
462
+ if (relativePath === "") relativePath = ".";
463
+ else if (relativePath[0] !== ".") relativePath = "./" + relativePath;
464
+ }
465
+ return normalizePath(`${relativePath}/${basename(pathTo, ext)}`);
466
+ };
467
+ const getComponentsDtsSrcFilePath = (config) => join$1(config.srcDir, GENERATED_DTS);
468
+ /**
469
+ * Helper to get an appropriate file path for `components.d.ts` for an output target.
470
+ *
471
+ * @param typesDir the directory where types are generated
472
+ * @returns a properly-formatted path
473
+ */
474
+ const getComponentsDtsTypesFilePath = (typesDir) => join$1(typesDir, GENERATED_DTS);
475
+ const isOutputTargetLoaderBundle = (o) => o.type === LOADER_BUNDLE;
476
+ const isOutputTargetStandalone = (o) => o.type === STANDALONE;
477
+ const isOutputTargetSsr = (o) => o.type === "ssr";
478
+ const isOutputTargetSsrWasm = (o) => o.type === SSR_WASM;
479
+ const isOutputTargetCollection = (o) => o.type === COLLECTION;
480
+ const isOutputTargetTypes = (o) => o.type === TYPES;
481
+ const isOutputTargetGlobalStyle = (o) => o.type === GLOBAL_STYLE;
482
+ const isOutputTargetAssets = (o) => o.type === ASSETS;
483
+ const isOutputTargetCopy = (o) => o.type === COPY;
484
+ const isOutputTargetDistLazy = (o) => o.type === DIST_LAZY;
485
+ const isOutputTargetCustom = (o) => o.type === CUSTOM;
486
+ const isOutputTargetDocs = (o) => o.type === "docs-readme" || o.type === "docs-json" || o.type === "docs-custom" || o.type === "docs-vscode" || o.type === "docs-custom-elements-manifest" || o.type === "docs-agent-skill";
487
+ const isOutputTargetDocsReadme = (o) => o.type === DOCS_README;
488
+ const isOutputTargetDocsJson = (o) => o.type === DOCS_JSON;
489
+ const isOutputTargetDocsCustom = (o) => o.type === DOCS_CUSTOM;
490
+ const isOutputTargetDocsVscode = (o) => o.type === DOCS_VSCODE;
491
+ const isOutputTargetDocsCustomElementsManifest = (o) => o.type === DOCS_CUSTOM_ELEMENTS_MANIFEST;
492
+ const isOutputTargetDocsAgentSkill = (o) => o.type === DOCS_AGENT_SKILL;
493
+ const isOutputTargetWww = (o) => o.type === "www";
494
+ const isOutputTargetStats = (o) => o.type === STATS;
495
+ /**
496
+ * Retrieve the Stencil component compiler metadata from a collection of Stencil {@link d.Module}s
497
+ * @param moduleFiles the collection of `Module`s to retrieve the metadata from
498
+ * @returns the metadata, lexicographically sorted by the tag names of the components
499
+ */
500
+ const getComponentsFromModules = (moduleFiles) => sortBy(flatOne(moduleFiles.map((m) => m.cmps)), (c) => c.tagName);
501
+ /**
502
+ * Check whether a given output target is a valid one to be set in a Stencil config
503
+ *
504
+ * @param targetType the type which we want to check
505
+ * @returns whether or not the targetType is a valid, configurable output target.
506
+ */
507
+ function isValidConfigOutputTarget(targetType) {
508
+ return VALID_CONFIG_OUTPUT_TARGETS.includes(targetType);
509
+ }
510
+ /**
511
+ * Filter output targets based on devMode and their skipInDev setting.
512
+ * In dev mode, targets with `skipInDev: true` are filtered out.
513
+ * In prod mode, all targets are included.
514
+ *
515
+ * @param targets Array of output targets to filter
516
+ * @param devMode Whether we're in dev mode
517
+ * @returns Filtered array of active targets
518
+ */
519
+ const filterActiveTargets = (targets, devMode) => {
520
+ if (!devMode) return targets;
521
+ return targets.filter((t) => !t.skipInDev);
522
+ };
523
+ //#endregion
524
+ //#region src/utils/util.ts
525
+ /**
526
+ * A set of JSDoc tags which should be excluded from JSDoc comments
527
+ * included in output typedefs.
528
+ */
529
+ const SUPPRESSED_JSDOC_TAGS = [
530
+ "virtualProp",
531
+ "slot",
532
+ "part",
533
+ "internal"
534
+ ];
535
+ const LINE_BREAK_REGEX = /\r?\n|\r/g;
536
+ /**
537
+ * Create a stylistically-appropriate JS variable name from a filename
538
+ *
539
+ * If the filename has any of the special characters "?", "#", "&" and "=" it
540
+ * will take the string before the left-most instance of one of those
541
+ * characters.
542
+ *
543
+ * @param fileName the filename which serves as starting material
544
+ * @returns a JS variable name based on the filename
545
+ */
546
+ const createJsVarName = (fileName) => {
547
+ if (isString(fileName)) {
548
+ fileName = fileName.split("?")[0];
549
+ fileName = fileName.split("#")[0];
550
+ fileName = fileName.split("&")[0];
551
+ fileName = fileName.split("=")[0];
552
+ fileName = toDashCase(fileName);
553
+ fileName = fileName.replace(/[|;$%@"<>()+,.{}_!/\\]/g, "-");
554
+ fileName = dashToPascalCase(fileName);
555
+ if (fileName.length > 1) fileName = fileName[0].toLowerCase() + fileName.slice(1);
556
+ else fileName = fileName.toLowerCase();
557
+ if (fileName.length > 0 && !isNaN(fileName[0])) fileName = "_" + fileName;
558
+ }
559
+ return fileName;
560
+ };
561
+ /**
562
+ * Create a function that lowercases the first string parameter before passing it to the provided function
563
+ * @param fn the function to pass the lowercased path to
564
+ * @returns the result of the provided function
565
+ */
566
+ const lowerPathParam = (fn) => (p) => fn(p.toLowerCase());
567
+ /**
568
+ * Determine if a stringified file path is a TypeScript declaration file based on the extension at the end of the path.
569
+ * @param p the path to evaluate
570
+ * @returns `true` if the path ends in `.d.ts` (case-sensitive), `false` otherwise.
571
+ */
572
+ const isDtsFile = lowerPathParam((p) => p.endsWith(".d.ts") || p.endsWith(".d.mts") || p.endsWith(".d.cts"));
573
+ /**
574
+ * Determine if a stringified file path is a TypeScript file based on the extension at the end of the path. This
575
+ * function does _not_ consider type declaration files (`.d.ts` files) to be TypeScript files.
576
+ * @param p the path to evaluate
577
+ * @returns `true` if the path ends in `.ts` (case-sensitive) but does _not_ end in `.d.ts`, `false` otherwise.
578
+ */
579
+ const isTsFile = lowerPathParam((p) => !isDtsFile(p) && (p.endsWith(".ts") || p.endsWith(".mts") || p.endsWith(".cts")));
580
+ /**
581
+ * Determine if a stringified file path is a TSX file based on the extension at the end of the path
582
+ * @param p the path to evaluate
583
+ * @returns `true` if the path ends in `.tsx` (case-sensitive), `false` otherwise.
584
+ */
585
+ const isTsxFile = lowerPathParam((p) => p.endsWith(".tsx") || p.endsWith(".mtsx") || p.endsWith(".ctsx"));
586
+ /**
587
+ * Determine if a stringified file path is a JSX file based on the extension at the end of the path
588
+ * @param p the path to evaluate
589
+ * @returns `true` if the path ends in `.jsx` (case-sensitive), `false` otherwise.
590
+ */
591
+ const isJsxFile = lowerPathParam((p) => p.endsWith(".jsx") || p.endsWith(".mjsx") || p.endsWith(".cjsx"));
592
+ /**
593
+ * Determine if a stringified file path is a JavaScript file based on the extension at the end of the path
594
+ * @param p the path to evaluate
595
+ * @returns `true` if the path ends in `.js` (case-sensitive), `false` otherwise.
596
+ */
597
+ const isJsFile = lowerPathParam((p) => p.endsWith(".js") || p.endsWith(".mjs") || p.endsWith(".cjs"));
598
+ /**
599
+ * Generate the preamble to be placed atop the main file of the build
600
+ * @param config the Stencil configuration file
601
+ * @returns the generated preamble
602
+ */
603
+ const generatePreamble = (config) => {
604
+ const { preamble } = config;
605
+ if (!preamble) return "";
606
+ const preambleComment = preamble.split("\n").map((l) => ` * ${l}`);
607
+ preambleComment.unshift(`/*!`);
608
+ preambleComment.push(` */`);
609
+ return preambleComment.join("\n");
610
+ };
611
+ function getTextDocs(docs) {
612
+ if (docs == null) return "";
613
+ return [escapeWithPattern(docs.text.replace(LINE_BREAK_REGEX, " "), /\*\//, "*\\/", true), ...docs.tags.filter((tag) => tag.name !== "internal").map((tag) => {
614
+ const tagText = escapeWithPattern((tag.text || "").replace(LINE_BREAK_REGEX, " "), /\*\//, "*\\/", true);
615
+ return `@${tag.name} ${tagText}`;
616
+ })].join("\n").trim();
617
+ }
618
+ /**
619
+ * Adds a doc block to a string
620
+ * @param str the string to add a doc block to
621
+ * @param docs the compiled JS docs
622
+ * @param indentation number of spaces to indent the block with
623
+ * @returns the doc block
624
+ */
625
+ function addDocBlock(str, docs, indentation = 0) {
626
+ if (!docs) return str;
627
+ return [formatDocBlock(docs, indentation), str].filter(Boolean).join(`\n`);
628
+ }
629
+ /**
630
+ * Formats the given compiled docs to a JavaScript doc block
631
+ * @param docs the compiled JS docs
632
+ * @param indentation number of spaces to indent the block with
633
+ * @returns the formatted doc block
634
+ */
635
+ function formatDocBlock(docs, indentation = 0) {
636
+ const textDocs = getDocBlockLines(docs);
637
+ if (!textDocs.filter(Boolean).length) return "";
638
+ const spaces = new Array(indentation + 1).join(" ");
639
+ return [
640
+ spaces + "/**",
641
+ ...textDocs.map((line) => spaces + ` * ${line}`),
642
+ spaces + " */"
643
+ ].join(`\n`);
644
+ }
645
+ /**
646
+ * Get all lines which are part of the doc block
647
+ *
648
+ * @param docs the compiled JS docs
649
+ * @returns list of lines part of the doc block
650
+ */
651
+ function getDocBlockLines(docs) {
652
+ return [...docs.text.split(LINE_BREAK_REGEX), ...docs.tags.filter((tag) => !SUPPRESSED_JSDOC_TAGS.includes(tag.name)).map((tag) => `@${tag.name} ${tag.text || ""}`.split(LINE_BREAK_REGEX))].flat().filter(Boolean);
653
+ }
654
+ /**
655
+ * Retrieve a project's dependencies from the current build context
656
+ * @param buildCtx the current build context to query for a specific package
657
+ * @returns a list of package names the project is dependent on
658
+ */
659
+ const getDependencies = (buildCtx) => Object.keys(buildCtx?.packageJson?.dependencies ?? {}).filter((pkgName) => !SKIP_DEPS.includes(pkgName));
660
+ /**
661
+ * Utility to determine whether a project has a dependency on a package
662
+ * @param buildCtx the current build context to query for a specific package
663
+ * @param depName the name of the dependency/package
664
+ * @returns `true` if the project has a dependency a packaged with the provided name, `false` otherwise
665
+ */
666
+ const hasDependency = (buildCtx, depName) => {
667
+ return getDependencies(buildCtx).includes(depName);
668
+ };
669
+ const readPackageJson = async (config, compilerCtx, buildCtx) => {
670
+ try {
671
+ const pkgJson = await compilerCtx.fs.readFile(config.packageJsonFilePath);
672
+ if (pkgJson) {
673
+ const parseResults = parsePackageJson(pkgJson, config.packageJsonFilePath);
674
+ if (parseResults.diagnostic) buildCtx.diagnostics.push(parseResults.diagnostic);
675
+ else buildCtx.packageJson = parseResults.data;
676
+ }
677
+ } catch {
678
+ if (!config.outputTargets.some((o) => o.type.includes("dist"))) {
679
+ const diagnostic = buildError(buildCtx.diagnostics);
680
+ diagnostic.header = `Missing "package.json"`;
681
+ diagnostic.messageText = `Valid "package.json" file is required for distribution: ${config.packageJsonFilePath}`;
682
+ }
683
+ }
684
+ };
685
+ /**
686
+ * Parse a string read from a `package.json` file
687
+ * @param pkgJsonStr the string read from a `package.json` file
688
+ * @param pkgJsonFilePath the path to the already read `package.json` file
689
+ * @returns the results of parsing the provided contents of the `package.json` file
690
+ */
691
+ const parsePackageJson = (pkgJsonStr, pkgJsonFilePath) => {
692
+ const parseResult = {
693
+ diagnostic: null,
694
+ data: null,
695
+ filePath: pkgJsonFilePath
696
+ };
697
+ try {
698
+ parseResult.data = JSON.parse(pkgJsonStr);
699
+ } catch (e) {
700
+ parseResult.diagnostic = buildError();
701
+ parseResult.diagnostic.absFilePath = isString(pkgJsonFilePath) ? pkgJsonFilePath : void 0;
702
+ parseResult.diagnostic.header = `Error Parsing JSON`;
703
+ if (e instanceof Error) parseResult.diagnostic.messageText = e.message;
704
+ }
705
+ return parseResult;
706
+ };
707
+ const SKIP_DEPS = ["@stencil/core"];
708
+ /**
709
+ * Check whether a string is a member of a ReadonlyArray<string>
710
+ *
711
+ * We need a little helper for this because unfortunately `includes` is typed
712
+ * on `ReadonlyArray<T>` as `(el: T): boolean` so a `string` cannot be passed
713
+ * to `includes` on a `ReadonlyArray` 😢 thus we have a little helper function
714
+ * where we do the type coercion just once.
715
+ *
716
+ * see microsoft/TypeScript#31018 for some discussion of this
717
+ *
718
+ * @param readOnlyArray the array we're checking
719
+ * @param maybeMember a value which is possibly a member of the array
720
+ * @returns whether the array contains the member or not
721
+ */
722
+ const readOnlyArrayHasStringMember = (readOnlyArray, maybeMember) => readOnlyArray.includes(maybeMember);
723
+ //#endregion
724
+ export { catchError as $, isOutputTargetDocsVscode as A, relativeImport as B, isOutputTargetDistLazy as C, isOutputTargetDocsCustomElementsManifest as D, isOutputTargetDocsCustom as E, isOutputTargetStandalone as F, normalizeFsPathQuery as G, join$1 as H, isOutputTargetStats as I, resolve$1 as J, normalizePath as K, isOutputTargetTypes as L, isOutputTargetLoaderBundle as M, isOutputTargetSsr as N, isOutputTargetDocsJson as O, isOutputTargetSsrWasm as P, buildWarn as Q, isOutputTargetWww as R, isOutputTargetCustom as S, isOutputTargetDocsAgentSkill as T, normalize as U, shouldExcludeComponent as V, normalizeFsPath as W, buildError as X, TASK_CANCELED_MSG as Y, buildJsonFileError as Z, getComponentsDtsTypesFilePath as _, hasDependency as a, isOutputTargetCollection as b, isJsxFile as c, parsePackageJson as d, hasError as et, readOnlyArrayHasStringMember as f, getComponentsDtsSrcFilePath as g, filterExcludedComponents as h, getTextDocs as i, isOutputTargetGlobalStyle as j, isOutputTargetDocsReadme as k, isTsFile as l, filterActiveTargets as m, createJsVarName as n, shouldIgnoreError as nt, isDtsFile as o, readPackageJson as p, relative$1 as q, generatePreamble as r, isGlob as rt, isJsFile as s, addDocBlock as t, hasWarning as tt, isTsxFile as u, getComponentsFromModules as v, isOutputTargetDocs as w, isOutputTargetCopy as x, isOutputTargetAssets as y, isValidConfigOutputTarget as z };