diorama-js 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +156 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +156 -15
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +159 -16
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +10 -0
- package/dist/react.d.ts +10 -0
- package/dist/react.js +159 -16
- package/dist/react.js.map +1 -1
- package/dist/svelte.cjs +157 -15
- package/dist/svelte.cjs.map +1 -1
- package/dist/svelte.d.cts +10 -0
- package/dist/svelte.d.ts +10 -0
- package/dist/svelte.js +157 -15
- package/dist/svelte.js.map +1 -1
- package/dist/vue.cjs +159 -16
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.d.cts +8 -0
- package/dist/vue.d.ts +8 -0
- package/dist/vue.js +159 -16
- package/dist/vue.js.map +1 -1
- package/package.json +1 -1
package/dist/svelte.cjs
CHANGED
|
@@ -623,6 +623,7 @@ function analyzeProject(project, overrideType, overrideEntry) {
|
|
|
623
623
|
hasBareImports: hasBareImports(files),
|
|
624
624
|
isVite
|
|
625
625
|
});
|
|
626
|
+
const usesTailwind = usesTailwindCSS(files);
|
|
626
627
|
return {
|
|
627
628
|
type,
|
|
628
629
|
entryPoint: htmlEntry,
|
|
@@ -631,7 +632,8 @@ function analyzeProject(project, overrideType, overrideEntry) {
|
|
|
631
632
|
hasJSX,
|
|
632
633
|
hasTypeScript,
|
|
633
634
|
jsEntryPoint: jsEntry,
|
|
634
|
-
isVite
|
|
635
|
+
isVite,
|
|
636
|
+
usesTailwind
|
|
635
637
|
};
|
|
636
638
|
}
|
|
637
639
|
function detectProjectType(input) {
|
|
@@ -653,6 +655,17 @@ function hasBareImports(files) {
|
|
|
653
655
|
}
|
|
654
656
|
return false;
|
|
655
657
|
}
|
|
658
|
+
function usesTailwindCSS(files) {
|
|
659
|
+
for (const [path, content] of files) {
|
|
660
|
+
if (/(?:^|\/)tailwind\.config\.(?:js|cjs|mjs|ts)$/.test(path)) {
|
|
661
|
+
return true;
|
|
662
|
+
}
|
|
663
|
+
if (path.endsWith(".css") && /@tailwind\b|@apply\b/.test(content)) {
|
|
664
|
+
return true;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
return false;
|
|
668
|
+
}
|
|
656
669
|
|
|
657
670
|
// src/core/sandbox.ts
|
|
658
671
|
function buildErrorHTML(message) {
|
|
@@ -1507,6 +1520,18 @@ function getCDNProvider(name) {
|
|
|
1507
1520
|
return esmShProvider;
|
|
1508
1521
|
}
|
|
1509
1522
|
}
|
|
1523
|
+
function buildCSSURL(specifier, options = {}) {
|
|
1524
|
+
const { dependencies = {}, cdnProvider = "esm.sh" } = options;
|
|
1525
|
+
const clean = specifier.replace(/[?#].*$/, "");
|
|
1526
|
+
const { packageName, subpath } = parseSpecifier(clean);
|
|
1527
|
+
const version = dependencies[packageName];
|
|
1528
|
+
const ver = version ? `@${version}` : "";
|
|
1529
|
+
const sub = subpath ? `/${subpath}` : "";
|
|
1530
|
+
if (cdnProvider === "unpkg") {
|
|
1531
|
+
return `https://unpkg.com/${packageName}${ver}${sub}`;
|
|
1532
|
+
}
|
|
1533
|
+
return `https://esm.sh/${packageName}${ver}${sub}`;
|
|
1534
|
+
}
|
|
1510
1535
|
function rewriteImports(source, options = {}) {
|
|
1511
1536
|
const {
|
|
1512
1537
|
dependencies = {},
|
|
@@ -1520,6 +1545,9 @@ function rewriteImports(source, options = {}) {
|
|
|
1520
1545
|
if (raw.startsWith(".") || raw.startsWith("/") || /^https?:\/\//.test(raw)) {
|
|
1521
1546
|
return raw;
|
|
1522
1547
|
}
|
|
1548
|
+
if (/\.css(?:[?#]|$)/.test(raw)) {
|
|
1549
|
+
return raw;
|
|
1550
|
+
}
|
|
1523
1551
|
const { packageName, subpath } = parseSpecifier(raw);
|
|
1524
1552
|
if (NODE_BUILTINS.has(packageName) || NODE_BUILTINS.has(packageName.replace("node:", ""))) {
|
|
1525
1553
|
throw new NodeBuiltinError(packageName);
|
|
@@ -1722,20 +1750,25 @@ var ASSET_IMPORT_EXTENSIONS = {
|
|
|
1722
1750
|
".otf": "font/otf"
|
|
1723
1751
|
};
|
|
1724
1752
|
function assembleHTML(options) {
|
|
1725
|
-
const { project, config, transformedFiles } = options;
|
|
1753
|
+
const { project, config, transformedFiles, cdnProvider, tailwind = "auto" } = options;
|
|
1726
1754
|
const files = transformedFiles ?? project.files;
|
|
1755
|
+
let result;
|
|
1727
1756
|
switch (config.type) {
|
|
1728
1757
|
case "static":
|
|
1729
|
-
|
|
1758
|
+
result = assembleStatic(files, project, config);
|
|
1759
|
+
break;
|
|
1730
1760
|
case "static-esm":
|
|
1731
1761
|
case "jsx":
|
|
1732
1762
|
case "typescript":
|
|
1733
1763
|
case "jsx-typescript":
|
|
1734
1764
|
case "vite":
|
|
1735
|
-
|
|
1765
|
+
result = assembleESM(files, project, config, cdnProvider);
|
|
1766
|
+
break;
|
|
1736
1767
|
default:
|
|
1737
1768
|
throw new AssemblyError(`Unsupported project type: ${config.type}`);
|
|
1738
1769
|
}
|
|
1770
|
+
result.html = applyTailwindRuntime(result.html, project, config, tailwind);
|
|
1771
|
+
return result;
|
|
1739
1772
|
}
|
|
1740
1773
|
function assembleStatic(files, project, config) {
|
|
1741
1774
|
let html = files.get(config.entryPoint);
|
|
@@ -1749,10 +1782,13 @@ function assembleStatic(files, project, config) {
|
|
|
1749
1782
|
html = inlineAssets(html, project, config.entryPoint);
|
|
1750
1783
|
return { html, usesESM: false };
|
|
1751
1784
|
}
|
|
1752
|
-
function assembleESM(files, project, config) {
|
|
1785
|
+
function assembleESM(files, project, config, cdnProvider) {
|
|
1753
1786
|
const isGenerated = config.entryPoint === "__generated__/index.html";
|
|
1754
1787
|
rewriteAssetImports(files, project);
|
|
1755
|
-
const cssFromJS = extractCSSImports(files
|
|
1788
|
+
const { css: cssFromJS, links: cssLinks } = extractCSSImports(files, {
|
|
1789
|
+
dependencies: config.dependencies,
|
|
1790
|
+
cdnProvider
|
|
1791
|
+
});
|
|
1756
1792
|
if (config.isVite) {
|
|
1757
1793
|
injectImportMetaEnv(files);
|
|
1758
1794
|
}
|
|
@@ -1771,6 +1807,9 @@ function assembleESM(files, project, config) {
|
|
|
1771
1807
|
html = rewriteScriptSrcsToImportMap(html, config.entryPoint);
|
|
1772
1808
|
html = inlineAssets(html, project, config.entryPoint);
|
|
1773
1809
|
}
|
|
1810
|
+
for (const href of cssLinks) {
|
|
1811
|
+
html = injectIntoHead(html, `<link rel="stylesheet" href="${href}">`);
|
|
1812
|
+
}
|
|
1774
1813
|
if (cssFromJS) {
|
|
1775
1814
|
html = injectIntoHead(html, `<style>
|
|
1776
1815
|
${cssFromJS}
|
|
@@ -2020,20 +2059,32 @@ function rewriteAssetImports(files, project) {
|
|
|
2020
2059
|
}
|
|
2021
2060
|
}
|
|
2022
2061
|
}
|
|
2023
|
-
function extractCSSImports(files) {
|
|
2062
|
+
function extractCSSImports(files, options = {}) {
|
|
2024
2063
|
const cssChunks = [];
|
|
2025
|
-
const
|
|
2064
|
+
const links = [];
|
|
2065
|
+
const seenLinks = /* @__PURE__ */ new Set();
|
|
2066
|
+
const cssImportRe = /import\s+['"]([^'"]+\.css(?:[?#][^'"]*)?)['"]\s*;?/g;
|
|
2026
2067
|
for (const [path, content] of files) {
|
|
2027
2068
|
if (!/\.(js|ts|jsx|tsx|mjs)$/.test(path)) continue;
|
|
2028
2069
|
let modified = content;
|
|
2029
2070
|
let match;
|
|
2071
|
+
cssImportRe.lastIndex = 0;
|
|
2030
2072
|
while ((match = cssImportRe.exec(content)) !== null) {
|
|
2031
|
-
const
|
|
2032
|
-
const
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2073
|
+
const specifier = match[1];
|
|
2074
|
+
const bare = specifier.replace(/[?#].*$/, "");
|
|
2075
|
+
if (bare.startsWith(".") || bare.startsWith("/")) {
|
|
2076
|
+
const resolved = resolvePath(directoryOf(path), bare);
|
|
2077
|
+
const css = files.get(resolved);
|
|
2078
|
+
if (css) {
|
|
2079
|
+
cssChunks.push(`/* ${resolved} */
|
|
2036
2080
|
${css}`);
|
|
2081
|
+
}
|
|
2082
|
+
} else {
|
|
2083
|
+
const href = /^https?:\/\//.test(bare) ? bare : buildCSSURL(bare, options);
|
|
2084
|
+
if (!seenLinks.has(href)) {
|
|
2085
|
+
seenLinks.add(href);
|
|
2086
|
+
links.push(href);
|
|
2087
|
+
}
|
|
2037
2088
|
}
|
|
2038
2089
|
modified = modified.replace(match[0], "");
|
|
2039
2090
|
}
|
|
@@ -2041,7 +2092,95 @@ ${css}`);
|
|
|
2041
2092
|
files.set(path, modified);
|
|
2042
2093
|
}
|
|
2043
2094
|
}
|
|
2044
|
-
return cssChunks.join("\n\n");
|
|
2095
|
+
return { css: cssChunks.join("\n\n"), links };
|
|
2096
|
+
}
|
|
2097
|
+
var TAILWIND_DIRECTIVE_RE = /@tailwind\b|@apply\b/;
|
|
2098
|
+
var TAILWIND_CDN_URL = "https://cdn.tailwindcss.com";
|
|
2099
|
+
function hasTailwindDirectives(css) {
|
|
2100
|
+
return TAILWIND_DIRECTIVE_RE.test(css);
|
|
2101
|
+
}
|
|
2102
|
+
function applyTailwindRuntime(html, project, config, tailwind) {
|
|
2103
|
+
const enabled = tailwind === true || tailwind === "auto" && (config.usesTailwind ?? usesTailwindCSS(project.files));
|
|
2104
|
+
if (!enabled) return html;
|
|
2105
|
+
html = html.replace(
|
|
2106
|
+
/<style>([\s\S]*?)<\/style>/g,
|
|
2107
|
+
(match, css) => hasTailwindDirectives(css) ? `<style type="text/tailwindcss">${css}</style>` : match
|
|
2108
|
+
);
|
|
2109
|
+
let injection = `<script src="${TAILWIND_CDN_URL}"></script>`;
|
|
2110
|
+
const configObject = extractTailwindConfig(project.files);
|
|
2111
|
+
if (configObject) {
|
|
2112
|
+
injection += `
|
|
2113
|
+
<script>tailwind.config = ${configObject};</script>`;
|
|
2114
|
+
}
|
|
2115
|
+
return injectIntoHead(html, injection);
|
|
2116
|
+
}
|
|
2117
|
+
function extractTailwindConfig(files) {
|
|
2118
|
+
let source;
|
|
2119
|
+
for (const [path, content] of files) {
|
|
2120
|
+
if (/(?:^|\/)tailwind\.config\.(?:js|cjs|mjs|ts)$/.test(path)) {
|
|
2121
|
+
source = content;
|
|
2122
|
+
break;
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
if (!source) return null;
|
|
2126
|
+
const object = extractBalancedObject(source);
|
|
2127
|
+
if (!object || !isSafeConfigObject(object)) return null;
|
|
2128
|
+
return object;
|
|
2129
|
+
}
|
|
2130
|
+
function extractBalancedObject(source) {
|
|
2131
|
+
const opener = source.match(/(?:export\s+default|module\.exports\s*=)\s*\{/);
|
|
2132
|
+
if (!opener || opener.index === void 0) return null;
|
|
2133
|
+
const start = opener.index + opener[0].length - 1;
|
|
2134
|
+
let depth = 0;
|
|
2135
|
+
let str = null;
|
|
2136
|
+
let lineComment = false;
|
|
2137
|
+
let blockComment = false;
|
|
2138
|
+
for (let i = start; i < source.length; i++) {
|
|
2139
|
+
const c = source[i];
|
|
2140
|
+
const n = source[i + 1];
|
|
2141
|
+
if (lineComment) {
|
|
2142
|
+
if (c === "\n") lineComment = false;
|
|
2143
|
+
continue;
|
|
2144
|
+
}
|
|
2145
|
+
if (blockComment) {
|
|
2146
|
+
if (c === "*" && n === "/") {
|
|
2147
|
+
blockComment = false;
|
|
2148
|
+
i++;
|
|
2149
|
+
}
|
|
2150
|
+
continue;
|
|
2151
|
+
}
|
|
2152
|
+
if (str) {
|
|
2153
|
+
if (c === "\\") {
|
|
2154
|
+
i++;
|
|
2155
|
+
continue;
|
|
2156
|
+
}
|
|
2157
|
+
if (c === str) str = null;
|
|
2158
|
+
continue;
|
|
2159
|
+
}
|
|
2160
|
+
if (c === "/" && n === "/") {
|
|
2161
|
+
lineComment = true;
|
|
2162
|
+
i++;
|
|
2163
|
+
continue;
|
|
2164
|
+
}
|
|
2165
|
+
if (c === "/" && n === "*") {
|
|
2166
|
+
blockComment = true;
|
|
2167
|
+
i++;
|
|
2168
|
+
continue;
|
|
2169
|
+
}
|
|
2170
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
2171
|
+
str = c;
|
|
2172
|
+
continue;
|
|
2173
|
+
}
|
|
2174
|
+
if (c === "{") depth++;
|
|
2175
|
+
else if (c === "}") {
|
|
2176
|
+
depth--;
|
|
2177
|
+
if (depth === 0) return source.slice(start, i + 1);
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
return null;
|
|
2181
|
+
}
|
|
2182
|
+
function isSafeConfigObject(object) {
|
|
2183
|
+
return !(/\brequire\s*\(/.test(object) || /\bimport\b/.test(object) || /=>/.test(object) || /\bfunction\b/.test(object) || /`/.test(object) || /\bprocess\b/.test(object) || /\b__dirname\b|\b__filename\b/.test(object));
|
|
2045
2184
|
}
|
|
2046
2185
|
function injectImportMetaEnv(files) {
|
|
2047
2186
|
const shim = `if(!import.meta.env){Object.defineProperty(import.meta,'env',{value:{MODE:'production',BASE_URL:'/',PROD:true,DEV:false,SSR:false}});}`;
|
|
@@ -2152,7 +2291,9 @@ var Diorama = class {
|
|
|
2152
2291
|
const { html: html2, usesESM: usesESM2 } = assembleHTML({
|
|
2153
2292
|
project,
|
|
2154
2293
|
config,
|
|
2155
|
-
transformedFiles: files
|
|
2294
|
+
transformedFiles: files,
|
|
2295
|
+
cdnProvider: this.options.cdnProvider,
|
|
2296
|
+
tailwind: options.tailwind ?? "auto"
|
|
2156
2297
|
});
|
|
2157
2298
|
return { html: html2, usesESM: usesESM2, repoName: repoName2 };
|
|
2158
2299
|
};
|
|
@@ -2272,6 +2413,7 @@ function dioramaAction(node, params) {
|
|
|
2272
2413
|
height: opts.height ?? "500px",
|
|
2273
2414
|
frame: opts.frame,
|
|
2274
2415
|
expand: opts.expand,
|
|
2416
|
+
tailwind: opts.tailwind,
|
|
2275
2417
|
onLoad: opts.onLoad,
|
|
2276
2418
|
onError: opts.onError
|
|
2277
2419
|
});
|