vite-plugin-shopify-easel 0.1.0-beta.1
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/LICENSE +21 -0
- package/README.md +158 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +1363 -0
- package/dist/index.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +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"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vite-plugin-shopify-easel",
|
|
3
|
+
"version": "0.1.0-beta.1",
|
|
4
|
+
"description": "A Vite build adapter for Shopify Liquid themes",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/BillyNoyes/Easel.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://easel.billynoyes.co.uk/",
|
|
12
|
+
"bugs": "https://github.com/BillyNoyes/Easel/issues",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"shopify",
|
|
15
|
+
"liquid",
|
|
16
|
+
"theme",
|
|
17
|
+
"vite"
|
|
18
|
+
],
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"import": "./dist/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public",
|
|
31
|
+
"provenance": true
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsup src/index.ts --format esm --dts --sourcemap --clean",
|
|
35
|
+
"check": "pnpm format:check && pnpm lint && pnpm typecheck && pnpm test && pnpm test:examples && pnpm test:site && pnpm build && pnpm test:package",
|
|
36
|
+
"format": "prettier --write .",
|
|
37
|
+
"format:check": "prettier --check .",
|
|
38
|
+
"lint": "eslint .",
|
|
39
|
+
"prepublishOnly": "pnpm check",
|
|
40
|
+
"scaffold:theme": "node scripts/scaffold-theme.mjs",
|
|
41
|
+
"test": "vitest run",
|
|
42
|
+
"test:example:alpine-tailwind": "pnpm --dir examples/alpine-tailwind check",
|
|
43
|
+
"test:example:react": "pnpm --dir examples/react check",
|
|
44
|
+
"test:example:vanilla": "pnpm --dir examples/vanilla check",
|
|
45
|
+
"test:example:vue": "pnpm --dir examples/vue check",
|
|
46
|
+
"test:examples": "node scripts/check-examples.mjs",
|
|
47
|
+
"test:package": "node scripts/check-package.mjs",
|
|
48
|
+
"test:site": "pnpm --dir site check",
|
|
49
|
+
"test:theme-check": "node scripts/check-themes.mjs",
|
|
50
|
+
"test:watch": "vitest",
|
|
51
|
+
"typecheck": "tsc --noEmit",
|
|
52
|
+
"tmp:env": "node /tmp/easel-env-check.mjs"
|
|
53
|
+
},
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=22.12.0"
|
|
56
|
+
},
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"vite": "^7.0.0 || ^8.0.0"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@tailwindcss/vite": "4.3.3",
|
|
62
|
+
"@types/node": "^24.0.0",
|
|
63
|
+
"alpinejs": "3.17.1",
|
|
64
|
+
"eslint": "^10.9.1",
|
|
65
|
+
"prettier": "^3.9.6",
|
|
66
|
+
"tailwindcss": "4.3.3",
|
|
67
|
+
"tsup": "^8.5.0",
|
|
68
|
+
"typescript": "^5.9.0",
|
|
69
|
+
"typescript-eslint": "^8.68.0",
|
|
70
|
+
"vite": "^8.0.0",
|
|
71
|
+
"vitest": "^4.0.0"
|
|
72
|
+
},
|
|
73
|
+
"license": "MIT",
|
|
74
|
+
"packageManager": "pnpm@10.28.0"
|
|
75
|
+
}
|