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>
73 lines
2.4 KiB
JavaScript
73 lines
2.4 KiB
JavaScript
#!/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.`);
|