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/index.cjs
CHANGED
|
@@ -640,6 +640,7 @@ function analyzeProject(project, overrideType, overrideEntry) {
|
|
|
640
640
|
hasBareImports: hasBareImports(files),
|
|
641
641
|
isVite
|
|
642
642
|
});
|
|
643
|
+
const usesTailwind = usesTailwindCSS(files);
|
|
643
644
|
return {
|
|
644
645
|
type,
|
|
645
646
|
entryPoint: htmlEntry,
|
|
@@ -648,7 +649,8 @@ function analyzeProject(project, overrideType, overrideEntry) {
|
|
|
648
649
|
hasJSX,
|
|
649
650
|
hasTypeScript,
|
|
650
651
|
jsEntryPoint: jsEntry,
|
|
651
|
-
isVite
|
|
652
|
+
isVite,
|
|
653
|
+
usesTailwind
|
|
652
654
|
};
|
|
653
655
|
}
|
|
654
656
|
function detectProjectType(input) {
|
|
@@ -670,6 +672,17 @@ function hasBareImports(files) {
|
|
|
670
672
|
}
|
|
671
673
|
return false;
|
|
672
674
|
}
|
|
675
|
+
function usesTailwindCSS(files) {
|
|
676
|
+
for (const [path, content] of files) {
|
|
677
|
+
if (/(?:^|\/)tailwind\.config\.(?:js|cjs|mjs|ts)$/.test(path)) {
|
|
678
|
+
return true;
|
|
679
|
+
}
|
|
680
|
+
if (path.endsWith(".css") && /@tailwind\b|@apply\b/.test(content)) {
|
|
681
|
+
return true;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
return false;
|
|
685
|
+
}
|
|
673
686
|
|
|
674
687
|
// src/core/sandbox.ts
|
|
675
688
|
function buildErrorHTML(message) {
|
|
@@ -1524,6 +1537,18 @@ function getCDNProvider(name) {
|
|
|
1524
1537
|
return esmShProvider;
|
|
1525
1538
|
}
|
|
1526
1539
|
}
|
|
1540
|
+
function buildCSSURL(specifier, options = {}) {
|
|
1541
|
+
const { dependencies = {}, cdnProvider = "esm.sh" } = options;
|
|
1542
|
+
const clean = specifier.replace(/[?#].*$/, "");
|
|
1543
|
+
const { packageName, subpath } = parseSpecifier(clean);
|
|
1544
|
+
const version = dependencies[packageName];
|
|
1545
|
+
const ver = version ? `@${version}` : "";
|
|
1546
|
+
const sub = subpath ? `/${subpath}` : "";
|
|
1547
|
+
if (cdnProvider === "unpkg") {
|
|
1548
|
+
return `https://unpkg.com/${packageName}${ver}${sub}`;
|
|
1549
|
+
}
|
|
1550
|
+
return `https://esm.sh/${packageName}${ver}${sub}`;
|
|
1551
|
+
}
|
|
1527
1552
|
function rewriteImports(source, options = {}) {
|
|
1528
1553
|
const {
|
|
1529
1554
|
dependencies = {},
|
|
@@ -1537,6 +1562,9 @@ function rewriteImports(source, options = {}) {
|
|
|
1537
1562
|
if (raw.startsWith(".") || raw.startsWith("/") || /^https?:\/\//.test(raw)) {
|
|
1538
1563
|
return raw;
|
|
1539
1564
|
}
|
|
1565
|
+
if (/\.css(?:[?#]|$)/.test(raw)) {
|
|
1566
|
+
return raw;
|
|
1567
|
+
}
|
|
1540
1568
|
const { packageName, subpath } = parseSpecifier(raw);
|
|
1541
1569
|
if (NODE_BUILTINS.has(packageName) || NODE_BUILTINS.has(packageName.replace("node:", ""))) {
|
|
1542
1570
|
throw new NodeBuiltinError(packageName);
|
|
@@ -1739,20 +1767,25 @@ var ASSET_IMPORT_EXTENSIONS = {
|
|
|
1739
1767
|
".otf": "font/otf"
|
|
1740
1768
|
};
|
|
1741
1769
|
function assembleHTML(options) {
|
|
1742
|
-
const { project, config, transformedFiles } = options;
|
|
1770
|
+
const { project, config, transformedFiles, cdnProvider, tailwind = "auto" } = options;
|
|
1743
1771
|
const files = transformedFiles ?? project.files;
|
|
1772
|
+
let result;
|
|
1744
1773
|
switch (config.type) {
|
|
1745
1774
|
case "static":
|
|
1746
|
-
|
|
1775
|
+
result = assembleStatic(files, project, config);
|
|
1776
|
+
break;
|
|
1747
1777
|
case "static-esm":
|
|
1748
1778
|
case "jsx":
|
|
1749
1779
|
case "typescript":
|
|
1750
1780
|
case "jsx-typescript":
|
|
1751
1781
|
case "vite":
|
|
1752
|
-
|
|
1782
|
+
result = assembleESM(files, project, config, cdnProvider);
|
|
1783
|
+
break;
|
|
1753
1784
|
default:
|
|
1754
1785
|
throw new AssemblyError(`Unsupported project type: ${config.type}`);
|
|
1755
1786
|
}
|
|
1787
|
+
result.html = applyTailwindRuntime(result.html, project, config, tailwind);
|
|
1788
|
+
return result;
|
|
1756
1789
|
}
|
|
1757
1790
|
function assembleStatic(files, project, config) {
|
|
1758
1791
|
let html = files.get(config.entryPoint);
|
|
@@ -1766,10 +1799,13 @@ function assembleStatic(files, project, config) {
|
|
|
1766
1799
|
html = inlineAssets(html, project, config.entryPoint);
|
|
1767
1800
|
return { html, usesESM: false };
|
|
1768
1801
|
}
|
|
1769
|
-
function assembleESM(files, project, config) {
|
|
1802
|
+
function assembleESM(files, project, config, cdnProvider) {
|
|
1770
1803
|
const isGenerated = config.entryPoint === "__generated__/index.html";
|
|
1771
1804
|
rewriteAssetImports(files, project);
|
|
1772
|
-
const cssFromJS = extractCSSImports(files
|
|
1805
|
+
const { css: cssFromJS, links: cssLinks } = extractCSSImports(files, {
|
|
1806
|
+
dependencies: config.dependencies,
|
|
1807
|
+
cdnProvider
|
|
1808
|
+
});
|
|
1773
1809
|
if (config.isVite) {
|
|
1774
1810
|
injectImportMetaEnv(files);
|
|
1775
1811
|
}
|
|
@@ -1788,6 +1824,9 @@ function assembleESM(files, project, config) {
|
|
|
1788
1824
|
html = rewriteScriptSrcsToImportMap(html, config.entryPoint);
|
|
1789
1825
|
html = inlineAssets(html, project, config.entryPoint);
|
|
1790
1826
|
}
|
|
1827
|
+
for (const href of cssLinks) {
|
|
1828
|
+
html = injectIntoHead(html, `<link rel="stylesheet" href="${href}">`);
|
|
1829
|
+
}
|
|
1791
1830
|
if (cssFromJS) {
|
|
1792
1831
|
html = injectIntoHead(html, `<style>
|
|
1793
1832
|
${cssFromJS}
|
|
@@ -2037,20 +2076,32 @@ function rewriteAssetImports(files, project) {
|
|
|
2037
2076
|
}
|
|
2038
2077
|
}
|
|
2039
2078
|
}
|
|
2040
|
-
function extractCSSImports(files) {
|
|
2079
|
+
function extractCSSImports(files, options = {}) {
|
|
2041
2080
|
const cssChunks = [];
|
|
2042
|
-
const
|
|
2081
|
+
const links = [];
|
|
2082
|
+
const seenLinks = /* @__PURE__ */ new Set();
|
|
2083
|
+
const cssImportRe = /import\s+['"]([^'"]+\.css(?:[?#][^'"]*)?)['"]\s*;?/g;
|
|
2043
2084
|
for (const [path, content] of files) {
|
|
2044
2085
|
if (!/\.(js|ts|jsx|tsx|mjs)$/.test(path)) continue;
|
|
2045
2086
|
let modified = content;
|
|
2046
2087
|
let match;
|
|
2088
|
+
cssImportRe.lastIndex = 0;
|
|
2047
2089
|
while ((match = cssImportRe.exec(content)) !== null) {
|
|
2048
|
-
const
|
|
2049
|
-
const
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2090
|
+
const specifier = match[1];
|
|
2091
|
+
const bare = specifier.replace(/[?#].*$/, "");
|
|
2092
|
+
if (bare.startsWith(".") || bare.startsWith("/")) {
|
|
2093
|
+
const resolved = resolvePath(directoryOf(path), bare);
|
|
2094
|
+
const css = files.get(resolved);
|
|
2095
|
+
if (css) {
|
|
2096
|
+
cssChunks.push(`/* ${resolved} */
|
|
2053
2097
|
${css}`);
|
|
2098
|
+
}
|
|
2099
|
+
} else {
|
|
2100
|
+
const href = /^https?:\/\//.test(bare) ? bare : buildCSSURL(bare, options);
|
|
2101
|
+
if (!seenLinks.has(href)) {
|
|
2102
|
+
seenLinks.add(href);
|
|
2103
|
+
links.push(href);
|
|
2104
|
+
}
|
|
2054
2105
|
}
|
|
2055
2106
|
modified = modified.replace(match[0], "");
|
|
2056
2107
|
}
|
|
@@ -2058,7 +2109,95 @@ ${css}`);
|
|
|
2058
2109
|
files.set(path, modified);
|
|
2059
2110
|
}
|
|
2060
2111
|
}
|
|
2061
|
-
return cssChunks.join("\n\n");
|
|
2112
|
+
return { css: cssChunks.join("\n\n"), links };
|
|
2113
|
+
}
|
|
2114
|
+
var TAILWIND_DIRECTIVE_RE = /@tailwind\b|@apply\b/;
|
|
2115
|
+
var TAILWIND_CDN_URL = "https://cdn.tailwindcss.com";
|
|
2116
|
+
function hasTailwindDirectives(css) {
|
|
2117
|
+
return TAILWIND_DIRECTIVE_RE.test(css);
|
|
2118
|
+
}
|
|
2119
|
+
function applyTailwindRuntime(html, project, config, tailwind) {
|
|
2120
|
+
const enabled = tailwind === true || tailwind === "auto" && (config.usesTailwind ?? usesTailwindCSS(project.files));
|
|
2121
|
+
if (!enabled) return html;
|
|
2122
|
+
html = html.replace(
|
|
2123
|
+
/<style>([\s\S]*?)<\/style>/g,
|
|
2124
|
+
(match, css) => hasTailwindDirectives(css) ? `<style type="text/tailwindcss">${css}</style>` : match
|
|
2125
|
+
);
|
|
2126
|
+
let injection = `<script src="${TAILWIND_CDN_URL}"></script>`;
|
|
2127
|
+
const configObject = extractTailwindConfig(project.files);
|
|
2128
|
+
if (configObject) {
|
|
2129
|
+
injection += `
|
|
2130
|
+
<script>tailwind.config = ${configObject};</script>`;
|
|
2131
|
+
}
|
|
2132
|
+
return injectIntoHead(html, injection);
|
|
2133
|
+
}
|
|
2134
|
+
function extractTailwindConfig(files) {
|
|
2135
|
+
let source;
|
|
2136
|
+
for (const [path, content] of files) {
|
|
2137
|
+
if (/(?:^|\/)tailwind\.config\.(?:js|cjs|mjs|ts)$/.test(path)) {
|
|
2138
|
+
source = content;
|
|
2139
|
+
break;
|
|
2140
|
+
}
|
|
2141
|
+
}
|
|
2142
|
+
if (!source) return null;
|
|
2143
|
+
const object = extractBalancedObject(source);
|
|
2144
|
+
if (!object || !isSafeConfigObject(object)) return null;
|
|
2145
|
+
return object;
|
|
2146
|
+
}
|
|
2147
|
+
function extractBalancedObject(source) {
|
|
2148
|
+
const opener = source.match(/(?:export\s+default|module\.exports\s*=)\s*\{/);
|
|
2149
|
+
if (!opener || opener.index === void 0) return null;
|
|
2150
|
+
const start = opener.index + opener[0].length - 1;
|
|
2151
|
+
let depth = 0;
|
|
2152
|
+
let str = null;
|
|
2153
|
+
let lineComment = false;
|
|
2154
|
+
let blockComment = false;
|
|
2155
|
+
for (let i = start; i < source.length; i++) {
|
|
2156
|
+
const c = source[i];
|
|
2157
|
+
const n = source[i + 1];
|
|
2158
|
+
if (lineComment) {
|
|
2159
|
+
if (c === "\n") lineComment = false;
|
|
2160
|
+
continue;
|
|
2161
|
+
}
|
|
2162
|
+
if (blockComment) {
|
|
2163
|
+
if (c === "*" && n === "/") {
|
|
2164
|
+
blockComment = false;
|
|
2165
|
+
i++;
|
|
2166
|
+
}
|
|
2167
|
+
continue;
|
|
2168
|
+
}
|
|
2169
|
+
if (str) {
|
|
2170
|
+
if (c === "\\") {
|
|
2171
|
+
i++;
|
|
2172
|
+
continue;
|
|
2173
|
+
}
|
|
2174
|
+
if (c === str) str = null;
|
|
2175
|
+
continue;
|
|
2176
|
+
}
|
|
2177
|
+
if (c === "/" && n === "/") {
|
|
2178
|
+
lineComment = true;
|
|
2179
|
+
i++;
|
|
2180
|
+
continue;
|
|
2181
|
+
}
|
|
2182
|
+
if (c === "/" && n === "*") {
|
|
2183
|
+
blockComment = true;
|
|
2184
|
+
i++;
|
|
2185
|
+
continue;
|
|
2186
|
+
}
|
|
2187
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
2188
|
+
str = c;
|
|
2189
|
+
continue;
|
|
2190
|
+
}
|
|
2191
|
+
if (c === "{") depth++;
|
|
2192
|
+
else if (c === "}") {
|
|
2193
|
+
depth--;
|
|
2194
|
+
if (depth === 0) return source.slice(start, i + 1);
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
return null;
|
|
2198
|
+
}
|
|
2199
|
+
function isSafeConfigObject(object) {
|
|
2200
|
+
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));
|
|
2062
2201
|
}
|
|
2063
2202
|
function injectImportMetaEnv(files) {
|
|
2064
2203
|
const shim = `if(!import.meta.env){Object.defineProperty(import.meta,'env',{value:{MODE:'production',BASE_URL:'/',PROD:true,DEV:false,SSR:false}});}`;
|
|
@@ -2169,7 +2308,9 @@ var Diorama = class {
|
|
|
2169
2308
|
const { html: html2, usesESM: usesESM2 } = assembleHTML({
|
|
2170
2309
|
project,
|
|
2171
2310
|
config,
|
|
2172
|
-
transformedFiles: files
|
|
2311
|
+
transformedFiles: files,
|
|
2312
|
+
cdnProvider: this.options.cdnProvider,
|
|
2313
|
+
tailwind: options.tailwind ?? "auto"
|
|
2173
2314
|
});
|
|
2174
2315
|
return { html: html2, usesESM: usesESM2, repoName: repoName2 };
|
|
2175
2316
|
};
|