fix(build): postinstall script patches flowbite-svelte TypeScript optional params
flowbite-svelte ships TypeScript optional-param syntax (x?: string, event?: MouseEvent, date?: Date) in its dist .svelte files. Vite's esbuild dep pre-bundler processes these files (via dist/*/index.js re-exports) and fails with "Unexpected '?'" parse errors whenever the lockfile changes and the dep cache is rebuilt. - Add scripts/postinstall.mjs: patches 4 specific TypeScript signatures in CommandPalette.svelte, ScrollSpy.svelte, and Datepicker.svelte after every npm install. Patches are idempotent and targeted — only the ?-in-param-position syntax is removed; optional-chaining (?.) in function bodies is untouched. - Add "postinstall" script to package.json to run it automatically. - Upgrade flowbite-svelte 1.31.0 → 1.33.1 (both have the same issue; 1.33.1 is current). - npm update now works without breaking the dev server. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
72
scripts/postinstall.mjs
Normal file
72
scripts/postinstall.mjs
Normal file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Postinstall: strip TypeScript optional-param syntax from flowbite-svelte dist files.
|
||||
*
|
||||
* flowbite-svelte ships raw .svelte files with `<script lang="ts">` in its dist.
|
||||
* esbuild (used by Vite's dep pre-bundler) cannot parse TypeScript optional params
|
||||
* like `(x?: string)` or `event?` in function signatures — it fails with
|
||||
* "Unexpected '?'" or "Expected ')' but found '?'" errors.
|
||||
*
|
||||
* The patches below remove only the TypeScript syntax that causes esbuild to fail.
|
||||
* The `?.` optional-chaining calls in function bodies are left untouched (those are
|
||||
* valid JavaScript and handle undefined correctly at runtime).
|
||||
*
|
||||
* This runs automatically via `"postinstall": "node scripts/postinstall.mjs"` and
|
||||
* is safe to re-run — the replacements are idempotent.
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
const root = fileURLToPath(new URL('..', import.meta.url));
|
||||
const dist = resolve(root, 'node_modules/flowbite-svelte/dist');
|
||||
|
||||
if (!existsSync(dist)) {
|
||||
console.log('postinstall: flowbite-svelte dist not found, skipping.');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
let patched = 0;
|
||||
|
||||
function patch(relPath, from, to) {
|
||||
const file = resolve(dist, relPath);
|
||||
if (!existsSync(file)) return;
|
||||
const original = readFileSync(file, 'utf8');
|
||||
const updated = original.replace(from, to);
|
||||
if (updated !== original) {
|
||||
writeFileSync(file, updated, 'utf8');
|
||||
console.log(` patched: ${relPath}`);
|
||||
patched++;
|
||||
}
|
||||
}
|
||||
|
||||
// CommandPalette.svelte: (x?: string) => x?.toLowerCase()...
|
||||
// Remove optional type annotation from the `check` helper param.
|
||||
patch(
|
||||
'command-palette/CommandPalette.svelte',
|
||||
/\(x\?:\s*string\)/g,
|
||||
'(x)'
|
||||
);
|
||||
|
||||
// ScrollSpy.svelte: function scrollToSection(itemId: string, event?: MouseEvent)
|
||||
// Remove type annotations from both params.
|
||||
patch(
|
||||
'scroll-spy/ScrollSpy.svelte',
|
||||
/scrollToSection\(itemId:\s*string,\s*event\?:\s*MouseEvent\)/g,
|
||||
'scrollToSection(itemId, event)'
|
||||
);
|
||||
|
||||
// Datepicker.svelte: two functions with optional typed params + return-type annotations.
|
||||
patch(
|
||||
'datepicker/Datepicker.svelte',
|
||||
/\(date\?:\s*Date\):\s*string/g,
|
||||
'(date)'
|
||||
);
|
||||
patch(
|
||||
'datepicker/Datepicker.svelte',
|
||||
/\(date1\?:\s*Date,\s*date2\?:\s*Date\):\s*boolean/g,
|
||||
'(date1, date2)'
|
||||
);
|
||||
|
||||
console.log(`postinstall: flowbite-svelte — ${patched} file(s) patched.`);
|
||||
Reference in New Issue
Block a user