UNPKG

@stencil/react-output-target

Version:

React output target for @stencil/core components.

392 lines (384 loc) • 13.1 kB
import D, { isAbsolute as Q, relative as X } from "node:path"; import { Project as x, VariableDeclarationKind as A } from "ts-morph"; const H = (t) => t.toLowerCase().split("-").map((n) => n.charAt(0).toUpperCase() + n.slice(1)).join(""), Z = (t) => t.replace(/-([_a-z])/g, (n, c) => c.toUpperCase()), ee = (t) => t.replace(/\/([a-z])/g, (n, c) => c.toUpperCase()), te = (t) => { const n = ee(t); return Z(`on-${n}`); }, ne = (t) => t.replace(/\/\/.*$/gm, "").replace(/\n/g, " ").replace(/\s{2,}/g, " ").trim(), L = async ({ components: t, project: n, outDir: c, filename: b = "components.ts", componentSuffix: l = "", serializeShadowRoot: g }) => { const $ = n || new x({ useInMemoryFileSystem: !0 }), T = `/* eslint-disable */ `, y = `/** * This file was automatically generated by the Stencil React Output Target. * Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. */ `, v = D.join(c || "", b), p = $.createSourceFile(v, y + T, { overwrite: !0 }); l && (p.addImportDeclaration({ moduleSpecifier: "@stencil/react-output-target/ssr", namedImports: [{ name: "SerializeShadowRootOptions", isTypeOnly: !0 }] }), p.addVariableStatement({ isExported: !0, declarationKind: A.Const, declarations: [ { name: "serializeShadowRoot", type: "SerializeShadowRootOptions", initializer: g ? JSON.stringify(g) : '{ default: "declarative-shadow-dom" }' } ] })); for (const f of t) { const h = f.tagName, E = H(h), r = f.tagName; p.addExportDeclaration({ moduleSpecifier: `./${r}${l}.js`, namedExports: [E] }); } return p.organizeImports(), p.formatText(), await p.save(), p; }, M = ({ components: t, stencilPackageName: n, customElementsDir: c, componentsTypesDir: b, hydrateModule: l, clientModule: g, serializeShadowRoot: $, transformTag: T, exportMaps: y, typesFromComponentsFile: v }) => { const p = new x({ useInMemoryFileSystem: !0 }), f = y ? `${n}/components` : `${n}/${b}`, h = y || v ? f : n, E = `'use client'; `, r = `/** * This file was automatically generated by the Stencil React Output Target. * Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. */ `, C = `/* eslint-disable */ `, i = l ? [ T ? `import { getTagTransformer } from './tag-transformer.js'; ` : "", "import { createComponent, type SerializeShadowRootOptions, type HydrateModule, type ReactWebComponent } from '@stencil/react-output-target/ssr';" ].filter(Boolean).join(` `) : "import { createComponent } from '@stencil/react-output-target/runtime';", d = T ? `import { transformTag } from './tag-transformer.js'; ` : "", e = p.createSourceFile( "component.ts", `${E}${r}${C} import React from 'react'; ${i} import type { EventName, StencilReactComponent } from '@stencil/react-output-target/runtime'; ${d} import type { Components } from "${f}"; ` ); l && g && e.addImportDeclaration({ moduleSpecifier: g, namespaceImport: "clientComponents" }), l && e.addVariableStatement({ isExported: !0, declarationKind: A.Const, declarations: [ { name: "serializeShadowRoot", type: "SerializeShadowRootOptions", initializer: $ ? JSON.stringify($) : '{ default: "declarative-shadow-dom" }' } ] }); for (const s of t) { const m = s.tagName, u = H(m), S = `${u}Element`, I = `${u}CustomEvent`; e.addImportDeclaration({ moduleSpecifier: y ? `${n}/${m}` : `${n}/${c}/${m}.js`, namedImports: [ { name: u, alias: S }, { name: "defineCustomElement", alias: `define${u}` } ] }); const F = (s.events || []).filter((o) => o.internal === !1), N = [], z = /* @__PURE__ */ new Set(); let q = !1; for (const o of F) { if (Object.keys(o.complexType.references).length > 0) for (const R of Object.keys(o.complexType.references)) !(o.complexType.references[R].location === "global") && !z.has(R) && (z.add(R), e.addImportDeclaration({ moduleSpecifier: h, namedImports: [ { name: R, isTypeOnly: !0 } ] })); q || (q = !0, e.addImportDeclaration({ moduleSpecifier: h, namedImports: [ { name: I, isTypeOnly: !0 } ] })), N.push({ originalName: o.name, name: te(o.name), type: `EventName<${I}<${ne(o.complexType.original)}>>` }); } const _ = `${u}Events`, V = s.properties.filter((o) => o.required && !o.internal).map((o) => `'${o.name}'`), O = V.length > 0 ? `, ${V.join(" | ")}` : ""; e.addTypeAlias({ isExported: !0, name: _, type: N.length > 0 ? `{ ${N.map((o) => `${o.name}: ${o.type}`).join(`, `)} }` : "NonNullable<unknown>" }); const Y = T ? `, transformTag` : "", k = `/*@__PURE__*/ createComponent<${S}, ${_}, Components.${u}${O}>({ tagName: '${m}', elementClass: ${S}, // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project. react: React, events: {${N.map((o) => `${o.name}: '${o.originalName}'`).join(`, `)}} as ${_}, defineCustomElement: define${u}${Y} })`, B = T ? `, getTagTransformer` : "", W = `/*@__PURE__*/ createComponent<${S}, ${_}, Components.${u}${O}>({ tagName: '${m}', properties: {${s.properties.filter((o) => !!o.attribute).map((o) => `${o.name}: '${o.attribute}'`).join(`, `)}}, hydrateModule: typeof window === 'undefined' ? (import('${l}') as Promise<HydrateModule>) : undefined, clientModule: clientComponents.${u} as StencilReactComponent<${S}, ${_}, Components.${u}${O}>, serializeShadowRoot${B} })`; e.addVariableStatement({ isExported: !0, declarationKind: A.Const, declarations: [ { name: u, type: `StencilReactComponent<${S}, ${_}, Components.${u}${O}>`, initializer: l ? W : k } ] }); } if (e.organizeImports(), l && g) { const s = e.getImportDeclarations().find((m) => { var u; return ((u = m.getNamespaceImport()) == null ? void 0 : u.getText()) === "clientComponents"; }); s && e.insertText( s.getStart(), `// @ts-ignore - ignore potential type issues as the project is importing itself ` ); } return e.formatText(), e.getFullText(); }, oe = ({ stencilPackageName: t, customElementsDir: n, exportMaps: c }) => `/* eslint-disable */ /* tslint:disable */ import { setTagTransformer as clientSetTagTransformer } from '${c ? `${t}/standalone` : `${t}/${n}/index.js`}'; let tagTransformer: ((tagName: string) => string) | undefined; export const setTagTransformer = (transformer: (tagName: string) => string) => { clientSetTagTransformer(transformer); tagTransformer = transformer; }; export const transformTag = (tag: string): string => { return tagTransformer ? tagTransformer(tag) : tag; }; export const getTagTransformer = () => tagTransformer; `, re = async ({ stencilPackageName: t, components: n, outDir: c, esModules: b, customElementsDir: l, componentsTypesDir: g, excludeComponents: $, project: T, hydrateModule: y, clientModule: v, excludeServerSideRenderingFor: p, serializeShadowRoot: f, transformTag: h, exportMaps: E, typesFromComponentsFile: r }) => { const C = [], a = n.filter((e) => !(e.internal === !0 || $ != null && $.includes(e.tagName))); if (a.length === 0) return []; const i = {}; function d(e, s = "components") { const m = D.join(c, `${s}.ts`), u = M({ components: e, stencilPackageName: t, customElementsDir: l, componentsTypesDir: g, exportMaps: E, typesFromComponentsFile: r, transformTag: h }); if (i[m] = u, h) { const S = D.join(c, "tag-transformer.ts"); i[S] = oe({ stencilPackageName: t, customElementsDir: l, exportMaps: E }); } if (y) { const S = D.join(c, `${s}.server.ts`), I = M({ components: e.filter( (F) => !p || !p.includes(F.tagName) ), stencilPackageName: t, customElementsDir: l, componentsTypesDir: g, exportMaps: E, typesFromComponentsFile: r, hydrateModule: y, clientModule: v, serializeShadowRoot: f, transformTag: h }); i[S] = I; } } if (b) { for (const s of a) d([s], s.tagName); const e = await L({ components: a, project: T, outDir: c }); if (C.push(e), y) { const s = await L({ components: a.filter( (m) => !p || !p.includes(m.tagName) ), project: T, outDir: c, filename: "components.server.ts", componentSuffix: ".server", serializeShadowRoot: f }); C.push(s); } } else d(a); return await Promise.all( Object.entries(i).map(async ([e, s]) => { const m = T.createSourceFile(e, s, { overwrite: !0 }); await m.save(), C.push(m); }) ), C; }, w = "react-output-target", G = "dist/components", j = "dist-custom-elements", P = "standalone", J = "dist-hydrate-script", K = "ssr", ae = "types", se = "dist/types", U = (t, n) => (Q(n) ? X(t, n) : n).replace(/\\/g, "/"), me = ({ outDir: t, esModules: n, stencilPackageName: c, excludeComponents: b, customElementsDir: l, hydrateModule: g, clientModule: $, excludeServerSideRenderingFor: T, serializeShadowRoot: y, transformTag: v }) => { let p = G, f = G, h = !1, E = !1; return { type: "custom", name: w, validate(r) { const C = (r.outputTargets || []).some( (a) => ["loader-bundle", "standalone", "ssr", "types"].includes(a.type) ); if (h = C && r.generateExportMaps === !0, E = C, l) p = l, f = l; else { const a = (r.outputTargets || []).find( (i) => i.type === j || i.type === P ); if (a == null) { const d = (r.outputTargets || []).some( (e) => ["loader-bundle", "standalone", "ssr", "types"].includes(e.type) ) ? P : j; throw new Error( `The '${w}' requires '${d}' output target. Add { type: '${d}' }, to the outputTargets config.` ); } if (a.type === P) { const i = (r.outputTargets || []).find((s) => s.type === ae), d = (i == null ? void 0 : i.dir) ?? se; if (f = `${U(r.rootDir, d)}/components`, a.dir !== void 0) { const s = a.dir; p = U(r.rootDir, s); } } else if (a.dir !== void 0) { const i = a.dir; p = U(r.rootDir, i), f = p; } if (a.type === j && a.externalRuntime !== !1) throw new Error( `The '${w}' requires the '${j}' output target to have 'externalRuntime: false' set in its configuration.` ); } if (g) { if ((r.outputTargets || []).find( (i) => i.type === J || i.type === K ) == null) { const d = (r.outputTargets || []).some( (e) => ["loader-bundle", "standalone", "ssr", "types"].includes(e.type) ) ? K : J; throw new Error( `The '${w}' requires '${d}' output target when the 'hydrateModule' option is set. Add { type: '${d}' }, to the outputTargets config.` ); } if ($ == null) throw new Error( `The '${w}' requires the 'clientModule' option when the 'hydrateModule' option is set. Please provide the clientModule manually to the ${w} output target.` ); } if (c === void 0) { if (r.sys && r.packageJsonFilePath) { const { name: a } = JSON.parse(r.sys.readFileSync(r.packageJsonFilePath, "utf8")); c = a; } if (!c) throw new Error( `Unable to find the package name in the package.json file: ${r.packageJsonFilePath}. Please provide the stencilPackageName manually to the ${w} output target.` ); } }, async generator(r, C, a) { const i = a.createTimeSpan(`generate ${w} started`, !0), d = a.components, e = new x(), s = await re({ outDir: t, components: d, stencilPackageName: c, customElementsDir: p, componentsTypesDir: f, excludeComponents: b, esModules: n === !0, project: e, hydrateModule: g, clientModule: $, excludeServerSideRenderingFor: T, serializeShadowRoot: y, transformTag: v, exportMaps: h, typesFromComponentsFile: E }); await Promise.all( s.map((m) => C.fs.writeFile(m.getFilePath(), m.getFullText())) ), i.finish(`generate ${w} finished`); }, __internal_getCustomElementsDir() { return p; } }; }; export { me as reactOutputTarget }; //# sourceMappingURL=index.js.map