diorama-js 0.1.1 → 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/vue.cjs CHANGED
@@ -627,6 +627,7 @@ function analyzeProject(project, overrideType, overrideEntry) {
627
627
  hasBareImports: hasBareImports(files),
628
628
  isVite
629
629
  });
630
+ const usesTailwind = usesTailwindCSS(files);
630
631
  return {
631
632
  type,
632
633
  entryPoint: htmlEntry,
@@ -635,7 +636,8 @@ function analyzeProject(project, overrideType, overrideEntry) {
635
636
  hasJSX,
636
637
  hasTypeScript,
637
638
  jsEntryPoint: jsEntry,
638
- isVite
639
+ isVite,
640
+ usesTailwind
639
641
  };
640
642
  }
641
643
  function detectProjectType(input) {
@@ -657,6 +659,17 @@ function hasBareImports(files) {
657
659
  }
658
660
  return false;
659
661
  }
662
+ function usesTailwindCSS(files) {
663
+ for (const [path, content] of files) {
664
+ if (/(?:^|\/)tailwind\.config\.(?:js|cjs|mjs|ts)$/.test(path)) {
665
+ return true;
666
+ }
667
+ if (path.endsWith(".css") && /@tailwind\b|@apply\b/.test(content)) {
668
+ return true;
669
+ }
670
+ }
671
+ return false;
672
+ }
660
673
 
661
674
  // src/core/sandbox.ts
662
675
  function buildErrorHTML(message) {
@@ -1741,20 +1754,25 @@ var ASSET_IMPORT_EXTENSIONS = {
1741
1754
  ".otf": "font/otf"
1742
1755
  };
1743
1756
  function assembleHTML(options) {
1744
- const { project, config, transformedFiles, cdnProvider } = options;
1757
+ const { project, config, transformedFiles, cdnProvider, tailwind = "auto" } = options;
1745
1758
  const files = transformedFiles ?? project.files;
1759
+ let result;
1746
1760
  switch (config.type) {
1747
1761
  case "static":
1748
- return assembleStatic(files, project, config);
1762
+ result = assembleStatic(files, project, config);
1763
+ break;
1749
1764
  case "static-esm":
1750
1765
  case "jsx":
1751
1766
  case "typescript":
1752
1767
  case "jsx-typescript":
1753
1768
  case "vite":
1754
- return assembleESM(files, project, config, cdnProvider);
1769
+ result = assembleESM(files, project, config, cdnProvider);
1770
+ break;
1755
1771
  default:
1756
1772
  throw new AssemblyError(`Unsupported project type: ${config.type}`);
1757
1773
  }
1774
+ result.html = applyTailwindRuntime(result.html, project, config, tailwind);
1775
+ return result;
1758
1776
  }
1759
1777
  function assembleStatic(files, project, config) {
1760
1778
  let html = files.get(config.entryPoint);
@@ -2080,6 +2098,94 @@ ${css}`);
2080
2098
  }
2081
2099
  return { css: cssChunks.join("\n\n"), links };
2082
2100
  }
2101
+ var TAILWIND_DIRECTIVE_RE = /@tailwind\b|@apply\b/;
2102
+ var TAILWIND_CDN_URL = "https://cdn.tailwindcss.com";
2103
+ function hasTailwindDirectives(css) {
2104
+ return TAILWIND_DIRECTIVE_RE.test(css);
2105
+ }
2106
+ function applyTailwindRuntime(html, project, config, tailwind) {
2107
+ const enabled = tailwind === true || tailwind === "auto" && (config.usesTailwind ?? usesTailwindCSS(project.files));
2108
+ if (!enabled) return html;
2109
+ html = html.replace(
2110
+ /<style>([\s\S]*?)<\/style>/g,
2111
+ (match, css) => hasTailwindDirectives(css) ? `<style type="text/tailwindcss">${css}</style>` : match
2112
+ );
2113
+ let injection = `<script src="${TAILWIND_CDN_URL}"></script>`;
2114
+ const configObject = extractTailwindConfig(project.files);
2115
+ if (configObject) {
2116
+ injection += `
2117
+ <script>tailwind.config = ${configObject};</script>`;
2118
+ }
2119
+ return injectIntoHead(html, injection);
2120
+ }
2121
+ function extractTailwindConfig(files) {
2122
+ let source;
2123
+ for (const [path, content] of files) {
2124
+ if (/(?:^|\/)tailwind\.config\.(?:js|cjs|mjs|ts)$/.test(path)) {
2125
+ source = content;
2126
+ break;
2127
+ }
2128
+ }
2129
+ if (!source) return null;
2130
+ const object = extractBalancedObject(source);
2131
+ if (!object || !isSafeConfigObject(object)) return null;
2132
+ return object;
2133
+ }
2134
+ function extractBalancedObject(source) {
2135
+ const opener = source.match(/(?:export\s+default|module\.exports\s*=)\s*\{/);
2136
+ if (!opener || opener.index === void 0) return null;
2137
+ const start = opener.index + opener[0].length - 1;
2138
+ let depth = 0;
2139
+ let str = null;
2140
+ let lineComment = false;
2141
+ let blockComment = false;
2142
+ for (let i = start; i < source.length; i++) {
2143
+ const c = source[i];
2144
+ const n = source[i + 1];
2145
+ if (lineComment) {
2146
+ if (c === "\n") lineComment = false;
2147
+ continue;
2148
+ }
2149
+ if (blockComment) {
2150
+ if (c === "*" && n === "/") {
2151
+ blockComment = false;
2152
+ i++;
2153
+ }
2154
+ continue;
2155
+ }
2156
+ if (str) {
2157
+ if (c === "\\") {
2158
+ i++;
2159
+ continue;
2160
+ }
2161
+ if (c === str) str = null;
2162
+ continue;
2163
+ }
2164
+ if (c === "/" && n === "/") {
2165
+ lineComment = true;
2166
+ i++;
2167
+ continue;
2168
+ }
2169
+ if (c === "/" && n === "*") {
2170
+ blockComment = true;
2171
+ i++;
2172
+ continue;
2173
+ }
2174
+ if (c === '"' || c === "'" || c === "`") {
2175
+ str = c;
2176
+ continue;
2177
+ }
2178
+ if (c === "{") depth++;
2179
+ else if (c === "}") {
2180
+ depth--;
2181
+ if (depth === 0) return source.slice(start, i + 1);
2182
+ }
2183
+ }
2184
+ return null;
2185
+ }
2186
+ function isSafeConfigObject(object) {
2187
+ 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));
2188
+ }
2083
2189
  function injectImportMetaEnv(files) {
2084
2190
  const shim = `if(!import.meta.env){Object.defineProperty(import.meta,'env',{value:{MODE:'production',BASE_URL:'/',PROD:true,DEV:false,SSR:false}});}`;
2085
2191
  for (const [path, content] of files) {
@@ -2190,7 +2296,8 @@ var Diorama = class {
2190
2296
  project,
2191
2297
  config,
2192
2298
  transformedFiles: files,
2193
- cdnProvider: this.options.cdnProvider
2299
+ cdnProvider: this.options.cdnProvider,
2300
+ tailwind: options.tailwind ?? "auto"
2194
2301
  });
2195
2302
  return { html: html2, usesESM: usesESM2, repoName: repoName2 };
2196
2303
  };
@@ -2304,6 +2411,7 @@ var dioramaProps = {
2304
2411
  height: { type: String, default: "500px" },
2305
2412
  frame: { type: String, default: "none" },
2306
2413
  expand: { type: Boolean, default: false },
2414
+ tailwind: { type: [String, Boolean], default: "auto" },
2307
2415
  options: { type: Object, default: void 0 }
2308
2416
  };
2309
2417
  var DioramaPreview = vue.defineComponent({
@@ -2328,6 +2436,7 @@ var DioramaPreview = vue.defineComponent({
2328
2436
  height: props.height,
2329
2437
  frame: props.frame,
2330
2438
  expand: props.expand,
2439
+ tailwind: props.tailwind,
2331
2440
  onLoad: () => emit("load"),
2332
2441
  onError: (err) => emit("error", err)
2333
2442
  });
@@ -2343,7 +2452,7 @@ var DioramaPreview = vue.defineComponent({
2343
2452
  instance = null;
2344
2453
  });
2345
2454
  vue.watch(
2346
- () => [props.repo, props.branch, props.subdirectory, props.loading, props.height, props.frame, props.expand],
2455
+ () => [props.repo, props.branch, props.subdirectory, props.loading, props.height, props.frame, props.expand, props.tailwind],
2347
2456
  () => {
2348
2457
  renderProject();
2349
2458
  }