vite-plugin-shopify-easel 0.2.0 → 0.2.2

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/README.md CHANGED
@@ -1,35 +1,38 @@
1
1
  # Easel
2
2
 
3
- Easel is an independent Vite toolkit for Shopify Liquid themes.
3
+ Easel is an independent Vite plugin and theme generator for Shopify Liquid themes.
4
4
 
5
- It builds JavaScript, TypeScript, and CSS into Shopify theme assets, generates the Liquid snippet that loads them, and safely replaces old build output. During development, it can coordinate Vite updates with Shopify CLI reloads. Shopify CLI still handles previews, syncing, and deployment.
5
+ It builds JavaScript, TypeScript, and CSS into Shopify theme assets, generates the Liquid that loads them, and safely replaces only output it owns. Shopify CLI remains responsible for authentication, previews, synchronization, and deployment.
6
6
 
7
- [Read the documentation](https://easel.billynoyes.co.uk/docs/)
7
+ [Create a theme](#create-a-new-theme) · [Add Easel to a theme](#add-easel-to-an-existing-theme) · [Choosing Easel](https://easel.billynoyes.co.uk/docs/#choosing-easel) · [Documentation](https://easel.billynoyes.co.uk/docs/) · [Examples](#examples)
8
8
 
9
- ## Install
9
+ ## Create a new theme
10
10
 
11
11
  ```sh
12
- pnpm add -D vite-plugin-shopify-easel vite
12
+ npm create easel-theme@latest my-theme
13
13
  ```
14
14
 
15
- Easel requires Node.js 22.12 or newer and supports Vite 7 and 8.
15
+ [`create-easel-theme`](packages/create-easel) scaffolds TypeScript or JavaScript, optional Alpine, React or Vue, and plain CSS or Tailwind CSS. It includes generic Online Store 2.0 JSON templates for the standard storefront page types while leaving current customer accounts to Shopify.
16
16
 
17
- ## Create a theme
17
+ Use `.` instead of `my-theme` to scaffold into an empty current directory. Use `--yes --no-install` for non-interactive automation. Existing files are never overwritten. Generated projects include `npm run check:theme` for Shopify Theme Check and `npm run check:all` for source, build, and Liquid validation.
18
18
 
19
- The [Clack-based scaffolder, `create-easel-theme`](packages/create-easel) creates a theme with TypeScript or JavaScript, optional Alpine, React or Vue, and plain CSS or Tailwind. It includes generic templates for the standard storefront page types while leaving current customer accounts to Shopify.
19
+ ## Why Easel
20
20
 
21
- ```sh
22
- npm create easel-theme@latest my-theme
23
- ```
21
+ - **Vite-native:** use normal Vite plugins, configuration, dynamic imports, HMR, and production builds.
22
+ - **Shopify-native:** keep the standard Liquid theme structure and use Shopify CLI directly for store operations.
23
+ - **Safe publication:** stage output, track ownership, reject unsafe overwrites, and roll back interrupted commits.
24
+ - **Selective loading:** start with one shared entry and add named script, style, or CSS-only bundles when needed.
25
+ - **Framework optional:** use vanilla TypeScript, Alpine, React, Vue, Tailwind CSS, Sass, or PostCSS through their standard Vite integrations.
24
26
 
25
- From a checkout of this repository:
27
+ ## Add Easel to an existing theme
26
28
 
27
29
  ```sh
28
- pnpm install
29
- pnpm create:theme ../my-theme
30
+ pnpm add -D vite-plugin-shopify-easel vite
30
31
  ```
31
32
 
32
- Use `--yes --no-install` for a non-interactive starter. The CLI also accepts `.` to use the current folder; see [current-directory setup](packages/create-easel#use-the-current-directory) for running it from outside this checkout. Existing folders must be empty apart from Git or Finder metadata. Shopify CLI remains separate.
33
+ Easel requires Node.js 22.12 or newer and supports Vite 7 and 8.
34
+
35
+ From a checkout of this repository, run `pnpm install` and `pnpm create:theme ../my-theme` to exercise the local generator. Shopify CLI is installed and authenticated separately.
33
36
 
34
37
  ## Start
35
38
 
@@ -59,7 +62,7 @@ export default defineConfig({
59
62
  });
60
63
  ```
61
64
 
62
- Render the generated loader in `layout/theme.liquid`.
65
+ Render the generated loader inside `<head>` in `layout/theme.liquid`.
63
66
 
64
67
  ```liquid
65
68
  {% render 'easel-assets' %}
@@ -92,6 +95,10 @@ npm run build
92
95
  shopify theme push
93
96
  ```
94
97
 
98
+ Shopify automatically preloads render-blocking stylesheets in `<head>` through `Link` headers, so the generated stylesheet tags don't need `preload: true`.
99
+
100
+ Because generated output is ignored by Git, anything that deploys straight from the repository, such as the Shopify GitHub integration, gets no loader or assets. Build in CI and deploy with Shopify CLI, or commit the generated output on the branch Shopify deploys. Run Theme Check after the build, since layouts that render `easel-assets` report `MissingTemplate` until it exists.
101
+
95
102
  ## Named bundles
96
103
 
97
104
  Load only the code each Liquid surface needs.
@@ -172,6 +179,10 @@ Shopify CLI remains responsible for authentication, previews, synchronization, p
172
179
 
173
180
  Each example includes Shopify Theme Editor lifecycle handling and automated build checks.
174
181
 
182
+ ## Support and security
183
+
184
+ Use the [documentation](https://easel.billynoyes.co.uk/docs/) for setup and troubleshooting, [open an issue](https://github.com/BillyNoyes/Easel/issues) for reproducible bugs and focused feature requests, and use [private vulnerability reporting](https://github.com/BillyNoyes/Easel/security/advisories/new) for security concerns. See [CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request.
185
+
175
186
  ## License
176
187
 
177
188
  MIT
package/dist/index.js CHANGED
@@ -74,7 +74,7 @@ function renderProductionLiquid(manifest) {
74
74
  }
75
75
  if (entry.script !== void 0) {
76
76
  lines.push(
77
- ` <script src="{{ ${liquidAssetLiteral(entry.script, "entry script", ".js")} | asset_url }}" type="module" defer></script>`
77
+ ` <script src="{{ ${liquidAssetLiteral(entry.script, "entry script", ".js")} | asset_url }}" type="module"></script>`
78
78
  );
79
79
  }
80
80
  }
@@ -1097,6 +1097,7 @@ function configureDevelopmentServer(server, options) {
1097
1097
  assertDevelopmentLiquidWritable(options);
1098
1098
  const stopWatching = configureRefresh(server, options);
1099
1099
  let restoreDevelopmentLiquid2;
1100
+ let detachTerminationHandlers;
1100
1101
  server.httpServer.once("listening", () => {
1101
1102
  restoreDevelopmentLiquid2 = writeDevelopmentLiquid(
1102
1103
  options,
@@ -1105,12 +1106,48 @@ function configureDevelopmentServer(server, options) {
1105
1106
  developmentOrigin(server)
1106
1107
  )
1107
1108
  );
1109
+ detachTerminationHandlers = restoreOnTermination(restoreDevelopmentLiquid2);
1108
1110
  });
1109
1111
  server.httpServer.once("close", () => {
1110
1112
  stopWatching?.();
1113
+ detachTerminationHandlers?.();
1111
1114
  restoreDevelopmentLiquid2?.();
1112
1115
  });
1113
1116
  }
1117
+ var TERMINATION_SIGNALS = ["SIGINT", "SIGHUP"];
1118
+ function signalExitListenerCount() {
1119
+ const current = globalThis[/* @__PURE__ */ Symbol.for("signal-exit emitter")];
1120
+ const legacy = process.__signal_exit_emitter__;
1121
+ return emitterCount(current) + emitterCount(legacy);
1122
+ }
1123
+ function emitterCount(emitter) {
1124
+ if (typeof emitter !== "object" || emitter === null) return 0;
1125
+ const { count } = emitter;
1126
+ return typeof count === "number" ? count : 0;
1127
+ }
1128
+ function restoreOnTermination(restore, target = process, passiveListenerCount = signalExitListenerCount) {
1129
+ let restored = false;
1130
+ const restoreOnce = () => {
1131
+ if (restored) return;
1132
+ restored = true;
1133
+ restore();
1134
+ };
1135
+ const onExit = () => restoreOnce();
1136
+ const onSignal = (signal) => {
1137
+ restoreOnce();
1138
+ detach();
1139
+ if (target.listenerCount(signal) <= passiveListenerCount()) {
1140
+ target.kill(target.pid, signal);
1141
+ }
1142
+ };
1143
+ const detach = () => {
1144
+ target.off("exit", onExit);
1145
+ for (const signal of TERMINATION_SIGNALS) target.off(signal, onSignal);
1146
+ };
1147
+ target.on("exit", onExit);
1148
+ for (const signal of TERMINATION_SIGNALS) target.on(signal, onSignal);
1149
+ return detach;
1150
+ }
1114
1151
  function configureRefresh(server, options) {
1115
1152
  if (!options.refresh.enabled) return void 0;
1116
1153
  const stopWatching = watchRefreshSignal(
@@ -1179,7 +1216,7 @@ function createViteConfig(config, options, command) {
1179
1216
  input,
1180
1217
  output: {
1181
1218
  entryFileNames: `${options.prefix}[name].js`,
1182
- chunkFileNames: `${options.prefix}[name]-[hash].js`,
1219
+ chunkFileNames: (chunk) => `${options.prefix}${sharedChunkName(chunk)}-[hash].js`,
1183
1220
  assetFileNames(asset) {
1184
1221
  const original = asset.names[0] ?? asset.name ?? "asset";
1185
1222
  if (!original.endsWith(".css")) {
@@ -1198,6 +1235,22 @@ function createViteConfig(config, options, command) {
1198
1235
  }
1199
1236
  };
1200
1237
  }
1238
+ var STYLESHEET_MODULE = /\.(?:css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:\?|$)/;
1239
+ function sharedChunkName(chunk) {
1240
+ const namedAfterStylesheet = chunk.moduleIds.some(
1241
+ (id) => STYLESHEET_MODULE.test(id) && moduleBasename(id) === chunk.name
1242
+ );
1243
+ if (!namedAfterStylesheet) return "[name]";
1244
+ const script = chunk.moduleIds.filter((id) => !id.startsWith("\0") && !STYLESHEET_MODULE.test(id)).at(-1);
1245
+ const name = script === void 0 ? "" : moduleBasename(script);
1246
+ return /^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(name) ? name : "[name]";
1247
+ }
1248
+ function moduleBasename(id) {
1249
+ const path = id.replaceAll("\\", "/").split("?")[0] ?? "";
1250
+ const file = path.slice(path.lastIndexOf("/") + 1);
1251
+ const extension = file.lastIndexOf(".");
1252
+ return extension > 0 ? file.slice(0, extension) : file;
1253
+ }
1201
1254
  function isEntryStylesheet(originalFileNames, stableCssEntryIds) {
1202
1255
  return originalFileNames.some((file) => {
1203
1256
  const normalized = file.replaceAll("\\", "/");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/build.ts","../src/validation.ts","../src/virtual.ts","../src/liquid.ts","../src/manifest.ts","../src/output.ts","../src/lock.ts","../src/ownership.ts","../src/transaction.ts","../src/options.ts","../src/refresh.ts","../src/development.ts","../src/vite-config.ts","../src/plugin.ts"],"sourcesContent":["import {existsSync, readFileSync, readdirSync, rmSync} from 'node:fs';\nimport {join} from 'node:path';\nimport type {Manifest, ResolvedConfig} from 'vite';\nimport {renderProductionLiquid} from './liquid.js';\nimport {createEaselManifest} from './manifest.js';\nimport {commitProductionOutput} from './output.js';\nimport type {ResolvedEaselOptions} from './types.js';\n\nexport function finalizeProductionBuild(\n options: ResolvedEaselOptions,\n config: ResolvedConfig,\n publish: boolean,\n): void {\n try {\n if (!publish) return;\n const viteManifest = readViteManifest(options.stagingPath);\n const manifest = createEaselManifest(\n viteManifest,\n options.bundles,\n listEmittedFiles(options.stagingPath),\n );\n commitProductionOutput(options, manifest, renderProductionLiquid(manifest));\n } finally {\n removeStagingDirectory(options.stagingPath, config);\n }\n}\n\nfunction readViteManifest(stagingPath: string): Manifest {\n const path = join(stagingPath, '.vite', 'manifest.json');\n if (!existsSync(path)) {\n throw new Error(`[easel] Vite did not write its build manifest: ${path}`);\n }\n try {\n return JSON.parse(readFileSync(path, 'utf8')) as Manifest;\n } catch (error) {\n throw new Error(`[easel] Vite wrote an invalid build manifest: ${path}`, {\n cause: error,\n });\n }\n}\n\nfunction removeStagingDirectory(stagingPath: string, config: ResolvedConfig): void {\n try {\n rmSync(stagingPath, {recursive: true, force: true});\n } catch (error) {\n config.logger.warn(\n `[easel] could not remove staging directory ${stagingPath}: ${errorMessage(error)}`,\n );\n }\n}\n\nfunction listEmittedFiles(stagingPath: string): string[] {\n const files: string[] = [];\n for (const entry of readdirSync(stagingPath, {withFileTypes: true})) {\n if (entry.name === '.vite' && entry.isDirectory()) continue;\n if (!entry.isFile()) {\n throw new Error(`[easel] unexpected output in staging directory: ${entry.name}`);\n }\n files.push(entry.name);\n }\n return files;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","export const SAFE_OUTPUT_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nexport const SAFE_ASSET_FILENAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;\nexport const SAFE_LIQUID_FILENAME = /^[a-z0-9][a-z0-9_-]*\\.liquid$/;\n","import type {Plugin} from 'vite';\nimport type {ResolvedEaselBundle} from './types.js';\n\nconst INTERNAL_PREFIX = '\\0easel:';\nexport const PUBLIC_PREFIX = '/@easel/';\n\nexport function virtualBundleId(name: string): string {\n return `${INTERNAL_PREFIX}${name}`;\n}\n\nexport function easelBundleModules(getBundles: () => ResolvedEaselBundle[]): Plugin {\n return {\n name: 'easel:bundle-modules',\n enforce: 'pre',\n resolveId(id) {\n const bundles = getBundles();\n if (id.startsWith(PUBLIC_PREFIX)) {\n const name = id.slice(PUBLIC_PREFIX.length);\n if (bundles.some((bundle) => bundle.name === name)) {\n return virtualBundleId(name);\n }\n }\n if (id.startsWith(INTERNAL_PREFIX)) return id;\n\n const normalizedId = normalizeModulePath(id);\n const isBundleInput = bundles\n .flatMap(bundleInputs)\n .some((path) => normalizeModulePath(path) === normalizedId);\n // Bundle inputs are storefront entry points even when their exports are unused.\n return isBundleInput ? {id: normalizedId, moduleSideEffects: true} : undefined;\n },\n load(id) {\n if (!id.startsWith(INTERNAL_PREFIX)) return undefined;\n const name = id.slice(INTERNAL_PREFIX.length);\n const bundle = getBundles().find((candidate) => candidate.name === name);\n if (bundle === undefined) {\n throw new Error(`[easel] unknown virtual bundle \"${name}\"`);\n }\n\n return `${bundleInputs(bundle)\n .map((path) => `import ${JSON.stringify(path)};`)\n .join('\\n')}\\n`;\n },\n };\n}\n\nfunction bundleInputs(bundle: ResolvedEaselBundle): string[] {\n return [bundle.script, bundle.style].filter(\n (path): path is string => path !== undefined,\n );\n}\n\nfunction normalizeModulePath(path: string): string {\n return path.replaceAll('\\\\', '/');\n}\n","import type {EaselManifest, EaselManifestEntry} from './types.js';\nimport {SAFE_ASSET_FILENAME, SAFE_OUTPUT_NAME} from './validation.js';\nimport {PUBLIC_PREFIX} from './virtual.js';\n\nconst MAX_LIQUID_BYTES = 200_000;\n\nexport function renderProductionLiquid(manifest: EaselManifest): string {\n const entries = validatedManifestEntries(manifest);\n const defaultEntry = entries[0]?.[0];\n if (defaultEntry === undefined) {\n throw new Error('[easel] cannot render Liquid without an entry');\n }\n\n const lines = loaderHeader('Generated asset loader managed by Easel.', defaultEntry);\n\n for (const [name, entry] of entries) {\n lines.push(` {% when ${liquidEntryLiteral(name)} %}`);\n for (const style of entry.styles) {\n lines.push(\n ` {{ ${liquidAssetLiteral(style, 'stylesheet', '.css')} | asset_url | stylesheet_tag }}`,\n );\n }\n for (const imported of entry.imports) {\n lines.push(\n ` <link rel=\"modulepreload\" href=\"{{ ${liquidAssetLiteral(imported, 'module import', '.js')} | asset_url }}\">`,\n );\n }\n if (entry.script !== undefined) {\n lines.push(\n ` <script src=\"{{ ${liquidAssetLiteral(entry.script, 'entry script', '.js')} | asset_url }}\" type=\"module\" defer></script>`,\n );\n }\n }\n\n return finishLoader(lines);\n}\n\nexport function renderDevelopmentLiquid(names: string[], origin: string): string {\n const entries = validatedEntryNames(names);\n const defaultEntry = entries[0];\n if (defaultEntry === undefined) {\n throw new Error('[easel] cannot render Liquid without an entry');\n }\n\n const safeOrigin = normalizeOrigin(origin);\n const lines = loaderHeader(\n 'Generated development asset loader managed by Easel.',\n defaultEntry,\n [`<script src=\"${safeOrigin}/@vite/client\" type=\"module\"></script>`],\n );\n\n for (const name of entries) {\n lines.push(` {% when ${liquidEntryLiteral(name)} %}`);\n lines.push(\n ` <script src=\"${safeOrigin}${PUBLIC_PREFIX}${encodeURIComponent(name)}\" type=\"module\"></script>`,\n );\n }\n\n return finishLoader(lines);\n}\n\nfunction loaderHeader(\n description: string,\n defaultEntry: string,\n preamble: string[] = [],\n): string[] {\n return [\n '{% doc %}',\n description,\n '@param {string} [entry] - Named Easel bundle to render.',\n '{% enddoc %}',\n '{% liquid',\n ` assign easel_entry = entry | default: ${liquidEntryLiteral(defaultEntry)}`,\n '%}',\n ...preamble,\n '{% case easel_entry %}',\n ];\n}\n\nfunction finishLoader(lines: string[]): string {\n lines.push(\n ' {% else %}',\n ' <!-- [easel] Unknown bundle \"{{ easel_entry | escape }}\". -->',\n '{% endcase %}',\n '',\n );\n return assertLiquidSize(lines.join('\\n'));\n}\n\nfunction validatedManifestEntries(\n manifest: EaselManifest,\n): [string, EaselManifestEntry][] {\n if (manifest.schemaVersion !== 1) {\n throw new Error(\n `[easel] unsupported manifest schema version: ${JSON.stringify(manifest.schemaVersion)}`,\n );\n }\n const entries = Object.entries(manifest.entries);\n validatedEntryNames(entries.map(([name]) => name));\n return entries;\n}\n\nfunction validatedEntryNames(names: string[]): string[] {\n const seen = new Set<string>();\n for (const name of names) {\n if (!SAFE_OUTPUT_NAME.test(name)) {\n throw new Error(`[easel] cannot render unsafe Liquid bundle name: ${name}`);\n }\n if (seen.has(name)) {\n throw new Error(`[easel] cannot render duplicate Liquid bundle name: ${name}`);\n }\n seen.add(name);\n }\n return names;\n}\n\nfunction liquidEntryLiteral(name: string): string {\n if (!SAFE_OUTPUT_NAME.test(name)) {\n throw new Error(`[easel] cannot render unsafe Liquid bundle name: ${name}`);\n }\n return `'${name}'`;\n}\n\nfunction liquidAssetLiteral(\n filename: string,\n role: string,\n extension: '.css' | '.js',\n): string {\n if (!SAFE_ASSET_FILENAME.test(filename) || !filename.endsWith(extension)) {\n throw new Error(`[easel] cannot render unsafe ${role} filename: ${filename}`);\n }\n return `'${filename}'`;\n}\n\nfunction normalizeOrigin(origin: string): string {\n let url: URL;\n try {\n url = new URL(origin);\n } catch {\n throw new Error(`[easel] invalid Vite development origin: ${origin}`);\n }\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n throw new Error(`[easel] Vite development origin must use HTTP or HTTPS: ${origin}`);\n }\n if (\n url.username !== '' ||\n url.password !== '' ||\n url.pathname !== '/' ||\n url.search !== '' ||\n url.hash !== ''\n ) {\n throw new Error(\n `[easel] Vite development origin cannot contain credentials, a path, a query, or a fragment: ${origin}`,\n );\n }\n return url.origin;\n}\n\nfunction assertLiquidSize(content: string): string {\n const size = Buffer.byteLength(content);\n if (size > MAX_LIQUID_BYTES) {\n throw new Error(\n `[easel] generated Liquid is ${size} bytes; reduce the number of bundles below ${MAX_LIQUID_BYTES} bytes`,\n );\n }\n return content;\n}\n","import type {Manifest, ManifestChunk} from 'vite';\nimport type {EaselManifest, EaselManifestEntry, ResolvedEaselBundle} from './types.js';\n\nexport function createEaselManifest(\n viteManifest: Manifest,\n bundles: ResolvedEaselBundle[],\n emittedFiles: string[] = [],\n): EaselManifest {\n const entries: Record<string, EaselManifestEntry> = {};\n const generated = new Set(emittedFiles);\n\n for (const bundle of bundles) {\n const chunk = findEntry(viteManifest, bundle.name);\n const {styles, imports} = collectStaticDependencies(viteManifest, chunk);\n\n if (bundle.script === undefined) {\n generated.delete(chunk.file);\n } else {\n generated.add(chunk.file);\n }\n for (const style of styles) generated.add(style);\n for (const imported of imports) generated.add(imported);\n collectGeneratedFiles(viteManifest, chunk, generated);\n\n entries[bundle.name] = {\n ...(bundle.script === undefined ? {} : {script: chunk.file}),\n styles,\n imports,\n };\n }\n\n return {\n schemaVersion: 1,\n entries,\n generated: [...generated].sort(),\n };\n}\n\nfunction findEntry(manifest: Manifest, name: string): ManifestChunk {\n const chunk = Object.values(manifest).find(\n (candidate) => candidate.isEntry === true && candidate.name === name,\n );\n if (chunk === undefined) {\n throw new Error(`[easel] Vite manifest does not contain bundle \"${name}\"`);\n }\n return chunk;\n}\n\nfunction collectStaticDependencies(\n manifest: Manifest,\n entry: ManifestChunk,\n): {styles: string[]; imports: string[]} {\n const styles = new Set<string>();\n const imports = new Set<string>();\n const visited = new Set<string>();\n\n const visit = (chunk: ManifestChunk): void => {\n for (const key of chunk.imports ?? []) {\n if (visited.has(key)) continue;\n visited.add(key);\n const imported = requiredChunk(manifest, key);\n imports.add(imported.file);\n visit(imported);\n }\n for (const style of chunk.css ?? []) styles.add(style);\n };\n\n visit(entry);\n return {styles: [...styles], imports: [...imports]};\n}\n\nfunction collectGeneratedFiles(\n manifest: Manifest,\n entry: ManifestChunk,\n files: Set<string>,\n): void {\n const visited = new Set<string>();\n\n const visit = (chunk: ManifestChunk): void => {\n for (const asset of chunk.assets ?? []) files.add(asset);\n for (const style of chunk.css ?? []) files.add(style);\n for (const key of [...(chunk.imports ?? []), ...(chunk.dynamicImports ?? [])]) {\n if (visited.has(key)) continue;\n visited.add(key);\n const imported = requiredChunk(manifest, key);\n files.add(imported.file);\n visit(imported);\n }\n };\n\n visit(entry);\n}\n\nfunction requiredChunk(manifest: Manifest, key: string): ManifestChunk {\n const chunk = manifest[key];\n if (chunk === undefined) {\n throw new Error(`[easel] Vite manifest import is missing: ${key}`);\n }\n return chunk;\n}\n","import {existsSync, readFileSync, rmSync} from 'node:fs';\nimport {dirname, join} from 'node:path';\nimport {acquireCommitLock} from './lock.js';\nimport {\n assertAssetWritable,\n assertLiquidWritable,\n isDevelopmentLiquid,\n isGeneratedLiquid,\n ownedAssetPath,\n ownedLiquidPath,\n readOwnershipLedger,\n} from './ownership.js';\nimport {\n recoverInterruptedCommit,\n runFileTransaction,\n safeResolve,\n writeIfChanged,\n} from './transaction.js';\nimport type {EaselManifest, EaselOwnershipLedger, ResolvedEaselOptions} from './types.js';\n\ninterface PreparedAsset {\n relativePath: string;\n destinationPath: string;\n content: Buffer;\n}\n\nexport function commitProductionOutput(\n options: ResolvedEaselOptions,\n manifest: EaselManifest,\n liquid: string,\n): void {\n const releaseLock = acquireCommitLock(options.commitLockPath);\n try {\n recoverInterruptedCommit(options);\n migrateLegacyProductionBackup(options);\n\n const previous = readOwnershipLedger(options);\n const previousFiles = new Set(previous?.generated ?? []);\n const assets = prepareAssets(options, manifest.generated);\n const nextFiles = new Set([\n ...assets.map((asset) => asset.relativePath),\n ownedLiquidPath(options),\n ]);\n\n assertProductionOutputWritable(options, assets, previousFiles);\n const stalePaths = [...previousFiles]\n .filter((file) => !nextFiles.has(file))\n .map((file) => safeResolve(options.themePath, file));\n\n runFileTransaction(options, changedOutputPaths(options, assets, stalePaths), () =>\n publishProductionOutput(options, manifest, liquid, assets, stalePaths, nextFiles),\n );\n } finally {\n releaseLock();\n }\n}\n\nexport function assertDevelopmentLiquidWritable(options: ResolvedEaselOptions): void {\n migrateLegacyProductionBackup(options);\n const previous = readOwnershipLedger(options);\n assertLiquidWritable(\n options.liquidPath,\n ownedLiquidPath(options),\n new Set(previous?.generated ?? []),\n );\n}\n\nexport function writeDevelopmentLiquid(\n options: ResolvedEaselOptions,\n content: string,\n): () => void {\n assertDevelopmentLiquidWritable(options);\n const currentContent = readOptionalFile(options.liquidPath);\n preserveProductionLiquid(options, currentContent);\n const productionContent =\n currentContent !== undefined && isDevelopmentLiquid(currentContent.toString())\n ? readProductionLiquidBackup(options)\n : currentContent;\n writeIfChanged(options.liquidPath, content);\n\n return () => restoreDevelopmentLiquid(options.liquidPath, content, productionContent);\n}\n\nfunction prepareAssets(\n options: ResolvedEaselOptions,\n generatedFiles: string[],\n): PreparedAsset[] {\n return generatedFiles.map((file) => {\n const sourcePath = safeResolve(options.stagingPath, file);\n if (!existsSync(sourcePath)) {\n throw new Error(`[easel] generated Vite asset is missing: ${sourcePath}`);\n }\n return {\n relativePath: ownedAssetPath(options, file),\n destinationPath: safeResolve(join(options.themePath, 'assets'), file),\n content: readFileSync(sourcePath),\n };\n });\n}\n\nfunction assertProductionOutputWritable(\n options: ResolvedEaselOptions,\n assets: PreparedAsset[],\n previousFiles: Set<string>,\n): void {\n for (const asset of assets) {\n assertAssetWritable(\n asset.destinationPath,\n asset.relativePath,\n asset.content,\n previousFiles,\n );\n }\n assertLiquidWritable(options.liquidPath, ownedLiquidPath(options), previousFiles);\n}\n\nfunction changedOutputPaths(\n options: ResolvedEaselOptions,\n assets: PreparedAsset[],\n stalePaths: string[],\n): string[] {\n return [\n ...assets.map((asset) => asset.destinationPath),\n options.liquidPath,\n options.productionLiquidPath,\n options.manifestPath,\n ...stalePaths,\n options.ledgerPath,\n ];\n}\n\nfunction publishProductionOutput(\n options: ResolvedEaselOptions,\n manifest: EaselManifest,\n liquid: string,\n assets: PreparedAsset[],\n stalePaths: string[],\n nextFiles: Set<string>,\n): void {\n for (const asset of assets) {\n writeIfChanged(asset.destinationPath, asset.content);\n }\n writeIfChanged(options.liquidPath, liquid);\n writeIfChanged(options.productionLiquidPath, liquid);\n writeIfChanged(options.manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`);\n\n for (const stale of stalePaths) {\n if (existsSync(stale)) rmSync(stale);\n }\n\n const ledger: EaselOwnershipLedger = {\n schemaVersion: 2,\n themePath: options.themePath,\n prefix: options.prefix,\n liquidFilename: options.liquidFilename,\n generated: [...nextFiles].sort(),\n };\n writeIfChanged(options.ledgerPath, `${JSON.stringify(ledger, null, 2)}\\n`);\n}\n\nfunction preserveProductionLiquid(\n options: ResolvedEaselOptions,\n currentContent: Buffer | undefined,\n): void {\n if (\n currentContent !== undefined &&\n isGeneratedLiquid(currentContent.toString()) &&\n !isDevelopmentLiquid(currentContent.toString())\n ) {\n writeIfChanged(options.productionLiquidPath, currentContent);\n } else if (currentContent === undefined && existsSync(options.productionLiquidPath)) {\n rmSync(options.productionLiquidPath);\n }\n}\n\nfunction restoreDevelopmentLiquid(\n liquidPath: string,\n developmentContent: string,\n productionContent: Buffer | undefined,\n): void {\n if (!existsSync(liquidPath)) return;\n if (readFileSync(liquidPath, 'utf8') !== developmentContent) return;\n if (productionContent === undefined) {\n rmSync(liquidPath);\n } else {\n writeIfChanged(liquidPath, productionContent);\n }\n}\n\nfunction migrateLegacyProductionBackup(options: ResolvedEaselOptions): void {\n const legacyPath = join(dirname(options.productionLiquidPath), 'production.liquid');\n if (!existsSync(legacyPath)) return;\n\n const legacyContent = readFileSync(legacyPath);\n if (!isGeneratedLiquid(legacyContent.toString())) {\n throw new Error(\n `[easel] legacy production backup is not generated by Easel: ${legacyPath}`,\n );\n }\n if (!existsSync(options.productionLiquidPath)) {\n writeIfChanged(options.productionLiquidPath, legacyContent);\n }\n rmSync(legacyPath);\n}\n\nfunction readProductionLiquidBackup(options: ResolvedEaselOptions): Buffer | undefined {\n const content = readOptionalFile(options.productionLiquidPath);\n return content !== undefined &&\n isGeneratedLiquid(content.toString()) &&\n !isDevelopmentLiquid(content.toString())\n ? content\n : undefined;\n}\n\nfunction readOptionalFile(path: string): Buffer | undefined {\n return existsSync(path) ? readFileSync(path) : undefined;\n}\n","import {randomUUID} from 'node:crypto';\nimport {\n lstatSync,\n mkdirSync,\n readFileSync,\n rmSync,\n statSync,\n writeFileSync,\n} from 'node:fs';\nimport {dirname, join} from 'node:path';\n\ninterface LockOwner {\n pid: number;\n token: string;\n}\n\nexport function acquireCommitLock(lockPath: string): () => void {\n mkdirSync(dirname(lockPath), {recursive: true});\n const token = randomUUID();\n\n for (let attempt = 0; attempt < 2; attempt += 1) {\n try {\n createLock(lockPath, token);\n return () => releaseLock(lockPath, token);\n } catch (error) {\n if (!isAlreadyExistsError(error)) throw error;\n if (!isStaleLock(lockPath)) {\n throw new Error(`[easel] another build is publishing this theme: ${lockPath}`);\n }\n rmSync(lockPath, {recursive: true});\n }\n }\n\n throw new Error(`[easel] could not acquire the theme commit lock: ${lockPath}`);\n}\n\nfunction createLock(lockPath: string, token: string): void {\n mkdirSync(lockPath);\n try {\n writeFileSync(\n join(lockPath, 'owner.json'),\n `${JSON.stringify({pid: process.pid, token})}\\n`,\n );\n } catch (error) {\n rmSync(lockPath, {recursive: true});\n throw error;\n }\n}\n\nfunction releaseLock(lockPath: string, token: string): void {\n if (readLockOwner(lockPath)?.token === token) {\n rmSync(lockPath, {recursive: true});\n }\n}\n\nfunction isStaleLock(lockPath: string): boolean {\n const metadata = lstatSync(lockPath);\n if (!metadata.isDirectory() || metadata.isSymbolicLink()) {\n throw new Error(`[easel] commit lock must be a real directory: ${lockPath}`);\n }\n const owner = readLockOwner(lockPath);\n if (owner === undefined) {\n return Date.now() - statSync(lockPath).mtimeMs > 30_000;\n }\n try {\n process.kill(owner.pid, 0);\n return false;\n } catch (error) {\n return isNodeError(error) && error.code === 'ESRCH';\n }\n}\n\nfunction readLockOwner(lockPath: string): LockOwner | undefined {\n try {\n const value = JSON.parse(\n readFileSync(join(lockPath, 'owner.json'), 'utf8'),\n ) as unknown;\n if (isLockOwner(value)) return value;\n } catch {\n return undefined;\n }\n return undefined;\n}\n\nfunction isLockOwner(value: unknown): value is LockOwner {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'pid' in value &&\n typeof value.pid === 'number' &&\n Number.isInteger(value.pid) &&\n value.pid > 0 &&\n 'token' in value &&\n typeof value.token === 'string' &&\n value.token.length > 0\n );\n}\n\nfunction isAlreadyExistsError(error: unknown): boolean {\n return isNodeError(error) && error.code === 'EEXIST';\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && 'code' in error;\n}\n","import {existsSync, readFileSync} from 'node:fs';\nimport {sep} from 'node:path';\nimport type {EaselOwnershipLedger, ResolvedEaselOptions} from './types.js';\nimport {\n SAFE_ASSET_FILENAME,\n SAFE_LIQUID_FILENAME,\n SAFE_OUTPUT_NAME,\n} from './validation.js';\n\nexport function readOwnershipLedger(\n options: ResolvedEaselOptions,\n): EaselOwnershipLedger | undefined {\n const path = options.ledgerPath;\n if (!existsSync(path)) return undefined;\n\n let value: unknown;\n try {\n value = JSON.parse(readFileSync(path, 'utf8')) as unknown;\n } catch {\n throw new Error(`[easel] ownership ledger is not valid JSON: ${path}`);\n }\n if (!isRecord(value) || value.themePath !== options.themePath) {\n throw invalidLedger(options);\n }\n\n if (value.schemaVersion === 1 && isLegacyGeneratedList(value.generated)) {\n return {\n schemaVersion: 2,\n themePath: options.themePath,\n prefix: options.prefix,\n liquidFilename: options.liquidFilename,\n generated: value.generated,\n };\n }\n\n if (!isCurrentLedger(value)) throw invalidLedger(options);\n return value;\n}\n\nexport function ownedAssetPath(\n options: Pick<ResolvedEaselOptions, 'prefix'>,\n file: string,\n): string {\n return namespacedAssetPath(options.prefix, file);\n}\n\nexport function ownedLiquidPath(\n options: Pick<ResolvedEaselOptions, 'liquidFilename'>,\n): string {\n return `snippets/${options.liquidFilename}`;\n}\n\nexport function assertAssetWritable(\n destinationPath: string,\n relativePath: string,\n content: Buffer,\n previousFiles: Set<string>,\n): void {\n if (\n existsSync(destinationPath) &&\n !previousFiles.has(relativePath) &&\n !readFileSync(destinationPath).equals(content)\n ) {\n throw new Error(\n `[easel] refusing to overwrite a file Easel does not own: ${destinationPath}`,\n );\n }\n}\n\nexport function assertLiquidWritable(\n absolutePath: string,\n relativePath: string,\n previousFiles: Set<string>,\n): void {\n if (!existsSync(absolutePath) || previousFiles.has(relativePath)) return;\n if (isGeneratedLiquid(readFileSync(absolutePath, 'utf8'))) return;\n throw new Error(\n `[easel] refusing to overwrite a Liquid file Easel does not own: ${absolutePath}`,\n );\n}\n\nexport function isGeneratedLiquid(content: string): boolean {\n return (\n content.startsWith('{% doc %}\\nGenerated asset loader managed by Easel.\\n') ||\n isDevelopmentLiquid(content)\n );\n}\n\nexport function isDevelopmentLiquid(content: string): boolean {\n return content.startsWith(\n '{% doc %}\\nGenerated development asset loader managed by Easel.\\n',\n );\n}\n\nfunction isCurrentLedger(\n value: Record<string, unknown>,\n): value is EaselOwnershipLedger & Record<string, unknown> {\n if (\n value.schemaVersion !== 2 ||\n typeof value.themePath !== 'string' ||\n typeof value.prefix !== 'string' ||\n typeof value.liquidFilename !== 'string'\n ) {\n return false;\n }\n const namespace = value.prefix.slice(0, -1);\n return (\n value.prefix.endsWith('-') &&\n SAFE_OUTPUT_NAME.test(namespace) &&\n SAFE_LIQUID_FILENAME.test(value.liquidFilename) &&\n isGeneratedList(value.generated, value.prefix, value.liquidFilename)\n );\n}\n\nfunction isLegacyGeneratedList(value: unknown): value is string[] {\n if (!Array.isArray(value) || !value.every((file) => typeof file === 'string')) {\n return false;\n }\n const snippets = value.filter((file) => file.startsWith('snippets/'));\n return (\n snippets.length === 1 &&\n SAFE_LIQUID_FILENAME.test(snippets[0]?.slice('snippets/'.length) ?? '') &&\n value.every(\n (file) => /^assets\\/[a-z0-9][a-z0-9._-]*$/.test(file) || file === snippets[0],\n )\n );\n}\n\nfunction isGeneratedList(\n value: unknown,\n prefix: string,\n liquidFilename: string,\n): value is string[] {\n return (\n Array.isArray(value) &&\n value.every(\n (file): file is string =>\n typeof file === 'string' && isOwnedThemePath(file, prefix, liquidFilename),\n )\n );\n}\n\nfunction isOwnedThemePath(file: string, prefix: string, liquidFilename: string): boolean {\n if (file === `snippets/${liquidFilename}`) return true;\n if (!file.startsWith('assets/')) return false;\n try {\n return namespacedAssetPath(prefix, file.slice('assets/'.length)) === file;\n } catch {\n return false;\n }\n}\n\nfunction namespacedAssetPath(prefix: string, file: string): string {\n const normalized = file.split(sep).join('/');\n if (\n !SAFE_ASSET_FILENAME.test(normalized) ||\n !normalized.startsWith(prefix) ||\n normalized === prefix\n ) {\n throw new Error(`[easel] generated asset is outside Easel's namespace: ${file}`);\n }\n return `assets/${normalized}`;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction invalidLedger(options: ResolvedEaselOptions): Error {\n return new Error(\n `[easel] invalid ownership ledger for ${options.themePath}: ${options.ledgerPath}`,\n );\n}\n","import {randomUUID} from 'node:crypto';\nimport {\n existsSync,\n lstatSync,\n mkdirSync,\n readFileSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from 'node:fs';\nimport {dirname, join, relative, resolve, sep} from 'node:path';\nimport type {ResolvedEaselOptions} from './types.js';\nimport {SAFE_ASSET_FILENAME, SAFE_LIQUID_FILENAME} from './validation.js';\n\ninterface TransactionEntry {\n scope: 'theme' | 'state';\n path: string;\n existed: boolean;\n blob?: string;\n}\n\ninterface TransactionJournal {\n schemaVersion: 1;\n themePath: string;\n entries: TransactionEntry[];\n}\n\ntype FileSnapshots = Map<string, Buffer | undefined>;\n\nfunction snapshotFiles(paths: string[]): FileSnapshots {\n return new Map(\n [...new Set(paths)].map((path) => [\n path,\n existsSync(path) ? readFileSync(path) : undefined,\n ]),\n );\n}\n\nfunction restoreSnapshots(snapshots: FileSnapshots): void {\n for (const [path, content] of snapshots) {\n if (content === undefined) {\n if (existsSync(path)) rmSync(path);\n } else {\n writeIfChanged(path, content);\n }\n }\n}\n\nfunction writeTransactionJournal(\n options: ResolvedEaselOptions,\n snapshots: FileSnapshots,\n): void {\n const temporary = `${options.transactionPath}-${randomUUID()}`;\n mkdirSync(temporary, {recursive: true});\n try {\n const entries: TransactionEntry[] = [];\n let index = 0;\n for (const [path, content] of snapshots) {\n const location = journalLocation(options, path);\n if (content === undefined) {\n entries.push({...location, existed: false});\n } else {\n const blob = `${index}.bin`;\n writeFileSync(join(temporary, blob), content);\n entries.push({...location, existed: true, blob});\n index += 1;\n }\n }\n const journal: TransactionJournal = {\n schemaVersion: 1,\n themePath: options.themePath,\n entries,\n };\n writeFileSync(\n join(temporary, 'journal.json'),\n `${JSON.stringify(journal, null, 2)}\\n`,\n );\n renameSync(temporary, options.transactionPath);\n } finally {\n if (existsSync(temporary)) rmSync(temporary, {recursive: true});\n }\n}\n\nexport function runFileTransaction(\n options: ResolvedEaselOptions,\n paths: string[],\n action: () => void,\n): void {\n const snapshots = snapshotFiles(paths);\n writeTransactionJournal(options, snapshots);\n\n try {\n action();\n rmSync(options.transactionPath, {recursive: true});\n } catch (error) {\n try {\n restoreSnapshots(snapshots);\n rmSync(options.transactionPath, {recursive: true, force: true});\n } catch (rollbackError) {\n throw new AggregateError(\n [error, rollbackError],\n '[easel] output commit failed and could not be rolled back completely',\n );\n }\n throw error;\n }\n}\n\nexport function recoverInterruptedCommit(options: ResolvedEaselOptions): void {\n if (!existsSync(options.transactionPath)) return;\n const metadata = lstatSync(options.transactionPath);\n if (!metadata.isDirectory() || metadata.isSymbolicLink()) {\n throw new Error(\n `[easel] transaction journal must be a real directory: ${options.transactionPath}`,\n );\n }\n\n let value: unknown;\n try {\n value = JSON.parse(\n readFileSync(join(options.transactionPath, 'journal.json'), 'utf8'),\n ) as unknown;\n } catch {\n throw new Error(\n `[easel] interrupted transaction journal is invalid: ${options.transactionPath}`,\n );\n }\n if (!isTransactionJournal(value) || value.themePath !== options.themePath) {\n throw new Error(\n `[easel] interrupted transaction journal is invalid: ${options.transactionPath}`,\n );\n }\n\n const snapshots: FileSnapshots = new Map();\n for (const entry of value.entries) {\n const path = resolveJournalLocation(options, entry);\n if (!entry.existed) {\n snapshots.set(path, undefined);\n continue;\n }\n if (entry.blob === undefined || !/^\\d+\\.bin$/.test(entry.blob)) {\n throw new Error(\n `[easel] interrupted transaction journal is invalid: ${options.transactionPath}`,\n );\n }\n const blobPath = join(options.transactionPath, entry.blob);\n if (!existsSync(blobPath)) {\n throw new Error(`[easel] interrupted transaction snapshot is missing: ${blobPath}`);\n }\n snapshots.set(path, readFileSync(blobPath));\n }\n\n restoreSnapshots(snapshots);\n rmSync(options.transactionPath, {recursive: true});\n}\n\nexport function safeResolve(root: string, path: string): string {\n const base = resolve(root);\n const result = resolve(base, path);\n const relativePath = relative(base, result);\n if (relativePath === '..' || relativePath.startsWith(`..${sep}`)) {\n throw new Error(`[easel] output escapes its allowed root: ${path}`);\n }\n return result;\n}\n\nexport function writeIfChanged(path: string, content: string | Buffer): void {\n const next = Buffer.isBuffer(content) ? content : Buffer.from(content);\n if (existsSync(path) && readFileSync(path).equals(next)) return;\n mkdirSync(dirname(path), {recursive: true});\n const temporary = `${path}.easel-${process.pid}-${Date.now()}`;\n writeFileSync(temporary, next);\n try {\n if (process.platform === 'win32' && existsSync(path)) {\n replaceFileOnWindows(temporary, path);\n } else {\n renameSync(temporary, path);\n }\n } finally {\n if (existsSync(temporary)) rmSync(temporary);\n }\n}\n\nfunction journalLocation(\n options: ResolvedEaselOptions,\n path: string,\n): Pick<TransactionEntry, 'scope' | 'path'> {\n const statePath = relativeWithin(dirname(options.ledgerPath), path);\n if (statePath !== undefined) {\n return assertJournalLocation({scope: 'state', path: statePath});\n }\n const themePath = relativeWithin(options.themePath, path);\n if (themePath !== undefined) {\n return assertJournalLocation({scope: 'theme', path: themePath});\n }\n throw new Error(`[easel] cannot journal output outside Easel's roots: ${path}`);\n}\n\nfunction resolveJournalLocation(\n options: ResolvedEaselOptions,\n entry: TransactionEntry,\n): string {\n assertJournalLocation(entry);\n const root = entry.scope === 'theme' ? options.themePath : dirname(options.ledgerPath);\n const path = safeResolve(root, entry.path);\n if (relativeWithin(root, path) !== entry.path) {\n throw new Error(\n `[easel] interrupted transaction journal contains an invalid path: ${entry.path}`,\n );\n }\n return path;\n}\n\nfunction assertJournalLocation<T extends Pick<TransactionEntry, 'scope' | 'path'>>(\n location: T,\n): T {\n const valid =\n location.scope === 'theme'\n ? isJournalThemePath(location.path)\n : ['outputs.json', 'production.txt', 'production.liquid', 'manifest.json'].includes(\n location.path,\n );\n if (!valid) {\n throw new Error(\n `[easel] transaction journal contains an invalid path: ${location.path}`,\n );\n }\n return location;\n}\n\nfunction isJournalThemePath(path: string): boolean {\n const [directory, filename, extra] = path.split('/');\n if (filename === undefined || extra !== undefined) return false;\n if (directory === 'assets') return SAFE_ASSET_FILENAME.test(filename);\n return directory === 'snippets' && SAFE_LIQUID_FILENAME.test(filename);\n}\n\nfunction relativeWithin(root: string, path: string): string | undefined {\n const value = relative(resolve(root), resolve(path));\n if (value === '' || value === '..' || value.startsWith(`..${sep}`)) {\n return undefined;\n }\n return value.split(sep).join('/');\n}\n\nfunction isTransactionJournal(value: unknown): value is TransactionJournal {\n if (\n typeof value !== 'object' ||\n value === null ||\n !('schemaVersion' in value) ||\n value.schemaVersion !== 1 ||\n !('themePath' in value) ||\n typeof value.themePath !== 'string' ||\n !('entries' in value) ||\n !Array.isArray(value.entries)\n ) {\n return false;\n }\n return value.entries.every((entry: unknown) => isTransactionEntry(entry));\n}\n\nfunction isTransactionEntry(entry: unknown): entry is TransactionEntry {\n return (\n typeof entry === 'object' &&\n entry !== null &&\n 'scope' in entry &&\n (entry.scope === 'theme' || entry.scope === 'state') &&\n 'path' in entry &&\n typeof entry.path === 'string' &&\n 'existed' in entry &&\n typeof entry.existed === 'boolean' &&\n (!('blob' in entry) || entry.blob === undefined || typeof entry.blob === 'string')\n );\n}\n\nfunction replaceFileOnWindows(temporary: string, destination: string): void {\n const backup = `${temporary}.previous`;\n renameSync(destination, backup);\n try {\n renameSync(temporary, destination);\n rmSync(backup);\n } catch (error) {\n if (existsSync(destination)) rmSync(destination);\n renameSync(backup, destination);\n throw error;\n }\n}\n","import {createHash, randomUUID} from 'node:crypto';\nimport {existsSync, lstatSync, realpathSync, statSync} from 'node:fs';\nimport {isAbsolute, join, relative, resolve, sep} from 'node:path';\nimport type {\n EaselBundle,\n EaselOptions,\n ResolvedEaselBundle,\n ResolvedEaselOptions,\n} from './types.js';\nimport {SAFE_OUTPUT_NAME} from './validation.js';\n\nconst DEFAULT_SOURCE = 'src';\nconst DEFAULT_NAMESPACE = 'easel';\nconst DEFAULT_REFRESH_SIGNAL = '.easel/shopify-ready';\nconst DEFAULT_REFRESH_DELAY = 100;\n\ntype EaselStatePaths = Pick<\n ResolvedEaselOptions,\n | 'stagingPath'\n | 'ledgerPath'\n | 'commitLockPath'\n | 'manifestPath'\n | 'productionLiquidPath'\n | 'transactionPath'\n>;\n\nexport function resolveEaselOptions(\n options: EaselOptions,\n projectRoot: string,\n): ResolvedEaselOptions {\n const root = realpathSync(resolve(projectRoot));\n const configuredThemePath = resolveFrom(root, options.theme ?? '.');\n assertTheme(configuredThemePath);\n const themePath = realpathSync(configuredThemePath);\n const configuredSourcePath = resolveFrom(root, options.source ?? DEFAULT_SOURCE);\n const namespace = options.namespace ?? DEFAULT_NAMESPACE;\n\n assertSource(configuredSourcePath);\n const sourcePath = realpathSync(configuredSourcePath);\n assertNamespace(namespace);\n const liquidFilename = `${namespace}-assets.liquid`;\n const prefix = `${namespace}-`;\n const refresh = resolveRefresh(options.refresh, root);\n\n const bundles = resolveBundles(options.bundles, sourcePath);\n const statePaths = resolveEaselStatePaths(root, themePath);\n\n return {\n projectRoot: root,\n themePath,\n sourcePath,\n ...statePaths,\n liquidPath: join(themePath, 'snippets', liquidFilename),\n liquidFilename,\n namespace,\n prefix,\n refresh,\n bundles,\n };\n}\n\nfunction resolveRefresh(\n configured: EaselOptions['refresh'],\n projectRoot: string,\n): ResolvedEaselOptions['refresh'] {\n if (configured === false) {\n return {\n enabled: false,\n signalPath: join(projectRoot, DEFAULT_REFRESH_SIGNAL),\n delay: DEFAULT_REFRESH_DELAY,\n };\n }\n\n const options = configured === true || configured === undefined ? {} : configured;\n const delay = options.delay ?? DEFAULT_REFRESH_DELAY;\n if (!Number.isInteger(delay) || delay < 0 || delay > 10_000) {\n throw new Error(\n '[easel] refresh.delay must be an integer from 0 to 10000 milliseconds',\n );\n }\n\n return {\n enabled: true,\n signalPath: resolveFrom(projectRoot, options.signal ?? DEFAULT_REFRESH_SIGNAL),\n delay,\n };\n}\n\nfunction resolveBundles(\n configured: Record<string, EaselBundle> | undefined,\n sourcePath: string,\n): ResolvedEaselBundle[] {\n const bundles = configured ?? {theme: resolveDefaultBundle(sourcePath)};\n const entries = Object.entries(bundles);\n\n if (entries.length === 0) {\n throw new Error('[easel] bundles must contain at least one named bundle');\n }\n\n const resolved = entries.map(([name, bundle]) => {\n if (!SAFE_OUTPUT_NAME.test(name)) {\n throw new Error(\n `[easel] invalid bundle name \"${name}\"; use lowercase letters, numbers, and hyphens`,\n );\n }\n if (bundle.script === undefined && bundle.style === undefined) {\n throw new Error(`[easel] bundle \"${name}\" needs a script, a style, or both`);\n }\n\n return {\n name,\n ...resolveBundleFiles(name, bundle, sourcePath),\n };\n });\n\n const scriptOwners = new Map<string, string>();\n for (const bundle of resolved) {\n if (bundle.script === undefined) continue;\n const owner = scriptOwners.get(bundle.script);\n if (owner !== undefined) {\n throw new Error(\n `[easel] bundles \"${owner}\" and \"${bundle.name}\" use the same script; each named bundle needs a distinct script entry`,\n );\n }\n scriptOwners.set(bundle.script, bundle.name);\n }\n\n return resolved;\n}\n\nfunction resolveDefaultBundle(sourcePath: string): EaselBundle {\n const typescriptEntry = join(sourcePath, 'main.ts');\n const javascriptEntry = join(sourcePath, 'main.js');\n const styleEntry = join(sourcePath, 'style.css');\n const hasTypescript = isFile(typescriptEntry);\n const hasJavascript = isFile(javascriptEntry);\n\n if (hasTypescript && hasJavascript) {\n throw new Error(\n `[easel] both main.ts and main.js exist in ${sourcePath}; configure bundles to choose one explicitly`,\n );\n }\n if (!hasTypescript && !hasJavascript) {\n throw new Error(\n `[easel] expected main.ts or main.js in ${sourcePath}; configure source or bundles for a different layout`,\n );\n }\n if (!isFile(styleEntry)) {\n throw new Error(\n `[easel] expected style.css in ${sourcePath}; configure bundles explicitly to build without a stylesheet`,\n );\n }\n\n return {\n script: hasTypescript ? typescriptEntry : javascriptEntry,\n style: styleEntry,\n };\n}\n\nfunction resolveBundleFiles(\n name: string,\n bundle: EaselBundle,\n sourcePath: string,\n): Omit<ResolvedEaselBundle, 'name'> {\n const resolved: Omit<ResolvedEaselBundle, 'name'> = {};\n\n if (bundle.script !== undefined) {\n resolved.script = resolveInput(name, 'script', bundle.script, sourcePath);\n }\n if (bundle.style !== undefined) {\n resolved.style = resolveInput(name, 'style', bundle.style, sourcePath);\n }\n\n return resolved;\n}\n\nfunction resolveInput(\n bundleName: string,\n kind: 'script' | 'style',\n input: string,\n sourcePath: string,\n): string {\n const path = resolveFrom(sourcePath, input);\n if (!isFile(path)) {\n throw new Error(`[easel] ${kind} for bundle \"${bundleName}\" does not exist: ${path}`);\n }\n return realpathSync(path);\n}\n\nfunction resolveEaselStatePaths(projectRoot: string, themePath: string): EaselStatePaths {\n const easelPath = join(projectRoot, '.easel');\n const themeId = createHash('sha256').update(themePath).digest('hex').slice(0, 16);\n const stagingParent = join(easelPath, 'build', themeId);\n const themeStatePath = join(easelPath, 'themes', themeId);\n assertEaselStatePaths([\n easelPath,\n join(easelPath, 'build'),\n stagingParent,\n join(easelPath, 'themes'),\n themeStatePath,\n ]);\n\n return {\n stagingPath: join(stagingParent, randomUUID()),\n ledgerPath: join(themeStatePath, 'outputs.json'),\n commitLockPath: join(themeStatePath, 'commit.lock'),\n manifestPath: join(themeStatePath, 'manifest.json'),\n productionLiquidPath: join(themeStatePath, 'production.txt'),\n transactionPath: join(themeStatePath, 'transaction'),\n };\n}\n\nfunction assertTheme(themePath: string): void {\n for (const directory of ['assets', 'layout', 'snippets']) {\n const path = join(themePath, directory);\n const metadata = lstatSync(path, {throwIfNoEntry: false});\n if (metadata?.isSymbolicLink()) {\n throw new Error(\n `[easel] Shopify theme output directory cannot be a symbolic link: ${path}`,\n );\n }\n if (metadata === undefined || !metadata.isDirectory()) {\n throw new Error(\n `[easel] invalid Shopify theme at ${themePath}: missing ${directory}/`,\n );\n }\n }\n}\n\nfunction assertEaselStatePaths(paths: string[]): void {\n for (const path of paths) {\n const metadata = lstatSync(path, {throwIfNoEntry: false});\n if (metadata === undefined) continue;\n if (metadata.isSymbolicLink() || !metadata.isDirectory()) {\n throw new Error(`[easel] state directory must be a real directory: ${path}`);\n }\n }\n}\n\nfunction assertSource(sourcePath: string): void {\n if (!existsSync(sourcePath) || !statSync(sourcePath).isDirectory()) {\n throw new Error(`[easel] source directory does not exist: ${sourcePath}`);\n }\n}\n\nfunction assertNamespace(namespace: string): void {\n if (!SAFE_OUTPUT_NAME.test(namespace)) {\n throw new Error(\n '[easel] namespace must use lowercase letters, numbers, and single hyphens',\n );\n }\n}\n\nfunction resolveFrom(base: string, path: string): string {\n return isAbsolute(path) ? resolve(path) : resolve(base, path);\n}\n\nfunction isFile(path: string): boolean {\n return existsSync(path) && statSync(path).isFile();\n}\n\nexport function projectRelative(path: string, projectRoot: string): string {\n const value = relative(projectRoot, path);\n return value.split(sep).join('/');\n}\n","import {existsSync, mkdirSync, statSync, writeFileSync} from 'node:fs';\nimport type {Stats} from 'node:fs';\nimport {dirname} from 'node:path';\n\nconst POLL_INTERVAL = 50;\n\nexport function watchRefreshSignal(\n signalPath: string,\n delay: number,\n refresh: () => void,\n): () => void {\n mkdirSync(dirname(signalPath), {recursive: true});\n if (!existsSync(signalPath)) writeFileSync(signalPath, '');\n\n let previous = readStats(signalPath);\n let timer: ReturnType<typeof setTimeout> | undefined;\n const poller = setInterval(() => {\n const current = readStats(signalPath);\n if (sameStats(current, previous)) return;\n previous = current;\n clearTimeout(timer);\n timer = setTimeout(refresh, delay);\n }, POLL_INTERVAL);\n poller.unref();\n\n return () => {\n clearTimeout(timer);\n clearInterval(poller);\n };\n}\n\nfunction readStats(path: string): Stats | undefined {\n try {\n return statSync(path);\n } catch {\n return undefined;\n }\n}\n\nfunction sameStats(current: Stats | undefined, previous: Stats | undefined): boolean {\n if (current === undefined || previous === undefined) return current === previous;\n return (\n current.mtimeMs === previous.mtimeMs &&\n current.ctimeMs === previous.ctimeMs &&\n current.size === previous.size\n );\n}\n","import type {ViteDevServer} from 'vite';\nimport {renderDevelopmentLiquid} from './liquid.js';\nimport {projectRelative} from './options.js';\nimport {assertDevelopmentLiquidWritable, writeDevelopmentLiquid} from './output.js';\nimport {watchRefreshSignal} from './refresh.js';\nimport type {ResolvedEaselOptions} from './types.js';\n\nexport function configureDevelopmentServer(\n server: ViteDevServer,\n options: ResolvedEaselOptions,\n): void {\n if (server.httpServer === null) {\n throw new Error(\n '[easel] Vite middleware mode is not supported; Easel requires the development server lifecycle',\n );\n }\n\n assertDevelopmentLiquidWritable(options);\n const stopWatching = configureRefresh(server, options);\n let restoreDevelopmentLiquid: (() => void) | undefined;\n\n server.httpServer.once('listening', () => {\n restoreDevelopmentLiquid = writeDevelopmentLiquid(\n options,\n renderDevelopmentLiquid(\n options.bundles.map((bundle) => bundle.name),\n developmentOrigin(server),\n ),\n );\n });\n server.httpServer.once('close', () => {\n stopWatching?.();\n restoreDevelopmentLiquid?.();\n });\n}\n\nfunction configureRefresh(\n server: ViteDevServer,\n options: ResolvedEaselOptions,\n): (() => void) | undefined {\n if (!options.refresh.enabled) return undefined;\n\n const stopWatching = watchRefreshSignal(\n options.refresh.signalPath,\n options.refresh.delay,\n () => server.ws.send({type: 'full-reload', path: '*'}),\n );\n server.config.logger.info(\n `[easel] Shopify refresh signal: ${projectRelative(\n options.refresh.signalPath,\n options.projectRoot,\n )}`,\n );\n return stopWatching;\n}\n\nfunction developmentOrigin(server: ViteDevServer): string {\n const origin =\n server.config.server.origin ??\n server.resolvedUrls?.local[0] ??\n server.resolvedUrls?.network[0];\n if (origin === undefined) {\n throw new Error(\n '[easel] Vite did not expose a development URL; set server.origin explicitly',\n );\n }\n return origin;\n}\n","import type {ConfigEnv, ResolvedConfig, UserConfig} from 'vite';\nimport {resolveEaselOptions} from './options.js';\nimport type {EaselOptions, ResolvedEaselOptions} from './types.js';\nimport {virtualBundleId} from './virtual.js';\n\nexport interface PreparedViteConfig {\n options: ResolvedEaselOptions;\n config: UserConfig;\n}\n\nexport function prepareViteConfig(\n easelOptions: EaselOptions,\n userConfig: UserConfig,\n command: ConfigEnv['command'],\n): PreparedViteConfig {\n const options = resolveEaselOptions(easelOptions, userConfig.root ?? process.cwd());\n\n switch (command) {\n case 'build':\n assertCompatibleBuildConfig(userConfig);\n break;\n case 'serve':\n break;\n }\n\n return {\n options,\n config: createViteConfig(userConfig, options, command),\n };\n}\n\nexport function validateResolvedViteConfig(\n config: ResolvedConfig,\n options: ResolvedEaselOptions,\n): void {\n switch (config.command) {\n case 'build':\n assertResolvedBuildConfig(config, options);\n assertNoLaterPostBuildHooks(config);\n break;\n case 'serve':\n break;\n }\n}\n\nfunction createViteConfig(\n config: UserConfig,\n options: ResolvedEaselOptions,\n command: ConfigEnv['command'],\n): UserConfig {\n const stableCssEntryIds = new Set(\n options.bundles.map((bundle) => `easel:${bundle.name}`),\n );\n const input = Object.fromEntries(\n options.bundles.map((bundle) => [bundle.name, virtualBundleId(bundle.name)]),\n );\n\n return {\n ...(command === 'build' ? {base: './'} : {}),\n build: {\n outDir: options.stagingPath,\n emptyOutDir: true,\n assetsDir: '',\n manifest: true,\n rollupOptions: {\n input,\n output: {\n entryFileNames: `${options.prefix}[name].js`,\n chunkFileNames: `${options.prefix}[name]-[hash].js`,\n assetFileNames(asset) {\n const original = asset.names[0] ?? asset.name ?? 'asset';\n if (!original.endsWith('.css')) {\n return `${options.prefix}[name]-[hash][extname]`;\n }\n return isEntryStylesheet(asset.originalFileNames, stableCssEntryIds)\n ? `${options.prefix}[name].css`\n : `${options.prefix}[name]-[hash].css`;\n },\n },\n },\n },\n server: {\n ...(config.server?.cors === undefined ? {cors: shopifyCorsPolicy()} : {}),\n fs: {\n allow: easelFileSystemAllowList(config.server?.fs?.allow ?? [], options),\n },\n },\n };\n}\n\nfunction isEntryStylesheet(\n originalFileNames: string[],\n stableCssEntryIds: Set<string>,\n): boolean {\n return originalFileNames.some((file) => {\n const normalized = file.replaceAll('\\\\', '/');\n return stableCssEntryIds.has(normalized.slice(normalized.lastIndexOf('/') + 1));\n });\n}\n\nfunction shopifyCorsPolicy(): {origin: RegExp[]} {\n return {\n origin: [\n /^https?:\\/\\/(?:[^.]+\\.)*myshopify\\.com$/,\n /^https:\\/\\/admin\\.shopify\\.com$/,\n /^https?:\\/\\/(?:localhost|127\\.0\\.0\\.1|\\[::1\\])(?::\\d+)?$/,\n ],\n };\n}\n\nfunction easelFileSystemAllowList(\n configured: string[],\n options: ResolvedEaselOptions,\n): string[] {\n const existing = new Set(configured);\n return unique([options.projectRoot, options.sourcePath]).filter(\n (path) => !existing.has(path),\n );\n}\n\nfunction assertCompatibleBuildConfig(config: UserConfig): void {\n const build = config.build;\n const conflict = firstViolation([\n [\n config.base !== undefined && config.base !== './',\n 'Vite base must be \"./\" for Shopify CDN assets',\n ],\n [\n build?.outDir !== undefined,\n 'build.outDir conflicts with Easel staging; configure the Shopify theme with easel({ theme }) instead',\n ],\n [\n build?.emptyOutDir !== undefined,\n 'build.emptyOutDir is managed by Easel for safe staging',\n ],\n [\n build?.assetsDir !== undefined,\n 'build.assetsDir is managed by Easel for flat Shopify assets',\n ],\n [build?.manifest !== undefined, 'build.manifest is managed by Easel'],\n [build?.write === false, 'build.write must remain enabled'],\n [\n build?.rollupOptions?.input !== undefined,\n 'build.rollupOptions.input conflicts with Easel bundles',\n ],\n [\n build?.rollupOptions?.output !== undefined,\n 'build.rollupOptions.output is managed by Easel',\n ],\n ]);\n if (conflict !== undefined) throw new Error(`[easel] ${conflict}`);\n}\n\nfunction assertResolvedBuildConfig(\n config: ResolvedConfig,\n options: ResolvedEaselOptions,\n): void {\n const violation = firstViolation([\n [config.base !== './', 'resolved Vite base must be \"./\"'],\n [\n config.build.outDir !== options.stagingPath,\n \"another Vite plugin changed Easel's staging directory\",\n ],\n [\n config.build.assetsDir !== '',\n \"another Vite plugin changed Easel's flat asset layout\",\n ],\n [\n config.build.emptyOutDir !== true,\n \"another Vite plugin disabled Easel's staging cleanup\",\n ],\n [\n config.build.manifest !== true,\n \"another Vite plugin changed Easel's manifest setting\",\n ],\n [config.build.write === false, 'build.write must remain enabled'],\n ]);\n if (violation !== undefined) throw new Error(`[easel] ${violation}`);\n}\n\nfunction firstViolation(\n checks: [violated: boolean, message: string][],\n): string | undefined {\n return checks.find(([violated]) => violated)?.[1];\n}\n\nfunction assertNoLaterPostBuildHooks(config: ResolvedConfig): void {\n const easelIndex = config.plugins.findIndex(\n (plugin) => plugin.name === 'easel:shopify-theme',\n );\n const unsafe = config.plugins.slice(easelIndex + 1).filter(hasPostOutputHook);\n if (unsafe.length > 0) {\n throw new Error(\n `[easel] Easel must run after plugins with post-order output hooks: ${unsafe\n .map((plugin) => plugin.name)\n .join(', ')}. Move easel() after those plugins.`,\n );\n }\n}\n\nfunction hasPostOutputHook(plugin: ResolvedConfig['plugins'][number]): boolean {\n return [plugin.writeBundle, plugin.closeBundle].some(\n (hook) => typeof hook === 'object' && hook.order === 'post',\n );\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values)];\n}\n","import type {Plugin, ResolvedConfig} from 'vite';\nimport {finalizeProductionBuild} from './build.js';\nimport {configureDevelopmentServer} from './development.js';\nimport type {EaselOptions, ResolvedEaselOptions} from './types.js';\nimport {easelBundleModules} from './virtual.js';\nimport {prepareViteConfig, validateResolvedViteConfig} from './vite-config.js';\n\ninterface BuildLifecycle {\n failed: boolean;\n outputHooksCompleted: boolean;\n}\n\nexport function easel(options: EaselOptions = {}): Plugin[] {\n let resolvedOptions: ResolvedEaselOptions | undefined;\n let resolvedConfig: ResolvedConfig | undefined;\n const build: BuildLifecycle = {\n failed: false,\n outputHooksCompleted: false,\n };\n\n const requireOptions = (): ResolvedEaselOptions => {\n if (resolvedOptions === undefined) {\n throw new Error('[easel] plugin options have not been resolved');\n }\n return resolvedOptions;\n };\n\n const integration: Plugin = {\n name: 'easel:shopify-theme',\n enforce: 'post',\n config(config, environment) {\n const prepared = prepareViteConfig(options, config, environment.command);\n resolvedOptions = prepared.options;\n return prepared.config;\n },\n configResolved(config) {\n resolvedConfig = config;\n validateResolvedViteConfig(config, requireOptions());\n },\n configureServer(server) {\n configureDevelopmentServer(server, requireOptions());\n },\n buildStart() {\n build.failed = false;\n build.outputHooksCompleted = false;\n },\n buildEnd(error) {\n if (error !== undefined) build.failed = true;\n },\n writeBundle: {\n order: 'post',\n sequential: true,\n handler() {\n build.outputHooksCompleted = true;\n },\n },\n closeBundle: {\n order: 'post',\n sequential: true,\n handler() {\n const config = resolvedConfig;\n if (config?.command !== 'build') return;\n finalizeProductionBuild(\n requireOptions(),\n config,\n !build.failed && build.outputHooksCompleted,\n );\n },\n },\n };\n\n return [easelBundleModules(() => requireOptions().bundles), integration];\n}\n"],"mappings":"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","names":["existsSync","readFileSync","rmSync","join","existsSync","readFileSync","rmSync","dirname","join","readFileSync","readFileSync","randomUUID","existsSync","lstatSync","mkdirSync","readFileSync","rmSync","writeFileSync","dirname","join","sep","existsSync","readFileSync","rmSync","randomUUID","mkdirSync","writeFileSync","join","lstatSync","sep","dirname","releaseLock","existsSync","join","readFileSync","rmSync","dirname","join","existsSync","readFileSync","rmSync","randomUUID","existsSync","lstatSync","statSync","join","relative","resolve","sep","resolve","join","randomUUID","lstatSync","existsSync","statSync","relative","sep","existsSync","mkdirSync","statSync","writeFileSync","dirname","restoreDevelopmentLiquid"]}
1
+ {"version":3,"sources":["../src/build.ts","../src/validation.ts","../src/virtual.ts","../src/liquid.ts","../src/manifest.ts","../src/output.ts","../src/lock.ts","../src/ownership.ts","../src/transaction.ts","../src/options.ts","../src/refresh.ts","../src/development.ts","../src/vite-config.ts","../src/plugin.ts"],"sourcesContent":["import {existsSync, readFileSync, readdirSync, rmSync} from 'node:fs';\nimport {join} from 'node:path';\nimport type {Manifest, ResolvedConfig} from 'vite';\nimport {renderProductionLiquid} from './liquid.js';\nimport {createEaselManifest} from './manifest.js';\nimport {commitProductionOutput} from './output.js';\nimport type {ResolvedEaselOptions} from './types.js';\n\nexport function finalizeProductionBuild(\n options: ResolvedEaselOptions,\n config: ResolvedConfig,\n publish: boolean,\n): void {\n try {\n if (!publish) return;\n const viteManifest = readViteManifest(options.stagingPath);\n const manifest = createEaselManifest(\n viteManifest,\n options.bundles,\n listEmittedFiles(options.stagingPath),\n );\n commitProductionOutput(options, manifest, renderProductionLiquid(manifest));\n } finally {\n removeStagingDirectory(options.stagingPath, config);\n }\n}\n\nfunction readViteManifest(stagingPath: string): Manifest {\n const path = join(stagingPath, '.vite', 'manifest.json');\n if (!existsSync(path)) {\n throw new Error(`[easel] Vite did not write its build manifest: ${path}`);\n }\n try {\n return JSON.parse(readFileSync(path, 'utf8')) as Manifest;\n } catch (error) {\n throw new Error(`[easel] Vite wrote an invalid build manifest: ${path}`, {\n cause: error,\n });\n }\n}\n\nfunction removeStagingDirectory(stagingPath: string, config: ResolvedConfig): void {\n try {\n rmSync(stagingPath, {recursive: true, force: true});\n } catch (error) {\n config.logger.warn(\n `[easel] could not remove staging directory ${stagingPath}: ${errorMessage(error)}`,\n );\n }\n}\n\nfunction listEmittedFiles(stagingPath: string): string[] {\n const files: string[] = [];\n for (const entry of readdirSync(stagingPath, {withFileTypes: true})) {\n if (entry.name === '.vite' && entry.isDirectory()) continue;\n if (!entry.isFile()) {\n throw new Error(`[easel] unexpected output in staging directory: ${entry.name}`);\n }\n files.push(entry.name);\n }\n return files;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","export const SAFE_OUTPUT_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\nexport const SAFE_ASSET_FILENAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;\nexport const SAFE_LIQUID_FILENAME = /^[a-z0-9][a-z0-9_-]*\\.liquid$/;\n","import type {Plugin} from 'vite';\nimport type {ResolvedEaselBundle} from './types.js';\n\nconst INTERNAL_PREFIX = '\\0easel:';\nexport const PUBLIC_PREFIX = '/@easel/';\n\nexport function virtualBundleId(name: string): string {\n return `${INTERNAL_PREFIX}${name}`;\n}\n\nexport function easelBundleModules(getBundles: () => ResolvedEaselBundle[]): Plugin {\n return {\n name: 'easel:bundle-modules',\n enforce: 'pre',\n resolveId(id) {\n const bundles = getBundles();\n if (id.startsWith(PUBLIC_PREFIX)) {\n const name = id.slice(PUBLIC_PREFIX.length);\n if (bundles.some((bundle) => bundle.name === name)) {\n return virtualBundleId(name);\n }\n }\n if (id.startsWith(INTERNAL_PREFIX)) return id;\n\n const normalizedId = normalizeModulePath(id);\n const isBundleInput = bundles\n .flatMap(bundleInputs)\n .some((path) => normalizeModulePath(path) === normalizedId);\n // Bundle inputs are storefront entry points even when their exports are unused.\n return isBundleInput ? {id: normalizedId, moduleSideEffects: true} : undefined;\n },\n load(id) {\n if (!id.startsWith(INTERNAL_PREFIX)) return undefined;\n const name = id.slice(INTERNAL_PREFIX.length);\n const bundle = getBundles().find((candidate) => candidate.name === name);\n if (bundle === undefined) {\n throw new Error(`[easel] unknown virtual bundle \"${name}\"`);\n }\n\n return `${bundleInputs(bundle)\n .map((path) => `import ${JSON.stringify(path)};`)\n .join('\\n')}\\n`;\n },\n };\n}\n\nfunction bundleInputs(bundle: ResolvedEaselBundle): string[] {\n return [bundle.script, bundle.style].filter(\n (path): path is string => path !== undefined,\n );\n}\n\nfunction normalizeModulePath(path: string): string {\n return path.replaceAll('\\\\', '/');\n}\n","import type {EaselManifest, EaselManifestEntry} from './types.js';\nimport {SAFE_ASSET_FILENAME, SAFE_OUTPUT_NAME} from './validation.js';\nimport {PUBLIC_PREFIX} from './virtual.js';\n\nconst MAX_LIQUID_BYTES = 200_000;\n\nexport function renderProductionLiquid(manifest: EaselManifest): string {\n const entries = validatedManifestEntries(manifest);\n const defaultEntry = entries[0]?.[0];\n if (defaultEntry === undefined) {\n throw new Error('[easel] cannot render Liquid without an entry');\n }\n\n const lines = loaderHeader('Generated asset loader managed by Easel.', defaultEntry);\n\n for (const [name, entry] of entries) {\n lines.push(` {% when ${liquidEntryLiteral(name)} %}`);\n for (const style of entry.styles) {\n lines.push(\n ` {{ ${liquidAssetLiteral(style, 'stylesheet', '.css')} | asset_url | stylesheet_tag }}`,\n );\n }\n for (const imported of entry.imports) {\n lines.push(\n ` <link rel=\"modulepreload\" href=\"{{ ${liquidAssetLiteral(imported, 'module import', '.js')} | asset_url }}\">`,\n );\n }\n if (entry.script !== undefined) {\n lines.push(\n ` <script src=\"{{ ${liquidAssetLiteral(entry.script, 'entry script', '.js')} | asset_url }}\" type=\"module\"></script>`,\n );\n }\n }\n\n return finishLoader(lines);\n}\n\nexport function renderDevelopmentLiquid(names: string[], origin: string): string {\n const entries = validatedEntryNames(names);\n const defaultEntry = entries[0];\n if (defaultEntry === undefined) {\n throw new Error('[easel] cannot render Liquid without an entry');\n }\n\n const safeOrigin = normalizeOrigin(origin);\n const lines = loaderHeader(\n 'Generated development asset loader managed by Easel.',\n defaultEntry,\n [`<script src=\"${safeOrigin}/@vite/client\" type=\"module\"></script>`],\n );\n\n for (const name of entries) {\n lines.push(` {% when ${liquidEntryLiteral(name)} %}`);\n lines.push(\n ` <script src=\"${safeOrigin}${PUBLIC_PREFIX}${encodeURIComponent(name)}\" type=\"module\"></script>`,\n );\n }\n\n return finishLoader(lines);\n}\n\nfunction loaderHeader(\n description: string,\n defaultEntry: string,\n preamble: string[] = [],\n): string[] {\n return [\n '{% doc %}',\n description,\n '@param {string} [entry] - Named Easel bundle to render.',\n '{% enddoc %}',\n '{% liquid',\n ` assign easel_entry = entry | default: ${liquidEntryLiteral(defaultEntry)}`,\n '%}',\n ...preamble,\n '{% case easel_entry %}',\n ];\n}\n\nfunction finishLoader(lines: string[]): string {\n lines.push(\n ' {% else %}',\n ' <!-- [easel] Unknown bundle \"{{ easel_entry | escape }}\". -->',\n '{% endcase %}',\n '',\n );\n return assertLiquidSize(lines.join('\\n'));\n}\n\nfunction validatedManifestEntries(\n manifest: EaselManifest,\n): [string, EaselManifestEntry][] {\n if (manifest.schemaVersion !== 1) {\n throw new Error(\n `[easel] unsupported manifest schema version: ${JSON.stringify(manifest.schemaVersion)}`,\n );\n }\n const entries = Object.entries(manifest.entries);\n validatedEntryNames(entries.map(([name]) => name));\n return entries;\n}\n\nfunction validatedEntryNames(names: string[]): string[] {\n const seen = new Set<string>();\n for (const name of names) {\n if (!SAFE_OUTPUT_NAME.test(name)) {\n throw new Error(`[easel] cannot render unsafe Liquid bundle name: ${name}`);\n }\n if (seen.has(name)) {\n throw new Error(`[easel] cannot render duplicate Liquid bundle name: ${name}`);\n }\n seen.add(name);\n }\n return names;\n}\n\nfunction liquidEntryLiteral(name: string): string {\n if (!SAFE_OUTPUT_NAME.test(name)) {\n throw new Error(`[easel] cannot render unsafe Liquid bundle name: ${name}`);\n }\n return `'${name}'`;\n}\n\nfunction liquidAssetLiteral(\n filename: string,\n role: string,\n extension: '.css' | '.js',\n): string {\n if (!SAFE_ASSET_FILENAME.test(filename) || !filename.endsWith(extension)) {\n throw new Error(`[easel] cannot render unsafe ${role} filename: ${filename}`);\n }\n return `'${filename}'`;\n}\n\nfunction normalizeOrigin(origin: string): string {\n let url: URL;\n try {\n url = new URL(origin);\n } catch {\n throw new Error(`[easel] invalid Vite development origin: ${origin}`);\n }\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n throw new Error(`[easel] Vite development origin must use HTTP or HTTPS: ${origin}`);\n }\n if (\n url.username !== '' ||\n url.password !== '' ||\n url.pathname !== '/' ||\n url.search !== '' ||\n url.hash !== ''\n ) {\n throw new Error(\n `[easel] Vite development origin cannot contain credentials, a path, a query, or a fragment: ${origin}`,\n );\n }\n return url.origin;\n}\n\nfunction assertLiquidSize(content: string): string {\n const size = Buffer.byteLength(content);\n if (size > MAX_LIQUID_BYTES) {\n throw new Error(\n `[easel] generated Liquid is ${size} bytes; reduce the number of bundles below ${MAX_LIQUID_BYTES} bytes`,\n );\n }\n return content;\n}\n","import type {Manifest, ManifestChunk} from 'vite';\nimport type {EaselManifest, EaselManifestEntry, ResolvedEaselBundle} from './types.js';\n\nexport function createEaselManifest(\n viteManifest: Manifest,\n bundles: ResolvedEaselBundle[],\n emittedFiles: string[] = [],\n): EaselManifest {\n const entries: Record<string, EaselManifestEntry> = {};\n const generated = new Set(emittedFiles);\n\n for (const bundle of bundles) {\n const chunk = findEntry(viteManifest, bundle.name);\n const {styles, imports} = collectStaticDependencies(viteManifest, chunk);\n\n if (bundle.script === undefined) {\n generated.delete(chunk.file);\n } else {\n generated.add(chunk.file);\n }\n for (const style of styles) generated.add(style);\n for (const imported of imports) generated.add(imported);\n collectGeneratedFiles(viteManifest, chunk, generated);\n\n entries[bundle.name] = {\n ...(bundle.script === undefined ? {} : {script: chunk.file}),\n styles,\n imports,\n };\n }\n\n return {\n schemaVersion: 1,\n entries,\n generated: [...generated].sort(),\n };\n}\n\nfunction findEntry(manifest: Manifest, name: string): ManifestChunk {\n const chunk = Object.values(manifest).find(\n (candidate) => candidate.isEntry === true && candidate.name === name,\n );\n if (chunk === undefined) {\n throw new Error(`[easel] Vite manifest does not contain bundle \"${name}\"`);\n }\n return chunk;\n}\n\nfunction collectStaticDependencies(\n manifest: Manifest,\n entry: ManifestChunk,\n): {styles: string[]; imports: string[]} {\n const styles = new Set<string>();\n const imports = new Set<string>();\n const visited = new Set<string>();\n\n const visit = (chunk: ManifestChunk): void => {\n for (const key of chunk.imports ?? []) {\n if (visited.has(key)) continue;\n visited.add(key);\n const imported = requiredChunk(manifest, key);\n imports.add(imported.file);\n visit(imported);\n }\n for (const style of chunk.css ?? []) styles.add(style);\n };\n\n visit(entry);\n return {styles: [...styles], imports: [...imports]};\n}\n\nfunction collectGeneratedFiles(\n manifest: Manifest,\n entry: ManifestChunk,\n files: Set<string>,\n): void {\n const visited = new Set<string>();\n\n const visit = (chunk: ManifestChunk): void => {\n for (const asset of chunk.assets ?? []) files.add(asset);\n for (const style of chunk.css ?? []) files.add(style);\n for (const key of [...(chunk.imports ?? []), ...(chunk.dynamicImports ?? [])]) {\n if (visited.has(key)) continue;\n visited.add(key);\n const imported = requiredChunk(manifest, key);\n files.add(imported.file);\n visit(imported);\n }\n };\n\n visit(entry);\n}\n\nfunction requiredChunk(manifest: Manifest, key: string): ManifestChunk {\n const chunk = manifest[key];\n if (chunk === undefined) {\n throw new Error(`[easel] Vite manifest import is missing: ${key}`);\n }\n return chunk;\n}\n","import {existsSync, readFileSync, rmSync} from 'node:fs';\nimport {dirname, join} from 'node:path';\nimport {acquireCommitLock} from './lock.js';\nimport {\n assertAssetWritable,\n assertLiquidWritable,\n isDevelopmentLiquid,\n isGeneratedLiquid,\n ownedAssetPath,\n ownedLiquidPath,\n readOwnershipLedger,\n} from './ownership.js';\nimport {\n recoverInterruptedCommit,\n runFileTransaction,\n safeResolve,\n writeIfChanged,\n} from './transaction.js';\nimport type {EaselManifest, EaselOwnershipLedger, ResolvedEaselOptions} from './types.js';\n\ninterface PreparedAsset {\n relativePath: string;\n destinationPath: string;\n content: Buffer;\n}\n\nexport function commitProductionOutput(\n options: ResolvedEaselOptions,\n manifest: EaselManifest,\n liquid: string,\n): void {\n const releaseLock = acquireCommitLock(options.commitLockPath);\n try {\n recoverInterruptedCommit(options);\n migrateLegacyProductionBackup(options);\n\n const previous = readOwnershipLedger(options);\n const previousFiles = new Set(previous?.generated ?? []);\n const assets = prepareAssets(options, manifest.generated);\n const nextFiles = new Set([\n ...assets.map((asset) => asset.relativePath),\n ownedLiquidPath(options),\n ]);\n\n assertProductionOutputWritable(options, assets, previousFiles);\n const stalePaths = [...previousFiles]\n .filter((file) => !nextFiles.has(file))\n .map((file) => safeResolve(options.themePath, file));\n\n runFileTransaction(options, changedOutputPaths(options, assets, stalePaths), () =>\n publishProductionOutput(options, manifest, liquid, assets, stalePaths, nextFiles),\n );\n } finally {\n releaseLock();\n }\n}\n\nexport function assertDevelopmentLiquidWritable(options: ResolvedEaselOptions): void {\n migrateLegacyProductionBackup(options);\n const previous = readOwnershipLedger(options);\n assertLiquidWritable(\n options.liquidPath,\n ownedLiquidPath(options),\n new Set(previous?.generated ?? []),\n );\n}\n\nexport function writeDevelopmentLiquid(\n options: ResolvedEaselOptions,\n content: string,\n): () => void {\n assertDevelopmentLiquidWritable(options);\n const currentContent = readOptionalFile(options.liquidPath);\n preserveProductionLiquid(options, currentContent);\n const productionContent =\n currentContent !== undefined && isDevelopmentLiquid(currentContent.toString())\n ? readProductionLiquidBackup(options)\n : currentContent;\n writeIfChanged(options.liquidPath, content);\n\n return () => restoreDevelopmentLiquid(options.liquidPath, content, productionContent);\n}\n\nfunction prepareAssets(\n options: ResolvedEaselOptions,\n generatedFiles: string[],\n): PreparedAsset[] {\n return generatedFiles.map((file) => {\n const sourcePath = safeResolve(options.stagingPath, file);\n if (!existsSync(sourcePath)) {\n throw new Error(`[easel] generated Vite asset is missing: ${sourcePath}`);\n }\n return {\n relativePath: ownedAssetPath(options, file),\n destinationPath: safeResolve(join(options.themePath, 'assets'), file),\n content: readFileSync(sourcePath),\n };\n });\n}\n\nfunction assertProductionOutputWritable(\n options: ResolvedEaselOptions,\n assets: PreparedAsset[],\n previousFiles: Set<string>,\n): void {\n for (const asset of assets) {\n assertAssetWritable(\n asset.destinationPath,\n asset.relativePath,\n asset.content,\n previousFiles,\n );\n }\n assertLiquidWritable(options.liquidPath, ownedLiquidPath(options), previousFiles);\n}\n\nfunction changedOutputPaths(\n options: ResolvedEaselOptions,\n assets: PreparedAsset[],\n stalePaths: string[],\n): string[] {\n return [\n ...assets.map((asset) => asset.destinationPath),\n options.liquidPath,\n options.productionLiquidPath,\n options.manifestPath,\n ...stalePaths,\n options.ledgerPath,\n ];\n}\n\nfunction publishProductionOutput(\n options: ResolvedEaselOptions,\n manifest: EaselManifest,\n liquid: string,\n assets: PreparedAsset[],\n stalePaths: string[],\n nextFiles: Set<string>,\n): void {\n for (const asset of assets) {\n writeIfChanged(asset.destinationPath, asset.content);\n }\n writeIfChanged(options.liquidPath, liquid);\n writeIfChanged(options.productionLiquidPath, liquid);\n writeIfChanged(options.manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`);\n\n for (const stale of stalePaths) {\n if (existsSync(stale)) rmSync(stale);\n }\n\n const ledger: EaselOwnershipLedger = {\n schemaVersion: 2,\n themePath: options.themePath,\n prefix: options.prefix,\n liquidFilename: options.liquidFilename,\n generated: [...nextFiles].sort(),\n };\n writeIfChanged(options.ledgerPath, `${JSON.stringify(ledger, null, 2)}\\n`);\n}\n\nfunction preserveProductionLiquid(\n options: ResolvedEaselOptions,\n currentContent: Buffer | undefined,\n): void {\n if (\n currentContent !== undefined &&\n isGeneratedLiquid(currentContent.toString()) &&\n !isDevelopmentLiquid(currentContent.toString())\n ) {\n writeIfChanged(options.productionLiquidPath, currentContent);\n } else if (currentContent === undefined && existsSync(options.productionLiquidPath)) {\n rmSync(options.productionLiquidPath);\n }\n}\n\nfunction restoreDevelopmentLiquid(\n liquidPath: string,\n developmentContent: string,\n productionContent: Buffer | undefined,\n): void {\n if (!existsSync(liquidPath)) return;\n if (readFileSync(liquidPath, 'utf8') !== developmentContent) return;\n if (productionContent === undefined) {\n rmSync(liquidPath);\n } else {\n writeIfChanged(liquidPath, productionContent);\n }\n}\n\nfunction migrateLegacyProductionBackup(options: ResolvedEaselOptions): void {\n const legacyPath = join(dirname(options.productionLiquidPath), 'production.liquid');\n if (!existsSync(legacyPath)) return;\n\n const legacyContent = readFileSync(legacyPath);\n if (!isGeneratedLiquid(legacyContent.toString())) {\n throw new Error(\n `[easel] legacy production backup is not generated by Easel: ${legacyPath}`,\n );\n }\n if (!existsSync(options.productionLiquidPath)) {\n writeIfChanged(options.productionLiquidPath, legacyContent);\n }\n rmSync(legacyPath);\n}\n\nfunction readProductionLiquidBackup(options: ResolvedEaselOptions): Buffer | undefined {\n const content = readOptionalFile(options.productionLiquidPath);\n return content !== undefined &&\n isGeneratedLiquid(content.toString()) &&\n !isDevelopmentLiquid(content.toString())\n ? content\n : undefined;\n}\n\nfunction readOptionalFile(path: string): Buffer | undefined {\n return existsSync(path) ? readFileSync(path) : undefined;\n}\n","import {randomUUID} from 'node:crypto';\nimport {\n lstatSync,\n mkdirSync,\n readFileSync,\n rmSync,\n statSync,\n writeFileSync,\n} from 'node:fs';\nimport {dirname, join} from 'node:path';\n\ninterface LockOwner {\n pid: number;\n token: string;\n}\n\nexport function acquireCommitLock(lockPath: string): () => void {\n mkdirSync(dirname(lockPath), {recursive: true});\n const token = randomUUID();\n\n for (let attempt = 0; attempt < 2; attempt += 1) {\n try {\n createLock(lockPath, token);\n return () => releaseLock(lockPath, token);\n } catch (error) {\n if (!isAlreadyExistsError(error)) throw error;\n if (!isStaleLock(lockPath)) {\n throw new Error(`[easel] another build is publishing this theme: ${lockPath}`);\n }\n rmSync(lockPath, {recursive: true});\n }\n }\n\n throw new Error(`[easel] could not acquire the theme commit lock: ${lockPath}`);\n}\n\nfunction createLock(lockPath: string, token: string): void {\n mkdirSync(lockPath);\n try {\n writeFileSync(\n join(lockPath, 'owner.json'),\n `${JSON.stringify({pid: process.pid, token})}\\n`,\n );\n } catch (error) {\n rmSync(lockPath, {recursive: true});\n throw error;\n }\n}\n\nfunction releaseLock(lockPath: string, token: string): void {\n if (readLockOwner(lockPath)?.token === token) {\n rmSync(lockPath, {recursive: true});\n }\n}\n\nfunction isStaleLock(lockPath: string): boolean {\n const metadata = lstatSync(lockPath);\n if (!metadata.isDirectory() || metadata.isSymbolicLink()) {\n throw new Error(`[easel] commit lock must be a real directory: ${lockPath}`);\n }\n const owner = readLockOwner(lockPath);\n if (owner === undefined) {\n return Date.now() - statSync(lockPath).mtimeMs > 30_000;\n }\n try {\n process.kill(owner.pid, 0);\n return false;\n } catch (error) {\n return isNodeError(error) && error.code === 'ESRCH';\n }\n}\n\nfunction readLockOwner(lockPath: string): LockOwner | undefined {\n try {\n const value = JSON.parse(\n readFileSync(join(lockPath, 'owner.json'), 'utf8'),\n ) as unknown;\n if (isLockOwner(value)) return value;\n } catch {\n return undefined;\n }\n return undefined;\n}\n\nfunction isLockOwner(value: unknown): value is LockOwner {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'pid' in value &&\n typeof value.pid === 'number' &&\n Number.isInteger(value.pid) &&\n value.pid > 0 &&\n 'token' in value &&\n typeof value.token === 'string' &&\n value.token.length > 0\n );\n}\n\nfunction isAlreadyExistsError(error: unknown): boolean {\n return isNodeError(error) && error.code === 'EEXIST';\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && 'code' in error;\n}\n","import {existsSync, readFileSync} from 'node:fs';\nimport {sep} from 'node:path';\nimport type {EaselOwnershipLedger, ResolvedEaselOptions} from './types.js';\nimport {\n SAFE_ASSET_FILENAME,\n SAFE_LIQUID_FILENAME,\n SAFE_OUTPUT_NAME,\n} from './validation.js';\n\nexport function readOwnershipLedger(\n options: ResolvedEaselOptions,\n): EaselOwnershipLedger | undefined {\n const path = options.ledgerPath;\n if (!existsSync(path)) return undefined;\n\n let value: unknown;\n try {\n value = JSON.parse(readFileSync(path, 'utf8')) as unknown;\n } catch {\n throw new Error(`[easel] ownership ledger is not valid JSON: ${path}`);\n }\n if (!isRecord(value) || value.themePath !== options.themePath) {\n throw invalidLedger(options);\n }\n\n if (value.schemaVersion === 1 && isLegacyGeneratedList(value.generated)) {\n return {\n schemaVersion: 2,\n themePath: options.themePath,\n prefix: options.prefix,\n liquidFilename: options.liquidFilename,\n generated: value.generated,\n };\n }\n\n if (!isCurrentLedger(value)) throw invalidLedger(options);\n return value;\n}\n\nexport function ownedAssetPath(\n options: Pick<ResolvedEaselOptions, 'prefix'>,\n file: string,\n): string {\n return namespacedAssetPath(options.prefix, file);\n}\n\nexport function ownedLiquidPath(\n options: Pick<ResolvedEaselOptions, 'liquidFilename'>,\n): string {\n return `snippets/${options.liquidFilename}`;\n}\n\nexport function assertAssetWritable(\n destinationPath: string,\n relativePath: string,\n content: Buffer,\n previousFiles: Set<string>,\n): void {\n if (\n existsSync(destinationPath) &&\n !previousFiles.has(relativePath) &&\n !readFileSync(destinationPath).equals(content)\n ) {\n throw new Error(\n `[easel] refusing to overwrite a file Easel does not own: ${destinationPath}`,\n );\n }\n}\n\nexport function assertLiquidWritable(\n absolutePath: string,\n relativePath: string,\n previousFiles: Set<string>,\n): void {\n if (!existsSync(absolutePath) || previousFiles.has(relativePath)) return;\n if (isGeneratedLiquid(readFileSync(absolutePath, 'utf8'))) return;\n throw new Error(\n `[easel] refusing to overwrite a Liquid file Easel does not own: ${absolutePath}`,\n );\n}\n\nexport function isGeneratedLiquid(content: string): boolean {\n return (\n content.startsWith('{% doc %}\\nGenerated asset loader managed by Easel.\\n') ||\n isDevelopmentLiquid(content)\n );\n}\n\nexport function isDevelopmentLiquid(content: string): boolean {\n return content.startsWith(\n '{% doc %}\\nGenerated development asset loader managed by Easel.\\n',\n );\n}\n\nfunction isCurrentLedger(\n value: Record<string, unknown>,\n): value is EaselOwnershipLedger & Record<string, unknown> {\n if (\n value.schemaVersion !== 2 ||\n typeof value.themePath !== 'string' ||\n typeof value.prefix !== 'string' ||\n typeof value.liquidFilename !== 'string'\n ) {\n return false;\n }\n const namespace = value.prefix.slice(0, -1);\n return (\n value.prefix.endsWith('-') &&\n SAFE_OUTPUT_NAME.test(namespace) &&\n SAFE_LIQUID_FILENAME.test(value.liquidFilename) &&\n isGeneratedList(value.generated, value.prefix, value.liquidFilename)\n );\n}\n\nfunction isLegacyGeneratedList(value: unknown): value is string[] {\n if (!Array.isArray(value) || !value.every((file) => typeof file === 'string')) {\n return false;\n }\n const snippets = value.filter((file) => file.startsWith('snippets/'));\n return (\n snippets.length === 1 &&\n SAFE_LIQUID_FILENAME.test(snippets[0]?.slice('snippets/'.length) ?? '') &&\n value.every(\n (file) => /^assets\\/[a-z0-9][a-z0-9._-]*$/.test(file) || file === snippets[0],\n )\n );\n}\n\nfunction isGeneratedList(\n value: unknown,\n prefix: string,\n liquidFilename: string,\n): value is string[] {\n return (\n Array.isArray(value) &&\n value.every(\n (file): file is string =>\n typeof file === 'string' && isOwnedThemePath(file, prefix, liquidFilename),\n )\n );\n}\n\nfunction isOwnedThemePath(file: string, prefix: string, liquidFilename: string): boolean {\n if (file === `snippets/${liquidFilename}`) return true;\n if (!file.startsWith('assets/')) return false;\n try {\n return namespacedAssetPath(prefix, file.slice('assets/'.length)) === file;\n } catch {\n return false;\n }\n}\n\nfunction namespacedAssetPath(prefix: string, file: string): string {\n const normalized = file.split(sep).join('/');\n if (\n !SAFE_ASSET_FILENAME.test(normalized) ||\n !normalized.startsWith(prefix) ||\n normalized === prefix\n ) {\n throw new Error(`[easel] generated asset is outside Easel's namespace: ${file}`);\n }\n return `assets/${normalized}`;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction invalidLedger(options: ResolvedEaselOptions): Error {\n return new Error(\n `[easel] invalid ownership ledger for ${options.themePath}: ${options.ledgerPath}`,\n );\n}\n","import {randomUUID} from 'node:crypto';\nimport {\n existsSync,\n lstatSync,\n mkdirSync,\n readFileSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from 'node:fs';\nimport {dirname, join, relative, resolve, sep} from 'node:path';\nimport type {ResolvedEaselOptions} from './types.js';\nimport {SAFE_ASSET_FILENAME, SAFE_LIQUID_FILENAME} from './validation.js';\n\ninterface TransactionEntry {\n scope: 'theme' | 'state';\n path: string;\n existed: boolean;\n blob?: string;\n}\n\ninterface TransactionJournal {\n schemaVersion: 1;\n themePath: string;\n entries: TransactionEntry[];\n}\n\ntype FileSnapshots = Map<string, Buffer | undefined>;\n\nfunction snapshotFiles(paths: string[]): FileSnapshots {\n return new Map(\n [...new Set(paths)].map((path) => [\n path,\n existsSync(path) ? readFileSync(path) : undefined,\n ]),\n );\n}\n\nfunction restoreSnapshots(snapshots: FileSnapshots): void {\n for (const [path, content] of snapshots) {\n if (content === undefined) {\n if (existsSync(path)) rmSync(path);\n } else {\n writeIfChanged(path, content);\n }\n }\n}\n\nfunction writeTransactionJournal(\n options: ResolvedEaselOptions,\n snapshots: FileSnapshots,\n): void {\n const temporary = `${options.transactionPath}-${randomUUID()}`;\n mkdirSync(temporary, {recursive: true});\n try {\n const entries: TransactionEntry[] = [];\n let index = 0;\n for (const [path, content] of snapshots) {\n const location = journalLocation(options, path);\n if (content === undefined) {\n entries.push({...location, existed: false});\n } else {\n const blob = `${index}.bin`;\n writeFileSync(join(temporary, blob), content);\n entries.push({...location, existed: true, blob});\n index += 1;\n }\n }\n const journal: TransactionJournal = {\n schemaVersion: 1,\n themePath: options.themePath,\n entries,\n };\n writeFileSync(\n join(temporary, 'journal.json'),\n `${JSON.stringify(journal, null, 2)}\\n`,\n );\n renameSync(temporary, options.transactionPath);\n } finally {\n if (existsSync(temporary)) rmSync(temporary, {recursive: true});\n }\n}\n\nexport function runFileTransaction(\n options: ResolvedEaselOptions,\n paths: string[],\n action: () => void,\n): void {\n const snapshots = snapshotFiles(paths);\n writeTransactionJournal(options, snapshots);\n\n try {\n action();\n rmSync(options.transactionPath, {recursive: true});\n } catch (error) {\n try {\n restoreSnapshots(snapshots);\n rmSync(options.transactionPath, {recursive: true, force: true});\n } catch (rollbackError) {\n throw new AggregateError(\n [error, rollbackError],\n '[easel] output commit failed and could not be rolled back completely',\n );\n }\n throw error;\n }\n}\n\nexport function recoverInterruptedCommit(options: ResolvedEaselOptions): void {\n if (!existsSync(options.transactionPath)) return;\n const metadata = lstatSync(options.transactionPath);\n if (!metadata.isDirectory() || metadata.isSymbolicLink()) {\n throw new Error(\n `[easel] transaction journal must be a real directory: ${options.transactionPath}`,\n );\n }\n\n let value: unknown;\n try {\n value = JSON.parse(\n readFileSync(join(options.transactionPath, 'journal.json'), 'utf8'),\n ) as unknown;\n } catch {\n throw new Error(\n `[easel] interrupted transaction journal is invalid: ${options.transactionPath}`,\n );\n }\n if (!isTransactionJournal(value) || value.themePath !== options.themePath) {\n throw new Error(\n `[easel] interrupted transaction journal is invalid: ${options.transactionPath}`,\n );\n }\n\n const snapshots: FileSnapshots = new Map();\n for (const entry of value.entries) {\n const path = resolveJournalLocation(options, entry);\n if (!entry.existed) {\n snapshots.set(path, undefined);\n continue;\n }\n if (entry.blob === undefined || !/^\\d+\\.bin$/.test(entry.blob)) {\n throw new Error(\n `[easel] interrupted transaction journal is invalid: ${options.transactionPath}`,\n );\n }\n const blobPath = join(options.transactionPath, entry.blob);\n if (!existsSync(blobPath)) {\n throw new Error(`[easel] interrupted transaction snapshot is missing: ${blobPath}`);\n }\n snapshots.set(path, readFileSync(blobPath));\n }\n\n restoreSnapshots(snapshots);\n rmSync(options.transactionPath, {recursive: true});\n}\n\nexport function safeResolve(root: string, path: string): string {\n const base = resolve(root);\n const result = resolve(base, path);\n const relativePath = relative(base, result);\n if (relativePath === '..' || relativePath.startsWith(`..${sep}`)) {\n throw new Error(`[easel] output escapes its allowed root: ${path}`);\n }\n return result;\n}\n\nexport function writeIfChanged(path: string, content: string | Buffer): void {\n const next = Buffer.isBuffer(content) ? content : Buffer.from(content);\n if (existsSync(path) && readFileSync(path).equals(next)) return;\n mkdirSync(dirname(path), {recursive: true});\n const temporary = `${path}.easel-${process.pid}-${Date.now()}`;\n writeFileSync(temporary, next);\n try {\n if (process.platform === 'win32' && existsSync(path)) {\n replaceFileOnWindows(temporary, path);\n } else {\n renameSync(temporary, path);\n }\n } finally {\n if (existsSync(temporary)) rmSync(temporary);\n }\n}\n\nfunction journalLocation(\n options: ResolvedEaselOptions,\n path: string,\n): Pick<TransactionEntry, 'scope' | 'path'> {\n const statePath = relativeWithin(dirname(options.ledgerPath), path);\n if (statePath !== undefined) {\n return assertJournalLocation({scope: 'state', path: statePath});\n }\n const themePath = relativeWithin(options.themePath, path);\n if (themePath !== undefined) {\n return assertJournalLocation({scope: 'theme', path: themePath});\n }\n throw new Error(`[easel] cannot journal output outside Easel's roots: ${path}`);\n}\n\nfunction resolveJournalLocation(\n options: ResolvedEaselOptions,\n entry: TransactionEntry,\n): string {\n assertJournalLocation(entry);\n const root = entry.scope === 'theme' ? options.themePath : dirname(options.ledgerPath);\n const path = safeResolve(root, entry.path);\n if (relativeWithin(root, path) !== entry.path) {\n throw new Error(\n `[easel] interrupted transaction journal contains an invalid path: ${entry.path}`,\n );\n }\n return path;\n}\n\nfunction assertJournalLocation<T extends Pick<TransactionEntry, 'scope' | 'path'>>(\n location: T,\n): T {\n const valid =\n location.scope === 'theme'\n ? isJournalThemePath(location.path)\n : ['outputs.json', 'production.txt', 'production.liquid', 'manifest.json'].includes(\n location.path,\n );\n if (!valid) {\n throw new Error(\n `[easel] transaction journal contains an invalid path: ${location.path}`,\n );\n }\n return location;\n}\n\nfunction isJournalThemePath(path: string): boolean {\n const [directory, filename, extra] = path.split('/');\n if (filename === undefined || extra !== undefined) return false;\n if (directory === 'assets') return SAFE_ASSET_FILENAME.test(filename);\n return directory === 'snippets' && SAFE_LIQUID_FILENAME.test(filename);\n}\n\nfunction relativeWithin(root: string, path: string): string | undefined {\n const value = relative(resolve(root), resolve(path));\n if (value === '' || value === '..' || value.startsWith(`..${sep}`)) {\n return undefined;\n }\n return value.split(sep).join('/');\n}\n\nfunction isTransactionJournal(value: unknown): value is TransactionJournal {\n if (\n typeof value !== 'object' ||\n value === null ||\n !('schemaVersion' in value) ||\n value.schemaVersion !== 1 ||\n !('themePath' in value) ||\n typeof value.themePath !== 'string' ||\n !('entries' in value) ||\n !Array.isArray(value.entries)\n ) {\n return false;\n }\n return value.entries.every((entry: unknown) => isTransactionEntry(entry));\n}\n\nfunction isTransactionEntry(entry: unknown): entry is TransactionEntry {\n return (\n typeof entry === 'object' &&\n entry !== null &&\n 'scope' in entry &&\n (entry.scope === 'theme' || entry.scope === 'state') &&\n 'path' in entry &&\n typeof entry.path === 'string' &&\n 'existed' in entry &&\n typeof entry.existed === 'boolean' &&\n (!('blob' in entry) || entry.blob === undefined || typeof entry.blob === 'string')\n );\n}\n\nfunction replaceFileOnWindows(temporary: string, destination: string): void {\n const backup = `${temporary}.previous`;\n renameSync(destination, backup);\n try {\n renameSync(temporary, destination);\n rmSync(backup);\n } catch (error) {\n if (existsSync(destination)) rmSync(destination);\n renameSync(backup, destination);\n throw error;\n }\n}\n","import {createHash, randomUUID} from 'node:crypto';\nimport {existsSync, lstatSync, realpathSync, statSync} from 'node:fs';\nimport {isAbsolute, join, relative, resolve, sep} from 'node:path';\nimport type {\n EaselBundle,\n EaselOptions,\n ResolvedEaselBundle,\n ResolvedEaselOptions,\n} from './types.js';\nimport {SAFE_OUTPUT_NAME} from './validation.js';\n\nconst DEFAULT_SOURCE = 'src';\nconst DEFAULT_NAMESPACE = 'easel';\nconst DEFAULT_REFRESH_SIGNAL = '.easel/shopify-ready';\nconst DEFAULT_REFRESH_DELAY = 100;\n\ntype EaselStatePaths = Pick<\n ResolvedEaselOptions,\n | 'stagingPath'\n | 'ledgerPath'\n | 'commitLockPath'\n | 'manifestPath'\n | 'productionLiquidPath'\n | 'transactionPath'\n>;\n\nexport function resolveEaselOptions(\n options: EaselOptions,\n projectRoot: string,\n): ResolvedEaselOptions {\n const root = realpathSync(resolve(projectRoot));\n const configuredThemePath = resolveFrom(root, options.theme ?? '.');\n assertTheme(configuredThemePath);\n const themePath = realpathSync(configuredThemePath);\n const configuredSourcePath = resolveFrom(root, options.source ?? DEFAULT_SOURCE);\n const namespace = options.namespace ?? DEFAULT_NAMESPACE;\n\n assertSource(configuredSourcePath);\n const sourcePath = realpathSync(configuredSourcePath);\n assertNamespace(namespace);\n const liquidFilename = `${namespace}-assets.liquid`;\n const prefix = `${namespace}-`;\n const refresh = resolveRefresh(options.refresh, root);\n\n const bundles = resolveBundles(options.bundles, sourcePath);\n const statePaths = resolveEaselStatePaths(root, themePath);\n\n return {\n projectRoot: root,\n themePath,\n sourcePath,\n ...statePaths,\n liquidPath: join(themePath, 'snippets', liquidFilename),\n liquidFilename,\n namespace,\n prefix,\n refresh,\n bundles,\n };\n}\n\nfunction resolveRefresh(\n configured: EaselOptions['refresh'],\n projectRoot: string,\n): ResolvedEaselOptions['refresh'] {\n if (configured === false) {\n return {\n enabled: false,\n signalPath: join(projectRoot, DEFAULT_REFRESH_SIGNAL),\n delay: DEFAULT_REFRESH_DELAY,\n };\n }\n\n const options = configured === true || configured === undefined ? {} : configured;\n const delay = options.delay ?? DEFAULT_REFRESH_DELAY;\n if (!Number.isInteger(delay) || delay < 0 || delay > 10_000) {\n throw new Error(\n '[easel] refresh.delay must be an integer from 0 to 10000 milliseconds',\n );\n }\n\n return {\n enabled: true,\n signalPath: resolveFrom(projectRoot, options.signal ?? DEFAULT_REFRESH_SIGNAL),\n delay,\n };\n}\n\nfunction resolveBundles(\n configured: Record<string, EaselBundle> | undefined,\n sourcePath: string,\n): ResolvedEaselBundle[] {\n const bundles = configured ?? {theme: resolveDefaultBundle(sourcePath)};\n const entries = Object.entries(bundles);\n\n if (entries.length === 0) {\n throw new Error('[easel] bundles must contain at least one named bundle');\n }\n\n const resolved = entries.map(([name, bundle]) => {\n if (!SAFE_OUTPUT_NAME.test(name)) {\n throw new Error(\n `[easel] invalid bundle name \"${name}\"; use lowercase letters, numbers, and hyphens`,\n );\n }\n if (bundle.script === undefined && bundle.style === undefined) {\n throw new Error(`[easel] bundle \"${name}\" needs a script, a style, or both`);\n }\n\n return {\n name,\n ...resolveBundleFiles(name, bundle, sourcePath),\n };\n });\n\n const scriptOwners = new Map<string, string>();\n for (const bundle of resolved) {\n if (bundle.script === undefined) continue;\n const owner = scriptOwners.get(bundle.script);\n if (owner !== undefined) {\n throw new Error(\n `[easel] bundles \"${owner}\" and \"${bundle.name}\" use the same script; each named bundle needs a distinct script entry`,\n );\n }\n scriptOwners.set(bundle.script, bundle.name);\n }\n\n return resolved;\n}\n\nfunction resolveDefaultBundle(sourcePath: string): EaselBundle {\n const typescriptEntry = join(sourcePath, 'main.ts');\n const javascriptEntry = join(sourcePath, 'main.js');\n const styleEntry = join(sourcePath, 'style.css');\n const hasTypescript = isFile(typescriptEntry);\n const hasJavascript = isFile(javascriptEntry);\n\n if (hasTypescript && hasJavascript) {\n throw new Error(\n `[easel] both main.ts and main.js exist in ${sourcePath}; configure bundles to choose one explicitly`,\n );\n }\n if (!hasTypescript && !hasJavascript) {\n throw new Error(\n `[easel] expected main.ts or main.js in ${sourcePath}; configure source or bundles for a different layout`,\n );\n }\n if (!isFile(styleEntry)) {\n throw new Error(\n `[easel] expected style.css in ${sourcePath}; configure bundles explicitly to build without a stylesheet`,\n );\n }\n\n return {\n script: hasTypescript ? typescriptEntry : javascriptEntry,\n style: styleEntry,\n };\n}\n\nfunction resolveBundleFiles(\n name: string,\n bundle: EaselBundle,\n sourcePath: string,\n): Omit<ResolvedEaselBundle, 'name'> {\n const resolved: Omit<ResolvedEaselBundle, 'name'> = {};\n\n if (bundle.script !== undefined) {\n resolved.script = resolveInput(name, 'script', bundle.script, sourcePath);\n }\n if (bundle.style !== undefined) {\n resolved.style = resolveInput(name, 'style', bundle.style, sourcePath);\n }\n\n return resolved;\n}\n\nfunction resolveInput(\n bundleName: string,\n kind: 'script' | 'style',\n input: string,\n sourcePath: string,\n): string {\n const path = resolveFrom(sourcePath, input);\n if (!isFile(path)) {\n throw new Error(`[easel] ${kind} for bundle \"${bundleName}\" does not exist: ${path}`);\n }\n return realpathSync(path);\n}\n\nfunction resolveEaselStatePaths(projectRoot: string, themePath: string): EaselStatePaths {\n const easelPath = join(projectRoot, '.easel');\n const themeId = createHash('sha256').update(themePath).digest('hex').slice(0, 16);\n const stagingParent = join(easelPath, 'build', themeId);\n const themeStatePath = join(easelPath, 'themes', themeId);\n assertEaselStatePaths([\n easelPath,\n join(easelPath, 'build'),\n stagingParent,\n join(easelPath, 'themes'),\n themeStatePath,\n ]);\n\n return {\n stagingPath: join(stagingParent, randomUUID()),\n ledgerPath: join(themeStatePath, 'outputs.json'),\n commitLockPath: join(themeStatePath, 'commit.lock'),\n manifestPath: join(themeStatePath, 'manifest.json'),\n productionLiquidPath: join(themeStatePath, 'production.txt'),\n transactionPath: join(themeStatePath, 'transaction'),\n };\n}\n\nfunction assertTheme(themePath: string): void {\n for (const directory of ['assets', 'layout', 'snippets']) {\n const path = join(themePath, directory);\n const metadata = lstatSync(path, {throwIfNoEntry: false});\n if (metadata?.isSymbolicLink()) {\n throw new Error(\n `[easel] Shopify theme output directory cannot be a symbolic link: ${path}`,\n );\n }\n if (metadata === undefined || !metadata.isDirectory()) {\n throw new Error(\n `[easel] invalid Shopify theme at ${themePath}: missing ${directory}/`,\n );\n }\n }\n}\n\nfunction assertEaselStatePaths(paths: string[]): void {\n for (const path of paths) {\n const metadata = lstatSync(path, {throwIfNoEntry: false});\n if (metadata === undefined) continue;\n if (metadata.isSymbolicLink() || !metadata.isDirectory()) {\n throw new Error(`[easel] state directory must be a real directory: ${path}`);\n }\n }\n}\n\nfunction assertSource(sourcePath: string): void {\n if (!existsSync(sourcePath) || !statSync(sourcePath).isDirectory()) {\n throw new Error(`[easel] source directory does not exist: ${sourcePath}`);\n }\n}\n\nfunction assertNamespace(namespace: string): void {\n if (!SAFE_OUTPUT_NAME.test(namespace)) {\n throw new Error(\n '[easel] namespace must use lowercase letters, numbers, and single hyphens',\n );\n }\n}\n\nfunction resolveFrom(base: string, path: string): string {\n return isAbsolute(path) ? resolve(path) : resolve(base, path);\n}\n\nfunction isFile(path: string): boolean {\n return existsSync(path) && statSync(path).isFile();\n}\n\nexport function projectRelative(path: string, projectRoot: string): string {\n const value = relative(projectRoot, path);\n return value.split(sep).join('/');\n}\n","import {existsSync, mkdirSync, statSync, writeFileSync} from 'node:fs';\nimport type {Stats} from 'node:fs';\nimport {dirname} from 'node:path';\n\nconst POLL_INTERVAL = 50;\n\nexport function watchRefreshSignal(\n signalPath: string,\n delay: number,\n refresh: () => void,\n): () => void {\n mkdirSync(dirname(signalPath), {recursive: true});\n if (!existsSync(signalPath)) writeFileSync(signalPath, '');\n\n let previous = readStats(signalPath);\n let timer: ReturnType<typeof setTimeout> | undefined;\n const poller = setInterval(() => {\n const current = readStats(signalPath);\n if (sameStats(current, previous)) return;\n previous = current;\n clearTimeout(timer);\n timer = setTimeout(refresh, delay);\n }, POLL_INTERVAL);\n poller.unref();\n\n return () => {\n clearTimeout(timer);\n clearInterval(poller);\n };\n}\n\nfunction readStats(path: string): Stats | undefined {\n try {\n return statSync(path);\n } catch {\n return undefined;\n }\n}\n\nfunction sameStats(current: Stats | undefined, previous: Stats | undefined): boolean {\n if (current === undefined || previous === undefined) return current === previous;\n return (\n current.mtimeMs === previous.mtimeMs &&\n current.ctimeMs === previous.ctimeMs &&\n current.size === previous.size\n );\n}\n","import type {ViteDevServer} from 'vite';\nimport {renderDevelopmentLiquid} from './liquid.js';\nimport {projectRelative} from './options.js';\nimport {assertDevelopmentLiquidWritable, writeDevelopmentLiquid} from './output.js';\nimport {watchRefreshSignal} from './refresh.js';\nimport type {ResolvedEaselOptions} from './types.js';\n\nexport function configureDevelopmentServer(\n server: ViteDevServer,\n options: ResolvedEaselOptions,\n): void {\n if (server.httpServer === null) {\n throw new Error(\n '[easel] Vite middleware mode is not supported; Easel requires the development server lifecycle',\n );\n }\n\n assertDevelopmentLiquidWritable(options);\n const stopWatching = configureRefresh(server, options);\n let restoreDevelopmentLiquid: (() => void) | undefined;\n let detachTerminationHandlers: (() => void) | undefined;\n\n server.httpServer.once('listening', () => {\n restoreDevelopmentLiquid = writeDevelopmentLiquid(\n options,\n renderDevelopmentLiquid(\n options.bundles.map((bundle) => bundle.name),\n developmentOrigin(server),\n ),\n );\n detachTerminationHandlers = restoreOnTermination(restoreDevelopmentLiquid);\n });\n server.httpServer.once('close', () => {\n stopWatching?.();\n detachTerminationHandlers?.();\n restoreDevelopmentLiquid?.();\n });\n}\n\n/*\n * Vite closes the server on SIGTERM, which runs the `close` handler above.\n * SIGINT (Ctrl+C) and SIGHUP (closed terminal) keep Node's default behavior\n * and end the process without closing the server, which would leave the\n * development loader pointing at a dead Vite origin.\n */\nconst TERMINATION_SIGNALS = ['SIGINT', 'SIGHUP'] as const;\n\nexport interface TerminationProcess {\n readonly pid: number;\n on(event: 'exit', listener: () => void): unknown;\n on(event: NodeJS.Signals, listener: (signal: NodeJS.Signals) => void): unknown;\n off(event: 'exit', listener: () => void): unknown;\n off(event: NodeJS.Signals, listener: (signal: NodeJS.Signals) => void): unknown;\n listenerCount(event: NodeJS.Signals): number;\n kill(pid: number, signal: NodeJS.Signals): unknown;\n}\n\n/*\n * signal-exit, which Rolldown bundles into every Vite 8 process, re-raises a\n * signal only when all remaining listeners are its own, counted through these\n * shared globals. Easel counts them the same way so that neither observer waits\n * on the other while both still defer to a listener that owns shutdown.\n */\nfunction signalExitListenerCount(): number {\n const current = (globalThis as Record<symbol, unknown>)[\n Symbol.for('signal-exit emitter')\n ];\n const legacy = (process as {__signal_exit_emitter__?: unknown}).__signal_exit_emitter__;\n return emitterCount(current) + emitterCount(legacy);\n}\n\nfunction emitterCount(emitter: unknown): number {\n if (typeof emitter !== 'object' || emitter === null) return 0;\n const {count} = emitter as {count?: unknown};\n return typeof count === 'number' ? count : 0;\n}\n\n/**\n * Restores the production loader when the process ends without closing the\n * Vite server. The restore is synchronous, so it completes inside `exit` and\n * signal listeners. Returns a function that detaches the listeners.\n */\nexport function restoreOnTermination(\n restore: () => void,\n target: TerminationProcess = process,\n passiveListenerCount: () => number = signalExitListenerCount,\n): () => void {\n let restored = false;\n const restoreOnce = () => {\n if (restored) return;\n restored = true;\n restore();\n };\n\n const onExit = () => restoreOnce();\n const onSignal = (signal: NodeJS.Signals) => {\n restoreOnce();\n detach();\n // Re-raise so the default handler ends the process with the conventional\n // signal status, unless another listener has taken over shutdown.\n if (target.listenerCount(signal) <= passiveListenerCount()) {\n target.kill(target.pid, signal);\n }\n };\n const detach = () => {\n target.off('exit', onExit);\n for (const signal of TERMINATION_SIGNALS) target.off(signal, onSignal);\n };\n\n target.on('exit', onExit);\n for (const signal of TERMINATION_SIGNALS) target.on(signal, onSignal);\n return detach;\n}\n\nfunction configureRefresh(\n server: ViteDevServer,\n options: ResolvedEaselOptions,\n): (() => void) | undefined {\n if (!options.refresh.enabled) return undefined;\n\n const stopWatching = watchRefreshSignal(\n options.refresh.signalPath,\n options.refresh.delay,\n () => server.ws.send({type: 'full-reload', path: '*'}),\n );\n server.config.logger.info(\n `[easel] Shopify refresh signal: ${projectRelative(\n options.refresh.signalPath,\n options.projectRoot,\n )}`,\n );\n return stopWatching;\n}\n\nfunction developmentOrigin(server: ViteDevServer): string {\n const origin =\n server.config.server.origin ??\n server.resolvedUrls?.local[0] ??\n server.resolvedUrls?.network[0];\n if (origin === undefined) {\n throw new Error(\n '[easel] Vite did not expose a development URL; set server.origin explicitly',\n );\n }\n return origin;\n}\n","import type {ConfigEnv, ResolvedConfig, UserConfig} from 'vite';\nimport {resolveEaselOptions} from './options.js';\nimport type {EaselOptions, ResolvedEaselOptions} from './types.js';\nimport {virtualBundleId} from './virtual.js';\n\nexport interface PreparedViteConfig {\n options: ResolvedEaselOptions;\n config: UserConfig;\n}\n\nexport function prepareViteConfig(\n easelOptions: EaselOptions,\n userConfig: UserConfig,\n command: ConfigEnv['command'],\n): PreparedViteConfig {\n const options = resolveEaselOptions(easelOptions, userConfig.root ?? process.cwd());\n\n switch (command) {\n case 'build':\n assertCompatibleBuildConfig(userConfig);\n break;\n case 'serve':\n break;\n }\n\n return {\n options,\n config: createViteConfig(userConfig, options, command),\n };\n}\n\nexport function validateResolvedViteConfig(\n config: ResolvedConfig,\n options: ResolvedEaselOptions,\n): void {\n switch (config.command) {\n case 'build':\n assertResolvedBuildConfig(config, options);\n assertNoLaterPostBuildHooks(config);\n break;\n case 'serve':\n break;\n }\n}\n\nfunction createViteConfig(\n config: UserConfig,\n options: ResolvedEaselOptions,\n command: ConfigEnv['command'],\n): UserConfig {\n const stableCssEntryIds = new Set(\n options.bundles.map((bundle) => `easel:${bundle.name}`),\n );\n const input = Object.fromEntries(\n options.bundles.map((bundle) => [bundle.name, virtualBundleId(bundle.name)]),\n );\n\n return {\n ...(command === 'build' ? {base: './'} : {}),\n build: {\n outDir: options.stagingPath,\n emptyOutDir: true,\n assetsDir: '',\n manifest: true,\n rollupOptions: {\n input,\n output: {\n entryFileNames: `${options.prefix}[name].js`,\n chunkFileNames: (chunk) =>\n `${options.prefix}${sharedChunkName(chunk)}-[hash].js`,\n assetFileNames(asset) {\n const original = asset.names[0] ?? asset.name ?? 'asset';\n if (!original.endsWith('.css')) {\n return `${options.prefix}[name]-[hash][extname]`;\n }\n return isEntryStylesheet(asset.originalFileNames, stableCssEntryIds)\n ? `${options.prefix}[name].css`\n : `${options.prefix}[name]-[hash].css`;\n },\n },\n },\n },\n server: {\n ...(config.server?.cors === undefined ? {cors: shopifyCorsPolicy()} : {}),\n fs: {\n allow: easelFileSystemAllowList(config.server?.fs?.allow ?? [], options),\n },\n },\n };\n}\n\nconst STYLESHEET_MODULE = /\\.(?:css|less|sass|scss|styl|stylus|pcss|postcss|sss)(?:\\?|$)/;\n\n/*\n * A stylesheet shared by several bundles lands in a shared chunk, and the\n * bundler can name that chunk after the stylesheet. The extracted CSS keeps\n * that name; the JavaScript file is named after its last JavaScript module\n * instead, which matches how Rollup names shared chunks without stylesheets.\n */\nfunction sharedChunkName(chunk: {name: string; moduleIds: string[]}): string {\n const namedAfterStylesheet = chunk.moduleIds.some(\n (id) => STYLESHEET_MODULE.test(id) && moduleBasename(id) === chunk.name,\n );\n if (!namedAfterStylesheet) return '[name]';\n\n const script = chunk.moduleIds\n .filter((id) => !id.startsWith('\\0') && !STYLESHEET_MODULE.test(id))\n .at(-1);\n const name = script === undefined ? '' : moduleBasename(script);\n return /^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(name) ? name : '[name]';\n}\n\nfunction moduleBasename(id: string): string {\n const path = id.replaceAll('\\\\', '/').split('?')[0] ?? '';\n const file = path.slice(path.lastIndexOf('/') + 1);\n const extension = file.lastIndexOf('.');\n return extension > 0 ? file.slice(0, extension) : file;\n}\n\nfunction isEntryStylesheet(\n originalFileNames: string[],\n stableCssEntryIds: Set<string>,\n): boolean {\n return originalFileNames.some((file) => {\n const normalized = file.replaceAll('\\\\', '/');\n return stableCssEntryIds.has(normalized.slice(normalized.lastIndexOf('/') + 1));\n });\n}\n\nfunction shopifyCorsPolicy(): {origin: RegExp[]} {\n return {\n origin: [\n /^https?:\\/\\/(?:[^.]+\\.)*myshopify\\.com$/,\n /^https:\\/\\/admin\\.shopify\\.com$/,\n /^https?:\\/\\/(?:localhost|127\\.0\\.0\\.1|\\[::1\\])(?::\\d+)?$/,\n ],\n };\n}\n\nfunction easelFileSystemAllowList(\n configured: string[],\n options: ResolvedEaselOptions,\n): string[] {\n const existing = new Set(configured);\n return unique([options.projectRoot, options.sourcePath]).filter(\n (path) => !existing.has(path),\n );\n}\n\nfunction assertCompatibleBuildConfig(config: UserConfig): void {\n const build = config.build;\n const conflict = firstViolation([\n [\n config.base !== undefined && config.base !== './',\n 'Vite base must be \"./\" for Shopify CDN assets',\n ],\n [\n build?.outDir !== undefined,\n 'build.outDir conflicts with Easel staging; configure the Shopify theme with easel({ theme }) instead',\n ],\n [\n build?.emptyOutDir !== undefined,\n 'build.emptyOutDir is managed by Easel for safe staging',\n ],\n [\n build?.assetsDir !== undefined,\n 'build.assetsDir is managed by Easel for flat Shopify assets',\n ],\n [build?.manifest !== undefined, 'build.manifest is managed by Easel'],\n [build?.write === false, 'build.write must remain enabled'],\n [\n build?.rollupOptions?.input !== undefined,\n 'build.rollupOptions.input conflicts with Easel bundles',\n ],\n [\n build?.rollupOptions?.output !== undefined,\n 'build.rollupOptions.output is managed by Easel',\n ],\n ]);\n if (conflict !== undefined) throw new Error(`[easel] ${conflict}`);\n}\n\nfunction assertResolvedBuildConfig(\n config: ResolvedConfig,\n options: ResolvedEaselOptions,\n): void {\n const violation = firstViolation([\n [config.base !== './', 'resolved Vite base must be \"./\"'],\n [\n config.build.outDir !== options.stagingPath,\n \"another Vite plugin changed Easel's staging directory\",\n ],\n [\n config.build.assetsDir !== '',\n \"another Vite plugin changed Easel's flat asset layout\",\n ],\n [\n config.build.emptyOutDir !== true,\n \"another Vite plugin disabled Easel's staging cleanup\",\n ],\n [\n config.build.manifest !== true,\n \"another Vite plugin changed Easel's manifest setting\",\n ],\n [config.build.write === false, 'build.write must remain enabled'],\n ]);\n if (violation !== undefined) throw new Error(`[easel] ${violation}`);\n}\n\nfunction firstViolation(\n checks: [violated: boolean, message: string][],\n): string | undefined {\n return checks.find(([violated]) => violated)?.[1];\n}\n\nfunction assertNoLaterPostBuildHooks(config: ResolvedConfig): void {\n const easelIndex = config.plugins.findIndex(\n (plugin) => plugin.name === 'easel:shopify-theme',\n );\n const unsafe = config.plugins.slice(easelIndex + 1).filter(hasPostOutputHook);\n if (unsafe.length > 0) {\n throw new Error(\n `[easel] Easel must run after plugins with post-order output hooks: ${unsafe\n .map((plugin) => plugin.name)\n .join(', ')}. Move easel() after those plugins.`,\n );\n }\n}\n\nfunction hasPostOutputHook(plugin: ResolvedConfig['plugins'][number]): boolean {\n return [plugin.writeBundle, plugin.closeBundle].some(\n (hook) => typeof hook === 'object' && hook.order === 'post',\n );\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values)];\n}\n","import type {Plugin, ResolvedConfig} from 'vite';\nimport {finalizeProductionBuild} from './build.js';\nimport {configureDevelopmentServer} from './development.js';\nimport type {EaselOptions, ResolvedEaselOptions} from './types.js';\nimport {easelBundleModules} from './virtual.js';\nimport {prepareViteConfig, validateResolvedViteConfig} from './vite-config.js';\n\ninterface BuildLifecycle {\n failed: boolean;\n outputHooksCompleted: boolean;\n}\n\nexport function easel(options: EaselOptions = {}): Plugin[] {\n let resolvedOptions: ResolvedEaselOptions | undefined;\n let resolvedConfig: ResolvedConfig | undefined;\n const build: BuildLifecycle = {\n failed: false,\n outputHooksCompleted: false,\n };\n\n const requireOptions = (): ResolvedEaselOptions => {\n if (resolvedOptions === undefined) {\n throw new Error('[easel] plugin options have not been resolved');\n }\n return resolvedOptions;\n };\n\n const integration: Plugin = {\n name: 'easel:shopify-theme',\n enforce: 'post',\n config(config, environment) {\n const prepared = prepareViteConfig(options, config, environment.command);\n resolvedOptions = prepared.options;\n return prepared.config;\n },\n configResolved(config) {\n resolvedConfig = config;\n validateResolvedViteConfig(config, requireOptions());\n },\n configureServer(server) {\n configureDevelopmentServer(server, requireOptions());\n },\n buildStart() {\n build.failed = false;\n build.outputHooksCompleted = false;\n },\n buildEnd(error) {\n if (error !== undefined) build.failed = true;\n },\n writeBundle: {\n order: 'post',\n sequential: true,\n handler() {\n build.outputHooksCompleted = true;\n },\n },\n closeBundle: {\n order: 'post',\n sequential: true,\n handler() {\n const config = resolvedConfig;\n if (config?.command !== 'build') return;\n finalizeProductionBuild(\n requireOptions(),\n config,\n !build.failed && build.outputHooksCompleted,\n );\n },\n },\n };\n\n return [easelBundleModules(() => requireOptions().bundles), integration];\n}\n"],"mappings":"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","names":["existsSync","readFileSync","rmSync","join","existsSync","readFileSync","rmSync","dirname","join","readFileSync","readFileSync","randomUUID","existsSync","lstatSync","mkdirSync","readFileSync","rmSync","writeFileSync","dirname","join","sep","existsSync","readFileSync","rmSync","randomUUID","mkdirSync","writeFileSync","join","lstatSync","sep","dirname","releaseLock","existsSync","join","readFileSync","rmSync","dirname","join","existsSync","readFileSync","rmSync","randomUUID","existsSync","lstatSync","statSync","join","relative","resolve","sep","resolve","join","randomUUID","lstatSync","existsSync","statSync","relative","sep","existsSync","mkdirSync","statSync","writeFileSync","dirname","restoreDevelopmentLiquid"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vite-plugin-shopify-easel",
3
- "version": "0.2.0",
4
- "description": "A Vite build adapter for Shopify Liquid themes",
3
+ "version": "0.2.2",
4
+ "description": "Vite plugin for Shopify Liquid themes with HMR, safe asset builds, named bundles, and generated Liquid loaders",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "repository": {
@@ -12,16 +12,24 @@
12
12
  "bugs": "https://github.com/BillyNoyes/Easel/issues",
13
13
  "keywords": [
14
14
  "shopify",
15
+ "shopify-theme",
16
+ "shopify-liquid",
15
17
  "liquid",
16
18
  "theme",
17
- "vite"
19
+ "theme-development",
20
+ "theme-assets",
21
+ "storefront",
22
+ "vite",
23
+ "vite-plugin",
24
+ "hmr"
18
25
  ],
19
26
  "types": "./dist/index.d.ts",
20
27
  "exports": {
21
28
  ".": {
22
29
  "types": "./dist/index.d.ts",
23
30
  "import": "./dist/index.js"
24
- }
31
+ },
32
+ "./package.json": "./package.json"
25
33
  },
26
34
  "files": [
27
35
  "dist"
@@ -50,6 +58,10 @@
50
58
  "vitest": "^4.0.0"
51
59
  },
52
60
  "license": "MIT",
61
+ "author": {
62
+ "name": "Billy Noyes",
63
+ "url": "https://billynoyes.co.uk/"
64
+ },
53
65
  "scripts": {
54
66
  "build": "tsup src/index.ts --format esm --dts --sourcemap --clean",
55
67
  "check": "pnpm format:check && pnpm lint && pnpm typecheck && pnpm test && pnpm test:examples && pnpm test:site && pnpm build && pnpm test:package",