- Tailwind CSS: toolbar checkbox injects Play CDN into preview, persisted per-fiddle via new options JSON column - Markdown mode: uses marked.js CDN, renders markdown to HTML preview with CSS tab for custom styling - WASM mode: starter template with inline WebAssembly add function, supports top-level await via module detection - npm imports: auto-detect bare import specifiers in module code and inject importmap pointing to esm.sh CDN - Module auto-detection for html-css-js mode (import/export statements) - DB migration adds options column, server passes through all API endpoints - All features work across preview, export, and embed
44 lines
1.6 KiB
JavaScript
44 lines
1.6 KiB
JavaScript
/**
|
|
* Extract bare import specifiers from JS code.
|
|
* Matches `from 'pkg'`, `from "pkg"`, `import 'pkg'`, `import "pkg"`
|
|
* where the specifier doesn't start with `.`, `/`, `http:`, or `https:`.
|
|
*/
|
|
export function extractBareImports(jsCode) {
|
|
const imports = new Set();
|
|
const re = /(?:import\s+(?:[\s\S]*?\s+from\s+)?['"])([^'"\s][^'"]*?)(?=['"])/g;
|
|
let match;
|
|
while ((match = re.exec(jsCode)) !== null) {
|
|
const spec = match[1];
|
|
// Skip relative, absolute, and URL imports
|
|
if (spec.startsWith('.') || spec.startsWith('/') || spec.startsWith('http:') || spec.startsWith('https:')) {
|
|
continue;
|
|
}
|
|
// Skip svelte internal imports (already rewritten by the compiler)
|
|
if (spec.startsWith('svelte')) continue;
|
|
imports.add(spec);
|
|
}
|
|
return Array.from(imports);
|
|
}
|
|
|
|
/**
|
|
* Build an HTML <script type="importmap"> tag from bare import specifiers.
|
|
* Maps each bare import to its esm.sh URL.
|
|
*/
|
|
export function buildImportMapTag(bareImports) {
|
|
if (!bareImports.length) return '';
|
|
const imports = {};
|
|
for (const spec of bareImports) {
|
|
// Get the package name (handle scoped packages like @scope/pkg)
|
|
const parts = spec.split('/');
|
|
const pkgName = spec.startsWith('@') ? `${parts[0]}/${parts[1]}` : parts[0];
|
|
// Map the full specifier (e.g. 'lodash/fp' -> 'https://esm.sh/lodash/fp')
|
|
imports[spec] = `https://esm.sh/${spec}`;
|
|
// Also map the base package if it's different
|
|
if (spec !== pkgName) {
|
|
imports[pkgName] = `https://esm.sh/${pkgName}`;
|
|
}
|
|
}
|
|
const map = JSON.stringify({ imports }, null, 2);
|
|
return `<script type="importmap">\n${map}\n<\/script>`;
|
|
}
|