- Curated re-exports from @limitless/ui through /forms, /data, /feedback, /navigation, /utils sub-paths so apps stop importing from the lower layer. - /forms also re-exports the full @limitless/ui validation surface (hooks, format/security/address validators, types). - AppLayout is now a thin wrapper over @limitless/ui's <AppShell> — same ShellConfig DTO, no duplicated chrome code. - shell/types + shell/index re-export from @limitless/ui to keep one canonical type and one shared context. - auth middleware: loose NextRequestLike typing to avoid two-copies- of-next conflict with the consumer's next. - postbuild: rewrite ../images/ to ./images/ in copied CSS so refs resolve in dist/styles/. Widget family in /data is the intersection of limitless's two Widget files (Widget.d.ts vs Widget/index.d.ts collision in dist); upstream fix needed before exposing IconWidget/UserWidget/etc. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
78 lines
2.7 KiB
JavaScript
78 lines
2.7 KiB
JavaScript
/* Post-build: copy CSS + image assets into dist/, then fix ESM imports.
|
|
*
|
|
* tsc only emits .js + .d.ts. The CSS lives in src/styles/ alongside an
|
|
* `index.css` that @imports the other sheets; we copy the whole tree
|
|
* to dist/ so `@gsc/web-kit/css` resolves correctly.
|
|
*/
|
|
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
const root = path.join(__dirname, "..");
|
|
const distDir = path.join(root, "dist");
|
|
const srcStyles = path.join(root, "src", "styles");
|
|
const distStyles = path.join(distDir, "styles");
|
|
|
|
// 1. Mirror src/styles/ → dist/styles/ (CSS + images).
|
|
function copyDir(src, dst) {
|
|
fs.mkdirSync(dst, { recursive: true });
|
|
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
const s = path.join(src, entry.name);
|
|
const d = path.join(dst, entry.name);
|
|
if (entry.isDirectory()) copyDir(s, d);
|
|
else fs.copyFileSync(s, d);
|
|
}
|
|
}
|
|
if (fs.existsSync(srcStyles)) {
|
|
copyDir(srcStyles, distStyles);
|
|
|
|
// Rewrite ../images/... references in any copied CSS to ./images/...
|
|
// The source CSS assumes a sibling src/images/ dir; in dist/ the images
|
|
// live at dist/styles/images/ alongside the CSS, so the relative path
|
|
// is one level shorter.
|
|
for (const f of fs.readdirSync(distStyles)) {
|
|
if (!f.endsWith(".css")) continue;
|
|
const p = path.join(distStyles, f);
|
|
const c = fs.readFileSync(p, "utf8");
|
|
const fixed = c.replace(/\.\.\/images\//g, "./images/");
|
|
if (fixed !== c) fs.writeFileSync(p, fixed);
|
|
}
|
|
}
|
|
|
|
// 2. Fix ESM relative imports: append `.js` to bare specifiers like
|
|
// `from './layout/AppLayout'` so the resolver can find the file.
|
|
function fixImports(dir) {
|
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
const full = path.join(dir, entry.name);
|
|
if (entry.isDirectory()) {
|
|
fixImports(full);
|
|
continue;
|
|
}
|
|
if (!entry.name.endsWith(".js")) continue;
|
|
const content = fs.readFileSync(full, "utf8");
|
|
const fixed = content.replace(
|
|
/((?:from|import)\s+['"])(\.{1,2}\/[^'"]+?)(['"])/g,
|
|
(match, prefix, rel, quote) => {
|
|
if (rel.endsWith(".js") || rel.endsWith(".css")) return match;
|
|
const absDir = path.dirname(full);
|
|
const target = path.resolve(absDir, rel);
|
|
if (fs.existsSync(target) && fs.statSync(target).isDirectory()) {
|
|
if (fs.existsSync(path.join(target, "index.js"))) {
|
|
return `${prefix}${rel}/index.js${quote}`;
|
|
}
|
|
}
|
|
if (fs.existsSync(`${target}.js`)) {
|
|
return `${prefix}${rel}.js${quote}`;
|
|
}
|
|
return match;
|
|
},
|
|
);
|
|
if (fixed !== content) fs.writeFileSync(full, fixed);
|
|
}
|
|
}
|
|
if (fs.existsSync(distDir)) {
|
|
fixImports(distDir);
|
|
}
|
|
|
|
console.log("Post-build: CSS copied, ESM imports fixed");
|