@storybook/web-components 11.0.0-alpha.0 → 11.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_browser-chunks/{chunk-6TV4DYNC.js → chunk-6ZSMINL7.js} +6 -6
- package/dist/_browser-chunks/chunk-Z3YF52EY.js +172 -0
- package/dist/_browser-chunks/{chunk-6OBW3LSX.js → chunk-ZTODZABH.js} +2 -2
- package/dist/_node-chunks/chunk-36BPTBR5.js +56 -0
- package/dist/_node-chunks/chunk-FABV47GL.js +925 -0
- package/dist/docgen/docgen-worker.js +18 -0
- package/dist/docgen/index.d.ts +49 -0
- package/dist/docgen/index.js +23 -0
- package/dist/entry-preview-argtypes.js +61 -24
- package/dist/entry-preview-docs.js +1 -1
- package/dist/entry-preview.js +1 -1
- package/dist/index.d.ts +33 -858
- package/dist/index.js +3 -3
- package/dist/preset.js +62 -9
- package/package.json +10 -2
- package/template/cli/js/Header.js +6 -6
- package/template/cli/ts/Header.ts +6 -6
- package/template/stories/demo-wc-card/DemoWcCard.js +9 -9
- package/dist/_browser-chunks/chunk-UN5GYDGC.js +0 -62
|
@@ -0,0 +1,925 @@
|
|
|
1
|
+
import CJS_COMPAT_NODE_URL_rucz8cqr0ps from 'node:url';
|
|
2
|
+
import CJS_COMPAT_NODE_PATH_rucz8cqr0ps from 'node:path';
|
|
3
|
+
import CJS_COMPAT_NODE_MODULE_rucz8cqr0ps from "node:module";
|
|
4
|
+
|
|
5
|
+
var __filename = CJS_COMPAT_NODE_URL_rucz8cqr0ps.fileURLToPath(import.meta.url);
|
|
6
|
+
var __dirname = CJS_COMPAT_NODE_PATH_rucz8cqr0ps.dirname(__filename);
|
|
7
|
+
var require = CJS_COMPAT_NODE_MODULE_rucz8cqr0ps.createRequire(import.meta.url);
|
|
8
|
+
|
|
9
|
+
// ------------------------------------------------------------
|
|
10
|
+
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
|
|
11
|
+
// ------------------------------------------------------------
|
|
12
|
+
import {
|
|
13
|
+
deprecationMessage,
|
|
14
|
+
errorMessage,
|
|
15
|
+
firstValue,
|
|
16
|
+
isRecord,
|
|
17
|
+
namedItems,
|
|
18
|
+
readCssPropertySyntax,
|
|
19
|
+
readTypeText,
|
|
20
|
+
trimmedOrUndefined
|
|
21
|
+
} from "./chunk-36BPTBR5.js";
|
|
22
|
+
|
|
23
|
+
// src/docgen/docgen-worker.ts
|
|
24
|
+
import { createLazyDocgenMiddleware } from "storybook/internal/common";
|
|
25
|
+
import { logger as logger2 } from "storybook/internal/node-logger";
|
|
26
|
+
|
|
27
|
+
// src/docgen/component-docgen/build-docgen.ts
|
|
28
|
+
import { getComponentIdFromEntry, getStoryImportPathFromEntry } from "storybook/internal/common";
|
|
29
|
+
import { extractComponentDescription, extractDescription } from "storybook/internal/csf-tools";
|
|
30
|
+
import { resolve } from "node:path";
|
|
31
|
+
|
|
32
|
+
// src/arg-keys.ts
|
|
33
|
+
var DEFAULT_SLOT_NAME = "default";
|
|
34
|
+
function toArgKey(category, name) {
|
|
35
|
+
return category === "cssProperties" ? name : `${name}${ARG_KEY_SUFFIXES[category]}`;
|
|
36
|
+
}
|
|
37
|
+
var ARG_KEY_SUFFIXES = {
|
|
38
|
+
events: "-event",
|
|
39
|
+
methods: "-method",
|
|
40
|
+
slots: "-slot",
|
|
41
|
+
cssParts: "-part",
|
|
42
|
+
cssStates: "-state"
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// src/docgen/component-docgen/manifest/members.ts
|
|
46
|
+
function isPublicField(member) {
|
|
47
|
+
return isField(member) && isPublicMember(member);
|
|
48
|
+
}
|
|
49
|
+
function isPublicMethod(member) {
|
|
50
|
+
return isMethod(member) && isPublicMember(member);
|
|
51
|
+
}
|
|
52
|
+
function formatParameters(method) {
|
|
53
|
+
return (method.parameters ?? []).map(formatParameter).join(", ");
|
|
54
|
+
}
|
|
55
|
+
function isField(member) {
|
|
56
|
+
return member.kind === "field";
|
|
57
|
+
}
|
|
58
|
+
function isPublicMember(member) {
|
|
59
|
+
return member.privacy !== "private" && member.privacy !== "protected" && member.static !== !0 && !member.name.startsWith("#");
|
|
60
|
+
}
|
|
61
|
+
function isMethod(member) {
|
|
62
|
+
return member.kind === "method";
|
|
63
|
+
}
|
|
64
|
+
function formatParameter(parameter) {
|
|
65
|
+
let restPrefix = parameter.rest ? "..." : "", optionalSuffix = parameter.optional ? "?" : "", typeText = parameter.type?.text ? `: ${parameter.type.text}` : "", defaultText = parameter.default !== void 0 ? ` = ${parameter.default}` : "";
|
|
66
|
+
return `${restPrefix}${parameter.name}${optionalSuffix}${typeText}${defaultText}`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/docgen/component-docgen/manifest/declaration-api.ts
|
|
70
|
+
function classifyDeclaration(declaration) {
|
|
71
|
+
let members = namedItems(declaration.members), fields = members.filter(isField);
|
|
72
|
+
return {
|
|
73
|
+
attributes: namedItems(declaration.attributes).flatMap((attribute) => {
|
|
74
|
+
let field = backingField(attribute, fields);
|
|
75
|
+
return field && !isPublicField(field) ? [] : [{ attribute, field }];
|
|
76
|
+
}),
|
|
77
|
+
fields: fields.filter(isPublicField),
|
|
78
|
+
methods: members.filter(isPublicMethod),
|
|
79
|
+
events: namedItems(declaration.events),
|
|
80
|
+
slots: namedItems(declaration.slots),
|
|
81
|
+
cssProperties: namedItems(declaration.cssProperties),
|
|
82
|
+
cssParts: namedItems(declaration.cssParts),
|
|
83
|
+
cssStates: namedItems(declaration.cssStates)
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function isBackedByAttribute(field, attributes) {
|
|
87
|
+
return attributes.some(
|
|
88
|
+
(attribute) => attribute.field === field || attribute.attribute.name === field.name
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
function backingField(attribute, fields) {
|
|
92
|
+
return attribute.fieldName === void 0 ? void 0 : fields.find((field) => field.name === attribute.fieldName);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// src/docgen/component-docgen/api-description.ts
|
|
96
|
+
var IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
|
|
97
|
+
function buildApiDescription(declaration, typeProperty) {
|
|
98
|
+
let api = classifyDeclaration(declaration), attributes = api.attributes.map((attribute) => attributeDoc(attribute, typeProperty)), properties = api.fields.filter((field) => !isBackedByAttribute(field, api.attributes));
|
|
99
|
+
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)
|
|
100
|
+
return;
|
|
101
|
+
let typePrefix = declaration.name.replace(/\W+/g, "");
|
|
102
|
+
return [
|
|
103
|
+
attributesSection(typePrefix, attributes),
|
|
104
|
+
propertiesSection(typePrefix, properties, typeProperty),
|
|
105
|
+
eventsSection(typePrefix, api.events, typeProperty),
|
|
106
|
+
methodsSection(typePrefix, api.methods, typeProperty),
|
|
107
|
+
listSection(
|
|
108
|
+
"Slots",
|
|
109
|
+
api.slots.map((slot) => listItem(slot.name || DEFAULT_SLOT_NAME, memberDoc(slot)))
|
|
110
|
+
),
|
|
111
|
+
listSection(
|
|
112
|
+
"CSS Custom Properties",
|
|
113
|
+
api.cssProperties.map((property) => cssPropertyListItem(property, typeProperty))
|
|
114
|
+
),
|
|
115
|
+
listSection(
|
|
116
|
+
"CSS Parts",
|
|
117
|
+
api.cssParts.map((part) => listItem(part.name, memberDoc(part)))
|
|
118
|
+
),
|
|
119
|
+
listSection(
|
|
120
|
+
"CSS States",
|
|
121
|
+
api.cssStates.map((state) => listItem(state.name, memberDoc(state)))
|
|
122
|
+
)
|
|
123
|
+
].filter((section) => section !== void 0).join(`
|
|
124
|
+
|
|
125
|
+
`).trim();
|
|
126
|
+
}
|
|
127
|
+
function attributesSection(typePrefix, attributes) {
|
|
128
|
+
if (attributes.length !== 0)
|
|
129
|
+
return typeSection(
|
|
130
|
+
"Attributes",
|
|
131
|
+
`${typePrefix}Attributes`,
|
|
132
|
+
attributes.flatMap(({ attribute, field, type, doc }) => {
|
|
133
|
+
let suffix = field && field.name !== attribute.name ? ` // property: ${field.name}` : "";
|
|
134
|
+
return [
|
|
135
|
+
...docComment(doc),
|
|
136
|
+
` ${memberName(attribute.name)}?: ${type}${memberDefault(doc)};${suffix}`
|
|
137
|
+
];
|
|
138
|
+
})
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
function propertiesSection(typePrefix, properties, typeProperty) {
|
|
142
|
+
if (properties.length !== 0)
|
|
143
|
+
return typeSection(
|
|
144
|
+
"Properties",
|
|
145
|
+
`${typePrefix}Properties`,
|
|
146
|
+
properties.flatMap((property) => {
|
|
147
|
+
let doc = memberDoc(property), type = fieldType(property, typeProperty);
|
|
148
|
+
return [
|
|
149
|
+
...docComment(doc),
|
|
150
|
+
property.readonly === !0 ? ` readonly ${memberName(property.name)}: ${type}${memberDefault(doc)};` : ` ${memberName(property.name)}?: ${type}${memberDefault(doc)};`
|
|
151
|
+
];
|
|
152
|
+
})
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
function eventsSection(typePrefix, events, typeProperty) {
|
|
156
|
+
if (events.length !== 0)
|
|
157
|
+
return typeSection(
|
|
158
|
+
"Events",
|
|
159
|
+
`${typePrefix}Events`,
|
|
160
|
+
events.flatMap((event) => [
|
|
161
|
+
...docComment(memberDoc(event)),
|
|
162
|
+
` ${memberName(event.name)}: ${readTypeText(event, typeProperty) ?? "Event"};`
|
|
163
|
+
])
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
function methodsSection(typePrefix, methods, typeProperty) {
|
|
167
|
+
if (methods.length !== 0)
|
|
168
|
+
return typeSection(
|
|
169
|
+
"Methods",
|
|
170
|
+
`${typePrefix}Methods`,
|
|
171
|
+
methods.flatMap((method) => [
|
|
172
|
+
...docComment(memberDoc(method)),
|
|
173
|
+
` ${memberName(method.name)}(${formatParameters(method)}): ${methodReturnType(
|
|
174
|
+
method,
|
|
175
|
+
typeProperty
|
|
176
|
+
)};`
|
|
177
|
+
])
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
function typeSection(heading, typeName, lines) {
|
|
181
|
+
return [`## ${heading}`, "", "```", `export type ${typeName} = {`, ...lines, "}", "```"].join(
|
|
182
|
+
`
|
|
183
|
+
`
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
function listSection(heading, items) {
|
|
187
|
+
if (items.length !== 0)
|
|
188
|
+
return [`## ${heading}`, "", ...items].join(`
|
|
189
|
+
`);
|
|
190
|
+
}
|
|
191
|
+
function cssPropertyListItem(property, typeProperty) {
|
|
192
|
+
let syntax = readCssPropertySyntax(property, typeProperty), name = property.name, syntaxText = syntax ? ` \`${syntax}\`` : "";
|
|
193
|
+
return listItemPrefix(`${name}${syntaxText}`, memberDoc(property));
|
|
194
|
+
}
|
|
195
|
+
function listItem(name, doc) {
|
|
196
|
+
return listItemPrefix(name, doc);
|
|
197
|
+
}
|
|
198
|
+
function listItemPrefix(prefix, doc) {
|
|
199
|
+
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}.`;
|
|
200
|
+
return `- ${prefix}${text}${defaultText}${deprecatedText}`;
|
|
201
|
+
}
|
|
202
|
+
function attributeDoc(attribute, typeProperty) {
|
|
203
|
+
let { field } = attribute;
|
|
204
|
+
return {
|
|
205
|
+
...attribute,
|
|
206
|
+
type: attributeType(attribute, typeProperty),
|
|
207
|
+
doc: memberDoc(field, attribute.attribute)
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function attributeType({ attribute, field }, typeProperty) {
|
|
211
|
+
return firstValue(
|
|
212
|
+
[field, attribute],
|
|
213
|
+
(source) => source ? trimmedOrUndefined(readTypeText(source, typeProperty)) : void 0
|
|
214
|
+
) ?? "string";
|
|
215
|
+
}
|
|
216
|
+
function fieldType(field, typeProperty) {
|
|
217
|
+
return trimmedOrUndefined(readTypeText(field, typeProperty)) ?? "unknown";
|
|
218
|
+
}
|
|
219
|
+
function methodReturnType(method, typeProperty) {
|
|
220
|
+
return method.return ? readTypeText(method.return, typeProperty) ?? "void" : "void";
|
|
221
|
+
}
|
|
222
|
+
function memberDoc(...sources) {
|
|
223
|
+
return {
|
|
224
|
+
text: firstValue(
|
|
225
|
+
sources,
|
|
226
|
+
(source) => trimmedOrUndefined(source?.description) ?? trimmedOrUndefined(source?.summary)
|
|
227
|
+
),
|
|
228
|
+
deprecated: firstValue(sources, (source) => deprecationMessage(source?.deprecated)),
|
|
229
|
+
defaultValue: firstValue(sources, (source) => defaultValue(source?.default))
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function defaultValue(value) {
|
|
233
|
+
return value === void 0 || value === "undefined" ? void 0 : value.replace(/\s*\n\s*/g, " ").trim();
|
|
234
|
+
}
|
|
235
|
+
function memberDefault(doc) {
|
|
236
|
+
return doc.defaultValue === void 0 ? "" : ` = ${doc.defaultValue}`;
|
|
237
|
+
}
|
|
238
|
+
function docComment(doc) {
|
|
239
|
+
let body = doc.text ? commentLines(doc.text) : [], tags = [];
|
|
240
|
+
return doc.deprecated !== void 0 && tags.push(
|
|
241
|
+
...commentLines(
|
|
242
|
+
doc.deprecated === "deprecated" ? "@deprecated" : `@deprecated ${doc.deprecated}`
|
|
243
|
+
)
|
|
244
|
+
), tags.length > 0 && (body.length > 0 && body.push(""), body.push(...tags)), body.length === 0 ? [] : body.length === 1 ? [` /** ${body[0]} */`] : [" /**", ...body.map((line) => line ? ` * ${line}` : " *"), " */"];
|
|
245
|
+
}
|
|
246
|
+
function commentLines(text) {
|
|
247
|
+
return text.replace(/\*\//g, "*\\/").split(`
|
|
248
|
+
`).map((line) => line.trimEnd());
|
|
249
|
+
}
|
|
250
|
+
function memberName(name) {
|
|
251
|
+
return IDENTIFIER.test(name) ? name : `'${name.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// src/docgen/component-docgen/arg-types/parse-type-text.ts
|
|
255
|
+
var ARRAY_RE = /^(?:Array<(.+)>|(.+)\[\])$/, DROPPED_MEMBERS = /* @__PURE__ */ new Set([
|
|
256
|
+
"undefined",
|
|
257
|
+
"null",
|
|
258
|
+
"void",
|
|
259
|
+
"any",
|
|
260
|
+
"unknown",
|
|
261
|
+
"never",
|
|
262
|
+
"string & {}",
|
|
263
|
+
"(string & {})"
|
|
264
|
+
]), FUNCTION_RE = /^(new\s+)?(<.*>\s*)?\(.*\)\s*=>/, UNKNOWN_ARRAY_ELEMENT_TYPE = { name: "other", value: "" }, MAX_ARRAY_DEPTH = 8;
|
|
265
|
+
function parseTypeText(text, depth = 0) {
|
|
266
|
+
let trimmed = text?.trim() ?? "", members = normalizeMembers(trimmed);
|
|
267
|
+
if (members.length === 0)
|
|
268
|
+
return;
|
|
269
|
+
let literalValues = members.map(parseLiteral).filter((literal) => literal !== void 0);
|
|
270
|
+
if (literalValues.length === members.length)
|
|
271
|
+
return { type: { name: "enum", value: literalValues } };
|
|
272
|
+
if (literalValues.length > 0 && members.includes("string"))
|
|
273
|
+
return { type: { name: "string" } };
|
|
274
|
+
if (literalValues.length > 0)
|
|
275
|
+
return {
|
|
276
|
+
type: { name: "other", value: members.join(" | ") },
|
|
277
|
+
...members.some(isCallable) ? { control: !1 } : {}
|
|
278
|
+
};
|
|
279
|
+
let scalar = pickScalar(members);
|
|
280
|
+
if (scalar !== void 0)
|
|
281
|
+
return scalar;
|
|
282
|
+
if (members.length === 1) {
|
|
283
|
+
let member = stripWrappingParens(members[0]), array = ARRAY_RE.exec(member);
|
|
284
|
+
if (array) {
|
|
285
|
+
let element = depth >= MAX_ARRAY_DEPTH ? UNKNOWN_ARRAY_ELEMENT_TYPE : parseTypeText(stripWrappingParens(array[1] ?? array[2] ?? ""), depth + 1)?.type ?? UNKNOWN_ARRAY_ELEMENT_TYPE;
|
|
286
|
+
return element.name === "enum" ? {
|
|
287
|
+
type: { name: "array", value: element },
|
|
288
|
+
control: { type: "multi-select" },
|
|
289
|
+
options: element.value
|
|
290
|
+
} : { type: { name: "array", value: element } };
|
|
291
|
+
}
|
|
292
|
+
if (member === "Date")
|
|
293
|
+
return { type: { name: "date" }, control: { type: "date" } };
|
|
294
|
+
if (isBareObjectType(member))
|
|
295
|
+
return { type: { name: "object", value: {} } };
|
|
296
|
+
if (isBareArrayType(member))
|
|
297
|
+
return { type: { name: "array", value: UNKNOWN_ARRAY_ELEMENT_TYPE } };
|
|
298
|
+
if (isCallable(member))
|
|
299
|
+
return { type: { name: "function" } };
|
|
300
|
+
if (isObjectLike(member))
|
|
301
|
+
return { type: { name: "object", value: {} } };
|
|
302
|
+
}
|
|
303
|
+
return {
|
|
304
|
+
type: { name: "other", value: members.join(" | ") },
|
|
305
|
+
control: !1
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function normalizeMembers(text) {
|
|
309
|
+
return text ? flattenMembers(text).filter((member) => member && !DROPPED_MEMBERS.has(member)) : [];
|
|
310
|
+
}
|
|
311
|
+
function flattenMembers(text) {
|
|
312
|
+
return splitTopLevel(text).flatMap((part) => {
|
|
313
|
+
let member = stripWrappingParens(part);
|
|
314
|
+
return splitTopLevel(member).length > 1 ? flattenMembers(member) : [member];
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
function parseLiteral(text) {
|
|
318
|
+
let stringLiteral = /^(['"])(.*)\1$/.exec(text);
|
|
319
|
+
if (stringLiteral)
|
|
320
|
+
return stringLiteral[2];
|
|
321
|
+
if (/^-?(?:\d+|\d*\.\d+)$/.test(text))
|
|
322
|
+
return Number(text);
|
|
323
|
+
}
|
|
324
|
+
function pickScalar(members) {
|
|
325
|
+
if (members.includes("string"))
|
|
326
|
+
return { type: { name: "string" } };
|
|
327
|
+
let hasBoolean = members.some(
|
|
328
|
+
(member) => member === "boolean" || member === "true" || member === "false"
|
|
329
|
+
), hasNumber = members.some((member) => member === "number" || member === "bigint");
|
|
330
|
+
if (hasBoolean && hasNumber)
|
|
331
|
+
return { type: { name: "other", value: members.join(" | ") } };
|
|
332
|
+
if (hasBoolean)
|
|
333
|
+
return { type: { name: "boolean" } };
|
|
334
|
+
if (hasNumber)
|
|
335
|
+
return { type: { name: "number" } };
|
|
336
|
+
}
|
|
337
|
+
function isCallable(text) {
|
|
338
|
+
return text === "Function" || FUNCTION_RE.test(text) || /^\([^)]*\)\s*:/.test(text);
|
|
339
|
+
}
|
|
340
|
+
function isBareArrayType(text) {
|
|
341
|
+
return text.toLowerCase() === "array";
|
|
342
|
+
}
|
|
343
|
+
function isBareObjectType(text) {
|
|
344
|
+
return text.toLowerCase() === "object";
|
|
345
|
+
}
|
|
346
|
+
function isObjectLike(text) {
|
|
347
|
+
return /^\{.*\}$/.test(text) || /^\[.*\]$/.test(text) || text.includes("<");
|
|
348
|
+
}
|
|
349
|
+
function stripWrappingParens(text) {
|
|
350
|
+
let trimmed = text.trim();
|
|
351
|
+
if (!trimmed.startsWith("("))
|
|
352
|
+
return trimmed;
|
|
353
|
+
let depth = 0;
|
|
354
|
+
for (let index = 0; index < trimmed.length; index += 1) {
|
|
355
|
+
let char = trimmed[index];
|
|
356
|
+
if (char === "(")
|
|
357
|
+
depth += 1;
|
|
358
|
+
else if (char === ")" && (depth -= 1, depth === 0))
|
|
359
|
+
return index === trimmed.length - 1 ? trimmed.slice(1, -1).trim() : trimmed;
|
|
360
|
+
}
|
|
361
|
+
return trimmed;
|
|
362
|
+
}
|
|
363
|
+
function splitTopLevel(text) {
|
|
364
|
+
let members = [], current = "", depth = 0, hasTopLevelArrow = !1, quote;
|
|
365
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
366
|
+
let char = text[index], previous = text[index - 1];
|
|
367
|
+
if (quote) {
|
|
368
|
+
current += char, char === quote && previous !== "\\" && (quote = void 0);
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
if (char === '"' || char === "'") {
|
|
372
|
+
quote = char, current += char;
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
if (char === "=" && text[index + 1] === ">" && depth === 0 && (hasTopLevelArrow = !0), "<{[(".includes(char) ? depth += 1 : ">}])".includes(char) && !(char === ">" && previous === "=") && (depth = Math.max(0, depth - 1)), char === "|" && depth === 0 && !hasTopLevelArrow) {
|
|
376
|
+
members.push(current.trim()), current = "";
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
current += char;
|
|
380
|
+
}
|
|
381
|
+
return members.push(current.trim()), members;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// src/docgen/component-docgen/arg-types/map-arg-types.ts
|
|
385
|
+
var NAMED_ENTRY_CATEGORIES = {
|
|
386
|
+
slots: "slots",
|
|
387
|
+
cssParts: "css shadow parts",
|
|
388
|
+
cssStates: "css states"
|
|
389
|
+
};
|
|
390
|
+
function mapArgTypes(declaration, typeProperty) {
|
|
391
|
+
let api = classifyDeclaration(declaration);
|
|
392
|
+
return {
|
|
393
|
+
...Object.fromEntries([
|
|
394
|
+
...api.events.flatMap((event) => eventEntries(event, typeProperty)),
|
|
395
|
+
...api.methods.map(methodEntry),
|
|
396
|
+
...api.slots.map((slot) => namedEntry(slot, "slots")),
|
|
397
|
+
...api.cssParts.map((part) => namedEntry(part, "cssParts")),
|
|
398
|
+
...api.cssStates.map((state) => namedEntry(state, "cssStates")),
|
|
399
|
+
...api.cssProperties.map((property) => cssPropertyEntry(property, typeProperty))
|
|
400
|
+
]),
|
|
401
|
+
...mapAttributesAndProperties(api, typeProperty)
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
function mapAttributesAndProperties(api, typeProperty) {
|
|
405
|
+
let argTypes = {}, properties = api.fields.filter(
|
|
406
|
+
(field) => !api.attributes.some(({ attribute }) => attribute.name === field.name)
|
|
407
|
+
);
|
|
408
|
+
for (let field of properties) {
|
|
409
|
+
let attribute = api.attributes.find(({ field: backingField2 }) => backingField2 === field);
|
|
410
|
+
argTypes[field.name] = toArgType({
|
|
411
|
+
key: field.name,
|
|
412
|
+
category: "properties",
|
|
413
|
+
sources: attribute ? [field, attribute.attribute] : [field],
|
|
414
|
+
typeProperty
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
for (let { attribute, field } of api.attributes)
|
|
418
|
+
argTypes[attribute.name] = toArgType({
|
|
419
|
+
key: attribute.name,
|
|
420
|
+
category: "attributes",
|
|
421
|
+
sources: field ? [field, attribute] : [attribute],
|
|
422
|
+
typeProperty
|
|
423
|
+
});
|
|
424
|
+
return argTypes;
|
|
425
|
+
}
|
|
426
|
+
function toArgType({ key, category, sources, typeProperty }) {
|
|
427
|
+
let rawTypeText = firstValue(
|
|
428
|
+
sources,
|
|
429
|
+
(source) => typeof source.type?.text == "string" ? source.type.text : void 0
|
|
430
|
+
), text = firstValue(
|
|
431
|
+
sources,
|
|
432
|
+
(source) => trimmedOrUndefined(readTypeText(source, typeProperty))
|
|
433
|
+
), parsed = parseTypeText(text) ?? (category === "attributes" ? { type: { name: "string" } } : { type: { name: "other", value: text ?? "" }, control: !1 }), readonly = firstValue(
|
|
434
|
+
sources,
|
|
435
|
+
(source) => "readonly" in source && source.readonly === !0 ? !0 : void 0
|
|
436
|
+
);
|
|
437
|
+
return memberArgType(key, sources, category, {
|
|
438
|
+
...parsed,
|
|
439
|
+
...readonly ? { control: !1 } : {},
|
|
440
|
+
table: {
|
|
441
|
+
type: { summary: rawTypeText },
|
|
442
|
+
defaultValue: { summary: firstValue(sources, (source) => source.default) }
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
function eventEntries(event, typeProperty) {
|
|
447
|
+
let text = readTypeText(event, typeProperty) ?? "CustomEvent";
|
|
448
|
+
return [
|
|
449
|
+
[
|
|
450
|
+
toArgKey("events", event.name),
|
|
451
|
+
memberArgType(event.name, [event], "events", {
|
|
452
|
+
type: { name: "other", value: text },
|
|
453
|
+
control: !1,
|
|
454
|
+
table: { type: { summary: text } }
|
|
455
|
+
})
|
|
456
|
+
]
|
|
457
|
+
];
|
|
458
|
+
}
|
|
459
|
+
function methodEntry(method) {
|
|
460
|
+
return [
|
|
461
|
+
toArgKey("methods", method.name),
|
|
462
|
+
memberArgType(method.name, [method], "methods", {
|
|
463
|
+
type: { name: "function" },
|
|
464
|
+
table: { type: { summary: methodSignature(method) } }
|
|
465
|
+
})
|
|
466
|
+
];
|
|
467
|
+
}
|
|
468
|
+
function namedEntry(item, category) {
|
|
469
|
+
let name = item.name || DEFAULT_SLOT_NAME;
|
|
470
|
+
return [
|
|
471
|
+
toArgKey(category, name),
|
|
472
|
+
memberArgType(name, [item], NAMED_ENTRY_CATEGORIES[category], { type: { name: "string" } })
|
|
473
|
+
];
|
|
474
|
+
}
|
|
475
|
+
function cssPropertyEntry(property, typeProperty) {
|
|
476
|
+
let syntax = readCssPropertySyntax(property, typeProperty);
|
|
477
|
+
return [
|
|
478
|
+
toArgKey("cssProperties", property.name),
|
|
479
|
+
memberArgType(property.name, [property], "css custom properties", {
|
|
480
|
+
...cssCustomPropertyControl(syntax),
|
|
481
|
+
table: {
|
|
482
|
+
type: { summary: syntax },
|
|
483
|
+
defaultValue: { summary: property.default }
|
|
484
|
+
}
|
|
485
|
+
})
|
|
486
|
+
];
|
|
487
|
+
}
|
|
488
|
+
function memberArgType(name, sources, category, rest) {
|
|
489
|
+
let { table, ...input } = rest, { deprecated, ...fields } = docFields(sources);
|
|
490
|
+
return {
|
|
491
|
+
name,
|
|
492
|
+
...fields,
|
|
493
|
+
...input,
|
|
494
|
+
table: {
|
|
495
|
+
...table,
|
|
496
|
+
category,
|
|
497
|
+
...deprecated ? { jsDocTags: { deprecated } } : {}
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
function docFields(sources) {
|
|
502
|
+
return {
|
|
503
|
+
description: firstValue(
|
|
504
|
+
sources,
|
|
505
|
+
(source) => trimmedOrUndefined(source.summary ?? source.description)
|
|
506
|
+
),
|
|
507
|
+
deprecated: firstValue(sources, (source) => deprecationMessage(source.deprecated))
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
function methodSignature(method) {
|
|
511
|
+
let params = formatParameters(method), returnType = method.return?.type?.text;
|
|
512
|
+
return returnType ? `(${params}) => ${returnType}` : `(${params})`;
|
|
513
|
+
}
|
|
514
|
+
function cssCustomPropertyControl(syntax) {
|
|
515
|
+
let lowerSyntax = syntax?.toLowerCase();
|
|
516
|
+
return lowerSyntax === "<color>" ? { type: { name: "string" }, control: { type: "color" } } : lowerSyntax === "<number>" || lowerSyntax === "<integer>" ? { type: { name: "number" } } : { type: { name: "string" } };
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// src/docgen/component-docgen/resolve-component/resolve-component.ts
|
|
520
|
+
import { loadCsf, unwrapExpression } from "storybook/internal/csf-tools";
|
|
521
|
+
import { recast, types as t } from "storybook/internal/babel";
|
|
522
|
+
import { readFileSync } from "node:fs";
|
|
523
|
+
function parseStoryFile(storyFilePath, title) {
|
|
524
|
+
try {
|
|
525
|
+
let source = readFileSync(storyFilePath, "utf8");
|
|
526
|
+
return loadCsf(source, { makeTitle: () => title }).parse();
|
|
527
|
+
} catch {
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
var expressionFor = (node) => recast.print(node).code;
|
|
532
|
+
function tagFromNode(node) {
|
|
533
|
+
let expression = expressionFor(node), unwrapped = unwrapExpression(node);
|
|
534
|
+
if (t.isStringLiteral(unwrapped) && unwrapped.value !== "")
|
|
535
|
+
return { tag: unwrapped.value };
|
|
536
|
+
if (t.isTemplateLiteral(unwrapped) && unwrapped.expressions.length === 0) {
|
|
537
|
+
let tag = unwrapped.quasis[0]?.value.cooked;
|
|
538
|
+
if (tag)
|
|
539
|
+
return { tag };
|
|
540
|
+
}
|
|
541
|
+
return { reason: "component-not-a-tag", expression };
|
|
542
|
+
}
|
|
543
|
+
function resolveStoryComponent(csf) {
|
|
544
|
+
let component = csf._metaAnnotations.component;
|
|
545
|
+
return component ? tagFromNode(component) : { reason: "no-meta-component" };
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// src/docgen/component-docgen/build-docgen.ts
|
|
549
|
+
function buildDocgenPayload(input, context) {
|
|
550
|
+
let storyImportPath = getStoryImportPathFromEntry(input.entry);
|
|
551
|
+
if (!storyImportPath)
|
|
552
|
+
return;
|
|
553
|
+
let id = getComponentIdFromEntry(input.entry), path = storyImportPath, fail = (name, error) => ({
|
|
554
|
+
id,
|
|
555
|
+
name,
|
|
556
|
+
path,
|
|
557
|
+
jsDocTags: {},
|
|
558
|
+
error
|
|
559
|
+
}), storyFilePath = resolve(process.cwd(), storyImportPath), csf = parseStoryFile(storyFilePath, input.entry.title);
|
|
560
|
+
if (!csf)
|
|
561
|
+
return;
|
|
562
|
+
let resolved = resolveStoryComponent(csf);
|
|
563
|
+
if ("reason" in resolved) {
|
|
564
|
+
if (resolved.reason === "no-meta-component")
|
|
565
|
+
return;
|
|
566
|
+
let componentName = input.entry.title.slice(input.entry.title.lastIndexOf("/") + 1);
|
|
567
|
+
return fail(componentName, {
|
|
568
|
+
name: "component-not-a-tag",
|
|
569
|
+
message: `\`meta.component\` must be the element's tag name as a string, got \`${resolved.expression}\``
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
let { tag } = resolved, found = context.cem.tags.get(tag);
|
|
573
|
+
if (!found)
|
|
574
|
+
return fail(
|
|
575
|
+
tag,
|
|
576
|
+
context.cem.errors[0] ?? {
|
|
577
|
+
name: "tag-not-found",
|
|
578
|
+
message: `No declaration for "${tag}" was found in ${context.cem.paths.join(", ")}. If the element is new, rerun the custom elements manifest analyzer.`
|
|
579
|
+
}
|
|
580
|
+
);
|
|
581
|
+
let { description, summary, jsDocTags } = extractComponentDescription(
|
|
582
|
+
extractDescription(csf._metaStatement) || void 0,
|
|
583
|
+
found.declaration.description,
|
|
584
|
+
declarationTags(found.declaration)
|
|
585
|
+
);
|
|
586
|
+
return {
|
|
587
|
+
id,
|
|
588
|
+
name: tag,
|
|
589
|
+
path,
|
|
590
|
+
description,
|
|
591
|
+
summary,
|
|
592
|
+
jsDocTags,
|
|
593
|
+
argTypes: mapArgTypes(found.declaration, context.typeProperty),
|
|
594
|
+
apiDescription: buildApiDescription(found.declaration, context.typeProperty),
|
|
595
|
+
renderer: "web-components",
|
|
596
|
+
...found.warning ? { warning: found.warning } : {},
|
|
597
|
+
customElementsManifest: {
|
|
598
|
+
manifestPath: found.manifestPath,
|
|
599
|
+
declaration: found.declaration
|
|
600
|
+
}
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
function declarationTags(declaration) {
|
|
604
|
+
let tags = {}, summary = trimmedOrUndefined(declaration.summary);
|
|
605
|
+
summary && (tags.summary = [summary]);
|
|
606
|
+
let deprecated = deprecationMessage(declaration.deprecated);
|
|
607
|
+
return deprecated && (tags.deprecated = [deprecated]), tags;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// src/docgen/component-docgen/manifest/cem-manager.ts
|
|
611
|
+
import { logger } from "storybook/internal/node-logger";
|
|
612
|
+
import { stat } from "node:fs/promises";
|
|
613
|
+
import { relative as relative2 } from "node:path";
|
|
614
|
+
|
|
615
|
+
// src/docgen/component-docgen/manifest/build-tag-index.ts
|
|
616
|
+
function buildTagIndex(manifest) {
|
|
617
|
+
let tags = /* @__PURE__ */ new Map();
|
|
618
|
+
for (let module of manifest.modules)
|
|
619
|
+
if (!(!isRecord(module) || !Array.isArray(module.declarations)))
|
|
620
|
+
for (let declaration of module.declarations)
|
|
621
|
+
isManifestDeclaration(declaration) && declaration.tagName && !tags.has(declaration.tagName) && tags.set(declaration.tagName, declaration);
|
|
622
|
+
for (let module of manifest.modules)
|
|
623
|
+
if (!(!isRecord(module) || !Array.isArray(module.exports)))
|
|
624
|
+
for (let definition of module.exports) {
|
|
625
|
+
if (!isRecord(definition) || definition.kind !== "custom-element-definition" || typeof definition.name != "string" || tags.has(definition.name) || !isRecord(definition.declaration) || typeof definition.declaration.name != "string")
|
|
626
|
+
continue;
|
|
627
|
+
let modulePath = typeof definition.declaration.module == "string" ? definition.declaration.module : typeof module.path == "string" ? module.path : void 0;
|
|
628
|
+
if (modulePath === void 0)
|
|
629
|
+
continue;
|
|
630
|
+
let declaration = findDeclarationByName(manifest, definition.declaration.name, modulePath);
|
|
631
|
+
declaration && tags.set(definition.name, declaration);
|
|
632
|
+
}
|
|
633
|
+
return tags;
|
|
634
|
+
}
|
|
635
|
+
function findDeclarationByName(manifest, name, modulePath) {
|
|
636
|
+
for (let module of manifest.modules) {
|
|
637
|
+
if (!isRecord(module) || !Array.isArray(module.declarations) || module.path !== modulePath)
|
|
638
|
+
continue;
|
|
639
|
+
let declaration = module.declarations?.find(
|
|
640
|
+
(candidate) => isManifestDeclaration(candidate) && candidate.name === name
|
|
641
|
+
);
|
|
642
|
+
if (declaration)
|
|
643
|
+
return declaration;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
function isManifestDeclaration(candidate) {
|
|
647
|
+
return isRecord(candidate) && (candidate.kind === "class" || candidate.kind === "mixin") && "customElement" in candidate && candidate.customElement === !0;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// src/docgen/component-docgen/manifest/flatten-inheritance.ts
|
|
651
|
+
var INHERITED_FIELDS = [
|
|
652
|
+
"description",
|
|
653
|
+
"summary",
|
|
654
|
+
"deprecated",
|
|
655
|
+
"default",
|
|
656
|
+
"type",
|
|
657
|
+
"attribute",
|
|
658
|
+
"fieldName"
|
|
659
|
+
], LIST_KEYS = [
|
|
660
|
+
"members",
|
|
661
|
+
"attributes",
|
|
662
|
+
"events",
|
|
663
|
+
"slots",
|
|
664
|
+
"cssParts",
|
|
665
|
+
"cssProperties",
|
|
666
|
+
"cssStates"
|
|
667
|
+
];
|
|
668
|
+
function flattenInheritance(manifest) {
|
|
669
|
+
let index = indexDeclarations(manifest), flatten = createInheritanceResolver(index);
|
|
670
|
+
return {
|
|
671
|
+
...manifest,
|
|
672
|
+
modules: manifest.modules.map((module) => flattenModule(module, index, flatten))
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
function indexDeclarations(manifest) {
|
|
676
|
+
let byKey = /* @__PURE__ */ new Map();
|
|
677
|
+
for (let module of manifest.modules) {
|
|
678
|
+
if (!isRecord(module) || !Array.isArray(module.declarations))
|
|
679
|
+
continue;
|
|
680
|
+
let modulePath = modulePathOf(module);
|
|
681
|
+
for (let declaration of module.declarations) {
|
|
682
|
+
if (!isManifestClassLike(declaration))
|
|
683
|
+
continue;
|
|
684
|
+
let key = keyFor(modulePath, declaration.name);
|
|
685
|
+
byKey.has(key) || byKey.set(key, { declaration, modulePath, references: referencesOf(declaration) });
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
return (modulePath, name) => byKey.get(keyFor(modulePath, name));
|
|
689
|
+
}
|
|
690
|
+
function isManifestClassLike(candidate) {
|
|
691
|
+
return isRecord(candidate) && (candidate.kind === "class" || candidate.kind === "mixin") && typeof candidate.name == "string";
|
|
692
|
+
}
|
|
693
|
+
function referencesOf(declaration) {
|
|
694
|
+
return [
|
|
695
|
+
...Array.isArray(declaration.mixins) ? declaration.mixins : [],
|
|
696
|
+
declaration.superclass
|
|
697
|
+
].filter(isReference);
|
|
698
|
+
}
|
|
699
|
+
function isReference(candidate) {
|
|
700
|
+
return isRecord(candidate) && typeof candidate.name == "string" && (candidate.module === void 0 || typeof candidate.module == "string") && (candidate.package === void 0 || typeof candidate.package == "string");
|
|
701
|
+
}
|
|
702
|
+
function createInheritanceResolver(index) {
|
|
703
|
+
let flattened = /* @__PURE__ */ new Map();
|
|
704
|
+
function flatten(entry) {
|
|
705
|
+
let cached = flattened.get(entry.declaration);
|
|
706
|
+
if (cached !== void 0)
|
|
707
|
+
return cached;
|
|
708
|
+
flattened.set(entry.declaration, entry.declaration);
|
|
709
|
+
let parents = entry.references.flatMap((reference) => {
|
|
710
|
+
let parent = resolveReference(reference, index, entry.modulePath);
|
|
711
|
+
return parent ? [
|
|
712
|
+
{
|
|
713
|
+
declaration: flatten(parent),
|
|
714
|
+
from: {
|
|
715
|
+
name: parent.declaration.name,
|
|
716
|
+
...parent.modulePath ? { module: parent.modulePath } : {}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
] : [];
|
|
720
|
+
}), merged = mergeInherited(entry.declaration, parents);
|
|
721
|
+
return flattened.set(entry.declaration, merged), merged;
|
|
722
|
+
}
|
|
723
|
+
return flatten;
|
|
724
|
+
}
|
|
725
|
+
function flattenModule(module, index, flatten) {
|
|
726
|
+
if (!isRecord(module) || !Array.isArray(module.declarations))
|
|
727
|
+
return module;
|
|
728
|
+
let modulePath = modulePathOf(module), declarations = module.declarations.map((declaration) => {
|
|
729
|
+
if (!isManifestClassLike(declaration))
|
|
730
|
+
return declaration;
|
|
731
|
+
let entry = index(modulePath, declaration.name);
|
|
732
|
+
return entry?.declaration === declaration ? flatten(entry) : declaration;
|
|
733
|
+
});
|
|
734
|
+
return { ...module, declarations };
|
|
735
|
+
}
|
|
736
|
+
function mergeInherited(declaration, parents) {
|
|
737
|
+
let lists = {};
|
|
738
|
+
for (let key of LIST_KEYS) {
|
|
739
|
+
let own = namedItems(listOf(declaration, key)), items = /* @__PURE__ */ new Map();
|
|
740
|
+
for (let item of own) {
|
|
741
|
+
let existing = items.get(item.name);
|
|
742
|
+
(!existing || existing.inheritedFrom && !item.inheritedFrom) && items.set(item.name, item);
|
|
743
|
+
}
|
|
744
|
+
for (let parent of parents)
|
|
745
|
+
for (let item of namedItems(listOf(parent.declaration, key))) {
|
|
746
|
+
let existing = items.get(item.name);
|
|
747
|
+
existing ? existing.inheritedFrom || items.set(item.name, mergeOverride(existing, item)) : items.set(item.name, { ...item, inheritedFrom: item.inheritedFrom ?? parent.from });
|
|
748
|
+
}
|
|
749
|
+
items.size > 0 && (lists[key] = [...items.values()]);
|
|
750
|
+
}
|
|
751
|
+
return { ...declaration, ...lists };
|
|
752
|
+
}
|
|
753
|
+
function mergeOverride(own, inherited) {
|
|
754
|
+
let merged = { ...own };
|
|
755
|
+
for (let field of INHERITED_FIELDS)
|
|
756
|
+
!(field in merged) && field in inherited && (merged[field] = inherited[field]);
|
|
757
|
+
return merged;
|
|
758
|
+
}
|
|
759
|
+
function listOf(declaration, key) {
|
|
760
|
+
let list = declaration[key];
|
|
761
|
+
return Array.isArray(list) ? list : void 0;
|
|
762
|
+
}
|
|
763
|
+
function resolveReference(reference, index, modulePath) {
|
|
764
|
+
if (reference.module !== void 0)
|
|
765
|
+
return index(reference.module, reference.name);
|
|
766
|
+
if (reference.package === void 0)
|
|
767
|
+
return index(modulePath, reference.name);
|
|
768
|
+
}
|
|
769
|
+
function keyFor(modulePath, name) {
|
|
770
|
+
return `${modulePath.replace(/^\.?\//, "")}#${name}`;
|
|
771
|
+
}
|
|
772
|
+
function modulePathOf(module) {
|
|
773
|
+
return typeof module.path == "string" ? module.path : "";
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// src/docgen/component-docgen/manifest/load-manifest.ts
|
|
777
|
+
import { readFile } from "node:fs/promises";
|
|
778
|
+
import { relative } from "node:path";
|
|
779
|
+
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.`;
|
|
780
|
+
function classifyManifest(path, parsed) {
|
|
781
|
+
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) } };
|
|
782
|
+
}
|
|
783
|
+
async function loadManifest(absolutePath) {
|
|
784
|
+
let path = relative(process.cwd(), absolutePath);
|
|
785
|
+
try {
|
|
786
|
+
return classifyManifest(path, JSON.parse(await readFile(absolutePath, "utf8")));
|
|
787
|
+
} catch (error) {
|
|
788
|
+
return {
|
|
789
|
+
path,
|
|
790
|
+
error: {
|
|
791
|
+
name: "manifest-invalid",
|
|
792
|
+
message: invalidMessage(path, errorMessage(error))
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
// src/docgen/component-docgen/manifest/cem-manager.ts
|
|
799
|
+
var CemManager = class {
|
|
800
|
+
constructor(absolutePaths) {
|
|
801
|
+
this.states = absolutePaths.map((absolutePath) => ({
|
|
802
|
+
absolutePath,
|
|
803
|
+
path: relative2(process.cwd(), absolutePath)
|
|
804
|
+
}));
|
|
805
|
+
}
|
|
806
|
+
refresh() {
|
|
807
|
+
return this.current ? (this.next ??= this.current.then(
|
|
808
|
+
() => (this.next = void 0, this.refresh()),
|
|
809
|
+
() => (this.next = void 0, this.refresh())
|
|
810
|
+
), this.next) : (this.current = this.refreshStates().finally(() => {
|
|
811
|
+
this.current = void 0;
|
|
812
|
+
}), this.current);
|
|
813
|
+
}
|
|
814
|
+
async refreshStates() {
|
|
815
|
+
return this.states = await Promise.all(this.states.map((state) => this.refreshState(state))), buildSnapshot(this.states);
|
|
816
|
+
}
|
|
817
|
+
async refreshState(state) {
|
|
818
|
+
try {
|
|
819
|
+
let stats = await stat(state.absolutePath);
|
|
820
|
+
return state.mtimeMs === stats.mtimeMs ? state : await this.loadChangedManifest(state, stats.mtimeMs);
|
|
821
|
+
} catch (error) {
|
|
822
|
+
if (isNotFound(error)) {
|
|
823
|
+
let notFound = missingManifestError(state.path), nextState = {
|
|
824
|
+
...state,
|
|
825
|
+
mtimeMs: void 0,
|
|
826
|
+
entry: void 0,
|
|
827
|
+
error: notFound
|
|
828
|
+
};
|
|
829
|
+
return this.warnOnce(nextState, notFound.message), nextState;
|
|
830
|
+
}
|
|
831
|
+
return this.failedState(state, failureFromError(state.path, error), void 0);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
async loadChangedManifest(state, mtimeMs) {
|
|
835
|
+
let loaded = await loadManifest(state.absolutePath);
|
|
836
|
+
if (isFailedManifest(loaded))
|
|
837
|
+
return this.failedState(state, loaded.error, mtimeMs);
|
|
838
|
+
let entry = {
|
|
839
|
+
path: loaded.path,
|
|
840
|
+
tags: buildTagIndex(flattenInheritance(loaded.manifest))
|
|
841
|
+
}, nextState = {
|
|
842
|
+
...state,
|
|
843
|
+
mtimeMs,
|
|
844
|
+
entry,
|
|
845
|
+
error: void 0,
|
|
846
|
+
lastWarning: void 0
|
|
847
|
+
};
|
|
848
|
+
return logger.debug(`Loaded Custom Elements Manifest ${loaded.path}`), nextState;
|
|
849
|
+
}
|
|
850
|
+
failedState(state, error, mtimeMs) {
|
|
851
|
+
let nextState = {
|
|
852
|
+
...state,
|
|
853
|
+
mtimeMs,
|
|
854
|
+
error
|
|
855
|
+
};
|
|
856
|
+
return this.warnOnce(nextState, state.entry ? staleWarning(error) : error.message), nextState;
|
|
857
|
+
}
|
|
858
|
+
warnOnce(state, message) {
|
|
859
|
+
state.lastWarning !== message && (state.lastWarning = message, logger.warn(message));
|
|
860
|
+
}
|
|
861
|
+
};
|
|
862
|
+
function buildSnapshot(states) {
|
|
863
|
+
let tags = /* @__PURE__ */ new Map(), errors = [], paths = states.map(({ path }) => path);
|
|
864
|
+
for (let state of states) {
|
|
865
|
+
if (state.entry) {
|
|
866
|
+
let warning = state.error ? staleWarning(state.error) : void 0;
|
|
867
|
+
for (let [tag, declaration] of state.entry.tags)
|
|
868
|
+
tags.has(tag) || tags.set(tag, {
|
|
869
|
+
declaration,
|
|
870
|
+
manifestPath: state.entry.path,
|
|
871
|
+
...warning ? { warning } : {}
|
|
872
|
+
});
|
|
873
|
+
continue;
|
|
874
|
+
}
|
|
875
|
+
state.error && errors.push(state.error);
|
|
876
|
+
}
|
|
877
|
+
return {
|
|
878
|
+
tags,
|
|
879
|
+
errors,
|
|
880
|
+
paths
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
function failureFromError(path, error) {
|
|
884
|
+
return {
|
|
885
|
+
name: "manifest-invalid",
|
|
886
|
+
message: `Invalid Custom Elements Manifest at ${path}: ${errorMessage(error)}`
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
function isNotFound(error) {
|
|
890
|
+
return error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
891
|
+
}
|
|
892
|
+
function missingManifestError(path) {
|
|
893
|
+
return {
|
|
894
|
+
name: "manifest-not-found",
|
|
895
|
+
message: `Custom Elements Manifest ${path} not found yet; docs load once the analyzer writes it`
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
function staleWarning(error) {
|
|
899
|
+
return `${error.message}; using the last valid version`;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
// src/docgen/docgen-worker.ts
|
|
903
|
+
var createDocgenProvider = ({
|
|
904
|
+
manifestPaths,
|
|
905
|
+
typeProperty
|
|
906
|
+
}) => createLazyDocgenMiddleware({
|
|
907
|
+
createManager: async () => {
|
|
908
|
+
if (manifestPaths.length === 0) {
|
|
909
|
+
logger2.warn(
|
|
910
|
+
"No Custom Elements Manifest was configured; web-components server docgen is skipped. Set the `customElementsManifest` framework option or `customElements` in package.json."
|
|
911
|
+
);
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
return new CemManager(manifestPaths);
|
|
915
|
+
},
|
|
916
|
+
extract: async (manager, input) => buildDocgenPayload(input, {
|
|
917
|
+
cem: await manager.refresh(),
|
|
918
|
+
typeProperty
|
|
919
|
+
})
|
|
920
|
+
});
|
|
921
|
+
|
|
922
|
+
export {
|
|
923
|
+
buildDocgenPayload,
|
|
924
|
+
createDocgenProvider
|
|
925
|
+
};
|