@stencil/react-output-target
Version:
React output target for @stencil/core components.
171 lines (169 loc) • 7.15 kB
JavaScript
import { Project as N, SyntaxKind as g } from "ts-morph";
import { access as R, mkdir as $, writeFile as T } from "node:fs/promises";
import { join as o, dirname as v, relative as D } from "node:path";
function A(e, d, w) {
var S;
const r = new N({ skipAddingFilesFromTsConfig: !0 }).addSourceFileAtPath(e);
if (r.getImportDeclaration("@stencil/react-output-target") || r.addImportDeclaration({ moduleSpecifier: "@stencil/react-output-target", namedImports: ["reactOutputTarget"] }), !r.getDescendantsOfKind(g.PropertyAssignment).find((a) => a.getName() === "outputTargets")) {
const a = ((S = r.getVariableDeclaration("config")) == null ? void 0 : S.getInitializerIfKind(g.ObjectLiteralExpression)) ?? r.getDescendantsOfKind(g.ObjectLiteralExpression).find((O) => O.getProperty("namespace") !== void 0);
if (!a) throw new Error("Could not find Stencil config object in stencil.config.ts");
a.addPropertyAssignment({ name: "outputTargets", initializer: "[]" });
}
const u = r.getDescendantsOfKind(g.PropertyAssignment).find((a) => a.getName() === "outputTargets"), m = u.getInitializerIfKind(g.ArrayLiteralExpression);
if (!m) throw new Error("outputTargets is not an array literal in stencil.config.ts");
const n = m.getText(), p = n.includes("reactOutputTarget("), s = m.getElements().map((a) => a.getText().trim()).filter((a) => !a.includes("reactOutputTarget("));
return n.includes("type: 'standalone'") || n.includes('type: "standalone"') || n.includes("type: 'dist-custom-elements'") || n.includes('type: "dist-custom-elements"') || s.push("{ type: 'standalone' }"), w && (n.includes("type: 'ssr'") || n.includes('type: "ssr"') || n.includes("type: 'dist-hydrate-script'") || n.includes('type: "dist-hydrate-script"') || s.push("{ type: 'ssr' }")), s.push(d), u.setInitializer(`[
${s.map((a) => ` ${a}`).join(`,
`)},
]`), r.formatText(), r.saveSync(), !p;
}
async function I(e) {
try {
return await R(e), !0;
} catch {
return !1;
}
}
async function E(e, d, w, f) {
await $(o(e, "src"), { recursive: !0 });
const r = {
name: d,
version: "0.0.1",
type: "module",
main: "./dist/index.js",
types: "./dist/index.d.ts",
exports: { ".": { types: "./dist/index.d.ts", import: "./dist/index.js" } },
scripts: { build: "tsc", dev: "tsc --watch" },
peerDependencies: {
react: "^18 || ^19",
"react-dom": "^18 || ^19"
},
dependencies: { [w]: f },
devDependencies: { typescript: ">=4 <7" }
}, x = {
compilerOptions: {
target: "ES2022",
module: "esnext",
moduleResolution: "bundler",
declaration: !0,
rootDir: "src",
outDir: "dist",
strict: !0,
skipLibCheck: !0
},
include: ["src/**/*.ts", "src/**/*.tsx"]
};
await Promise.all([
T(o(e, ".gitignore"), `dist/
node_modules/
`, "utf8"),
T(o(e, "package.json"), JSON.stringify(r, null, 2) + `
`, "utf8"),
T(o(e, "tsconfig.json"), JSON.stringify(x, null, 2) + `
`, "utf8"),
T(o(e, "src", "index.ts"), `// Re-exports React wrappers generated by @stencil/react-output-target.
// src/components.ts is populated by \`stencil build\` — do not edit manually.
export * from './components.js';
`, "utf8")
]);
}
const z = {
init: {
id: "@stencil/react-output-target",
displayName: "React",
description: "Type-safe React wrappers for your Stencil components",
async run({ config: e, workspaceRoot: d, prompts: w, nypm: f }) {
var b, C;
const { intro: r, outro: x, text: u, confirm: m, spinner: n, isCancel: p, cancel: s, log: l } = w;
r("React output target");
const S = o(e.rootDir, "stencil.config.ts");
if ((C = (b = new N({ skipAddingFilesFromTsConfig: !0 }).addSourceFileAtPath(S).getDescendantsOfKind(g.PropertyAssignment).find((t) => t.getName() === "outputTargets")) == null ? void 0 : b.getInitializerIfKind(g.ArrayLiteralExpression)) == null ? void 0 : C.getText().includes("reactOutputTarget(")) {
const t = await m({
message: "reactOutputTarget is already in stencil.config.ts — reconfigure?",
initialValue: !1
});
if (p(t) || !t) {
s("Skipping React setup.");
return;
}
}
let i, c = `${e.fsNamespace}-react`;
if (d) {
const t = await u({
message: "Wrapper package name?",
placeholder: c,
defaultValue: c
});
if (p(t)) {
s("Setup cancelled.");
return;
}
c = t, i = o(v(e.rootDir), c);
} else {
const t = `../${e.fsNamespace}-react`, y = await u({
message: "Wrapper package directory? (relative to stencil.config.ts)",
placeholder: t,
defaultValue: t
});
if (p(y)) {
s("Setup cancelled.");
return;
}
i = o(e.rootDir, y);
}
const P = D(e.rootDir, o(i, "src")).replace(/\\/g, "/"), h = await m({ message: "Enable server-side rendering (SSR)?", initialValue: !1 });
if (p(h)) {
s("Setup cancelled.");
return;
}
if (h && !d) {
const t = await u({
message: "React wrapper npm package name? (used as clientModule in the SSR config)",
placeholder: c,
defaultValue: c
});
if (p(t)) {
s("Setup cancelled.");
return;
}
c = t;
}
const k = !await I(i);
if (k) {
const t = n();
t.start(`Scaffolding wrapper package at ${D(d ?? e.rootDir, i)}`);
try {
const y = d ? "workspace:*" : `file:${D(i, e.rootDir).replace(/\\/g, "/")}`;
await E(i, c, e.fsNamespace, y), t.stop("Wrapper package scaffolded");
} catch (y) {
t.stop("Scaffolding failed — continuing"), l.warn(`Could not scaffold wrapper package: ${y}`);
}
}
const j = h ? `reactOutputTarget({
outDir: '${P}',
hydrateModule: '${e.fsNamespace}/dist/ssr',
clientModule: '${c}',
})` : `reactOutputTarget({ outDir: '${P}' })`;
try {
const t = A(S, j, h);
l.success(t ? "stencil.config.ts updated" : "reactOutputTarget already present — no changes made");
} catch (t) {
l.warn(
`Could not automatically update stencil.config.ts (${t}). Add manually:
import { reactOutputTarget } from '@stencil/react-output-target';
// in outputTargets:
${j}` + (h ? `
{ type: 'ssr' }` : "")
);
}
l.info("Installing @stencil/react-output-target..."), await f.addDependency(["@stencil/react-output-target"], { cwd: e.rootDir, dev: !0 }), l.success("Installed @stencil/react-output-target"), k && await I(i) && (l.info("Installing React peer dependencies in wrapper package..."), await f.addDependency(["@stencil/react-output-target"], { cwd: i, dev: !0 }), await f.addDependency(["react", "react-dom", "@types/react", "@types/react-dom", "typescript"], {
cwd: i,
dev: !0
}), l.success("React peer dependencies installed")), x("React output target configured");
}
}
};
export {
z as wizard
};
//# sourceMappingURL=wizard.js.map