@wc-toolkit/vuejs-types 1.0.0

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/index.js ADDED
@@ -0,0 +1,637 @@
1
+ // src/type-generator.ts
2
+ import fs from "fs";
3
+ import path from "path";
4
+
5
+ // node_modules/.pnpm/@wc-toolkit+cem-utilities@1.4.1/node_modules/@wc-toolkit/cem-utilities/dist/index.js
6
+ var definitionExports = /* @__PURE__ */ new Map();
7
+ var components = [];
8
+ var manifest;
9
+ function getAllComponents(customElementsManifest, exclude = []) {
10
+ if (!customElementsManifest) {
11
+ return [];
12
+ }
13
+ if (!customElementsManifest || areObjectsEqual(customElementsManifest, manifest)) {
14
+ return components;
15
+ }
16
+ resetCache();
17
+ manifest = customElementsManifest;
18
+ setAllDefinitionExports(customElementsManifest);
19
+ manifest.modules.forEach((module) => {
20
+ const ces = module.declarations?.filter(
21
+ (d) => d.customElement
22
+ );
23
+ if (ces?.length) {
24
+ ces.forEach((ce) => {
25
+ if (exclude?.includes(ce.name)) {
26
+ return;
27
+ }
28
+ ce.modulePath = module.path;
29
+ ce.definitionPath = definitionExports.get(ce.name);
30
+ if ("typeDefinitionPath" in module && module.typeDefinitionPath) {
31
+ ce.typeDefinitionPath = module.typeDefinitionPath;
32
+ }
33
+ components.push(ce);
34
+ });
35
+ }
36
+ });
37
+ return components;
38
+ }
39
+ function resetCache() {
40
+ components = [];
41
+ manifest = void 0;
42
+ definitionExports.clear();
43
+ }
44
+ function getComponentPublicProperties(component) {
45
+ if (!component || !component.members) {
46
+ return [];
47
+ }
48
+ return component?.members?.filter(
49
+ (member) => member.kind === "field" && member.privacy !== "private" && member.privacy !== "protected" && !member.static && !member.name.startsWith("#")
50
+ ) || [];
51
+ }
52
+ function setAllDefinitionExports(customElementsManifest) {
53
+ if (!customElementsManifest) {
54
+ return;
55
+ }
56
+ customElementsManifest.modules.forEach((mod) => {
57
+ const defExports = mod?.exports?.filter(
58
+ (e) => e.kind === "custom-element-definition"
59
+ );
60
+ if (defExports?.length) {
61
+ defExports.forEach((e) => {
62
+ if (e.declaration.name) {
63
+ definitionExports.set(e.declaration.name, mod.path);
64
+ }
65
+ });
66
+ }
67
+ });
68
+ }
69
+ function areObjectsEqual(obj1, obj2) {
70
+ if (obj1 === obj2) return true;
71
+ if (obj1 === null || obj2 === null || typeof obj1 !== "object" || typeof obj2 !== "object")
72
+ return false;
73
+ if (Array.isArray(obj1) && Array.isArray(obj2)) {
74
+ if (obj1.length !== obj2.length) return false;
75
+ return obj1.every((item, index) => areObjectsEqual(item, obj2[index]));
76
+ }
77
+ const keys1 = Object.keys(obj1);
78
+ const keys2 = Object.keys(obj2);
79
+ if (keys1.length !== keys2.length) return false;
80
+ if (!keys2.every((key) => key in obj1)) return false;
81
+ return keys1.every((key) => {
82
+ const val1 = obj1[key];
83
+ const val2 = obj2[key];
84
+ if (val1 === null && val2 === null) return true;
85
+ if (val1 === null || val2 === null) return false;
86
+ if (typeof val1 === "object" && typeof val2 === "object") {
87
+ return areObjectsEqual(val1, val2);
88
+ }
89
+ return val1 === val2;
90
+ });
91
+ }
92
+ function getMemberDescription(description, deprecated) {
93
+ if (!deprecated) {
94
+ return description || "";
95
+ }
96
+ const desc = description ? `- ${description}` : "";
97
+ return typeof deprecated === "string" ? `@deprecated ${deprecated} ${desc}` : `@deprecated ${desc}`;
98
+ }
99
+ function toPascalCase(value) {
100
+ return value.replace(new RegExp(/[-_]+/, "g"), " ").replace(new RegExp(/[^\w\s]/, "g"), "").replace(
101
+ new RegExp(/\s+(.)(\w*)/, "g"),
102
+ ($1, $2, $3) => `${$2.toUpperCase() + $3}`
103
+ ).replace(new RegExp(/\w/), (s) => s.toUpperCase());
104
+ }
105
+
106
+ // src/logger.ts
107
+ var Logger = class {
108
+ #debug;
109
+ constructor(debug = false) {
110
+ this.#debug = debug;
111
+ }
112
+ log(message, color = "\x1B[30m%s\x1B[0m") {
113
+ if (!this.#debug) {
114
+ return;
115
+ }
116
+ console.log(color, message);
117
+ }
118
+ red(message) {
119
+ this.log(message, "\x1B[31m%s\x1B[0m");
120
+ }
121
+ green(message) {
122
+ this.log(message, "\x1B[32m%s\x1B[0m");
123
+ }
124
+ yellow(message) {
125
+ this.log(message, "\x1B[33m%s\x1B[0m");
126
+ }
127
+ blue(message) {
128
+ this.log(message, "\x1B[34m%s\x1B[0m");
129
+ }
130
+ magenta(message) {
131
+ this.log(message, "\x1B[35m%s\x1B[0m");
132
+ }
133
+ cyan(message) {
134
+ this.log(message, "\x1B[36m%s\x1B[0m");
135
+ }
136
+ };
137
+
138
+ // src/type-generator.ts
139
+ import prettier from "@prettier/sync";
140
+ var DEFAULT_OPTIONS = {
141
+ fileName: "custom-element-vuejs.d.ts",
142
+ outdir: "./",
143
+ exclude: [],
144
+ prefix: "",
145
+ suffix: ""
146
+ };
147
+ var KNOWN_FILE_EXTENSIONS = [
148
+ ".d.ts",
149
+ ".ts",
150
+ ".tsx",
151
+ ".js",
152
+ ".jsx",
153
+ ".mjs",
154
+ ".cjs",
155
+ ".mts",
156
+ ".cts"
157
+ ];
158
+ function toPosixPath(p) {
159
+ return p.split(path.sep).join("/");
160
+ }
161
+ function ensureRelativeSpecifier(p) {
162
+ return p.startsWith(".") ? p : `./${p}`;
163
+ }
164
+ function normalizeImportPath(importPath, options) {
165
+ const outDirAbs = path.resolve(options.outdir ?? "./");
166
+ const isAbsPath = importPath.startsWith("/") || /^[A-Za-z]:[\\/]/.test(importPath);
167
+ const hasPathSeparators = importPath.includes("/") || importPath.includes("\\");
168
+ const hasKnownExt = KNOWN_FILE_EXTENSIONS.some(
169
+ (ext) => importPath.endsWith(ext)
170
+ );
171
+ const shouldTryFs = isAbsPath || importPath.startsWith(".") || hasPathSeparators || hasKnownExt;
172
+ if (!shouldTryFs) {
173
+ return importPath;
174
+ }
175
+ const abs = path.resolve(importPath);
176
+ if (!fs.existsSync(abs)) {
177
+ return importPath;
178
+ }
179
+ try {
180
+ if (!fs.statSync(abs).isFile()) {
181
+ return importPath;
182
+ }
183
+ } catch {
184
+ return importPath;
185
+ }
186
+ const rel = toPosixPath(path.relative(outDirAbs, abs));
187
+ return ensureRelativeSpecifier(rel);
188
+ }
189
+ function generateVuejsTypes(manifest2, options = {}) {
190
+ const mergedOptions = { ...DEFAULT_OPTIONS, ...options };
191
+ const log = new Logger(mergedOptions.debug);
192
+ if (mergedOptions.skip) {
193
+ log.yellow("[vuejs-types] - Skipped");
194
+ return;
195
+ }
196
+ if (!manifest2 || !manifest2.modules || manifest2.modules.length === 0) {
197
+ log.red("[vuejs-types] - No modules found in the manifest.");
198
+ return;
199
+ }
200
+ if (!mergedOptions.outdir) {
201
+ log.red("[vuejs-types] - No output directory specified.");
202
+ return;
203
+ }
204
+ log.log("[vuejs-types] - Generating types...");
205
+ const template = getTypeTemplate(manifest2, mergedOptions);
206
+ if (mergedOptions.fileName) {
207
+ createOutDir(mergedOptions.outdir);
208
+ const outputPath = saveFile(
209
+ mergedOptions.outdir,
210
+ mergedOptions.fileName,
211
+ template
212
+ );
213
+ log.green(`[vuejs-types] - Generated "${outputPath}".`);
214
+ } else {
215
+ log.yellow(
216
+ `[vuejs-types] - File generation skipped because \`fileName\` was not defined.`
217
+ );
218
+ }
219
+ return template;
220
+ }
221
+ function getImports(manifest2, options) {
222
+ const imports = /* @__PURE__ */ new Map();
223
+ const componentModules = /* @__PURE__ */ new Map();
224
+ manifest2.modules.forEach((module) => {
225
+ if (!module.declarations || !module.declarations.length || !module.declarations.some((d) => d.customElement)) {
226
+ return;
227
+ }
228
+ module.declarations?.forEach((element) => {
229
+ const component = element;
230
+ if (!component.customElement || !component.name) {
231
+ return;
232
+ }
233
+ componentModules.set(component.name, {
234
+ modulePath: module.path,
235
+ tagName: component.tagName
236
+ });
237
+ });
238
+ if (options.globalTypePath) {
239
+ module.exports?.forEach((exportDeclaration) => {
240
+ const exportName = exportDeclaration.declaration.name;
241
+ if (!exportName || exportName === "*") {
242
+ return;
243
+ }
244
+ addImport(imports, options.globalTypePath, exportName);
245
+ });
246
+ } else {
247
+ module.declarations?.forEach((element) => {
248
+ const component = element;
249
+ if (!component.customElement || !component.name) {
250
+ return;
251
+ }
252
+ const importPath = normalizeImportPath(
253
+ getComponentImportPath(
254
+ component.name,
255
+ component.tagName,
256
+ module.path,
257
+ options
258
+ ),
259
+ options
260
+ );
261
+ module.exports?.forEach((exportDeclaration) => {
262
+ const exportName = exportDeclaration.declaration.name;
263
+ if (!exportName || exportName === "*") {
264
+ return;
265
+ }
266
+ if (!(options.defaultExport && exportName === component.name)) {
267
+ addImport(imports, importPath, exportName);
268
+ }
269
+ });
270
+ if (options.defaultExport) {
271
+ addImport(imports, importPath, `default as ${component.name}`);
272
+ }
273
+ });
274
+ }
275
+ });
276
+ if (options.useCemTypes) {
277
+ getAllComponents(manifest2, options.exclude).forEach((component) => {
278
+ if (!component.name) {
279
+ return;
280
+ }
281
+ const componentModule = componentModules.get(component.name);
282
+ if (!componentModule) {
283
+ return;
284
+ }
285
+ getComponentProps(component).forEach((prop) => {
286
+ const propType = getResolvedPropType(prop, options);
287
+ propType?.references?.forEach((reference) => {
288
+ if (!reference.name || reference.name === "default") {
289
+ return;
290
+ }
291
+ const importPath = getTypeImportPath(
292
+ reference,
293
+ componentModule.modulePath,
294
+ component,
295
+ options
296
+ );
297
+ if (!importPath) {
298
+ return;
299
+ }
300
+ addImport(imports, importPath, reference.name);
301
+ });
302
+ });
303
+ });
304
+ }
305
+ return Array.from(imports.entries()).map(
306
+ ([importPath, exportNames]) => `import type { ${Array.from(exportNames).join(", ")} } from "${importPath}";`
307
+ ).join("\n");
308
+ }
309
+ function getTypeTemplate(manifest2, options) {
310
+ const components2 = getAllComponents(manifest2, options.exclude);
311
+ const imports = getImports(manifest2, options);
312
+ return `
313
+ ${imports}
314
+ import type { HTMLAttributes, PublicProps, EmitFn, EmitsToProps } from "vue";
315
+
316
+ /**
317
+ * This file was autogenerated by @wc-toolkit/vuejs-types
318
+ ${options.stronglyTypedEvents ? `/**
319
+ * A generic type for strongly typing custom events with their targets
320
+ * @template T - The type of the event target (extends EventTarget)
321
+ * @template D - The type of the detail payload for the custom event
322
+ */
323
+ type TypedEvent<
324
+ T extends EventTarget,
325
+ E = Event
326
+ > = E & {
327
+ target: T;
328
+ };` : ""}
329
+
330
+ export type EventMap = {
331
+ [event: string]: Event;
332
+ };
333
+
334
+ // Vue's template type-checking reads props from $props and events from $emit.
335
+ // See: https://vuejs.org/guide/extras/web-components.html#non-vue-web-components-and-typescript
336
+ export type VueEmitsOptions<T extends EventMap> = {
337
+ [K in keyof T]: (event: T[K]) => void;
338
+ };
339
+
340
+ export type VueEmit<T extends EventMap> = EmitFn<VueEmitsOptions<T>>;
341
+
342
+ // Helps Volar autocomplete "@event" by providing "onXxx" props.
343
+ export type VueOnProps<T extends EventMap> = EmitsToProps<VueEmitsOptions<T>>;
344
+
345
+ export type DefineCustomElement<
346
+ ElementType extends HTMLElement,
347
+ Props = {},
348
+ Events extends EventMap = {},
349
+ > = new () => ElementType & {
350
+ /** @deprecated Do not use the $props property on a Custom Element ref; this is for template prop types only. */
351
+ $props: HTMLAttributes & Props & PublicProps & VueOnProps<Events>${options.allowUnknownProps ? " & Record<string, any>" : ""};
352
+
353
+ /** @deprecated Do not use the $emit property on a Custom Element ref; this is for template event types only. */
354
+ $emit: VueEmit<Events>;
355
+ };
356
+
357
+ ${components2?.map((component) => {
358
+ if (!component.name || !component.tagName) {
359
+ return "";
360
+ }
361
+ const cachedProps = getComponentProps(component)?.filter(
362
+ (prop) => !prop.readonly && !prop.static
363
+ ) || [];
364
+ const strongEventTypes = getStrongEventTypes(component);
365
+ const vueEventsTemplate = component.events?.filter((e) => e.name)?.map((event) => {
366
+ const eventType = event.type?.text?.startsWith("{") ? `CustomEvent<${event.type.text}>` : event.type?.text || "Event";
367
+ const resolvedEventType = getEventTypeName(
368
+ eventType,
369
+ strongEventTypes?.find((x) => x.name === event.name)?.newType || null,
370
+ component.name,
371
+ options.stronglyTypedEvents
372
+ );
373
+ return ` /** ${getMemberDescription(
374
+ event.description,
375
+ event.deprecated
376
+ )} */
377
+ "${event.name}": ${resolvedEventType};`;
378
+ }).join("\n") || "";
379
+ return `
380
+ ${options.stronglyTypedEvents ? getStronglyTypedEvents(component) : ""}
381
+
382
+ export type ${component.name}VueProps = {
383
+ ${(() => {
384
+ if (!cachedProps?.length) {
385
+ return "";
386
+ }
387
+ return cachedProps.reduce((acc, prop) => {
388
+ const description = getMemberDescription(prop.description, prop.deprecated);
389
+ const typeInfo = getResolvedPropType(prop, options);
390
+ const type = getPropType(component.name, prop, typeInfo, options);
391
+ const propExists = prop.propName ? acc.includes(` "${prop.propName}"?:`) : false;
392
+ const attrExists = prop.attrName ? acc.includes(` "${prop.attrName}"?:`) : false;
393
+ let result = acc;
394
+ if (prop.attrName && prop.attrName !== prop.propName && !attrExists) {
395
+ result += ` /** ${description} */
396
+ "${prop.attrName}"?: ${type};
397
+ `;
398
+ }
399
+ if (prop.propName && !propExists) {
400
+ result += ` /** ${description} */
401
+ "${prop.propName}"?: ${type};
402
+ `;
403
+ }
404
+ return result;
405
+ }, "");
406
+ })()}
407
+ };
408
+
409
+ export type ${component.name}VueEvents = {
410
+ ${vueEventsTemplate}
411
+ };
412
+ `;
413
+ }).join("\n")}
414
+
415
+ export type CustomCssProperties = {
416
+ ${(() => {
417
+ const uniqueCssProperties = /* @__PURE__ */ new Set();
418
+ const cssPropertiesArray = [];
419
+ components2.forEach((component) => {
420
+ component.cssProperties?.forEach((property) => {
421
+ if (!uniqueCssProperties.has(property.name)) {
422
+ uniqueCssProperties.add(property.name);
423
+ cssPropertiesArray.push(
424
+ ` /** ${getMemberDescription(property.description, property.deprecated)} */
425
+ "${property.name}"?: string;`
426
+ );
427
+ }
428
+ });
429
+ });
430
+ return cssPropertiesArray.join("\n");
431
+ })()}
432
+ }
433
+
434
+ // Vue SFC template type-checking (GlobalComponents) for non-Vue custom elements.
435
+ // Note: Some tooling expects this augmentation under "@vue/runtime-core", while
436
+ // other docs/examples use "vue". We emit both for compatibility.
437
+ export interface WcToolkitVueGlobalComponents {
438
+ ${components2.map((component) => {
439
+ if (!component.name || !component.tagName) {
440
+ return "";
441
+ }
442
+ let tagName = component.tagName;
443
+ if (options.tagFormatter) {
444
+ tagName = options.tagFormatter(component.tagName);
445
+ } else if (options.prefix || options.suffix) {
446
+ tagName = `${options.prefix}${component.tagName}${options.suffix}`;
447
+ }
448
+ const componentDoc = component.description ? getMemberDescription(
449
+ component.description,
450
+ component.deprecated
451
+ ).replace(/\n/g, " ").replace(/`/g, "'") : void 0;
452
+ return componentDoc ? ` /** ${componentDoc} */
453
+ "${tagName}": DefineCustomElement<${component.name}, ${component.name}VueProps, ${component.name}VueEvents>;` : ` "${tagName}": DefineCustomElement<${component.name}, ${component.name}VueProps, ${component.name}VueEvents>;`;
454
+ }).join("\n")}
455
+ }
456
+
457
+ declare module "@vue/runtime-core" {
458
+ interface GlobalComponents extends WcToolkitVueGlobalComponents {}
459
+ }
460
+
461
+ declare module "@vue/runtime-dom" {
462
+ interface GlobalComponents extends WcToolkitVueGlobalComponents {}
463
+
464
+ // Needed for named slots on native elements when using Web Components.
465
+ // Vue templates otherwise reject: <span slot="icon" />
466
+ interface HTMLAttributes {
467
+ slot?: string;
468
+ }
469
+ }
470
+
471
+ declare module "vue" {
472
+ interface GlobalComponents extends WcToolkitVueGlobalComponents {}
473
+
474
+ // Some package managers (notably pnpm) may not make "@vue/runtime-dom" directly
475
+ // resolvable from the consuming project, so we also augment via "vue".
476
+ interface HTMLAttributes {
477
+ slot?: string;
478
+ }
479
+
480
+ ${options.excludeCssCustomProperties ? "" : "interface CSSProperties extends CustomCssProperties {}"}
481
+ }
482
+ `;
483
+ }
484
+ function addImport(imports, importPath, exportName) {
485
+ const existing = imports.get(importPath);
486
+ if (existing) {
487
+ existing.add(exportName);
488
+ return;
489
+ }
490
+ imports.set(importPath, /* @__PURE__ */ new Set([exportName]));
491
+ }
492
+ function getComponentImportPath(componentName, tagName, modulePath, options) {
493
+ return typeof options.componentTypePath === "function" ? options.componentTypePath(componentName, tagName, modulePath) : modulePath;
494
+ }
495
+ function getTypeImportPath(reference, componentModulePath, component, options) {
496
+ if (reference.package) {
497
+ return reference.package;
498
+ }
499
+ if (!reference.module) {
500
+ return null;
501
+ }
502
+ if (reference.module === componentModulePath) {
503
+ if (options.globalTypePath) {
504
+ return normalizeImportPath(options.globalTypePath, options);
505
+ }
506
+ if (component.name) {
507
+ return normalizeImportPath(
508
+ getComponentImportPath(
509
+ component.name,
510
+ component.tagName,
511
+ componentModulePath,
512
+ options
513
+ ),
514
+ options
515
+ );
516
+ }
517
+ }
518
+ return normalizeImportPath(reference.module, options);
519
+ }
520
+ function getComponentProps(component) {
521
+ const properties = getComponentPublicProperties(
522
+ component
523
+ );
524
+ const propertyMap = new Map(
525
+ properties.map((property) => [property.name, property])
526
+ );
527
+ const attributeProps = component.attributes?.map(
528
+ (attribute) => ({
529
+ attrName: attribute.name,
530
+ propName: attribute.fieldName,
531
+ description: attribute.description,
532
+ deprecated: attribute.deprecated,
533
+ readonly: false,
534
+ static: false,
535
+ type: attribute.type,
536
+ attribute,
537
+ property: attribute.fieldName ? propertyMap.get(attribute.fieldName) : void 0
538
+ })
539
+ ) || [];
540
+ const attributePropNames = new Set(
541
+ attributeProps.map((attribute) => attribute.propName).filter((propName) => Boolean(propName))
542
+ );
543
+ const propertyOnlyProps = properties.filter((property) => !attributePropNames.has(property.name)).map((property) => ({
544
+ attrName: void 0,
545
+ propName: property.name,
546
+ description: property.description,
547
+ deprecated: property.deprecated,
548
+ readonly: property.readonly,
549
+ static: property.static,
550
+ type: property.type,
551
+ attribute: void 0,
552
+ property
553
+ }));
554
+ return [...attributeProps, ...propertyOnlyProps];
555
+ }
556
+ function getTypeFromSource(source, sourceKey) {
557
+ const candidate = source ? source[sourceKey] : void 0;
558
+ if (candidate && typeof candidate === "object" && "text" in candidate && typeof candidate.text === "string") {
559
+ return candidate;
560
+ }
561
+ return void 0;
562
+ }
563
+ function getResolvedPropType(prop, options) {
564
+ const sourceKey = options.typesSrc || "type";
565
+ return getTypeFromSource(prop.property, sourceKey) ?? getTypeFromSource(prop.attribute, sourceKey) ?? (sourceKey === "type" ? void 0 : getTypeFromSource(prop.property, "type")) ?? (sourceKey === "type" ? void 0 : getTypeFromSource(prop.attribute, "type")) ?? prop.type;
566
+ }
567
+ function getPropType(componentName, prop, propType, options) {
568
+ if (options.useCemTypes) {
569
+ return propType?.text || "unknown";
570
+ }
571
+ return prop.propName ? `${componentName}['${prop.propName}']` : "unknown";
572
+ }
573
+ function getEventTypeName(eventType, strongEventType, componentName = "", stronglyTyped) {
574
+ return stronglyTyped ? strongEventType ?? `${componentName}ElementEvent` : eventType;
575
+ }
576
+ function getStrongEventTypes(component) {
577
+ const eventTypes = component?.events?.filter((e) => e.name)?.map((event) => ({
578
+ name: event.name,
579
+ type: event?.type?.text
580
+ }));
581
+ if (!eventTypes) {
582
+ return [];
583
+ }
584
+ return eventTypes.filter(
585
+ (eventType) => eventType.type && eventType.type !== "Event" && eventType.type !== "CustomEvent"
586
+ ).map((eventType) => {
587
+ return {
588
+ name: eventType.name,
589
+ type: eventType.type.startsWith("{") ? `CustomEvent<${eventType.type}>` : eventType.type,
590
+ newType: `${component.name}${toPascalCase(eventType.name)}ElementEvent`
591
+ };
592
+ });
593
+ }
594
+ function getStronglyTypedEvents(component) {
595
+ if (!component.events?.length) {
596
+ return "";
597
+ }
598
+ const eventTypes = getStrongEventTypes(component);
599
+ const types = [
600
+ `/** \`${component.name}\` component event */
601
+ export type ${component.name}ElementEvent<E = Event> = TypedEvent<${component.name}, E>;`
602
+ ];
603
+ eventTypes.forEach((eventType) => {
604
+ types.push(
605
+ `/** \`${eventType.name}\` event type */
606
+ export type ${eventType.newType} = ${component.name}ElementEvent<${eventType.type}>;`
607
+ );
608
+ });
609
+ return types.join("\n");
610
+ }
611
+ function createOutDir(outDir) {
612
+ if (outDir !== "./" && !fs.existsSync(outDir)) {
613
+ fs.mkdirSync(outDir, { recursive: true });
614
+ }
615
+ }
616
+ function saveFile(outDir, fileName, contents) {
617
+ const outputPath = path.join(outDir, fileName);
618
+ fs.writeFileSync(
619
+ outputPath,
620
+ prettier.format(contents, { parser: "typescript", printWidth: 80 })
621
+ );
622
+ return outputPath;
623
+ }
624
+
625
+ // src/cem-plugin.ts
626
+ function vuejsTypesPlugin(options = {}) {
627
+ return {
628
+ name: "@wc-toolkit/vuejs-types",
629
+ packageLinkPhase({ customElementsManifest }) {
630
+ generateVuejsTypes(customElementsManifest, options);
631
+ }
632
+ };
633
+ }
634
+ export {
635
+ generateVuejsTypes,
636
+ vuejsTypesPlugin
637
+ };