@storybook/web-components 11.0.0-alpha.6 → 11.0.0-alpha.7

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,35 +1,107 @@
1
- import CJS_COMPAT_NODE_URL_3ov4ld79bt3 from 'node:url';
2
- import CJS_COMPAT_NODE_PATH_3ov4ld79bt3 from 'node:path';
3
- import CJS_COMPAT_NODE_MODULE_3ov4ld79bt3 from "node:module";
1
+ import CJS_COMPAT_NODE_URL_seyt09815b from 'node:url';
2
+ import CJS_COMPAT_NODE_PATH_seyt09815b from 'node:path';
3
+ import CJS_COMPAT_NODE_MODULE_seyt09815b from "node:module";
4
4
 
5
- var __filename = CJS_COMPAT_NODE_URL_3ov4ld79bt3.fileURLToPath(import.meta.url);
6
- var __dirname = CJS_COMPAT_NODE_PATH_3ov4ld79bt3.dirname(__filename);
7
- var require = CJS_COMPAT_NODE_MODULE_3ov4ld79bt3.createRequire(import.meta.url);
5
+ var __filename = CJS_COMPAT_NODE_URL_seyt09815b.fileURLToPath(import.meta.url);
6
+ var __dirname = CJS_COMPAT_NODE_PATH_seyt09815b.dirname(__filename);
7
+ var require = CJS_COMPAT_NODE_MODULE_seyt09815b.createRequire(import.meta.url);
8
8
 
9
9
  // ------------------------------------------------------------
10
10
  // end of CJS compatibility banner, injected by Storybook's esbuild configuration
11
11
  // ------------------------------------------------------------
12
12
  import {
13
- deprecationMessage,
14
- errorMessage,
15
- firstValue,
16
- isRecord,
17
- namedItems,
18
13
  parseStoryFile,
19
- readCssPropertySyntax,
20
- readTypeText,
21
- resolveStoryComponent,
22
- trimmedOrUndefined
23
- } from "./chunk-GDY64HEP.js";
14
+ resolveStoryComponent
15
+ } from "./chunk-MMJPCIXK.js";
24
16
 
25
17
  // src/docgen/docgen-worker.ts
26
18
  import { createLazyDocgenMiddleware } from "storybook/internal/common";
27
- import { logger as logger2 } from "storybook/internal/node-logger";
19
+ import { logger as logger5 } from "storybook/internal/node-logger";
28
20
 
29
21
  // src/docgen/component-docgen/build-docgen.ts
30
22
  import { getComponentIdFromEntry, getStoryImportPathFromEntry } from "storybook/internal/common";
31
23
  import { extractComponentDescription, extractDescription } from "storybook/internal/csf-tools";
32
- import { resolve } from "node:path";
24
+
25
+ // node_modules/pathe/dist/shared/pathe.ff20891b.mjs
26
+ var _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
27
+ function normalizeWindowsPath(input = "") {
28
+ return input && input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
29
+ }
30
+ var _UNC_REGEX = /^[/\\]{2}/, _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/, _DRIVE_LETTER_RE = /^[A-Za-z]:$/, _ROOT_FOLDER_RE = /^\/([A-Za-z]:)?$/;
31
+ var normalize = function(path2) {
32
+ if (path2.length === 0)
33
+ return ".";
34
+ path2 = normalizeWindowsPath(path2);
35
+ let isUNCPath = path2.match(_UNC_REGEX), isPathAbsolute = isAbsolute(path2), trailingSeparator = path2[path2.length - 1] === "/";
36
+ return path2 = normalizeString(path2, !isPathAbsolute), path2.length === 0 ? isPathAbsolute ? "/" : trailingSeparator ? "./" : "." : (trailingSeparator && (path2 += "/"), _DRIVE_LETTER_RE.test(path2) && (path2 += "/"), isUNCPath ? isPathAbsolute ? `//${path2}` : `//./${path2}` : isPathAbsolute && !isAbsolute(path2) ? `/${path2}` : path2);
37
+ }, join = function(...arguments_) {
38
+ if (arguments_.length === 0)
39
+ return ".";
40
+ let joined;
41
+ for (let argument of arguments_)
42
+ argument && argument.length > 0 && (joined === void 0 ? joined = argument : joined += `/${argument}`);
43
+ return joined === void 0 ? "." : normalize(joined.replace(/\/\/+/g, "/"));
44
+ };
45
+ function cwd() {
46
+ return typeof process < "u" && typeof process.cwd == "function" ? process.cwd().replace(/\\/g, "/") : "/";
47
+ }
48
+ var resolve = function(...arguments_) {
49
+ arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
50
+ let resolvedPath = "", resolvedAbsolute = !1;
51
+ for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
52
+ let path2 = index >= 0 ? arguments_[index] : cwd();
53
+ !path2 || path2.length === 0 || (resolvedPath = `${path2}/${resolvedPath}`, resolvedAbsolute = isAbsolute(path2));
54
+ }
55
+ return resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute), resolvedAbsolute && !isAbsolute(resolvedPath) ? `/${resolvedPath}` : resolvedPath.length > 0 ? resolvedPath : ".";
56
+ };
57
+ function normalizeString(path2, allowAboveRoot) {
58
+ let res = "", lastSegmentLength = 0, lastSlash = -1, dots = 0, char = null;
59
+ for (let index = 0; index <= path2.length; ++index) {
60
+ if (index < path2.length)
61
+ char = path2[index];
62
+ else {
63
+ if (char === "/")
64
+ break;
65
+ char = "/";
66
+ }
67
+ if (char === "/") {
68
+ if (!(lastSlash === index - 1 || dots === 1)) if (dots === 2) {
69
+ if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
70
+ if (res.length > 2) {
71
+ let lastSlashIndex = res.lastIndexOf("/");
72
+ lastSlashIndex === -1 ? (res = "", lastSegmentLength = 0) : (res = res.slice(0, lastSlashIndex), lastSegmentLength = res.length - 1 - res.lastIndexOf("/")), lastSlash = index, dots = 0;
73
+ continue;
74
+ } else if (res.length > 0) {
75
+ res = "", lastSegmentLength = 0, lastSlash = index, dots = 0;
76
+ continue;
77
+ }
78
+ }
79
+ allowAboveRoot && (res += res.length > 0 ? "/.." : "..", lastSegmentLength = 2);
80
+ } else
81
+ res.length > 0 ? res += `/${path2.slice(lastSlash + 1, index)}` : res = path2.slice(lastSlash + 1, index), lastSegmentLength = index - lastSlash - 1;
82
+ lastSlash = index, dots = 0;
83
+ } else char === "." && dots !== -1 ? ++dots : dots = -1;
84
+ }
85
+ return res;
86
+ }
87
+ var isAbsolute = function(p) {
88
+ return _IS_ABSOLUTE_RE.test(p);
89
+ };
90
+ var relative = function(from, to) {
91
+ let _from = resolve(from).replace(_ROOT_FOLDER_RE, "$1").split("/"), _to = resolve(to).replace(_ROOT_FOLDER_RE, "$1").split("/");
92
+ if (_to[0][1] === ":" && _from[0][1] === ":" && _from[0] !== _to[0])
93
+ return _to.join("/");
94
+ let _fromCopy = [..._from];
95
+ for (let segment of _fromCopy) {
96
+ if (_to[0] !== segment)
97
+ break;
98
+ _from.shift(), _to.shift();
99
+ }
100
+ return [..._from.map(() => ".."), ..._to].join("/");
101
+ }, dirname = function(p) {
102
+ let segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1);
103
+ return segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0]) && (segments[0] += "/"), segments.join("/") || (isAbsolute(p) ? "/" : ".");
104
+ };
33
105
 
34
106
  // src/arg-keys.ts
35
107
  var DEFAULT_SLOT_NAME = "default";
@@ -44,6 +116,37 @@ var ARG_KEY_SUFFIXES = {
44
116
  cssStates: "-state"
45
117
  };
46
118
 
119
+ // src/docgen/component-docgen/utils.ts
120
+ function isRecord(value) {
121
+ return value !== null && typeof value == "object";
122
+ }
123
+ function namedItems(value) {
124
+ return Array.isArray(value) ? value.filter((item) => isRecord(item) && typeof item.name == "string") : [];
125
+ }
126
+ function errorMessage(error) {
127
+ return error instanceof Error ? error.message : String(error);
128
+ }
129
+ var trimmedOrUndefined = (text) => typeof text == "string" && text.trim() || void 0;
130
+ function deprecationMessage(deprecated) {
131
+ if (deprecated)
132
+ return typeof deprecated == "string" ? trimmedOrUndefined(deprecated) : "deprecated";
133
+ }
134
+ function firstValue(sources, read) {
135
+ for (let source of sources) {
136
+ let value = read(source);
137
+ if (value !== void 0)
138
+ return value;
139
+ }
140
+ }
141
+
142
+ // src/docgen/component-docgen/manifest/type-text.ts
143
+ function readTypeText({ type, parsedType }) {
144
+ return isRecord(parsedType) && typeof parsedType.text == "string" && parsedType.text.trim() ? parsedType.text : typeof type?.text == "string" ? type.text : void 0;
145
+ }
146
+ function readCssPropertySyntax(property) {
147
+ return property.syntax ?? readTypeText(property);
148
+ }
149
+
47
150
  // src/docgen/component-docgen/manifest/members.ts
48
151
  function isPublicField(member) {
49
152
  return isField(member) && isPublicMember(member);
@@ -96,24 +199,21 @@ function backingField(attribute, fields) {
96
199
 
97
200
  // src/docgen/component-docgen/api-description.ts
98
201
  var IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
99
- function buildApiDescription(declaration, typeProperty) {
100
- let api = classifyDeclaration(declaration), attributes = api.attributes.map((attribute) => attributeDoc(attribute, typeProperty)), properties = api.fields.filter((field) => !isBackedByAttribute(field, api.attributes));
202
+ function buildApiDescription(declaration) {
203
+ let api = classifyDeclaration(declaration), attributes = api.attributes.map(attributeDoc), properties = api.fields.filter((field) => !isBackedByAttribute(field, api.attributes));
101
204
  if (attributes.length === 0 && properties.length === 0 && api.events.length === 0 && api.methods.length === 0 && api.slots.length === 0 && api.cssProperties.length === 0 && api.cssParts.length === 0 && api.cssStates.length === 0)
102
205
  return;
103
206
  let typePrefix = declaration.name.replace(/\W+/g, "");
104
207
  return [
105
208
  attributesSection(typePrefix, attributes),
106
- propertiesSection(typePrefix, properties, typeProperty),
107
- eventsSection(typePrefix, api.events, typeProperty),
108
- methodsSection(typePrefix, api.methods, typeProperty),
209
+ propertiesSection(typePrefix, properties),
210
+ eventsSection(typePrefix, api.events),
211
+ methodsSection(typePrefix, api.methods),
109
212
  listSection(
110
213
  "Slots",
111
214
  api.slots.map((slot) => listItem(slot.name || DEFAULT_SLOT_NAME, memberDoc(slot)))
112
215
  ),
113
- listSection(
114
- "CSS Custom Properties",
115
- api.cssProperties.map((property) => cssPropertyListItem(property, typeProperty))
116
- ),
216
+ listSection("CSS Custom Properties", api.cssProperties.map(cssPropertyListItem)),
117
217
  listSection(
118
218
  "CSS Parts",
119
219
  api.cssParts.map((part) => listItem(part.name, memberDoc(part)))
@@ -140,13 +240,13 @@ function attributesSection(typePrefix, attributes) {
140
240
  })
141
241
  );
142
242
  }
143
- function propertiesSection(typePrefix, properties, typeProperty) {
243
+ function propertiesSection(typePrefix, properties) {
144
244
  if (properties.length !== 0)
145
245
  return typeSection(
146
246
  "Properties",
147
247
  `${typePrefix}Properties`,
148
248
  properties.flatMap((property) => {
149
- let doc = memberDoc(property), type = fieldType(property, typeProperty);
249
+ let doc = memberDoc(property), type = fieldType(property);
150
250
  return [
151
251
  ...docComment(doc),
152
252
  property.readonly === !0 ? ` readonly ${memberName(property.name)}: ${type}${memberDefault(doc)};` : ` ${memberName(property.name)}?: ${type}${memberDefault(doc)};`
@@ -154,28 +254,25 @@ function propertiesSection(typePrefix, properties, typeProperty) {
154
254
  })
155
255
  );
156
256
  }
157
- function eventsSection(typePrefix, events, typeProperty) {
257
+ function eventsSection(typePrefix, events) {
158
258
  if (events.length !== 0)
159
259
  return typeSection(
160
260
  "Events",
161
261
  `${typePrefix}Events`,
162
262
  events.flatMap((event) => [
163
263
  ...docComment(memberDoc(event)),
164
- ` ${memberName(event.name)}: ${readTypeText(event, typeProperty) ?? "Event"};`
264
+ ` ${memberName(event.name)}: ${readTypeText(event) ?? "Event"};`
165
265
  ])
166
266
  );
167
267
  }
168
- function methodsSection(typePrefix, methods, typeProperty) {
268
+ function methodsSection(typePrefix, methods) {
169
269
  if (methods.length !== 0)
170
270
  return typeSection(
171
271
  "Methods",
172
272
  `${typePrefix}Methods`,
173
273
  methods.flatMap((method) => [
174
274
  ...docComment(memberDoc(method)),
175
- ` ${memberName(method.name)}(${formatParameters(method)}): ${methodReturnType(
176
- method,
177
- typeProperty
178
- )};`
275
+ ` ${memberName(method.name)}(${formatParameters(method)}): ${methodReturnType(method)};`
179
276
  ])
180
277
  );
181
278
  }
@@ -190,8 +287,8 @@ function listSection(heading, items) {
190
287
  return [`## ${heading}`, "", ...items].join(`
191
288
  `);
192
289
  }
193
- function cssPropertyListItem(property, typeProperty) {
194
- let syntax = readCssPropertySyntax(property, typeProperty), name = property.name, syntaxText = syntax ? ` \`${syntax}\`` : "";
290
+ function cssPropertyListItem(property) {
291
+ let syntax = readCssPropertySyntax(property), name = property.name, syntaxText = syntax ? ` \`${syntax}\`` : "";
195
292
  return listItemPrefix(`${name}${syntaxText}`, memberDoc(property));
196
293
  }
197
294
  function listItem(name, doc) {
@@ -201,25 +298,25 @@ function listItemPrefix(prefix, doc) {
201
298
  let text = doc.text ? `: ${doc.text}` : "", defaultText = doc.defaultValue === void 0 ? "" : ` Default: ${doc.defaultValue}.`, deprecatedText = doc.deprecated === void 0 ? "" : doc.deprecated === "deprecated" ? " Deprecated." : ` Deprecated: ${doc.deprecated}.`;
202
299
  return `- ${prefix}${text}${defaultText}${deprecatedText}`;
203
300
  }
204
- function attributeDoc(attribute, typeProperty) {
301
+ function attributeDoc(attribute) {
205
302
  let { field } = attribute;
206
303
  return {
207
304
  ...attribute,
208
- type: attributeType(attribute, typeProperty),
305
+ type: attributeType(attribute),
209
306
  doc: memberDoc(field, attribute.attribute)
210
307
  };
211
308
  }
212
- function attributeType({ attribute, field }, typeProperty) {
309
+ function attributeType({ attribute, field }) {
213
310
  return firstValue(
214
311
  [field, attribute],
215
- (source) => source ? trimmedOrUndefined(readTypeText(source, typeProperty)) : void 0
312
+ (source) => source ? trimmedOrUndefined(readTypeText(source)) : void 0
216
313
  ) ?? "string";
217
314
  }
218
- function fieldType(field, typeProperty) {
219
- return trimmedOrUndefined(readTypeText(field, typeProperty)) ?? "unknown";
315
+ function fieldType(field) {
316
+ return trimmedOrUndefined(readTypeText(field)) ?? "unknown";
220
317
  }
221
- function methodReturnType(method, typeProperty) {
222
- return method.return ? readTypeText(method.return, typeProperty) ?? "void" : "void";
318
+ function methodReturnType(method) {
319
+ return method.return ? readTypeText(method.return) ?? "void" : "void";
223
320
  }
224
321
  function memberDoc(...sources) {
225
322
  return {
@@ -389,21 +486,21 @@ var NAMED_ENTRY_CATEGORIES = {
389
486
  cssParts: "css shadow parts",
390
487
  cssStates: "css states"
391
488
  };
392
- function mapArgTypes(declaration, typeProperty) {
489
+ function mapArgTypes(declaration) {
393
490
  let api = classifyDeclaration(declaration);
394
491
  return {
395
492
  ...Object.fromEntries([
396
- ...api.events.flatMap((event) => eventEntries(event, typeProperty)),
493
+ ...api.events.flatMap(eventEntries),
397
494
  ...api.methods.map(methodEntry),
398
495
  ...api.slots.map((slot) => namedEntry(slot, "slots")),
399
496
  ...api.cssParts.map((part) => namedEntry(part, "cssParts")),
400
497
  ...api.cssStates.map((state) => namedEntry(state, "cssStates")),
401
- ...api.cssProperties.map((property) => cssPropertyEntry(property, typeProperty))
498
+ ...api.cssProperties.map(cssPropertyEntry)
402
499
  ]),
403
- ...mapAttributesAndProperties(api, typeProperty)
500
+ ...mapAttributesAndProperties(api)
404
501
  };
405
502
  }
406
- function mapAttributesAndProperties(api, typeProperty) {
503
+ function mapAttributesAndProperties(api) {
407
504
  let argTypes = {}, properties = api.fields.filter(
408
505
  (field) => !api.attributes.some(({ attribute }) => attribute.name === field.name)
409
506
  );
@@ -412,27 +509,22 @@ function mapAttributesAndProperties(api, typeProperty) {
412
509
  argTypes[field.name] = toArgType({
413
510
  key: field.name,
414
511
  category: "properties",
415
- sources: attribute ? [field, attribute.attribute] : [field],
416
- typeProperty
512
+ sources: attribute ? [field, attribute.attribute] : [field]
417
513
  });
418
514
  }
419
515
  for (let { attribute, field } of api.attributes)
420
516
  argTypes[attribute.name] = toArgType({
421
517
  key: attribute.name,
422
518
  category: "attributes",
423
- sources: field ? [field, attribute] : [attribute],
424
- typeProperty
519
+ sources: field ? [field, attribute] : [attribute]
425
520
  });
426
521
  return argTypes;
427
522
  }
428
- function toArgType({ key, category, sources, typeProperty }) {
523
+ function toArgType({ key, category, sources }) {
429
524
  let rawTypeText = firstValue(
430
525
  sources,
431
526
  (source) => typeof source.type?.text == "string" ? source.type.text : void 0
432
- ), text = firstValue(
433
- sources,
434
- (source) => trimmedOrUndefined(readTypeText(source, typeProperty))
435
- ), parsed = parseTypeText(text) ?? (category === "attributes" ? { type: { name: "string" } } : { type: { name: "other", value: text ?? "" }, control: !1 }), readonly = firstValue(
527
+ ), text = firstValue(sources, (source) => trimmedOrUndefined(readTypeText(source))), parsed = parseTypeText(text) ?? (category === "attributes" ? { type: { name: "string" } } : { type: { name: "other", value: text ?? "" }, control: !1 }), readonly = firstValue(
436
528
  sources,
437
529
  (source) => "readonly" in source && source.readonly === !0 ? !0 : void 0
438
530
  );
@@ -445,8 +537,8 @@ function toArgType({ key, category, sources, typeProperty }) {
445
537
  }
446
538
  });
447
539
  }
448
- function eventEntries(event, typeProperty) {
449
- let text = readTypeText(event, typeProperty) ?? "CustomEvent";
540
+ function eventEntries(event) {
541
+ let text = readTypeText(event) ?? "CustomEvent";
450
542
  return [
451
543
  [
452
544
  toArgKey("events", event.name),
@@ -474,8 +566,8 @@ function namedEntry(item, category) {
474
566
  memberArgType(name, [item], NAMED_ENTRY_CATEGORIES[category], { type: { name: "string" } })
475
567
  ];
476
568
  }
477
- function cssPropertyEntry(property, typeProperty) {
478
- let syntax = readCssPropertySyntax(property, typeProperty);
569
+ function cssPropertyEntry(property) {
570
+ let syntax = readCssPropertySyntax(property);
479
571
  return [
480
572
  toArgKey("cssProperties", property.name),
481
573
  memberArgType(property.name, [property], "css custom properties", {
@@ -519,14 +611,14 @@ function cssCustomPropertyControl(syntax) {
519
611
  }
520
612
 
521
613
  // src/docgen/component-docgen/build-docgen.ts
522
- function buildDocgenPayload(input, context) {
614
+ async function buildDocgenPayload(input, context) {
523
615
  let storyImportPath = getStoryImportPathFromEntry(input.entry);
524
616
  if (!storyImportPath)
525
617
  return;
526
- let id = getComponentIdFromEntry(input.entry), path = storyImportPath, fail = (name, error) => ({
618
+ let id = getComponentIdFromEntry(input.entry), path2 = storyImportPath, fail = (name, error) => ({
527
619
  id,
528
620
  name,
529
- path,
621
+ path: path2,
530
622
  jsDocTags: {},
531
623
  error
532
624
  }), storyFilePath = resolve(process.cwd(), storyImportPath), csf = parseStoryFile(storyFilePath, input.entry.title);
@@ -542,15 +634,9 @@ function buildDocgenPayload(input, context) {
542
634
  message: `\`meta.component\` must be the element's tag name as a string, got \`${resolved.expression}\``
543
635
  });
544
636
  }
545
- let { tag } = resolved, found = context.cem.tags.get(tag);
546
- if (!found)
547
- return fail(
548
- tag,
549
- context.cem.errors[0] ?? {
550
- name: "tag-not-found",
551
- message: `No declaration for "${tag}" was found in ${context.cem.paths.join(", ")}. If the element is new, rerun the custom elements manifest analyzer.`
552
- }
553
- );
637
+ let { tag } = resolved, found = await context.resolver.find(tag, { storyFilePath });
638
+ if (!("declaration" in found))
639
+ return fail(tag, found);
554
640
  let { description, summary, jsDocTags } = extractComponentDescription(
555
641
  extractDescription(csf._metaStatement) || void 0,
556
642
  found.declaration.description,
@@ -559,12 +645,12 @@ function buildDocgenPayload(input, context) {
559
645
  return {
560
646
  id,
561
647
  name: tag,
562
- path,
648
+ path: path2,
563
649
  description,
564
650
  summary,
565
651
  jsDocTags,
566
- argTypes: mapArgTypes(found.declaration, context.typeProperty),
567
- apiDescription: buildApiDescription(found.declaration, context.typeProperty),
652
+ argTypes: mapArgTypes(found.declaration),
653
+ apiDescription: buildApiDescription(found.declaration),
568
654
  renderer: "web-components",
569
655
  ...found.warning ? { warning: found.warning } : {},
570
656
  customElementsManifest: {
@@ -583,7 +669,7 @@ function declarationTags(declaration) {
583
669
  // src/docgen/component-docgen/manifest/cem-manager.ts
584
670
  import { logger } from "storybook/internal/node-logger";
585
671
  import { stat } from "node:fs/promises";
586
- import { relative as relative2 } from "node:path";
672
+ import { relative as relative3 } from "node:path";
587
673
 
588
674
  // src/docgen/component-docgen/manifest/build-tag-index.ts
589
675
  function buildTagIndex(manifest) {
@@ -748,21 +834,21 @@ function modulePathOf(module) {
748
834
 
749
835
  // src/docgen/component-docgen/manifest/load-manifest.ts
750
836
  import { readFile } from "node:fs/promises";
751
- import { relative } from "node:path";
752
- var isFailedManifest = (result) => "error" in result, isCustomElementsManifest = (value) => isRecord(value) && Array.isArray(value.modules), unsupportedMessage = (path) => `${path} uses the web-component-analyzer manifest shape. The Storybook docgen server reads Custom Elements Manifests only; generate one with @custom-elements-manifest/analyzer.`, invalidMessage = (path, detail) => detail ? `Invalid Custom Elements Manifest at ${path}: ${detail}` : `Invalid Custom Elements Manifest at ${path}: expected a top-level modules array.`;
753
- function classifyManifest(path, parsed) {
754
- return isRecord(parsed) ? isCustomElementsManifest(parsed) ? { path, manifest: parsed } : parsed.version === "experimental" || Array.isArray(parsed.tags) ? { path, error: { name: "manifest-unsupported", message: unsupportedMessage(path) } } : { path, error: { name: "manifest-invalid", message: invalidMessage(path) } } : { path, error: { name: "manifest-invalid", message: invalidMessage(path) } };
837
+ import { relative as relative2 } from "node:path";
838
+ var isFailedManifest = (result) => "error" in result, isCustomElementsManifest = (value) => isRecord(value) && Array.isArray(value.modules), unsupportedMessage = (path2) => `${path2} uses the web-component-analyzer manifest shape. The Storybook docgen server reads Custom Elements Manifests only; generate one with @custom-elements-manifest/analyzer.`, invalidMessage = (path2, detail) => detail ? `Invalid Custom Elements Manifest at ${path2}: ${detail}` : `Invalid Custom Elements Manifest at ${path2}: expected a top-level modules array.`;
839
+ function classifyManifest(path2, parsed) {
840
+ return isRecord(parsed) ? isCustomElementsManifest(parsed) ? { path: path2, manifest: parsed } : parsed.version === "experimental" || Array.isArray(parsed.tags) ? { path: path2, error: { name: "manifest-unsupported", message: unsupportedMessage(path2) } } : { path: path2, error: { name: "manifest-invalid", message: invalidMessage(path2) } } : { path: path2, error: { name: "manifest-invalid", message: invalidMessage(path2) } };
755
841
  }
756
842
  async function loadManifest(absolutePath) {
757
- let path = relative(process.cwd(), absolutePath);
843
+ let path2 = relative2(process.cwd(), absolutePath);
758
844
  try {
759
- return classifyManifest(path, JSON.parse(await readFile(absolutePath, "utf8")));
845
+ return classifyManifest(path2, JSON.parse(await readFile(absolutePath, "utf8")));
760
846
  } catch (error) {
761
847
  return {
762
- path,
848
+ path: path2,
763
849
  error: {
764
850
  name: "manifest-invalid",
765
- message: invalidMessage(path, errorMessage(error))
851
+ message: invalidMessage(path2, errorMessage(error))
766
852
  }
767
853
  };
768
854
  }
@@ -773,9 +859,12 @@ var CemManager = class {
773
859
  constructor(absolutePaths) {
774
860
  this.states = absolutePaths.map((absolutePath) => ({
775
861
  absolutePath,
776
- path: relative2(process.cwd(), absolutePath)
862
+ path: relative3(process.cwd(), absolutePath)
777
863
  }));
778
864
  }
865
+ async find(tag) {
866
+ return findInSnapshot(await this.refresh(), tag);
867
+ }
779
868
  refresh() {
780
869
  return this.current ? (this.next ??= this.current.then(
781
870
  () => (this.next = void 0, this.refresh()),
@@ -832,8 +921,14 @@ var CemManager = class {
832
921
  state.lastWarning !== message && (state.lastWarning = message, logger.warn(message));
833
922
  }
834
923
  };
924
+ function findInSnapshot(snapshot, tag) {
925
+ return snapshot.tags.get(tag) ?? snapshot.errors[0] ?? {
926
+ name: "tag-not-found",
927
+ message: `No declaration for "${tag}" was found in ${snapshot.paths.join(", ")}. If the element is new, rerun the custom elements manifest analyzer.`
928
+ };
929
+ }
835
930
  function buildSnapshot(states) {
836
- let tags = /* @__PURE__ */ new Map(), errors = [], paths = states.map(({ path }) => path);
931
+ let tags = /* @__PURE__ */ new Map(), errors = [], paths = states.map(({ path: path2 }) => path2);
837
932
  for (let state of states) {
838
933
  if (state.entry) {
839
934
  let warning = state.error ? staleWarning(state.error) : void 0;
@@ -853,44 +948,343 @@ function buildSnapshot(states) {
853
948
  paths
854
949
  };
855
950
  }
856
- function failureFromError(path, error) {
951
+ function failureFromError(path2, error) {
857
952
  return {
858
953
  name: "manifest-invalid",
859
- message: `Invalid Custom Elements Manifest at ${path}: ${errorMessage(error)}`
954
+ message: `Invalid Custom Elements Manifest at ${path2}: ${errorMessage(error)}`
860
955
  };
861
956
  }
862
957
  function isNotFound(error) {
863
958
  return error instanceof Error && "code" in error && error.code === "ENOENT";
864
959
  }
865
- function missingManifestError(path) {
960
+ function missingManifestError(path2) {
866
961
  return {
867
962
  name: "manifest-not-found",
868
- message: `Custom Elements Manifest ${path} not found yet; docs load once the analyzer writes it`
963
+ message: `Custom Elements Manifest ${path2} not found yet; docs load once the analyzer writes it`
869
964
  };
870
965
  }
871
966
  function staleWarning(error) {
872
967
  return `${error.message}; using the last valid version`;
873
968
  }
874
969
 
970
+ // src/docgen/component-docgen/source/generator.ts
971
+ import { logger as logger2 } from "storybook/internal/node-logger";
972
+ var loadPromise;
973
+ async function loadGenerator() {
974
+ return loadPromise ??= loadGeneratorModule(), loadPromise;
975
+ }
976
+ async function loadGeneratorModule() {
977
+ let [generator, lit] = await Promise.all([
978
+ import("@wc-toolkit/cem-generator"),
979
+ import("@wc-toolkit/cem-generator-lit")
980
+ ]);
981
+ return {
982
+ generate: (tsConfigPath, files) => generator.generateCem({
983
+ tsConfigPath,
984
+ include: files,
985
+ plugins: [lit.litPlugin()],
986
+ validation: {
987
+ invariants: "warning",
988
+ onWarning: (message) => logger2.debug(message)
989
+ },
990
+ modulePathResolver: { skip: !0 }
991
+ })
992
+ };
993
+ }
994
+
995
+ // src/docgen/component-docgen/source/source-manager.ts
996
+ import { logger as logger4 } from "storybook/internal/node-logger";
997
+
998
+ // src/docgen/component-docgen/source/generator-manager.ts
999
+ import {
1000
+ ComponentMetaManager,
1001
+ parseTsconfigCommandLine
1002
+ } from "storybook/internal/component-meta";
1003
+
1004
+ // src/docgen/component-docgen/source/generator-project.ts
1005
+ import { isInNodeModules } from "storybook/internal/common";
1006
+ import {
1007
+ filterSourceFilePaths
1008
+ } from "storybook/internal/component-meta";
1009
+ import { logger as logger3 } from "storybook/internal/node-logger";
1010
+ var GeneratorProject = class {
1011
+ constructor(typescript, generator, commandLine, configFileName, getCommandLineFn) {
1012
+ this.typescript = typescript;
1013
+ this.generator = generator;
1014
+ this.commandLine = commandLine;
1015
+ this.configFileName = configFileName;
1016
+ this.getCommandLineFn = getCommandLineFn;
1017
+ this.importsByFile = /* @__PURE__ */ new Map();
1018
+ this.rootsStale = !1;
1019
+ this.revisionCount = 0;
1020
+ }
1021
+ /** Moves on every file event or new root, so callers can tell whether a cached miss is still valid. */
1022
+ get revision() {
1023
+ return this.revisionCount;
1024
+ }
1025
+ getCommandLine() {
1026
+ return this.rootsStale && this.getCommandLineFn && (this.commandLine = this.getCommandLineFn()), this.rootsStale = !1, this.commandLine;
1027
+ }
1028
+ rootFileNames() {
1029
+ return this.getCommandLine().fileNames;
1030
+ }
1031
+ hasSourceFile(fileName) {
1032
+ let normalized = normalize(fileName);
1033
+ return this.importsByFile.has(normalized) || this.rootFileNames().includes(normalized);
1034
+ }
1035
+ ensureFiles(fileNames) {
1036
+ for (let fileName of fileNames.map(normalize))
1037
+ this.commandLine.fileNames.includes(fileName) || (this.commandLine.fileNames.push(fileName), this.revisionCount++);
1038
+ }
1039
+ getSourceFilePaths() {
1040
+ return filterSourceFilePaths([
1041
+ .../* @__PURE__ */ new Set([...this.rootFileNames(), ...this.importsByFile.keys()])
1042
+ ]);
1043
+ }
1044
+ onFilesChanged(changes) {
1045
+ for (let { filePath, type } of changes) {
1046
+ if (type === "changed") {
1047
+ this.importsByFile.delete(normalize(filePath));
1048
+ continue;
1049
+ }
1050
+ this.importsByFile.clear(), this.rootsStale = !0;
1051
+ }
1052
+ this.revisionCount++;
1053
+ }
1054
+ dispose() {
1055
+ this.importsByFile.clear();
1056
+ }
1057
+ createManifestForRoots(rootPaths) {
1058
+ let roots = rootPaths.map(normalize), closure = this.importClosure(roots);
1059
+ if (closure.length === 0) {
1060
+ this.debug(`none of ${rootPaths.join(", ")} could be read`);
1061
+ return;
1062
+ }
1063
+ let tsConfigPath = this.configFileName ?? join(commonDirectory(roots), "tsconfig.json");
1064
+ return this.generator.generate(tsConfigPath, closure);
1065
+ }
1066
+ importClosure(roots) {
1067
+ let closure = /* @__PURE__ */ new Set(), queue = [...roots];
1068
+ for (; queue.length > 0; ) {
1069
+ let fileName = queue.pop();
1070
+ if (closure.has(fileName) || isInNodeModules(fileName))
1071
+ continue;
1072
+ let imports = this.importsOf(fileName);
1073
+ imports && (closure.add(fileName), queue.push(...imports));
1074
+ }
1075
+ return [...closure];
1076
+ }
1077
+ importsOf(fileName) {
1078
+ let { sys } = this.typescript, mtime = sys.getModifiedTime?.(fileName)?.valueOf(), cached = this.importsByFile.get(fileName);
1079
+ if (cached && cached.mtime === mtime)
1080
+ return cached.imports;
1081
+ let text = sys.readFile(fileName);
1082
+ if (text === void 0) {
1083
+ this.importsByFile.delete(fileName);
1084
+ return;
1085
+ }
1086
+ let { options } = this.getCommandLine(), imports = this.typescript.preProcessFile(text, !0, !0).importedFiles.flatMap(
1087
+ ({ fileName: specifier }) => this.typescript.resolveModuleName(specifier, fileName, options, sys).resolvedModule?.resolvedFileName ?? []
1088
+ ).map(normalize);
1089
+ return this.importsByFile.set(fileName, { mtime, imports }), imports;
1090
+ }
1091
+ debug(message) {
1092
+ logger3.debug(
1093
+ `[web-components-cem] ${message}${this.configFileName ? ` (${this.configFileName})` : ""}`
1094
+ );
1095
+ }
1096
+ };
1097
+ function commonDirectory(fileNames) {
1098
+ let [first, ...rest] = fileNames.map((fileName) => dirname(fileName).split("/")), length = first.length;
1099
+ for (let segments of rest) {
1100
+ let mismatch = first.slice(0, length).findIndex((segment, index) => segment !== segments[index]);
1101
+ mismatch !== -1 && (length = mismatch);
1102
+ }
1103
+ return first.slice(0, length).join("/") || "/";
1104
+ }
1105
+
1106
+ // src/docgen/component-docgen/source/generator-manager.ts
1107
+ var GeneratorManager = class extends ComponentMetaManager {
1108
+ constructor(typescript, generator) {
1109
+ super(typescript, createGeneratorProjectFactory(typescript, generator));
1110
+ }
1111
+ };
1112
+ function createGeneratorProjectFactory(typescript, generator) {
1113
+ return {
1114
+ // A JS story outside a tsconfig's files falls to the inferred project, whose generator run
1115
+ // scans the story's folder with `allowJs`; matching it to the tsconfig would hide it instead.
1116
+ parseCommandLine: (tsconfig) => parseTsconfigCommandLine(typescript, tsconfig),
1117
+ createConfiguredProject: (commandLine, tsconfig, getCommandLine) => new GeneratorProject(typescript, generator, commandLine, tsconfig, getCommandLine),
1118
+ createInferredProject: () => new GeneratorProject(
1119
+ typescript,
1120
+ generator,
1121
+ {
1122
+ options: {
1123
+ allowJs: !0,
1124
+ target: typescript.ScriptTarget.Latest,
1125
+ module: typescript.ModuleKind.ESNext,
1126
+ moduleResolution: typescript.ModuleResolutionKind.Bundler
1127
+ },
1128
+ fileNames: [],
1129
+ errors: []
1130
+ },
1131
+ void 0
1132
+ )
1133
+ };
1134
+ }
1135
+
1136
+ // src/docgen/component-docgen/source/source-manager.ts
1137
+ var SourceManager = class {
1138
+ constructor(typescript, generator, previewFilePath) {
1139
+ this.typescript = typescript;
1140
+ this.generator = generator;
1141
+ this.previewFilePath = previewFilePath;
1142
+ this.rootsByTag = /* @__PURE__ */ new WeakMap();
1143
+ this.literalMisses = /* @__PURE__ */ new WeakMap();
1144
+ /** Keyed by story file, then tag; valid until a searched project sees a file event. */
1145
+ this.misses = /* @__PURE__ */ new Map();
1146
+ this.warnedAnalysisFailures = /* @__PURE__ */ new Set();
1147
+ }
1148
+ async find(tag, lookup) {
1149
+ try {
1150
+ let manager = this.getManager(), story = normalize(lookup.storyFilePath), preview = this.previewFilePath ? normalize(this.previewFilePath) : void 0, storyProject = manager.getProjectForFile(story), previewProject = preview ? manager.getProjectForFile(preview) : void 0, projects = [.../* @__PURE__ */ new Set([storyProject, previewProject ?? storyProject])], tried = [story, ...preview ? [preview] : []], miss = this.misses.get(story)?.get(tag);
1151
+ if (miss && projects.every((project) => miss.revisions.get(project) === project.revision))
1152
+ return miss.error;
1153
+ let probes = [
1154
+ () => this.findFromRememberedRoot(tag, storyProject),
1155
+ () => this.findFromRoots(tag, [story], storyProject),
1156
+ () => preview && previewProject ? this.findFromRoots(tag, [preview], previewProject) : void 0,
1157
+ ...projects.map((project) => () => this.findFromTagLiteral(tag, project, tried))
1158
+ ];
1159
+ for (let probe of probes) {
1160
+ let found = probe();
1161
+ if (found)
1162
+ return found;
1163
+ }
1164
+ let error = tagNotFound(tag, story, preview, projects), storyMisses = this.misses.get(story) ?? /* @__PURE__ */ new Map();
1165
+ return storyMisses.set(tag, {
1166
+ error,
1167
+ revisions: new Map(projects.map((project) => [project, project.revision]))
1168
+ }), this.misses.set(story, storyMisses), error;
1169
+ } catch (error) {
1170
+ let message = `Failed to analyze sources for "${tag}": ${errorMessage(error)}`;
1171
+ return this.warnOnce(message), { name: "source-analysis-failed", message };
1172
+ }
1173
+ }
1174
+ dispose() {
1175
+ this.manager?.dispose(), this.manager = void 0;
1176
+ }
1177
+ getManager() {
1178
+ return this.manager || (this.manager = new GeneratorManager(this.typescript, this.generator), this.manager.startWatching()), this.manager;
1179
+ }
1180
+ findFromRememberedRoot(tag, project) {
1181
+ let root = this.rootsByTag.get(project)?.get(tag);
1182
+ if (!root)
1183
+ return;
1184
+ let found = this.findFromRoots(tag, [root], project);
1185
+ return found || this.rootsByTag.get(project)?.delete(tag), found;
1186
+ }
1187
+ findFromTagLiteral(tag, project, tried) {
1188
+ let misses = this.literalMisses.get(project) ?? /* @__PURE__ */ new Map();
1189
+ if (this.literalMisses.set(project, misses), misses.get(tag) === project.revision)
1190
+ return;
1191
+ let pattern = tagLiteralPattern(tag), candidates = project.rootFileNames().filter(
1192
+ (fileName) => !tried.includes(fileName) && pattern.test(this.typescript.sys.readFile(fileName) ?? "")
1193
+ ), found = candidates.length > 0 ? this.findFromRoots(tag, candidates, project) : void 0;
1194
+ return found || misses.set(tag, project.revision), found;
1195
+ }
1196
+ findFromRoots(tag, roots, project) {
1197
+ let manifest = project.createManifestForRoots(roots), found = manifest ? cemTagFromManifest(tag, manifest) : void 0;
1198
+ if (!found)
1199
+ return;
1200
+ let projectRoots = this.rootsByTag.get(project) ?? /* @__PURE__ */ new Map();
1201
+ return projectRoots.set(tag, found.rootPath), this.rootsByTag.set(project, projectRoots), { declaration: found.declaration, manifestPath: found.manifestPath };
1202
+ }
1203
+ warnOnce(message) {
1204
+ this.warnedAnalysisFailures.has(message) || (this.warnedAnalysisFailures.add(message), logger4.warn(message));
1205
+ }
1206
+ };
1207
+ function cemTagFromManifest(tag, manifest) {
1208
+ let flattened = flattenInheritance(manifest), declaration = buildTagIndex(flattened).get(tag);
1209
+ if (!declaration)
1210
+ return;
1211
+ let modulePath = declarationModulePath(flattened, declaration), rootPath = definitionModulePath(flattened, tag) ?? modulePath;
1212
+ if (rootPath)
1213
+ return {
1214
+ declaration,
1215
+ manifestPath: modulePath ? cwdRelative(modulePath) : "",
1216
+ rootPath
1217
+ };
1218
+ }
1219
+ function definitionModulePath(manifest, tag) {
1220
+ for (let module of manifest.modules)
1221
+ if (module.exports?.some(
1222
+ (candidate) => candidate.kind === "custom-element-definition" && candidate.name === tag
1223
+ ) && typeof module.path == "string")
1224
+ return normalize(module.path);
1225
+ }
1226
+ function declarationModulePath(manifest, declaration) {
1227
+ for (let module of manifest.modules)
1228
+ if (Array.isArray(module.declarations) && module.declarations.includes(declaration))
1229
+ return typeof module.path == "string" ? normalize(module.path) : void 0;
1230
+ }
1231
+ function cwdRelative(path2) {
1232
+ return isAbsolute(path2) ? relative(process.cwd(), path2) : normalize(path2);
1233
+ }
1234
+ function tagLiteralPattern(tag) {
1235
+ let escaped = tag.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1236
+ return new RegExp(`(['"\`])${escaped}\\1`);
1237
+ }
1238
+ function tagNotFound(tag, storyFilePath, previewFilePath, projects) {
1239
+ let searched = projects.map(
1240
+ (project) => project.configFileName ? cwdRelative(project.configFileName) : "the inferred TypeScript project"
1241
+ ), preview = previewFilePath ? ` and preview file ${cwdRelative(previewFilePath)}` : "";
1242
+ return {
1243
+ name: "tag-not-found",
1244
+ message: `No declaration for "${tag}" was found from story file ${cwdRelative(storyFilePath)}${preview}. Searched the tsconfig files covering those files: ${searched.join(", ") || "none"}. Import the element module in the story or configure customElementsManifest.`
1245
+ };
1246
+ }
1247
+
1248
+ // src/docgen/component-docgen/tag-resolver.ts
1249
+ function firstMatch([first, ...rest]) {
1250
+ return {
1251
+ async find(tag, lookup) {
1252
+ let result = await first.find(tag, lookup);
1253
+ for (let resolver of rest) {
1254
+ if ("declaration" in result)
1255
+ break;
1256
+ result = await resolver.find(tag, lookup);
1257
+ }
1258
+ return result;
1259
+ }
1260
+ };
1261
+ }
1262
+
875
1263
  // src/docgen/docgen-worker.ts
876
1264
  var createDocgenProvider = ({
877
1265
  manifestPaths,
878
- typeProperty
1266
+ previewFilePath
879
1267
  }) => createLazyDocgenMiddleware({
880
1268
  createManager: async () => {
881
- if (manifestPaths.length === 0) {
882
- logger2.warn(
883
- "No Custom Elements Manifest was configured; web-components server docgen is skipped. Set the `customElementsManifest` framework option or `customElements` in package.json."
884
- );
885
- return;
886
- }
887
- return new CemManager(manifestPaths);
1269
+ let sources = await loadSourceManager(previewFilePath), [first, ...rest] = [
1270
+ ...manifestPaths.length > 0 ? [new CemManager(manifestPaths)] : [],
1271
+ ...sources ? [sources] : []
1272
+ ];
1273
+ return first ? firstMatch([first, ...rest]) : void 0;
888
1274
  },
889
- extract: async (manager, input) => buildDocgenPayload(input, {
890
- cem: await manager.refresh(),
891
- typeProperty
892
- })
1275
+ extract: async (resolver, input) => buildDocgenPayload(input, { resolver })
893
1276
  });
1277
+ async function loadSourceManager(previewFilePath) {
1278
+ try {
1279
+ let [typescript, generator] = await Promise.all([import("typescript"), loadGenerator()]);
1280
+ return new SourceManager(typescript.default ?? typescript, generator, previewFilePath);
1281
+ } catch (error) {
1282
+ logger5.warn(
1283
+ `Web components docgen cannot generate declarations from sources: ${errorMessage(error)}`
1284
+ );
1285
+ return;
1286
+ }
1287
+ }
894
1288
 
895
1289
  export {
896
1290
  buildDocgenPayload,