diff --git a/.gitignore b/.gitignore index 602799e0..ec972b9d 100755 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,4 @@ test/e2e/custom/dist dump.rdb !packages/tests packages/**/dist - - - +dist/ diff --git a/dist/api.js b/dist/api.js deleted file mode 100644 index 1f10835e..00000000 --- a/dist/api.js +++ /dev/null @@ -1,36 +0,0 @@ -'use strict'; - -var syncify_js = require('./syncify.js'); - -// syncify/api.ts -function api(resource, options) { - if (syncify_js.isString(resource)) { - if (resource === "watch" || resource === "build" || resource === "export" || resource === "import" || resource === "upload") { - return (cb) => syncify_js.syncify(); - } else { - throw new Error([ - "Invalid Resource, available resource modes via API:", - "", - '- "watch"', - '- "build"', - '- "export"', - '- "import"', - '- "upload"', - "" - ].join("\n")); - } - } else if (syncify_js.isObject(resource)) { - if (!syncify_js.isUndefined(options)) { - throw new Error("You cannot provide options when running instance"); - } - return { - watch: (cb) => syncify_js.syncify(), - build: (cb) => syncify_js.syncify(), - download: (cb) => syncify_js.syncify(), - upload: (cb) => syncify_js.syncify() - }; - } -} -var api_default = api; - -module.exports = api_default; diff --git a/dist/cli.js b/dist/cli.js deleted file mode 100644 index fd4f74a1..00000000 --- a/dist/cli.js +++ /dev/null @@ -1,615 +0,0 @@ -'use strict'; - -var syncify_js = require('./syncify.js'); -var node_path = require('node:path'); -var node_process = require('node:process'); -var node_util = require('node:util'); - -// syncify/cli/help/utils.ts -function describe(message) { - return syncify_js.$.terminal.cols < 75 ? "" : syncify_js.gray2(`\u203A ${message}`); -} -function highlight(input) { - return input.replace(/([${}<>])/g, syncify_js.gray2("$1")).replace(/(,)(?= -)/g, syncify_js.gray2("$1")).replace(/(\[options\])/g, `${syncify_js.LSB}options${syncify_js.RSB}`).replace(/(?<= )(-|--)(?=[a-zA-Z]+)/g, syncify_js.gray2("$1")); -} -function encase({ banner = false }) { - const arrow = `${syncify_js.Encase("SB", syncify_js.gray2("\u25B2"))} AND DOWN ${syncify_js.Encase("SB", syncify_js.gray2("\u25BC"))}`; - const label = syncify_js.gray2(`UP ${arrow} ARROW KEYS TO SCROLL`); - const header = syncify_js.Create().Break(2).Top(label, false).Newline(); - const footer = syncify_js.Create().Newline(2).End(label, false).Break(); - if (banner) { - header.Line("\u2588\u2580\u2580 \u2588 \u2588 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2580\u2588\u2580 \u2588\u2580\u2580 \u2588 \u2588", syncify_js.lightGray).Line("\u2580\u2580\u2588 \u2580\u2580\u2588 \u2588 \u2588 \u2588 \u2588 \u2588\u2580\u2580 \u2580\u2580\u2588", syncify_js.lightGray).Line("\u2580\u2580\u2580 \u2580\u2580\u2580 \u2580 \u2580 \u2580\u2580\u2580 \u2580\u2580\u2580 \u2580 \u2580\u2580\u2580", syncify_js.lightGray).Newline(); - } - return [header.toString(), footer]; -} - -// syncify/cli/help/default.ts -function Default() { - syncify_js.Create().Header(`HELP${syncify_js.COL}`, syncify_js.bold2).Line(` $ sy help ${describe("Prints this screen")}`).Line(` $ sy help {mode} ${describe("Pick a mode and view usage guide")}`).Line(` $ sy help examples ${describe("Real world command line examples")}`).Header(`USAGE${syncify_js.COL}`, syncify_js.bold2).Line(` $ sy {mode} ${describe("Command mode is required")}`).Line(` $ sy {mode} --flags ${describe("Flags can be provided to modes")}`).Line(` $ sy {mode} [options] ${describe("Some modes accept positionals")}`).Line(` $ sy {mode} [options] --flags ${describe("Mode with positional and flags")}`).Header("MODES" + syncify_js.COL, syncify_js.bold2).Line(` $ sy init ${describe("Setup Syncify in existing project")}`).Line(` $ sy build ${describe("Build theme from source")}`).Line(` $ sy watch ${describe("Watch and rebuild changes")}`).Line(` $ sy pull ${describe("Download from a store theme")}`).Line(` $ sy push ${describe("Upload to a store theme")}`).Line(` $ sy create ${describe("Create a new Syncify project")}`).Line(` $ sy publish ${describe("Changes a theme role to and makes it main")}`, syncify_js.dim2).Line(` $ sy delete ${describe("Remove files/resources from a store or theme")}`, syncify_js.dim2).Line(` $ sy pack ${describe("Generate a .zip package of the current theme")}`, syncify_js.dim2).Line(` $ sy link ${describe("Link existing themes/s from a store")}`).Line(` $ sy unlink ${describe("Remove a linked theme/s from project")}`, syncify_js.dim2).Line(` $ sy duplicate ${describe("Duplicates an existing theme in a store")}`).Line(` $ sy keychain ${describe("Access the global token keychain")}`).Line(` $ sy git ${describe("Git integration configuration and information")}`, syncify_js.dim2).Line(` $ sy prune ${describe("Clears internal project caches from disk")}`, syncify_js.dim2).Line(` $ sy inspect ${describe("Prints information about Syncify installation")}`).Line(` $ sy projects ${describe("Lists all Syncify projects on this device")}`).Line(` $ sy doctor ${describe("Diagnostics and fixable operations")}`, syncify_js.dim2).Line(` $ sy help ${describe("Print complete command list")}`).Header(`FLAGS${syncify_js.COL}`, syncify_js.bold2).Line(` --input, -i ${describe("Define input (source) directory")}`).Line(` --output, -o ${describe("Define output directory")}`).Line(` --config, -c ${describe("Define config directory")}`).Line(` --hot, -h ${describe("HOT Reload when running watch mode")}`).Line(` --target, -T ${describe("Theme and store targeting")}`).Line(` --filter, -F ${describe("File filtering and globs")}`).Line(` --align ${describe("Subset theme file merge with remote sources")}`).Line(` --new ${describe("Used with sy pull to create a new theme")}`).Line(` --bind ${describe("Live bindings in watch mode")}`).Line(` --dev ${describe("Development environment (default)")}`).Line(` --prod ${describe("Production environment")}`).Line(` --terse ${describe("Terse distribution (minification)")}`).Line(` --clean ${describe("Clean output directory")}`).Line(` --silent ${describe("Suppress logging via stdout")}`).Line(` --patch ${describe("Apply a patch version bump")}`).Line(` --minor ${describe("Apply a minor version bump")}`).Line(` --major ${describe("Apply a major version bump")}`).Line(` --force ${describe("Force overwrite or action (caution)")}`).Line(` --batch ${describe("Control batch limit (default is 10)")}`).Ruler().Append("\xA9 2025 \u039D\u03B9\u03BA\u03BF\u03BB\u03B1\u03C2 \u03A3\u03B1\u03B2\u03B2\u03B9\u03B4\u03B7\u03C2", syncify_js.gray2.bold).Line(`Version${syncify_js.COL} ${syncify_js.$.version}`, syncify_js.gray2).Line(`License${syncify_js.COL} Apache 2.0`, syncify_js.gray2).Line(`Website${syncify_js.COL} ${syncify_js.underline2("https://syncify.sh")}`, syncify_js.gray2).Line(`Github${syncify_js.COL} ${syncify_js.underline2("https://github.com/panoply/syncify")}`, syncify_js.gray2).Line(`Discord${syncify_js.COL} ${syncify_js.underline2("https://discord.gg/shopify-developers-597504637167468564")}`, syncify_js.gray2).Newline().toString((input) => { - const [header, footer] = encase({ banner: true }); - const heading = syncify_js.Scroll({ input: header, height: 8 }); - const content = syncify_js.Scroll({ - input: highlight(input), - yPos: 8, - height: syncify_js.$.terminal.rows - 12 - }); - heading.print(); - content.print(); - content.setKeypress(syncify_js.$.terminal.rows, content.maxHeight); - footer.toLog(); - }); -} - -// syncify/cli/help/information.ts -function Inspect() { - syncify_js.log.clear(); - syncify_js.Create().BR.Top("Inspect").Header(`${syncify_js.white2.bold("@syncify/cli")}`).Line(`${syncify_js.gray2("VERSION")}${syncify_js.COL} v${syncify_js.whiteBright2("1.0.0-alpha.1")}`).Line(`${syncify_js.gray2("HOT")}${syncify_js.COL} v${syncify_js.whiteBright2("0.4.9")}`).Line(`${syncify_js.gray2("LICENSE")}${syncify_js.COL} ${syncify_js.whiteBright2("Apache 2.0")}`).Line(`${syncify_js.gray2("AUTHOR")}${syncify_js.COL} ${syncify_js.whiteBright2("\u039D\u03B9\u03BA\u03BF\u03BB\u03B1\u03C2 \u03A3\u03B1\u03B2\u03B2\u03B9\u03B4\u03B7\u03C2")}`).Line(`${syncify_js.gray2("PM")}${syncify_js.COL} ${syncify_js.whiteBright2(syncify_js.$.pm)}`).Line(`${syncify_js.gray2("OS")}${syncify_js.COL} ${syncify_js.whiteBright2(syncify_js.$.platform)}`).Line(`${syncify_js.gray2("BINARY")}${syncify_js.COL} ${syncify_js.whiteBright2(syncify_js.$.using)}`).Line(`${syncify_js.gray2("CWD")}${syncify_js.COL} ${syncify_js.whiteBright2(syncify_js.$.cwd)}`).Line(`${syncify_js.gray2("HASH")}${syncify_js.COL} ${syncify_js.whiteBright2(syncify_js.$.hash)}`).Line(`${syncify_js.gray2("SCRIPT")}${syncify_js.COL} ${syncify_js.whiteBright2(syncify_js.$.bin)}`).Line(`${syncify_js.gray2("MODULE")}${syncify_js.COL} ${syncify_js.whiteBright2(syncify_js.$.dirs.module)}`).Line(`${syncify_js.gray2("STORE")}${syncify_js.COL} ${syncify_js.whiteBright2(syncify_js.$.home)}`).Line(`${syncify_js.gray2("KEYCHAIN")}${syncify_js.COL} ${syncify_js.whiteBright2(`${syncify_js.$.file.keychain}`)}`).Line(`${syncify_js.gray2("GITHUB")}${syncify_js.COL} ${syncify_js.whiteBright2(syncify_js.$.github)}`).Line(`${syncify_js.gray2("WEBSITE")}${syncify_js.COL} ${syncify_js.whiteBright2("https://syncify.sh")}`).NL.End("Inspect").BR.toLog().Break(); -} -function Version() { - syncify_js.log.clear(); - syncify_js.Create().BR.Top("Versions", false).NL.Line(`${syncify_js.whiteBright2("@syncify/cli")} ${syncify_js.ARR} ${syncify_js.whiteBright2("v1.0.0-alpha.1")}`).Line(`${syncify_js.whiteBright2("@syncify/hot")} ${syncify_js.ARR} ${syncify_js.whiteBright2("v0.4.9")}`).NL.End("Versions", false).BR.toLog().Break(); -} - -// syncify/cli/help/descriptions.ts -var description = (mode) => ({ - create: { - reference: "https://syncify.sh/cli/sy-create", - overview: "The create command is an interactive command prompt. You can (optionally) provide a strap name option to skip choice selection. Options with strikethrough are either deprecated or not yet available for use." - }, - build: { - reference: "https://syncify.sh/cli/sy-build", - overview: "Runs Syncify in build mode, processing files from the input directory to create a Shopify-compliant theme structure in the output directory, ready for deployment." - }, - watch: { - reference: "https://syncify.sh/cli/sy-watch", - overview: "Runs Syncify in watch mode, monitors the input directory for file changes. On modification, it updates the output directory and uploads to a Shopify theme/store, keeping both in sync with local files." - }, - push: { - reference: "https://syncify.sh/cli/sy-push", - overview: "Upload theme files and/or resources to an online store. Use the push command to perform various sync operations with local versions." - }, - pull: { - reference: "https://syncify.sh/cli/sy-pull", - overview: "Download theme files and/or resources from an online store. This command can be used to align remote versions with local ones and carry out merge operations." - }, - projects: { - reference: "https://syncify.sh/cli/sy-projects", - overview: "Lists details of all Syncify projects on the device. Syncify maintains a hard cache in the OS home directory, which is accessed when the command runs. Optionally, specify a project directory name to retrieve info for that project." - }, - inspect: { - reference: "https://syncify.sh/cli/sy-inspect", - overview: "Prints information about the Syncify installation on your device or within your project. This information can be provided when submitting issues or reporting bugs." - }, - __: null -})[mode || "__"]; - -// syncify/cli/help/modes.ts -function Modes(mode) { - if (mode in Modes) return Modes[mode](); - const tui = syncify_js.Create().Top(`Syncify ${syncify_js.CHV} Error`, false).Header("NOT YET AVAILABLE", syncify_js.yellowBright2.bold); - if (syncify_js.COMMAND_MODES.has(mode)) { - const message = [ - `Help reference for the ${syncify_js.bold2(`sy help ${mode}`)} command is not yet available to`, - `${syncify_js.bold2("sy help")} but is slated for inclusion in upcoming releases.`, - "The command itself is valid and functional, only the help information is unavailable." - ]; - const modes = syncify_js.toArray(syncify_js.COMMAND_MODES).filter((n) => n !== "help").sort((a, b) => a in Modes === b in Modes ? 0 : a in Modes ? -1 : 1); - const equal = syncify_js.eqWS(modes, { padding: 0 }); - tui.Wrap(message, syncify_js.yellowBright2).Newline().Each(modes, (name) => name in Modes ? tui.Line(`$ sy help ${name} ${equal(name) + syncify_js.CHK}`, syncify_js.whiteBright2) : tui.Line(`$ ${syncify_js.strikethrough2(`sy help ${name}`)}`, syncify_js.gray2)); - } - tui.Newline().End(`Syncify ${syncify_js.CHV} Error`, false).BR.toLog(highlight); -} -Modes.push = () => { - const info = description("push"); - syncify_js.Create().BR.Top(`help ${syncify_js.TLD} sy push`, false).True(info, (tui) => tui.Header(`DESCRIPTION${syncify_js.COL}`, syncify_js.bold2).Wrap(syncify_js.gray2, info.overview)).True(info, (tui) => tui.Prepend(info.reference, syncify_js.gray2.underline)).Header(`COMMANDS${syncify_js.COL}`, syncify_js.bold2).Line(" $ sy push").Line(" $ sy push --flags").Header(`FLAGS${syncify_js.COL}`, syncify_js.bold2).Line(` --force ${describe("Skips diffing and force overwrites")}`).Line(` --filter, -F ${describe("filter specific files/directories")}`).Line(` --target, -T ${describe("Target a theme or store")}`).Line(` --batch ${describe("Upsert batch limits (default 10)")}`).Newline().End(`help ${syncify_js.TLD} sy push`, false).BR.toLog(highlight); - syncify_js.kill.exit(0); -}; -Modes.pull = () => { - const info = description("pull"); - syncify_js.Create().BR.Top(`help ${syncify_js.TLD} sy pull`, false).True(info, (tui) => tui.Header(`DESCRIPTION${syncify_js.COL}`, syncify_js.bold2).Wrap(syncify_js.gray2, info.overview)).True(info, (tui) => tui.Prepend(info.reference, syncify_js.gray2.underline)).Header(`COMMANDS${syncify_js.COL}`, syncify_js.bold2).Line(" $ sy pull").Line(" $ sy pull --flags").Header(`FLAGS${syncify_js.COL}`, syncify_js.bold2).Line(` --filter, -F ${describe("Filter specific files/directories")}`).Line(` --target, -T ${describe("Target a theme or store")}`).Line(` --merge ${describe(`Merges local ${syncify_js.ARL} remote theme`)}`).Line(` --align ${describe(`Align local ${syncify_js.ARL} remote theme JSON files`)}`).Line(` --force ${describe("Skips diffing and force overwrites")}`).Line(` --output, -o ${describe("Controls where theme file/s are written")}`).Line(` --batch ${describe("Upsert batch limits (default 10)")}`).Line(` --help ${describe("Show this screen")}`).NL.End(`help ${syncify_js.TLD} sy push`, false).BR.toLog(highlight); -}; -Modes.watch = () => { - const info = description("watch"); - syncify_js.Create().BR.Top(`help ${syncify_js.TLD} sy watch`, false).True(info, (tui) => tui.Header(`DESCRIPTION${syncify_js.COL}`, syncify_js.bold2).Wrap(syncify_js.gray2, info.overview)).True(info, (tui) => tui.Prepend(info.reference, syncify_js.gray2.underline)).Header(`COMMANDS${syncify_js.COL}`, syncify_js.bold2).Line(" $ sy watch").Line(" $ sy watch --flags").Header(`FLAGS${syncify_js.COL}`, syncify_js.bold2).Line(` --target, -T ${describe("Target a theme or store")}`).Line(` --filter, -F ${describe("Filter specific files/directories")}`).Line(` --hot ${describe("Activates HOT Reloading")}`).Line(` --align ${describe("Align local theme JSON files before watching")}`).Line(` --bind ${describe("Activates 2 way bindings")}`).Line(` --terse ${describe("Terse minification")}`).Line(` --dev ${describe("Development build mode (default)")}`).Line(` --prod ${describe("Production build mode")}`).Line(` --help ${describe("Show this screen")}`).NL.End(`help ${syncify_js.TLD} sy watch`, false).BR.toLog(highlight); -}; -Modes.inspect = () => { - const info = description("watch"); - syncify_js.Create().BR.Top(`help ${syncify_js.TLD} sy inspect`, false).True(info, (tui) => tui.Header(`DESCRIPTION${syncify_js.COL}`, syncify_js.bold2).Wrap(syncify_js.gray2, info.overview)).True(info, (tui) => tui.Prepend(info.reference, syncify_js.gray2.underline)).Header(`COMMANDS${syncify_js.COL}`, syncify_js.bold2).Line(" $ sy inspect").NL.End(`help ${syncify_js.TLD} sy inspect`, false).BR.toLog(highlight); -}; -Modes.create = () => { - const info = description("build"); - const message = syncify_js.Create().BR.Top(`help ${syncify_js.TLD} sy create`, false).True(info, (tui) => tui.Header(`DESCRIPTION${syncify_js.COL}`, syncify_js.bold2).Wrap(syncify_js.gray2, info.overview)).True(info, (tui) => tui.Prepend(info.reference, syncify_js.gray2.underline)).Header(`COMMANDS${syncify_js.COL}`, syncify_js.bold2).Line(" $ sy create").Line(` $ sy create ${syncify_js.Encase("AN", "strap")}`).Header(`OPTIONS${syncify_js.COL}`, syncify_js.bold2); - const straps = [...syncify_js.STRAP_THEMES, ...syncify_js.STRAP_EXAMPLES]; - const eq = syncify_js.eqWS(straps.map(([name]) => name), { padding: 2 }); - syncify_js.forEach(([name, desc, unavilable]) => { - const line = unavilable ? ` $ ${syncify_js.strikethrough2(`sy create ${name}`)}${eq(name)} ${describe("unavilable")}` : ` $ sy create ${name}${eq(name)} ${describe(desc.trim())}`; - message.Line(line); - }, straps); - message.NL.End(`help ${syncify_js.TLD} sy push`, false).BR.toLog(highlight); -}; -Modes.projects = () => { - const info = description("projects"); - syncify_js.Create().BR.Top(`help ${syncify_js.TLD} sy projects`, false).True(info, (tui) => tui.Header(`DESCRIPTION${syncify_js.COL}`, syncify_js.bold2).Wrap(syncify_js.gray2, info.overview)).True(info, (tui) => tui.Prepend(info.reference, syncify_js.gray2.underline)).Header(`COMMANDS${syncify_js.COL}`, syncify_js.bold2).Line(" $ sy projects").Line(` $ sy projects ${syncify_js.Encase("AN", syncify_js.magenta2("name"))}`).NL.End(`help ${syncify_js.TLD} sy push`, false).BR.toLog(highlight); -}; -Modes.build = () => { - const info = description("build"); - syncify_js.Create().BR.Top(`help ${syncify_js.TLD} sy build`, false).True(info, (tui) => tui.Header(`DESCRIPTION${syncify_js.COL}`, syncify_js.bold2).Wrap(syncify_js.gray2, info.overview)).True(info, (tui) => tui.Prepend(info.reference, syncify_js.gray2.underline)).Header(`COMMANDS${syncify_js.COL}`, syncify_js.bold2).Line(" $ sy build").Line(" $ sy build --flags").Line(` $ sy build ${syncify_js.Encase("SB", "option")}`).Line(` $ sy build ${syncify_js.Encase("SB", "option")} --flags`).Header(`OPTIONS${syncify_js.COL}`, syncify_js.bold2).Line(` $ sy build script ${describe("Run build on script transform")}`).Line(` $ sy build style ${describe("Run build on style transform")}`).Line(` $ sy build svg ${describe("Run build on svg transform")}`).Line(` $ sy build liquid ${describe("Run build on liquid transform")}`).Line(` $ sy build json ${describe("Run build on json transform")}`).Header(`FLAGS${syncify_js.COL}`, syncify_js.bold2).Line(` --terse ${describe("Terse minification")}`).Line(` --dev ${describe("Development build mode (default)")}`).Line(` --prod ${describe("Production build mode")}`).Line(` --help ${describe("Show this screen")}`).NL.End(`help ${syncify_js.TLD} sy build`, false).BR.toLog(highlight); -}; - -// syncify/cli/help/suggest.ts -function Suggest() { - syncify_js.Create().Top(`Syncify ${syncify_js.CHV} Error`, false).Header("1.0.0-alpha.1", syncify_js.gray2).Error("MISSING COMMAND " + syncify_js.BAD, syncify_js.bold2.redBright).Newline("red").Error("Please provide a command line argument", syncify_js.redBright2).Header(`USAGE${syncify_js.COL}`, syncify_js.bold2).Line(` $ sy <${syncify_js.magenta2("mode")}>`).Line(` $ sy <${syncify_js.magenta2("mode")}> --flags`).Line(` $ sy <${syncify_js.magenta2("mode")}> [options]`).Line(` $ sy <${syncify_js.magenta2("mode")}> [options] --flags`).Header(`HELP${syncify_js.COL}`, syncify_js.bold2).Line(" $ sy help").Line(` $ sy <${syncify_js.magenta2("mode")}> --help`).NL.End(`Syncify ${syncify_js.CHV} Error`, false).BR.toLog(highlight).Break(); -} - -// syncify/mode/help.ts -function Help(mode) { - syncify_js.log.clear(); - if (mode.suggest) { - Suggest(); - } else if (mode.inspect) { - Inspect(); - } else if (mode.version) { - Version(); - } else if (syncify_js.isNull(mode._)) { - Default(); - } else { - Modes(mode._); - } -} - -// syncify/options/command.ts -var flags = () => ({ - input: { type: "string", short: "i" }, - output: { type: "string", short: "o" }, - config: { type: "string", short: "c" }, - target: { type: "string", multiple: true, short: "T" }, - filter: { type: "string", multiple: true, short: "F" }, - help: { type: "boolean", short: "h" }, - version: { type: "boolean", short: "v" }, - align: { type: "boolean" }, - merge: { type: "boolean" }, - dev: { type: "boolean" }, - prod: { type: "boolean" }, - terse: { type: "boolean" }, - clean: { type: "boolean" }, - silent: { type: "boolean" }, - batch: { type: "string" }, - hot: { type: "boolean" }, - bind: { type: "boolean" }, - force: { type: "boolean" }, - patch: { type: "boolean" }, - minor: { type: "boolean" }, - major: { type: "boolean" }, - main: { type: "boolean" }, - unpublished: { type: "boolean" } -}); -function parse(cmd) { - syncify_js.log.clear(); - const fallback = [ - { mode: "suggest" }, - { values: null, positionals: null, tokens: null } - ]; - if (node_process.argv.length === 2) { - syncify_js.$.mode.suggest = true; - return fallback; - } else { - const find = node_process.argv[2]; - switch (find) { - case "-v": - case "--version": - syncify_js.$.mode.help = true; - syncify_js.$.mode.version = true; - fallback[0].mode = "version"; - return fallback; - case "-h": - case "--help": - syncify_js.$.mode.help = true; - fallback[0].mode = "help"; - return fallback; - } - let i = -1; - let s = cmd.length; - while (++i < s) if (cmd[i].mode === find) break; - if (i === s) { - syncify_js.throwCommand([ - `Invalid positional or mode${syncify_js.COL} "${syncify_js.red2.bold(find)}" -`, - "You must provide a known and valid execution mode.", - `For a list of available modes, run the help command${syncify_js.COL} - -`, - `${syncify_js.gray2("$")} ${syncify_js.blue2("sy help modes")}` - ]); - } - const flag = flags(); - const mode = cmd[i]; - const options = syncify_js.o(); - if ("flags" in mode) { - i = -1; - s = mode.flags.length; - while (++i < s) { - if (mode.flags[i] in flag) { - options[mode.flags[i]] = flag[mode.flags[i]]; - } else { - syncify_js.throwCommand([ - `Unknown flag expression provided "${syncify_js.bold2(`--${mode.flags[i]}`)}" -`, - `Accepted flags for ${syncify_js.bold2(mode.mode)} mode${syncify_js.COL} - -`, - `${syncify_js.g.nl(mode.flags.map((v) => syncify_js.gray2("--") + syncify_js.blue2(v)))}` - ]); - } - } - } - try { - const args = node_util.parseArgs({ - args: node_process.argv, - allowPositionals: true, - tokens: true, - options - }); - return [mode, args]; - } catch (error) { - syncify_js.throwCommand(error.message.replace(/(--?)([a-z-]+)?/g, syncify_js.red2.bold("$1$2"))); - } - } -} -function positional(cmd, tokens) { - function parseBuild() { - if (tokens.length > 1) { - syncify_js.throwCommand([ - `Invalid positional ${syncify_js.bold2("build")} arguments expression provided. No more than 1 transform`, - `can be passed. Use comma ${syncify_js.bold2(",")} separated expression instead, e.g: - -`, - `${syncify_js.gray2("$")} ${syncify_js.blue2(`sy build ${syncify_js.bold2(tokens.join(syncify_js.gray2(",")))}`)}` - ]); - return false; - } else { - if (tokens[0].indexOf(",") > -1) { - for (const transform of tokens[0].split(",")) { - if (!syncify_js.includes(transform, cmd.accepts)) { - syncify_js.throwCommand([ - `Invalid ${syncify_js.bold2("sy build")} transform "${syncify_js.bold2(transform)}" provided.`, - `Must be one of the following${syncify_js.COL} - -`, - `${syncify_js.g.nl(cmd.accepts.map((v) => syncify_js.blue2(v)))}` - ]); - return false; - } else { - syncify_js.$.mode[transform] = true; - return true; - } - } - } else { - if (!syncify_js.includes(tokens[0], cmd.accepts)) { - syncify_js.throwCommand([ - `Invalid ${syncify_js.bold2("sy build")} transform "${syncify_js.bold2(tokens[0])}"`, - `Must be one of the following${syncify_js.COL} - -`, - `${syncify_js.g.nl(cmd.accepts.map((v) => syncify_js.blue2(v)))}` - ]); - return false; - } else { - syncify_js.$.mode[tokens[0]] = true; - return true; - } - } - } - } - function parseHelp() { - if (cmd.accepts.includes(tokens[0])) { - syncify_js.$.mode._ = tokens[0]; - return true; - } else { - syncify_js.throwCommand([ - `Invalid ${syncify_js.bold2("sy help")} argument "${syncify_js.bold2(tokens[0])}" ${syncify_js.TLD}`, - `Must be one of the following${syncify_js.COL} - -`, - `${syncify_js.g.nl(cmd.accepts.map((v) => `${syncify_js.DSH} sy help ${v}`))}` - ]); - return false; - } - } - function parseKeychain() { - if (cmd.accepts.includes(tokens[0])) { - syncify_js.$.mode._ = tokens[0]; - return true; - } else { - syncify_js.throwCommand([ - `Invalid ${syncify_js.bold2("keychain")} argument "${syncify_js.bold2(tokens[0])}" ${syncify_js.TLD}`, - `Must be one of the following${syncify_js.COL} - -`, - `${syncify_js.g.nl(cmd.accepts.map((v) => `${syncify_js.DSH} ${syncify_js.blue2(v)}`))}` - ]); - return false; - } - } - if (syncify_js.$.mode.build) return parseBuild(); - if (syncify_js.$.mode.help) return parseHelp(); - if (syncify_js.$.mode.keychain) return parseKeychain(); - return true; -} -function command(commands) { - syncify_js.runtime(); - const [cmd, flags2] = parse(commands); - if (cmd.mode === "suggest") { - Help(syncify_js.$.mode); - return syncify_js.NooP; - } - const [node, bin] = node_process.argv; - const position = flags2.positionals ? positional(cmd, flags2.positionals.slice(3)) : false; - syncify_js.event.mode(cmd.mode); - syncify_js.$.node = node; - syncify_js.$.bin = bin; - syncify_js.$.argv = node_process.argv.slice(2); - syncify_js.$.dirs.module = bin.slice(0, bin.indexOf("dist/")); - syncify_js.$.using = syncify_js.$.dirs.module.startsWith(node_path.join(syncify_js.$.cwd, "node_modules")) ? "local" : "global"; - syncify_js.$.terminal.wrap = Math.round(syncify_js.$.terminal.cols - syncify_js.$.terminal.cols / 3); - syncify_js.$.mode[cmd.mode] = true; - if (syncify_js.$.mode.build) { - syncify_js.$.log.mode = 4 /* Build */; - syncify_js.$.mode.script = true; - syncify_js.$.mode.style = true; - syncify_js.$.mode.svg = true; - syncify_js.$.mode.liquid = true; - syncify_js.$.mode.json = true; - } else { - if (syncify_js.$.mode.watch) syncify_js.$.log.mode = 1 /* Watch */; - if (syncify_js.isNull(syncify_js.$.log.mode) && syncify_js.$.mode.push) syncify_js.$.log.mode = 6 /* Push */; - if (syncify_js.isNull(syncify_js.$.log.mode) && syncify_js.$.mode.pull) syncify_js.$.log.mode = 7 /* Pull */; - if (syncify_js.isNull(syncify_js.$.log.mode) && syncify_js.$.mode.build) syncify_js.$.log.mode = 4 /* Build */; - if (syncify_js.isNull(syncify_js.$.log.mode) && syncify_js.$.mode.pack) syncify_js.$.log.mode = 8 /* Pack */; - } - if (cmd.accepts !== null && syncify_js.$.argv.length > 1 && position === false) return syncify_js.NooP; - if (syncify_js.$.mode.build) { - syncify_js.$.mode.script = true; - syncify_js.$.mode.style = true; - syncify_js.$.mode.svg = true; - syncify_js.$.mode.liquid = true; - syncify_js.$.mode.json = true; - } - if (syncify_js.$.mode.help || syncify_js.$.mode.inspect) { - Help(syncify_js.$.mode); - return syncify_js.NooP; - } - syncify_js.assign(syncify_js.$.cmd, flags2.values); - syncify_js.forKeys((mode) => mode in syncify_js.$.mode ? syncify_js.$.mode[mode] = true : null, flags2.values); - if (syncify_js.$.mode.help) { - syncify_js.$.mode._ = cmd.mode; - Help(syncify_js.$.mode); - return syncify_js.NooP; - } - syncify_js.$.env.prod = syncify_js.$.mode.prod; - syncify_js.$.env.dev = syncify_js.$.mode.dev && !syncify_js.$.mode.prod; - syncify_js.$.env.cli = true; - node_process.env.SYNCIFY_ENV = syncify_js.$.env.dev ? "dev" : "prod"; - node_process.env.SYNCIFY_WATCH = String(syncify_js.$.mode.watch); - node_process.env.SYNCIFY_VERSION = "1.0.0-alpha.1"; - return (fn) => fn(); -} - -// syncify/cli.ts -command( - [ - { - mode: "build", - accepts: [ - "script", - "style", - "svg", - "liquid", - "json" - ], - flags: [ - "help", - "input", - "output", - "config", - "filter", - "dev", - "prod", - "terse", - "clean", - "silent" - ] - }, - { - mode: "watch", - accepts: null, - flags: [ - "help", - "hot", - "bind", - "align", - "input", - "output", - "config", - "target", - "filter", - "dev", - "prod", - "terse", - "clean", - "silent" - ] - }, - { - mode: "pack", - accepts: null, - flags: [ - "help", - "output", - "config", - "clean", - "dev", - "prod", - "terse", - "patch", - "minor", - "major" - ] - }, - { - mode: "delete", - accepts: null, - flags: [ - "config", - "target", - "filter", - "force" - ] - }, - { - mode: "push", - accepts: null, - flags: [ - "help", - "input", - "config", - "target", - "align", - "filter", - "force", - "batch" - ] - }, - { - mode: "pull", - accepts: null, - flags: [ - "help", - "output", - "config", - "target", - "filter", - "align", - "merge", - "force", - "batch" - ] - }, - { - mode: "publish", - accepts: null, - flags: [ - "output", - "config", - "patch", - "minor", - "major", - "clean", - "dev", - "prod", - "terse", - "target", - "main", - "unpublished" - ] - }, - { - mode: "version", - accepts: null, - alias: ["version"], - flags: [ - "help", - "patch", - "minor", - "major" - ] - }, - { - mode: "create", - flags: [ - "help" - ], - accepts: [ - "dawn", - "dusk", - "silk", - "using-paths", - "using-rename", - "using-sass", - "using-schema", - "using-tailwind", - "using-typescript" - ] - }, - { - mode: "keychain", - flags: [ - "help" - ], - accepts: [ - "create", - "update", - "associate", - "migrate", - "inspect" - ] - }, - { - mode: "help", - alias: ["help"], - accepts: [ - "examples", - // SUPPORTED - "watch", - "build", - "push", - "pull", - "create", - "inspect", - "projects", - // TODO - "export", - "import", - "stash", - "publish", - "version", - "keychain", - "theme", - "git", - "setup", - "prune", - "doctor" - ] - }, - { - mode: "init", - accepts: null - }, - { - mode: "projects", - accepts: null, - flags: [ - "help" - ] - }, - { - mode: "link", - accepts: null - }, - { - mode: "git", - accepts: null - }, - { - mode: "prune", - accepts: null - }, - { - mode: "doctor", - accepts: null - }, - { - mode: "inspect", - accepts: null - } - ] -)(syncify_js.syncify); diff --git a/dist/index.d.ts b/dist/index.d.ts deleted file mode 100644 index 9456b20a..00000000 --- a/dist/index.d.ts +++ /dev/null @@ -1,2264 +0,0 @@ -/// -/// -/// -/// -/// -/// - -import { BuildOptions } from 'esbuild'; -export { BuildOptions as ESBuildOptions } from 'esbuild'; -import { OptionsOutput } from 'clean-css'; -import { AcceptedPlugin, Plugin, Transformer, TransformCallback } from 'postcss'; -import { Config as Config$1 } from 'tailwindcss'; -import { Config as Config$2 } from 'svgo'; -export { Config as SVGOConfig } from 'svgo'; -import { Options } from 'markdown-it'; - -/* -------------------------------------------- */ -/* BASE DIRECTORIES */ -/* -------------------------------------------- */ - -type Directories = { - /** - * The resolved `input` directory path - * - * @default 'source/' - */ - input?: string; - /** - * The resolved `output` directory path - * - * @default 'theme/' - */ - output?: string; - /** - * The resolved `config` directory path for build tool files - * - * @default '/' - */ - config?: string; -} - -type Git = { - /** - * Specifies the default branch where your project exists. This branch will be be used to trigger - * the auto-merging behaviour when running `git pull`. Your `output` (theme) directory will not - * exist within this branch unless explicitly excluded from `.gitignore` file. - * - * > Please refer to the [Syncify Git Integration](https://syncify.sh/usage/git) for more information. - * - * @default 'master' - */ - default?: string; - /** - * Specifies the production branch name, which is primary sync branch. This is the branch - * that Syncify will auto-publish the flat **output** directory too, and is not to be confused - * with the branch where your **input** (source) lives. Instead, this is the branch used by the - * [Shopify Github Integration](https://shopify.dev/docs/storefronts/themes/tools/github). - * - * > **PLEASE NOTE** - * > - * > Syncify assumes that the default branch of your respository is named `master` (as per the original - * > and correct naming convention for Git). The `main` branch is **NOT** considered the "main" branch - * > but instead it is used as the distributed flat-structure point of your theme as per the `role` name - * > used for live themes published in your store. - * > - * > Please refer to the [Syncify Git Integration](https://syncify.sh/usage/git) for more information. - * - * @default 'main' - */ - branch?: string; - /** - * A glob pattern of files (or directories) which apply conflict-free merging. These entires force-merge - * into **input** (source) upon `git pull` operations. You'd use the option for `.json` configuration - * specific files such as templates that auto-write settings from the editor. - * - * ```js - * { - * // all templates will overwrite source. - * force: ['templates/*.json' ] - * } - * ``` - * - * @default [] - */ - force?: string[]; - /** - * Defines branch relationships for mirroring. Each key is a branch name, and the value is an - * array of branches that will mirror content changes published via the Shopify Github Integration. - * - * Mirrors allow developers to define dynamic branch reflections, for example: - * - * ```js - * { - * stage: ['pre'] // ensures the stage branch mirrors the pre branch. - * dev: ['main','pre'] // ensures the dev branch mirrors both main and pre branches. - * } - * ``` - * - * @default {} - */ - mirror?: { [branch: string]: string[] } -} - -/** -Matches any [primitive value](https://developer.mozilla.org/en-US/docs/Glossary/Primitive). - -@category Type -*/ -type Primitive = - | null - | undefined - | string - | number - | boolean - | symbol - | bigint; - -declare global { - // eslint-disable-next-line @typescript-eslint/consistent-type-definitions -- It has to be an `interface` so that it can be merged. - interface SymbolConstructor { - readonly observable: symbol; - } -} - -/** -Useful to flatten the type output to improve type hints shown in editors. And also to transform an interface into a type to aide with assignability. - -@example -``` -import type {Simplify} from 'type-fest'; - -type PositionProps = { - top: number; - left: number; -}; - -type SizeProps = { - width: number; - height: number; -}; - -// In your editor, hovering over `Props` will show a flattened object with all the properties. -type Props = Simplify; -``` - -Sometimes it is desired to pass a value as a function argument that has a different type. At first inspection it may seem assignable, and then you discover it is not because the `value`'s type definition was defined as an interface. In the following example, `fn` requires an argument of type `Record`. If the value is defined as a literal, then it is assignable. And if the `value` is defined as type using the `Simplify` utility the value is assignable. But if the `value` is defined as an interface, it is not assignable because the interface is not sealed and elsewhere a non-string property could be added to the interface. - -If the type definition must be an interface (perhaps it was defined in a third-party npm package), then the `value` can be defined as `const value: Simplify = ...`. Then `value` will be assignable to the `fn` argument. Or the `value` can be cast as `Simplify` if you can't re-declare the `value`. - -@example -``` -import type {Simplify} from 'type-fest'; - -interface SomeInterface { - foo: number; - bar?: string; - baz: number | undefined; -} - -type SomeType = { - foo: number; - bar?: string; - baz: number | undefined; -}; - -const literal = {foo: 123, bar: 'hello', baz: 456}; -const someType: SomeType = literal; -const someInterface: SomeInterface = literal; - -function fn(object: Record): void {} - -fn(literal); // Good: literal object type is sealed -fn(someType); // Good: type is sealed -fn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened -fn(someInterface as Simplify); // Good: transform an `interface` into a `type` -``` - -@link https://github.com/microsoft/TypeScript/issues/15300 -@see SimplifyDeep -@category Object -*/ -type Simplify = {[KeyType in keyof T]: T[KeyType]} & {}; - -/** -Omit any index signatures from the given object type, leaving only explicitly defined properties. - -This is the counterpart of `PickIndexSignature`. - -Use-cases: -- Remove overly permissive signatures from third-party types. - -This type was taken from this [StackOverflow answer](https://stackoverflow.com/a/68261113/420747). - -It relies on the fact that an empty object (`{}`) is assignable to an object with just an index signature, like `Record`, but not to an object with explicitly defined keys, like `Record<'foo' | 'bar', unknown>`. - -(The actual value type, `unknown`, is irrelevant and could be any type. Only the key type matters.) - -``` -const indexed: Record = {}; // Allowed - -const keyed: Record<'foo', unknown> = {}; // Error -// => TS2739: Type '{}' is missing the following properties from type 'Record<"foo" | "bar", unknown>': foo, bar -``` - -Instead of causing a type error like the above, you can also use a [conditional type](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html) to test whether a type is assignable to another: - -``` -type Indexed = {} extends Record - ? '✅ `{}` is assignable to `Record`' - : '❌ `{}` is NOT assignable to `Record`'; -// => '✅ `{}` is assignable to `Record`' - -type Keyed = {} extends Record<'foo' | 'bar', unknown> - ? "✅ `{}` is assignable to `Record<'foo' | 'bar', unknown>`" - : "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`"; -// => "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`" -``` - -Using a [mapped type](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#further-exploration), you can then check for each `KeyType` of `ObjectType`... - -``` -import type {OmitIndexSignature} from 'type-fest'; - -type OmitIndexSignature = { - [KeyType in keyof ObjectType // Map each key of `ObjectType`... - ]: ObjectType[KeyType]; // ...to its original value, i.e. `OmitIndexSignature == Foo`. -}; -``` - -...whether an empty object (`{}`) would be assignable to an object with that `KeyType` (`Record`)... - -``` -import type {OmitIndexSignature} from 'type-fest'; - -type OmitIndexSignature = { - [KeyType in keyof ObjectType - // Is `{}` assignable to `Record`? - as {} extends Record - ? ... // ✅ `{}` is assignable to `Record` - : ... // ❌ `{}` is NOT assignable to `Record` - ]: ObjectType[KeyType]; -}; -``` - -If `{}` is assignable, it means that `KeyType` is an index signature and we want to remove it. If it is not assignable, `KeyType` is a "real" key and we want to keep it. - -@example -``` -import type {OmitIndexSignature} from 'type-fest'; - -interface Example { - // These index signatures will be removed. - [x: string]: any - [x: number]: any - [x: symbol]: any - [x: `head-${string}`]: string - [x: `${string}-tail`]: string - [x: `head-${string}-tail`]: string - [x: `${bigint}`]: string - [x: `embedded-${number}`]: string - - // These explicitly defined keys will remain. - foo: 'bar'; - qux?: 'baz'; -} - -type ExampleWithoutIndexSignatures = OmitIndexSignature; -// => { foo: 'bar'; qux?: 'baz' | undefined; } -``` - -@see PickIndexSignature -@category Object -*/ -type OmitIndexSignature = { - [KeyType in keyof ObjectType as {} extends Record - ? never - : KeyType]: ObjectType[KeyType]; -}; - -/** -Pick only index signatures from the given object type, leaving out all explicitly defined properties. - -This is the counterpart of `OmitIndexSignature`. - -@example -``` -import type {PickIndexSignature} from 'type-fest'; - -declare const symbolKey: unique symbol; - -type Example = { - // These index signatures will remain. - [x: string]: unknown; - [x: number]: unknown; - [x: symbol]: unknown; - [x: `head-${string}`]: string; - [x: `${string}-tail`]: string; - [x: `head-${string}-tail`]: string; - [x: `${bigint}`]: string; - [x: `embedded-${number}`]: string; - - // These explicitly defined keys will be removed. - ['kebab-case-key']: string; - [symbolKey]: string; - foo: 'bar'; - qux?: 'baz'; -}; - -type ExampleIndexSignature = PickIndexSignature; -// { -// [x: string]: unknown; -// [x: number]: unknown; -// [x: symbol]: unknown; -// [x: `head-${string}`]: string; -// [x: `${string}-tail`]: string; -// [x: `head-${string}-tail`]: string; -// [x: `${bigint}`]: string; -// [x: `embedded-${number}`]: string; -// } -``` - -@see OmitIndexSignature -@category Object -*/ -type PickIndexSignature = { - [KeyType in keyof ObjectType as {} extends Record - ? KeyType - : never]: ObjectType[KeyType]; -}; - -// Merges two objects without worrying about index signatures. -type SimpleMerge = { - [Key in keyof Destination as Key extends keyof Source ? never : Key]: Destination[Key]; -} & Source; - -/** -Merge two types into a new type. Keys of the second type overrides keys of the first type. - -@example -``` -import type {Merge} from 'type-fest'; - -interface Foo { - [x: string]: unknown; - [x: number]: unknown; - foo: string; - bar: symbol; -} - -type Bar = { - [x: number]: number; - [x: symbol]: unknown; - bar: Date; - baz: boolean; -}; - -export type FooBar = Merge; -// => { -// [x: string]: unknown; -// [x: number]: number; -// [x: symbol]: unknown; -// foo: string; -// bar: Date; -// baz: boolean; -// } -``` - -@category Object -*/ -type Merge = -Simplify< -SimpleMerge, PickIndexSignature> -& SimpleMerge, OmitIndexSignature> ->; - -/** -Allows creating a union type by combining primitive types and literal types without sacrificing auto-completion in IDEs for the literal type part of the union. - -Currently, when a union type of a primitive type is combined with literal types, TypeScript loses all information about the combined literals. Thus, when such type is used in an IDE with autocompletion, no suggestions are made for the declared literals. - -This type is a workaround for [Microsoft/TypeScript#29729](https://github.com/Microsoft/TypeScript/issues/29729). It will be removed as soon as it's not needed anymore. - -@example -``` -import type {LiteralUnion} from 'type-fest'; - -// Before - -type Pet = 'dog' | 'cat' | string; - -const pet: Pet = ''; -// Start typing in your TypeScript-enabled IDE. -// You **will not** get auto-completion for `dog` and `cat` literals. - -// After - -type Pet2 = LiteralUnion<'dog' | 'cat', string>; - -const pet: Pet2 = ''; -// You **will** get auto-completion for `dog` and `cat` literals. -``` - -@category Type -*/ -type LiteralUnion< - LiteralType, - BaseType extends Primitive, -> = LiteralType | (BaseType & Record); - -type HOTShared = { - /** - * Specify the static server port. By default, Syncify uses port `41001` to - * avoid any conflicts with other running hosts of tools. - * - * @default 41001 - * @example 'http://localhost:41001/some-asset.js' - */ - server?: number; - /** - * Specify the websocket port. By default, Syncify uses port `51001` to - * avoid any conflicts with other running hosts of tools. - * - * @default w - * @example 'ws://localhost:51001/ws' - */ - socket?: number; - /** - * Determines the reload method Syncify should use. Syncify provides 3 - * reload tactics and defaults to using `hot`. - * - * > `hot` - * > - * > Performs real HMR and partial swaps (recommended) - * - * > `live` - * > - * > Similar to `hot` but each change will swap the entire `` - * - * > `refresh` - * > - * > Replicates the Shopify CLI behaviour (fake reloading). Hard refreshes on every change. - * - * @default 'hot' - */ - method?: LiteralUnion<'hot' | 'live' | 'refresh', string>; - /** - * Whether or not the Syncify UI status label should render. - * - * @default true - */ - label?: boolean; - /** - * Controls whether ot the HOT Snippet injection is auto-removed from layout/s. - * When set to `false`, the HOT render snippet is persisted on process exit whereas - * the default behaviour is to remove it from layouts. - * - * Setting this `false` will improve start-up runtime in `--hot` mode by a few hundred ms. - * - * @default true - */ - eject?: boolean - /** - * Accepts a string list of flags that enable Syncify to - * wrangle CFH slop in development mode along with normalisation. - * - * > `--no-preview-bar` - * > - * > Automatically hides the preview bar - * - * > `--no-web-pixels-manager` - * > - * > Prevents the WPM evaluation from ocurring and blocks the CFH injection scripting - * - * > `--no-checkout-preloads` - * > - * > Prevents the checkout preload tags from injecting. In development, you don't need them. - * - * > `--no-shopify-features` - * > - * > Prevents the Shopify Features scripting from evaluating and blocks the CFH injections. - * - * > `--no-trekkie` - * > - * > Prevents Trekkie from evaluating, helping per-page navigation performance in development. - * - * > `--no-perfkit` - * > - * > Prevents Perfkit scripting from evaluating and the CFH injections. - * - * @default - * [ - * '--no-preview-bar', - * ] - */ - flags?: [ - '--no-preview-bar'?, - '--no-web-pixels-manager'?, - '--no-checkout-preloads'?, - '--no-shopify-features'?, - '--no-trekkie'?, - '--no-perfkit'? - ]; -} - -type HOTExtension = HOTShared & { - /** - * > **!! NOT YET AVAILABLE !!** - * > - * > **This feature is planned and not yet available for usage** - * - * The type of client-side scripting method being used. If you are using the Syncify browser - * extension then set this value to `extension`, otherwise use `inject`. - * - * @default 'injection' - */ - client?: 'extension' -} - -type HOTInject = HOTShared & { - /** - * The type of client-side scripting method being used. If you are using the Syncify browser - * extension then set this value to `extension`, otherwise use `inject`. - * - * @default 'injection' - */ - client?: 'inject' - /** - * Set a list of theme layout files for snippet injection. This option is only applicable - * when `client` is set to `inject`. - * - * > **NOTE** - * > - * > Option does not accept path structures, only file names are to be provided - * > - * > ```js - * > // 𐄂 DO NOT DO THIS - * > ['source/layout/theme.liquid'] - * > - * > // ✓ THIS IS GOOD - * > ['theme.liquid'] - * > ``` - * - * @default - * [ - * 'theme.liquid' - * ] - */ - layouts?: string[]; -} - -type HOT = HOTInject | HOTExtension - -/* -------------------------------------------- */ -/* LOGGER */ -/* -------------------------------------------- */ - -interface Logger { - /** - * Whether or not file stats should print - * - * > Helpful when building for production (`--prod`) - * - * @default true - */ - stats?: boolean; - /** - * Whether or not to print warnings - * - * @default true - */ - warnings?: boolean; - /** - * Suppress CLI logs - * - * @default false - */ - silent?: boolean; - /** - * Whether or not to clear the screen between changes. - * - * @default true - */ - clear?: boolean; -} - -type StashType = string | number; - -/** - * Stash Reference - */ -type Stash = { - /** - * Set a stash import location for remote `pull` operations. Files which cannot - * be mapped to an existing project-level path location (relative to your `input`) - * will be written the provided stash destination defined here. - * - * > `*` - * > - * > asterisk value signals for stashes to be written within directory at index `0` - * - * > `number` - * > - * > number value will default to `*` and write within directories at that index. - * - * > `true` - * > - * > boolean `true` value signals for stashed to be written in `stash/` directory at index `0` - * - * --- - * - * You can optionally provide a sub-directory path. - * - */ - stash: StashType; -} - -/** - * String or Array of strings - */ -type Path = string | string[]; - -/** - * Union join of accepted Path patterns - */ -type Pattern = Path | [ ...globs: string[], stash: Stash ]; - -/** - * Section and Snippet Rename Paths - */ -type Rename = { - /** - * Uses the filename as per the source, idenitical behaviour as that of `[name]`. - * - * @example - * { - * sections: { - * '[dir]-[name]': [ - * 'sections/foo/*', // sections in this directory will prefix foo- - * 'sections/bar/*' // sections in this directory will prefix bar- - * ], - * '*': [ - * './sections/**', // all other sections will use source name - * { stash: 'files' } // stashes imports within sections/files - * ], - * }, - * snippets: { - * '[dir]-[name]': [ - * 'snippets/foo/*', // snippets in this directory will prefix foo- - * 'snippets/bar/*' // snippets in this directory will prefix bar- - * ], - * '*': [ - * './snippets/**', // all other snippets will use source name - * { stash: true } // stashes will be written - * ] - * } - * } - */ - '*'?: Pattern; - /** - * Use the filename as per the source. Passing `[name]` only will result in fallback - * behaviour, as that of `'*'`. - * - * @example - * @example - * { - * sections: { - * '[dir]-[name]': [ - * 'sections/foo/*', // sections in this directory will prefix foo- - * ], - * 'xxx-[name]': [ - * 'sections/bar/*', // sections in this directory will prefix xxx- - * ], - * '[name]': [ - * './sections/**' // all other sections will use source filename - * ] - * }, - * snippets: { - * '[dir]-[name]': [ - * 'snippets/foo/*', // snippets in this directory will prefix foo- - * ], - * 'xxx-[name]': [ - * 'snippets/bar/*', // snippets in this directory will prefix xxx- - * ], - * '[name]': [ - * './snippets/**' // all other sections will use source filename - * ] - * } - * } - */ - '[name]'?: Pattern; - /** - * Prefix directory name and suffix filename in **kebab-case** format. - * - * @example - * 'layout/header.liquid' > 'layout-header.liquid' - */ - '[dir]-[name]'?: Pattern; - /** - * Prefix directory name and suffix filename in **snake_case** format. - * - * @example - * 'layout/header.liquid' > 'layout_header.liquid' - */ - '[dir]_[name]'?: Pattern; - /** - * Prefix filename and suffix directory in **kebab-case** format. - * - * @example - * 'layout/header.liquid' > 'header-layout.liquid' - */ - '[name]-[dir]'?: Pattern; - /** - * Prefix filename and suffix directory in **snake_case** format. - * - * @example - * 'layout/header.liquid' > 'header_layout.liquid' - */ - '[name]_[dir]'?: Pattern; -} - -/** - * Snippet Renames accept `.` separated values - */ -type RenameSnippets = Rename & { - /** - * Prefix filename and suffix directory with `.` dot separator. - * - * @example - * 'layout/header.liquid' > 'header.layout.liquid' - */ - '[name].[dir]'?: Pattern; - /** - * Prefix directory and suffix filename with `.` dot separator. - * - * @example - * 'layout/header.liquid' > 'layout.header.liquid' - */ - '[dir].[name]'?: Pattern; -} - -type Paths = { - /** - * A glob string, glob array or rename `output → input` key/value object of files to be uploaded as snippets. - * - * @default 'source/snippets/*.{liquid}' - * @example - * - * //OPTION 1 - Globs - * { - * snippets: 'source/snippets/*.liquid' - * } - * - * //OPTION 2 - Globs Array - * { - * snippets: [ - * 'source/snippets/*.liquid', - * 'source/snippets/xxx/*' - * ] - * } - * - * //OPTION 3 - Rename Object - * { - * snippets: { - * // Output will be: snippets/foo.bar.liquid - * '[dir].[name]': 'source/snippets/foo/bar.liquid', - * // Output will be: snippets/quz-baz.liquid - * '[name]-[dir]': 'source/snippets/baz/qux.liquid' - * } - * } - * - * - * //OPTION 4 - Rename Object Glob Array - * { - * snippets: { - * // Output will be: snippets/foo.bar.liquid - * // Output will be: snippets/baz.qux.liquid - * '[dir].[name]': [ - * 'source/snippets/foo/bar.liquid', - * 'source/snippets/baz/qux.liquid' - * ] - * } - * } - */ - snippets?: Pattern | RenameSnippets - /** - * A glob string, glob array or rename `output → input` key/value object of files to be uploaded as sections. - * - * > **NOTE** - * > This path reference will also sync section group files. - * - * @default 'source/sections/*.{liquid,json}' - * @example - * - * //OPTION 1 - Globs - * { - * sections: 'source/sections/*.liquid' - * } - * - * //OPTION 2 - Globs Array - * { - * sections: [ - * 'source/sections/*.liquid', - * 'source/sections/xxx/*' - * ] - * } - * - * //OPTION 3 - Rename Object Glob - * { - * sections: { - * // Output will be: sections/foo.bar.liquid - * '[dir].[name]': 'source/sections/foo/bar.liquid', - * // Output will be: sections/quz-baz.liquid - * '[name]-[dir]': 'source/sections/baz/qux.liquid' - * } - * } - * - * //OPTION 4 - Rename Object Glob Array - * { - * sections: { - * // Output will be: sections/foo.bar.liquid - * // Output will be: sections/baz.qux.liquid - * '[dir].[name]': [ - * 'source/sections/foo/bar.liquid', - * 'source/sections/baz/qux.liquid' - * ] - * } - * } - * - * //OPTION 5 - Define a custom stash - * { - * sections: [ - * 'source/sections/*.liquid', - * 'source/sections/xxx/*', - * { stash: '*' } // pull stashes will write to source/sections/* - * ] - * } - */ - sections?: Pattern | Rename; - /** - * A glob string or glob array of files to be uploaded as blocks - * - * @default 'source/blocks/*.{liquid}' - */ - blocks?: Pattern; - /** - * A glob string or glob array of files to be uploaded as templates. - * - * @default 'source/templates/*.{liquid,json}' - */ - templates?: Pattern; - /** - * A glob string or glob array of files to be uploaded asas metaobject templates - * - * @default 'source/templates/metaobject/*.{liquid,json}' - */ - metaobject?: Pattern; - /** - * A glob string or glob array of files to be uploaded as template/customers - * - * @default 'source/templates/customers/*.{liquid,json}' - */ - customers?: Pattern; - /** - * A glob string or glob array of files to be uploaded as assets - * - * @default 'source/assets/*' - */ - assets?: Pattern; - /** - * A glob string or glob array of files to be uploaded as layouts - * - * @default 'source/layout/*.liquid' - */ - layout?: Pattern; - /** - * A glob string or glob array of files to be uploaded as configs, i.e, `settings_schema.json` - * - * @default 'source/config/.json' - */ - config?: Pattern; - /** - * A glob string or glob array of files to be uploaded as config, i.e, `en.default.json` - * - * @default 'source/locales/*.json' - */ - locales?: Pattern; - /** - * A glob string or glob array of files to be uploaded as **shared schema** `.json` or `.schema` files. - * - * @default 'source/+/schema/*.{json,schema}' - */ - schema?: Path; - /** - * **NOT YET AVAILABLE** - * - * **This option will be available in later versions** - * - * --- - * - * The resolved `metafields` directory path - * - * @default 'source/+/metafields/**' - */ - metafields?: Path; - /** - * **NOT YET AVAILABLE** - * - * **This option will be available in later versions** - * - * A glob string or glob array string to be uploaded, published and controlled as `pages` - * - * @default 'source/+/pages/*.{md,html}' - */ - pages?: Path; - /** - * **NOT YET AVAILABLE** - * - * **This option will be available in later versions** - * - * @default 'source/+/blogs/*' - */ - blogs?: Path; - /** - * **NOT YET AVAILABLE** - * - * **This option will be available in later versions** - * - * @default 'source/+/menus/*.json' - */ - navigation?: Path; - /** - * **NOT YET AVAILABLE** - * - * **This option will be available in later versions** - * - * @default 'source/+/policies/*.{html,md}' - */ - policies?: Path; - /** - * **NOT YET AVAILABLE** - * - * **This option will be available in later versions** - * - * @default 'source/+/files/**' - */ - files?: Path; -} - -type ScriptRename = `${'assets' | 'snippets'}/${string}` - -type TargetBrowser = ( - | 'chrome' - | 'deno' - | 'edge' - | 'firefox' - | 'hermes' - | 'ie' - | 'ios' - | 'node' - | 'opera' - | 'rhino' - | 'safari' -); - -type TargetBrowserVersion = ( - | `${TargetBrowser}${number}` - | `${TargetBrowser}${number}.${number}` - | `${TargetBrowser}${number}.${number}.${number}` -); - -type TargetESVersion = ( - | 'es3' - | 'es5' - | 'es6' - | 'es2015' - | 'es2016' - | 'es2017' - | 'es2018' - | 'es2019' - | 'es2020' - | 'es2021' - | 'es2022' - | 'esnext' -); - -type ESBuildAllowedOptions = Pick - - -type ESBuildTarget = ( - | TargetBrowser - | TargetBrowserVersion - | TargetESVersion -); - -/** - * Public exposed configurations - */ -type ESBuildConfig = Merge; - -/* -------------------------------------------- */ -/* TRANSFORM */ -/* -------------------------------------------- */ - -type ScriptSharedConfig = { - /** - * JS/TS input source paths. Accepts `string` or `string[]` glob patterns. - * Resolution is relative to your defined `input` directory. - * - * --- - * - * @default undefined - */ - input: string | string[]; - /** - * This sets the target environment for the generated JavaScript. It - * tells esbuild to transform JavaScript syntax which is too new for - * these environments into older JavaScript syntax that works in this - * environment\s. - * - * --- - * - * @default 'es2016' - */ - target?: ESBuildTarget | ESBuildTarget[]; - /** - * Instructs ESBuild to treat these modules as external. The import/s - * will be preserved and evaluated at run time instead. - * - * --- - * - * @see - * https://esbuild.github.io/api/#external - * - * @default - * [] - */ - external?: string[]; - /** - * Rename the JavaScript file/s. The same name as source file will be used - * when undefined. Accepts namespaces, `[file]` or `[name]`, `[dir]` and/or `[ext]`. - * - * --- - * - * @default undefined - */ - rename?: string; - /** - * Optionally write the javascript file inline as a snippet. This will transform - * the JS and contained code will be output within `` tags as a - * `snippet.liquid` file. - * - * @default false - */ - snippet?: boolean; - /** - * When `snippet` is `true` you can provide an additional list of attributes to - * be applied to inlined ` - * ``` - * - * // Output - * @default [] - */ - attrs?: Array; - /** - * Entry points (paths/files) to watch that will trigger a rebuilds of - * the defined _input_ file. By default, Syncify will watch all import entries - * imported by the _input_. - * - * @default [] - */ - watch?: string[] - /** - * [ESBuild](https://esbuild.github.io/) Override - * - * ESBuild file transforms will use the options provided to `processor.esbuild` - * but you can optionally override those defaults on a per-transform - * basis. Any configuration options defined here will be merged with - * the options defined in `processor.esbuild`. - * - * You can also skip pre-processing with esbuild by passing a _boolean_ - * `false` which will inform Syncify to skip processing scripts with ESBuild. - * - * @default true // if esbuild is not installed this is false - */ - esbuild?: boolean | ESBuildConfig; -} - -type ScriptFormatESM = ScriptSharedConfig & { - - /** - * The format to be generated. Because we are targeting - * browser environments, Syncify does not allow for CJS (commonjs) - * bundles to be produced. - * - * @default 'esm' - */ - format?: 'esm'; -} - -type ScriptFormatIIFE = ScriptSharedConfig & { - /** - * The format to be generated. Because we are targeting - * browser environments, Syncify does not allow for CJS (commonjs) - * bundles to be produced. - * - * @see https://esbuild.github.io/api/#format - * @default 'esm' - */ - format?: 'iife'; - /** - * Sets the name of the global variable which is used to store the - * exports from the entry point. - * - * @see https://esbuild.github.io/api/#global-name - * @default undefined - */ - globalName?: string; -} - -type ScriptTransform = ScriptFormatESM | ScriptFormatIIFE; - -/* -------------------------------------------- */ -/* TRANSFORMER */ -/* -------------------------------------------- */ - -type ScriptTransformer = ( - | string - | string[] - | ScriptTransform - | ScriptTransform[] - | Record - | Record - | Record> -) - -/* -------------------------------------------- */ -/* PROCESSOR CONFIGS */ -/* -------------------------------------------- */ - -type StyleRename = `${'assets' | 'snippets'}/${string}` - -type PostCSSConfig = ( - | AcceptedPlugin - | Plugin - | Transformer - | TransformCallback - | any -); - -/** - * Style Minification - */ -type StyleTerse = OptionsOutput & { - /** - * Whether or not to purge unused CSS class names - * - * @default false - */ - purgeUnusedCSS?: boolean; - /** - * Whether or not to obfuscate CSS class names - * - * @default false - */ - obfuscateClassNames?: boolean; - /** - * List of class names that should be excluded from - * obfuscation and shortnaming. - */ - obfuscateWhitelist?: string[]; - /** - * The alphabet used to generate the new class names. - * - * > **NOTE** - * > - * > There is no `d` in the default alphabet to avoid adblock issues. - * - * @default 'abcefghijklmnopqrstuvwxyz0123456789' - */ - obfuscateAlphabet?: string; - /** - * Excluded files from terser minification - * - * @default [] - */ - exclude?: string[] -} - -type TailwindConfig = Config$1 & { - config: string[] -} - -type SASSConfig = { - /** - * Whether or not to generate sourcemaps - * - * @default true - */ - sourcemap?: boolean; - /** - * The style compiled CSS should be output. - * - * @default 'compressed' - */ - style?: 'expanded' | 'compressed'; - /** - * Whether or not to print warnings to CLI - Warnings will require - * an `stdin` invocation to view. Setting this to `false` will hide - * warnings all together. - * - * @default true - */ - warnings?: boolean; - /** - * This option is passed to SASS Dart compile instance. If this option is set to `true`, - * Sass won’t print warnings that are caused by dependencies. A "dependency" is defined - * as any file that’s loaded through external sources. - * - * This is useful for silencing deprecation warnings that you can’t fix on your own. - * However, please also notify your dependencies of the deprecations so that they can get - * fixed as soon as possible! - * - * @default false - */ - quietDeps?: boolean; - /** - * A list of paths to include, ie: node_modules. - * - * @default ['node_modules'] - */ - include?: string[]; -} - -/* -------------------------------------------- */ -/* TRANSFORM */ -/* -------------------------------------------- */ - -type StyleTransform = { - /** - * SVG input source paths. Accepts `string` or `string[]` glob patterns. - * Resolution is relative to your defined `input` directory. - * - * @default undefined - */ - input: T; - /** - * Glob stylesheet paths/files to watch. When changes - * are applied to matched files, then the defined `input` - * will be compiled. - * - * @default [] - */ - watch?: string[]; - /** - * Rename the stylesheet file/s. The same name as source file will be used - * when undefined. Accepts namespaces, `[file]`, `[dir]` and `[ext]`. - * - * --- - * - * @default undefined - */ - rename?: string; - /** - * Optionally output the CSS as a snippet. This will transform - * the stylesheet inline, wrap output within `` - * tags and write it to `snippets`. - * - * @default false - */ - snippet?: boolean; - /** - * When `snippet` is `true` you can provide an additional list of attributes to - * be applied to ` - * ``` - * - * // Output - * @default [] - */ - attrs?: string[][]; - /** - * - * [TailwindCSS](https://tailwindcss.com/) Override - * - * Tailwind transforms will use the `tailwind.config.js` configuration - * file in your projects root (or defined `config` path). If you have not - * provided a tailwind config file, then syncify will use options defined - * via `processor.tailwind`. You can optionally override configuration - * on a per-transform basis and any options defined here will be merged with - * those defined in your `tailwind.config.js` or `processor.tailwind`. - * - * @default true // if tailwind is not installed this is false - */ - tailwind?: boolean | Partial; - /** - * [PostCSS](https://postcss.org/) Override - * - * CSS File transforms will use the options provided to `processor.postcss` - * but you can optionally override those defaults on a per-transform - * basis. Any configuration options defined here will be merged with - * the options defined in `processor.postcss`. - * - * You can also skip pre-processing with postcss by passing a _boolean_ - * `false` which will inform Syncify to not pass output to PostCSS. By - * default, Syncify will pass all compiled SASS and files with `.css` - * extensions to PostCSS. - * - * @default true // if postcss is not installed this is false - */ - postcss?: boolean | PostCSSConfig[]; - /** - * [SASS Dart](https://sass-lang.com/documentation/js-api/) Override - * - * SASS File transforms will use the options provided to `processor.sass` - * but you can optionally override those defaults on a per-transform - * basis. Any configuration options defined here will be merged with - * the options defined in `processor.sass`. - * - * You can also skip SASS transfroms by passing a _boolean_ `false` which will - * inform Syncify to not pass output to SASS, which is the default if SASS is not - * installed. - * - * By default, Syncify will forward all input files using `.scss` or `.sass` - * or extension to SASS Dart. If you have PostCSS installed then Syncify will - * automatically pass SASS files to PostCSS in the post-process. - * - * @default true // if sass is not installed this is false - */ - sass?: boolean | SASSConfig; - /** - * **NOTE YET AVAILABLE** - * - * Terse Style (CSS) Minification - * - * > Uses [clean-css](https://github.com/clean-css/clean-css) minification - * > Uses [purge-css](https://github.com/FullHuman/purgecss) - */ - terse?: boolean | SASSConfig; -} - -/* -------------------------------------------- */ -/* TRANSFORMER */ -/* -------------------------------------------- */ - -type StyleTransformer = ( - | string - | string[] - | StyleTransform - | StyleTransform[] - | Record - | Record - | Record> -) - -/* -------------------------------------------- */ -/* SHARED */ -/* -------------------------------------------- */ - -type RenamePaths = `${'assets' | 'snippets'}/${string}` - -type SVGFile = { - /** - * SVG input source paths. Accepts `string` or `string[]` glob patterns. - * Resolution is relative to your defined `input` directory. - * - * @default '' - */ - input: string | string[]; - /** - * The SVG export format. Syncify can produce 2 different SVG formats. - * All SVG file types will pre-process and transform using [SVGO](https://github.com/svg/svgo). - * This option cannot be undefined and is required. - * - * --- - * - * > `file` - * > - * > SVG transforms using a `file` format will produce individual `.svg` files from - * that can be output as an`asset` or inlined into a `snippet` - * - * > `sprite` - * > - * > SVG transforms using a `sprite` format will produce an SVG Sprite that can be - * output as an `asset` or inlined into a `snippet` - */ - format: 'file'; - /** - * Rename the svg file/s. The same name as source file will be used - * when undefined. Accepts namespaces, `[file]`, `[dir]` and `[ext]`. - * --- - * - * @default undefined - * - * @example - * 'source/svgs/arrow.svg' > 'arrow.svg' // if snippet is false - * 'source/svgs/checkmark.svg' > 'checkmark.liquid' // if snippet is true - */ - rename?: string; - /** - * Whether to generate svg as snippet or asset. When `true` the - * svg source will be written as a snippet - * - * @default false - */ - snippet?: boolean; - /** - * [SVGO](https://github.com/svg/svgo) Override - * - * SVG File transforms will use the options provided to `processor.svgo` - * but you can optionally override those defaults on a per-transform - * basis. Any configuration options defined here will be merged with - * the options defined in `processor.svgo`. - * - * @default - * processor.svgo // When processor configuration is defined - */ - svgo?: Config$2; -} - -type SVGSprite = Omit & { - /** - * The SVG export format. Syncify can produce 2 different SVG formats. - * All SVG file types will pre-process and transform using [SVGO](https://github.com/svg/svgo). - * This option cannot be undefined and is required. - * - * --- - * - * > `file` - * > - * > SVG transforms using a `file` format will produce individual `.svg` files from - * that can be output as an`asset` or inlined into a `snippet` - * - * > `sprite` - * > - * > SVG transforms using a `sprite` format will produce an SVG Sprite that can be - * output as an `asset` or inlined into a `snippet` - */ - format: 'sprite'; - /** - * Add a DOCTYPE declaration to SVG documents - * - * @type {boolean} - */ - sprite?: { - /** - * Apply a custome set of sprite attributes on the - * parent `` element containing the `` reference. - * - * **Example Definition** - * - * ```js - * // Attribute definitions - * { - * attrs: [ - * ['id', 'foo'] - * ['data-attr', 'bar'], - * ['{{ object.prop }}'], - * ['{% if xxx %}', 'data-xxx', '{% endif %}'] - * ] - * } - * ``` - * - * **Example Output** - * - * ```liquid - * - * .... - * .... - * .... - * - * ``` - * - * // Output - * @default [] - */ - attrs?: Array; - /** - * Additional optional to be applied on containing `` - * elements in the sprite. - */ - symbols?: { - /** - * The identifier applied to `` elements. This - * value will be the `` referenced via `xlink:href`. - * By default, Syncify prefixes `svg-` followed by SVG filename. - * - * > `[id]` - * > - * > Passing a value of `[id]` will instruct syncify to use the `id=""` value - * > already applied and when missing fallback to the default `svg-` - * - * - * **Example** - * - * ```liquid - * - * - * - * - * - * - * - * ... - * ... - * ... - * - * ``` - */ - id?: LiteralUnion<`${string}-[name]` | `[name]-${string}` | '[id]', string>; - /** - * Whether or not containing `` elements should be annotated - * with `xmlns` attributes. Defaults to `false`. - * - * **Example Output** - * - * ```liquid - * - * ... - * ... - * ... - * - * ``` - * - * @default false - */ - xmlns?: boolean; - } - } -} - -type SVGTransform = SVGFile | SVGSprite - -/* -------------------------------------------- */ -/* TRANSFORMER */ -/* -------------------------------------------- */ - -type SVGTransformer = ( - | string - | string[] - | SVGTransform - | SVGTransform[] - | Record - | Record - | Record -) - -/** - * Processor Default Configurations - * - * Holds reference to default config options for each supported processor. - */ -type Processors = { - /** - * [ESBuild](https://esbuild.github.io/) Config - */ - esbuild?: ESBuildConfig; - /** - * [PostCSS](https://postcss.org/) Plugins - */ - postcss?: PostCSSConfig[]; - /** - * [TailwindCSS](https://tailwindcss.com/) Config - */ - tailwind?: TailwindConfig[]; - /** - * [SASS Dart](https://sass-lang.com/documentation/js-api/) Config - */ - sass?: SASSConfig; - /** - * [SVGO](https://github.com/svg/svgo) Config - */ - svgo?: Config$2; - /** - * [Markdown](https://github.com/markdown-it/markdown-it) Config - */ - markdown?: Options; -} - -interface Publishing { - /** - * Git publish - */ - git: Git; -} - -/** - * JSON File Minification - */ -type JSONTerse = { - /** - * Minify `.json` files writing to `theme/assets` - * - * @default true - */ - assets?: boolean; - /** - * Minify `settings_schema.json` and `settings_data.json` config files. - * - * @default true - */ - config?: boolean; - /** - * Minify `locale` and `.json` files. - * - * @default true - */ - locales?: boolean; - /** - * Minify `metafield` and `.json` files. - * - * @default true - */ - metafields?: boolean; - /** - * Minify `metaobject` and `.json` files. - * - * @default true - */ - metaobject?: boolean; - /** - * Minify section group `.json` files - * - * @default true - */ - groups?: boolean; - /** - * Minify `template` and `.json` files. - * - * @default true - */ - templates?: boolean; - /** - * An optional list of paths/files to exclude from minification. - * - * @default [] - */ - exclude?: string[] -} - -type JSONTransform = { - /** - * If line termination should be Windows (CRLF) format. - * Unix (LF) format is the default. - * - * @default false - */ - crlf?: boolean; - /** - * The indentation level - * - * @default 2 - */ - indent?: number; - /** - * Whether to use tabbed `\t` identation characters. When `true`, tabs will apply - * at the division of `2` relative to the `indent` option value. - * - * @default false - */ - useTab?: boolean; - /** - * Whether or not comments should be stripped or preserved. - * This effects how Syncify handles both local and remote sources. - * - * @default false - */ - stripComments?: boolean; - /** - * Whether or not Syncify should apply alpha-numeric sorting to object properties - * or not. This will apply deep sorting, so all objects within a structure will adhere. - * - * Apply object sorting on a specific list of entries in the JSON structure. Target deeply nested - * property objects and their values using dot `.` separated expressions by passing sting list. - * - * ```js - * { sortObjects: ['a.b'] } // sort only these objects - * - * // BEFORE - * { a: { b: { z: '2', x: '1' } }, c: { b: '2', a: '1' } } - * - * // AFTER - * { a: { b: { x: '1', z: '2', } }, c: { b: '2', a: '1' } } - * ``` - * - * @default false - */ - sortObjects?: boolean | string[]; - /** - * Whether or not Syncify should apply alpha-numeric sorting to arrays in JSON. - * You should avoid setting this to `true` and use with caution. - * - * Apply array sorting on a specific list of entries in the JSON structure. Target deeply nested - * properties and their values using dot `.` separated expressions by passing sting list. - * - * @default false - */ - sortArrays?: boolean | string[]; - /** - * Define a list of property names with object values that should be excluded and skipped - * from sorting. This option only applies when `sortObjects` and/or `sortArrays` is set to - * `true` and will have no effect if `sortObjects` and/or `sortArrays` is not enabled. - * - * @default [] - */ - noSortList?: string[]; - /** - * An optional string list of paths/filenames to exclude - * from processing, ie: pass through - * - * @default false - */ - exclude?: string[]; - /** - * JSON minification options. By default, this option is set to `false` - * which disables minification being applied to `.json` file types. Setting - * this to `true` will enabled JSON minification to apply. - * - * > **NOTE** - * > - * > Terse operations require the explicit `--prod` OR `--terse` flags be provided. - * > Failure to pass such flags will result in minification being skipped. - */ - terse?: boolean | JSONTerse; -} - -type LiquidTerse = { - /** - * Removes redundant whitespace Liquid dash trims from Liquid tags and objects. - * - * @default false - */ - stripTrims?: boolean; - /** - * Minifies inner contents of `\\d+)m|\\${ANSI_ESCAPE_LINK}(?.*)${ANSI_ESCAPE_BELL})`).exec(preString.slice(preStringIndex)) || { groups: {} }; - if (groups.code !== void 0) { - const code2 = Number.parseFloat(groups.code); - escapeCode = code2 === END_CODE ? void 0 : code2; - } else if (groups.uri !== void 0) { - escapeUrl = groups.uri.length === 0 ? void 0 : groups.uri; - } - } - const code = ansi_styles_default.codes.get(Number(escapeCode)); - if (pre[index + 1] === "\n") { - if (escapeUrl) { - returnValue += wrapAnsiHyperlink(""); - } - if (escapeCode && code) { - returnValue += wrapAnsiCode(code); - } - } else if (character === "\n") { - if (escapeCode && code) { - returnValue += wrapAnsiCode(escapeCode); - } - if (escapeUrl) { - returnValue += wrapAnsiHyperlink(escapeUrl); - } - } - preStringIndex += character.length; - } - return returnValue; -}; -function wrapAnsi(string, columns, options) { - return String(string).normalize().replaceAll("\r\n", "\n").split("\n").map((line) => exec2(line, columns, options)).join("\n"); -} -function isFullwidthCodePoint(codePoint) { - if (!Number.isInteger(codePoint)) { - return false; - } - return eastAsianWidth(codePoint) === 2; -} -var ESCAPES2 = /* @__PURE__ */ new Set([27, 155]); -var CODE_POINT_0 = "0".codePointAt(0); -var CODE_POINT_9 = "9".codePointAt(0); -var endCodesSet = /* @__PURE__ */ new Set(); -var endCodesMap = /* @__PURE__ */ new Map(); -for (const [start, end] of ansi_styles_default.codes) { - endCodesSet.add(ansi_styles_default.color.ansi(end)); - endCodesMap.set(ansi_styles_default.color.ansi(start), ansi_styles_default.color.ansi(end)); -} -function getEndCode(code) { - if (endCodesSet.has(code)) { - return code; - } - if (endCodesMap.has(code)) { - return endCodesMap.get(code); - } - code = code.slice(2); - if (code.includes(";")) { - code = code[0] + "0"; - } - const returnValue = ansi_styles_default.codes.get(Number.parseInt(code, 10)); - if (returnValue) { - return ansi_styles_default.color.ansi(returnValue); - } - return ansi_styles_default.reset.open; -} -function findNumberIndex(string) { - for (let index = 0; index < string.length; index++) { - const codePoint = string.codePointAt(index); - if (codePoint >= CODE_POINT_0 && codePoint <= CODE_POINT_9) { - return index; - } - } - return -1; -} -function parseAnsiCode(string, offset) { - string = string.slice(offset, offset + 19); - const startIndex = findNumberIndex(string); - if (startIndex !== -1) { - let endIndex = string.indexOf("m", startIndex); - if (endIndex === -1) { - endIndex = string.length; - } - return string.slice(0, endIndex + 1); - } -} -function tokenize(string, endCharacter = Number.POSITIVE_INFINITY) { - const returnValue = []; - let index = 0; - let visibleCount = 0; - while (index < string.length) { - const codePoint = string.codePointAt(index); - if (ESCAPES2.has(codePoint)) { - const code = parseAnsiCode(string, index); - if (code) { - returnValue.push({ - type: "ansi", - code, - endCode: getEndCode(code) - }); - index += code.length; - continue; - } - } - const isFullWidth2 = isFullwidthCodePoint(codePoint); - const character = String.fromCodePoint(codePoint); - returnValue.push({ - type: "character", - value: character, - isFullWidth: isFullWidth2 - }); - index += character.length; - visibleCount += isFullWidth2 ? 2 : character.length; - if (visibleCount >= endCharacter) { - break; - } - } - return returnValue; -} -function reduceAnsiCodes(codes) { - let returnValue = []; - for (const code of codes) { - if (code.code === ansi_styles_default.reset.open) { - returnValue = []; - } else if (endCodesSet.has(code.code)) { - returnValue = returnValue.filter((returnValueCode) => returnValueCode.endCode !== code.code); - } else { - returnValue = returnValue.filter((returnValueCode) => returnValueCode.endCode !== code.endCode); - returnValue.push(code); - } - } - return returnValue; -} -function undoAnsiCodes(codes) { - const reduced = reduceAnsiCodes(codes); - const endCodes = reduced.map(({ endCode }) => endCode); - return endCodes.reverse().join(""); -} -function sliceAnsi(string, start, end) { - const tokens = tokenize(string, end); - let activeCodes = []; - let position = 0; - let returnValue = ""; - let include = false; - for (const token of tokens) { - if (token.type === "ansi") { - activeCodes.push(token); - if (include) { - returnValue += token.code; - } - } else { - if (!include && position >= start) { - include = true; - activeCodes = reduceAnsiCodes(activeCodes); - returnValue = activeCodes.map(({ code }) => code).join(""); - } - if (include) { - returnValue += token.value; - } - position += token.isFullWidth ? 2 : token.value.length; - } - } - returnValue += undoAnsiCodes(activeCodes); - return returnValue; -} -var defaultTerminalHeight = 24; -var getWidth = ({ columns = 80 }) => columns; -var fitToTerminalHeight = (stream, text) => { - const terminalHeight = stream.rows ?? defaultTerminalHeight; - const lines = text.split("\n"); - const toRemove = Math.max(0, lines.length - terminalHeight); - return toRemove ? sliceAnsi(text, stripAnsi(lines.slice(0, toRemove).join("\n")).length + 1) : text; -}; -function createLogUpdate(stream, { showCursor = false } = {}) { - let previousLineCount = 0; - let previousWidth = getWidth(stream); - let previousOutput = ""; - const reset3 = () => { - previousOutput = ""; - previousWidth = getWidth(stream); - previousLineCount = 0; - }; - const render2 = (...arguments_) => { - if (!showCursor) { - cli_cursor_default.hide(); - } - let output = fitToTerminalHeight(stream, arguments_.join(" ") + "\n"); - const width = getWidth(stream); - if (output === previousOutput && previousWidth === width) { - return; - } - previousOutput = output; - previousWidth = width; - output = wrapAnsi(output, width, { trim: false, hard: true, wordWrap: false }); - stream.write(base_exports.eraseLines(previousLineCount) + output); - previousLineCount = output.split("\n").length; - }; - render2.clear = () => { - stream.write(base_exports.eraseLines(previousLineCount)); - reset3(); - }; - render2.done = () => { - reset3(); - if (!showCursor) { - cli_cursor_default.show(); - } - }; - return render2; -} -var logUpdate = createLogUpdate(process8__default.default.stdout); -var log_update_default = logUpdate; -createLogUpdate(process8__default.default.stderr); -function escRegex(string) { - if (typeof string !== "string") throw new TypeError("Expected a string"); - return string.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d"); -} -var extractPathRegex = /\s+at.*[(\s](.*)\)?/; -var pathRegex = /^(?:(?:(?:node|node:[\w/]+|(?:(?:node:)?internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)(?:\.js)?:\d+:\d+)|native)/; -function cleanStack(stack, { pretty = false, basePath: basePath2, pathFilter } = {}) { - const basePathRegex = basePath2 && new RegExp(`(file://)?${escRegex(basePath2.replace(/\\/g, "/"))}/?`, "g"); - const homeDirectory = pretty ? node_os.homedir().replace(/\\/g, "/") : ""; - if (typeof stack !== "string") { - return void 0; - } - return stack.replace(/\\/g, "/").split("\n").filter((line) => { - const pathMatches = line.match(extractPathRegex); - if (pathMatches === null || !pathMatches[1]) return true; - const match = pathMatches[1]; - if (match.includes(".app/Contents/Resources/electron.asar") || match.includes(".app/Contents/Resources/default_app.asar") || match.includes("node_modules/electron/dist/resources/electron.asar") || match.includes("node_modules/electron/dist/resources/default_app.asar")) return false; - return pathFilter ? !pathRegex.test(match) && pathFilter(match) : !pathRegex.test(match); - }).filter((line) => line.trim() !== "").map((line) => { - if (basePathRegex) line = line.replace(basePathRegex, ""); - if (pretty) { - line = line.replace(extractPathRegex, (m2, p1) => m2.replace(p1, p1.replace(homeDirectory, "~"))); - } - return line; - }).join("\n"); -} -var PREFIX_LIMIT = 9; -var PREFIX_EXTRA = " "; -var PREFIX_SPACE = PREFIX_LIMIT + PREFIX_EXTRA.length; -var TIME_SUFFIX = /\d+[μmsec]{1,3}$/; -function Prefix(name, ...suffix) { - const label = detect(name) ? strip(name).trim() : name.trim(); - const spacer = label.length > PREFIX_LIMIT ? PREFIX_EXTRA : " ".repeat(PREFIX_SPACE - label.length); - const ICO = /^(error|invalid|failed|rejected)$/.test(label) ? BAD : NXT; - const prefix = label + PREFIX_EXTRA + spacer + ICO + PREFIX_EXTRA; - const length = suffix.length; - if (length > 0) { - if (length === 1) { - return g.ws(prefix, suffix[0]); - } else if (length === 2) { - return TIME_SUFFIX.test(strip(suffix[1])) ? g.ws(prefix, suffix[0], Append(suffix[1])) : g.ws(prefix, suffix[0], ARR, suffix[1]); - } else if (length === 3) { - return g.ws(prefix, suffix[0], ARR, suffix[1], Append(suffix[2])); - } else if (length === 4) { - return g.ws(prefix, suffix[0], ARR, suffix[1], ARR, suffix[2], Append(suffix[3])); - } - } - return prefix; -} -function Append(input) { - return input ? TLD + " " + reset2.gray(input) : ""; -} -function Encase(encase, input, { spaced = false } = {}) { - const WS = spaced ? " " : ""; - switch (encase) { - case "AN": - return LAN + WS + input + WS + RAN; - case "CB": - return LCB + WS + input + WS + RCB; - case "PR": - return LPR + WS + input + WS + RPR; - case "SB": - return LSB + WS + input + WS + RSB; - } -} -var Suffix = /* @__PURE__ */ Object.create(null); -Suffix.warning = yellow2(` ${TLD} Type ${bold2("w")} and press ${bold2("enter")} to view all warning/s`); -Suffix.error = red2(` ${TLD} Type ${bold2("v")} and press ${bold2("enter")} to view all error/s`); -Suffix.stack = gray2(`Type ${bold2("s")} and press ${bold2("enter")} to view stack trace`); -Suffix.bulk = gray2(`Type ${bold2("i")} and press ${bold2("enter")} to inspect bulk file/s`); -var Ruler = (width = void 0, newlines = true) => { - if (width === void 0) width = tsize().wrap; - const line = lightGray.open + "\u251C" + "\u2500".repeat(width - 10) + lightGray.close; - if (newlines) return Tree.trim + "\n" + line + "\n" + Tree.trim; - return line; -}; -function Top(label, timestamp = true) { - return Tree.open + reset2.gray(timestamp ? `${label} ~ ${getTime()}` : label); -} -var Multiline = (...input) => { - const style2 = { color: null, line: Tree.line }; - let write2 = ""; - let lines; - if (Array.isArray(input[0])) { - if (typeof input[1] === "object") { - Object.assign(style2, input[1]); - } - lines = input[0]; - } else { - if (typeof input[input.length - 1] === "object") Object.assign(style2, input.pop()); - lines = input; - } - while (lines.length !== 0) { - let line = lines.shift(); - if (/^\n+$/.test(line)) { - const nl = line.split("\n").length - 1; - for (let i = 0; i < nl; i++) write2 += style2.line + "\n"; - } else { - line = line.trim(); - if (line.length > 0) { - write2 += style2.line + (style2.color ? style2.color(line) : line) + "\n"; - } else { - write2 += style2.line + "\n"; - } - } - } - return write2.slice(0, -1); -}; -var Wrap = (...input) => { - const style2 = { color: null, line: Tree.line, firstLineTree: true }; - const width = tsize().wrap - 5; - let lines; - let write2 = ""; - if (Array.isArray(input[0])) { - if (typeof input[1] === "object") Object.assign(style2, input[1]); - lines = wrapAnsi(g.ws(input[0]), width, { hard: true }).split("\n"); - } else { - if (typeof input[input.length - 1] === "object") Object.assign(style2, input.pop()); - lines = wrapAnsi(input.join(" "), width, { hard: true }).split("\n"); - } - for (let i = 0, s2 = lines.length; i < s2; i++) { - const line = lines[i]; - const tree = i === 0 && style2.firstLineTree === false ? "" : style2.line; - write2 += tree + (line.length > 0 ? style2.color ? style2.color(line) : line : "") + "\n"; - } - return write2.trimEnd(); -}; -var Header = (input) => Tree.trim + "\n" + Tree.line + input + "\n" + Tree.trim; -function Line(input) { - return Tree.line + input; -} -function Dash(input) { - return Tree.dash + input; -} -function End(input, timestamp = true) { - return Tree.base + reset2.gray(timestamp ? `${input} ~ ${getTime()}` : input) + "\n"; -} -function Context(data) { - const space = eq(data.entries); - const tui = Create({ - type: data.type || "error", - tree: "tree" in data ? data.tree : true - }).Newline(); - if (typeof data.stack === "string") { - let stack = data.cleanStack ? cleanStack(data.stack, { pretty: true }) : data.stack; - if (/TypeError/.test(stack.trimStart())) { - stack = stack.slice(stack.indexOf("\n") + 1).replace(/^ +/gm, ARR + WSP2); - } - tui.Multiline(gray2(stack)).Newline(); - } - let line = ""; - let col = ""; - if ("line" in data.entries) { - line = `:${typeof data.entries.line === "number" ? data.entries.line : strip(data.entries.line)}`; - } - if (line !== "" && "column" in data.entries) { - col = `:${typeof data.entries.column === "number" ? data.entries.column : strip(data.entries.column)}`; - } - for (const key in data.entries) { - if (data.entries[key] === void 0) continue; - let string; - const isFailed = key === "failed"; - if (typeof data.entries[key] === "number") { - if (isNaN(data.entries[key])) continue; - string = neonRouge(sanitize(data.entries[key])); - } else if (!isFailed) { - string = sanitize(data.entries[key]); - } - if (string.length === 0) continue; - const entry = data.type === "warning" ? yellowBright2(key) : redBright2(key); - if (key === "source" || key === "output" || key === "input" || key === "file") { - tui.Line(`${entry}${COL} ${space(key)}${underline2(string + line + col)}`, gray2); - } else if (isFailed) { - if (Array.isArray(data.entries[key])) { - for (const fail of data.entries[key]) { - tui.Line(`${entry}${COL} ${space(key)}${underline2(fail)}`, gray2); - } - } else { - tui.Line(`${entry}${COL} ${space(key)}${underline2(data.entries[key])}`, gray2); - } - } else { - tui.Line(`${entry}${COL} ${space(key)}${string}`, gray2); - } - } - if (data.stack === true) { - tui.Newline().Line(Suffix.stack); - } - return tui.toString(); -} -function Spinner() { - let interval; - let active = false; - let message = ""; - let tline = true; - const { loaders } = Spinner; - const defaults2 = { - label: "", - line: true, - color: null, - style: "spinning", - action: null - }; - const spin = function spin2(input, settings) { - let options = { ...defaults2 }; - if (typeof input === "object") { - options = Object.assign(options, input); - } else if (typeof input === "string") { - options.label = input; - if (typeof settings === "object") { - options = Object.assign(options, settings); - } - } - active = true; - tline = options.line; - let color; - let frame = 0; - let frames; - let size = 0; - if (options.action !== null) { - options.style = "arrows"; - color = "color" in options.action ? options.action.color : neonGreen; - frames = loaders.arrows.frames; - size = frames.length; - } else { - color = typeof options.color === "function" ? options.color : pink; - message = options.label; - frames = loaders[options.style].frames; - size = frames.length; - } - log_update_default.done(); - interval = setInterval(() => { - if (!active) return; - let label; - if (options.action !== null) { - const string = bold2(options.action.before) + " " + frames[frame = ++frame % size] + " " + options.action.after; - label = color(message !== "" ? Prefix(message, string) : string); - } else { - label = color(frames[frame = ++frame % size] + " " + message); - } - log_update_default(options.line ? Header(label) : label); - }, loaders[options.style].interval); - }; - spin.update = function(input) { - message = input; - }; - spin.stop = function(input) { - if (active === false) return; - active = false; - if (input) { - log_update_default(tline ? Header(input) : input); - log_update_default.done(); - } else { - log_update_default.clear(); - } - clearInterval(interval); - interval = void 0; - message = ""; - }; - Object.defineProperty(spin, "active", { get() { - return active; - } }); - return spin; -} -Spinner.loaders = { - dots: { - interval: 100, - frames: [ - ".", - "..", - "...", - "...." - ] - }, - arrows: { - interval: 120, - frames: [ - "\u25B9\u25B9\u25B9\u25B9", - "\u25B8\u25B9\u25B9\u25B9", - "\u25B9\u25B8\u25B9\u25B9", - "\u25B9\u25B9\u25B8\u25B9", - "\u25B9\u25B9\u25B9\u25B8" - ] - }, - brielle: { - interval: 80, - frames: [ - "\u280B", - "\u2819", - "\u2839", - "\u2838", - "\u283C", - "\u2834", - "\u2826", - "\u2827", - "\u2807", - "\u280F" - ] - }, - spinning: { - interval: 80, - frames: [ - "\u25D0", - "\u25D3", - "\u25D1", - "\u25D2" - ] - } -}; -var Log = class _Log extends node_console.Console { - static get stdout() { - return process8__default.default.stdout; - } - static get stderr() { - return process8__default.default.stderr; - } - static update = createLogUpdate(_Log.stdout); - constructor() { - super(_Log.stdout, _Log.stderr); - } - write(message) { - _Log.stdout.write(message); - } - info(message, color = whiteBright2) { - _Log.stdout.write(Line(color(message.trim())) + "\n"); - } - dash(message, color = whiteBright2) { - _Log.stdout.write(Dash(color(message)) + "\n"); - } - error(message) { - _Log.stderr.write(Tree.red + redBright2(message.trim()) + "\n"); - } - warn(message) { - _Log.stderr.write(Tree.yellow + yellowBright2(message.trim()) + "\n"); - } - header(message, color = whiteBright2) { - _Log.stdout.write(Header(color(message.trim())) + "\n"); - return this; - } - wrap(...input) { - const color = typeof input[input.length - 1] === "function" ? input.pop() : gray2; - _Log.stdout.write(Wrap(input, { color, firstLineTree: false }) + "\n"); - return this; - } - tree(type2) { - _Log.stdout.write((type2 === "red" ? Tree.redTrim : type2 === "yellow" ? Tree.yellowTrim : Tree.trim) + "\n"); - return this; - } - break() { - _Log.stdout.write("\n\n"); - return this; - } -}; -var Tui = class _Tui { - /** - * Maintain Store - * - * Optional store reference used to maintain different TUI - * instances without variable assignment. - */ - // eslint-disable-next-line no-use-before-define - static store = /* @__PURE__ */ new Map(); - /** - * CLI Spinner instance - */ - spin = { - active: false, - index: NaN, - label: NIL2, - color: neonMagenta, - style: "spinning", - interval: null, - stopOn: "clear" - }; - /** - * Store ID - * - * When TUI is created with a self-maintaining instance. - * If this value is `null`, variable assignment instance was created. - * - * @default null - */ - id = null; - /** - * The type of tree message to generate - This will - * default the `Tree.line` to a specific color, meaning - * the `.line()` will be output according to the type. - * - * > `info` - * > - * > Output will be coloured `white` and Tree lines will be gray. - * - * > `warning` - * > - * > Output will be coloured `yellowBright` and Tree lines will be yellow. - * - * > `error` - * > - * > Output will be coloured `red` and Tree lines will be red. - * - * @default 'info - */ - type = "info"; - /** - * Stack entry track - * - * @default Map - */ - track = /* @__PURE__ */ new Map(); - /** - * The Tree line color based on message type - * - * @default Tree.line - */ - line; - /** - * The Tree trim color based on message type - * - * @default Tree.trim - */ - trim; - /** - * The Tree dash color based on message type - * - * @default Tree.dash - */ - dash; - /** - * Whether or not tree line prefixes apply - * - * @default true - */ - tree = true; - /** - * Optionally provide an existing structure to build from. - * - * @default [] - */ - stack; - /** - * Lambda functions - */ - lamdas = /* @__PURE__ */ new Map(); - /** - * Write index reference - */ - writes = 0; - /** - * Optional data store - */ - data; - /** - * The log-update instance - */ - get update() { - return Log.update; - } - /** - * Constructor - */ - constructor(options) { - if (typeof options === "object") { - this.id = "id" in options ? options.id : null; - this.tree = "tree" in options ? options.tree : true; - this.type = "type" in options ? options.type : "info"; - this.stack = "stack" in options ? options.stack : []; - if (this.tree) { - if (this.type === "error") { - this.line = Tree.red; - this.trim = Tree.redTrim; - this.dash = Tree.redDash; - } else if (this.type === "warning") { - this.line = Tree.yellow; - this.trim = Tree.yellowTrim; - this.dash = Tree.yellowDash; - } else { - this.line = Tree.line; - this.trim = Tree.trim; - this.dash = Tree.dash; - } - } else { - this.line = ""; - this.trim = ""; - this.dash = ""; - } - } else { - this.id = null; - this.line = Tree.line; - this.trim = Tree.trim; - this.dash = Tree.dash; - this.stack = []; - } - } - /** - * Log Output - * - * Writes to `process.stdout` or `process.stderr` or if custom stream was defined. - * Calling this option will apply the following `toString` options: - * - * ```js - * { - * clear: false, // stack will NOT clear when calling toLog() - * trim: false, // trim will NOT apply when calling toLog() - * color: undefined - * } - * ``` - * - * **Example Usage** - * - * ```js - * import * as _ from '@syncify/ansi' - * - * // Calling no parameter - * _.Create().Line('foo').Line('bar').toLog() - * - * // Passing a callback function - * _.Create().Line('foo').Line('bar').toLog((message) => {}) - * - * // Passing options with callback function - * _.Create().Line('foo').Line('bar').toLog({ clear: true },(message) => {}) - * ``` - */ - toLog(...input) { - const options = { clear: false, color: void 0, trim: false }; - let callback = null; - if (input.length > 0) { - if (input.length === 1) { - if (typeof input[0] === "function") { - callback = input[0]; - } else { - Object.assign(options, input[0]); - } - } else { - Object.assign(options, input[0]); - callback = input[1]; - } - } - const output = this.toString(options, callback); - if (this.type === "error" || this.type === "warning") { - Log.stderr.write(output); - } else { - Log.stdout.write(output); - } - return this; - } - /** - * Write Output - * - * Can be called multiple times, keeps track of stack index for each - * call and prints from the last known index. This method is different - * from `.toLog()` and `.toUpdate()` in the sense that stack is persisted - * and only new stack entries print. - * - * ```js - * { - * clear: false, // stack will NOT clear when calling toWrite() - * trim: false, // trim will NOT apply when calling toWrite() - * color: undefined - * } - * ``` - * - * **Example Usage** - * - * ```js - * import * as _ from '@syncify/ansi' - * - * const write = _.Create(); - * - * // Stack: ['│ foo'] - * write - * .Line('foo') - * .toWrite() // Logs: │ foo\n - * - * // Stack: ['│ foo\n', '│ bar\n'] - * write - * .Line('bar') - * .toWrite() // Logs: │ bar\n - * - * // Stack: ['│ foo\n', '│ bar\n', '│ baz\n'] - * write - * .Line('baz') - * .toWrite() // Logs: │ bar\n - * ``` - */ - toWrite(params2) { - const options = Object.assign({ - clear: false, - trim: false, - color: void 0, - from: this.writes - }, params2); - const output = this.toString(options); - if (this.type === "error" || this.type === "warning") { - Log.stderr.write(output); - } else { - Log.stdout.write(output); - } - this.writes = this.index + 1; - return this; - } - /** - * Generate string with ending line - * - * Applies a `.join` glue to the `this.stack[]`. Unlike other output - * methods, the `toLine` only accepts an {@link Ansis} color. - * - * Calling this option will apply the following `toString` options: - * - * ```js - * { - * clear: true, // stack will be reset - * trim: true, // trim applies because newline line appends - * color: undefined // Applied based on the parameter - * } - * ``` - * - * **Example** - * - * ```js - * import * as _ from '@syncify/ansi' - * - * // Calling no parameter - * _.Create().Line('foo').toLine() => '│ foo\n│ bar\n│' - * - * // Passing an ansis color - * _.Create().Line('foo').toLine(_.gray) - * ``` - */ - toLine(color) { - if (this.stack.length === 0) return ""; - this.stack[this.stack.length - 1] = this.stack[this.stack.length - 1].trimEnd(); - this.stack.push("\n" + this.trim); - const output = g(this.stack); - this.stack = []; - this.track.clear(); - if (color) return color(output); - if (this.type === "info") return white2(output); - if (this.type === "error") return redBright2(output); - if (this.type === "warning") return yellowBright2(output); - return output; - } - /** - * Log Update - * - * Updates the previous `stdout` using {@link update} module. The - * stack will be preserved and the last write will be removed, updated - * with the current stack. - * - * Calling this option will apply the following `toString` options: - * - * ```js - * { - * clear: false, // stack is preserved by default in toUpdate - * trim: false, // trim is not applied by default in toUpdate - * } - * ``` - * - * > The instance of log update is returned, so chaining cannot apply. - * - * **Example Usage** - * - * ```js - * import * as _ from '@syncify/ansi' - * - * // Calling no parameter - * _.Create().Line('foo').toUpdate() - * - * // Called log update methods - * _.Create().Line('foo').toUpdate().done() - * _.Create().Line('foo').toUpdate().clear() - * ``` - */ - toUpdate(options) { - if (options === null) return this; - const output = this.toString({ clear: false, trim: false, ...options }); - this.spin.stopOn = "done"; - this.update(output); - return this; - } - /** - * Generate string - * - * Applies a `.join` glue to the `text[]`, returning a string. - * Applies trim any newlines in last entry, clears the `this.stack[]` array - * and `track` Map. The resets can be prevented by passing `{ clear: false }` - * as option. The defaults are as followed: - * - * ```js - * { - * clear: true, // stack will be reset - * trim: true, // trim applies because newline line appends - * color: undefined // Applied based on the parameter - * } - * ``` - */ - toString(...input) { - if (this.stack.length === 0) return ""; - const options = { - clear: true, - trim: true, - from: 0, - color: void 0 - }; - let callback = null; - if (input.length > 0) { - if (input.length === 1) { - if (typeof input[0] === "function") { - callback = input[0]; - } else { - Object.assign(options, input[0]); - } - } else { - Object.assign(options, input[0]); - callback = input[1]; - } - } - if (options.trim) this.stack[this.index] = this.stack[this.index].trimEnd(); - const stack = options.from > 0 ? this.stack.slice(options.from) : this.stack; - let output; - if (options.color) { - output = options.color(g(stack)); - } else if (this.type === "info") { - output = white2(g(stack)); - } else if (this.type === "error") { - output = redBright2(g(stack)); - } else if (this.type === "warning") { - output = yellowBright2(g(stack)); - } else { - output = g(stack); - } - if (options.clear === true) { - this.Reset(); - } else if (Array.isArray(options.clear)) { - for (const clear2 of options.clear) { - if (this.track.has(clear2)) { - const track = this.track.get(clear2); - this.stack[track.index] = ""; - } - } - } else if (typeof options.clear === "string") { - if (this.track.has(options.clear)) { - const track = this.track.get(options.clear); - this.stack[track.index] = ""; - } - } - return callback === null ? output : callback(output); - } - /** - * Return Structure - * - * Returns the current structure being built. - * - * @example - * _.toStack() => ['│ foo', '│ bar', '│ baz'] - */ - toStack() { - return this.stack; - } - /** - * Function Lambda - * - * Tracks a function callback and fires on every call. - * - * @example - * _.Lambda('foo', () => console.label('hello')) - * - * _.Lambda('foo') - */ - Lambda(id, callback) { - if (typeof callback === "function") { - this.lamdas.set(id, callback); - } else if (this.lamdas.has(id)) { - if (callback === null) { - this.lamdas.delete(id); - } else { - this.lamdas.get(id).call(this, this); - } - } - return this; - } - /** - * String - * - * Similar to `toString()` but returns instance - */ - String(options, callback) { - callback(this.toString(options)); - return this; - } - /** - * True Conditional - * - * If parameter 1 is `truthy`, parameter to will trigger. - * - * @example - * _.True(foo === false, function(tui) { - * - * // context is parameter - * tui.Line('Hello World') - * - * // this binding applies - * this.Line('Hello World') - * }) - */ - True(condition, callback) { - if (condition) callback.call(this, this); - return this; - } - /** - * False Conditional - * - * If parameter 1 is `falsy`, parameter to will trigger. - * - * @example - * _.False(foo === false, function(tui) { - * - * // context is parameter - * tui.Line('Hello World') - * - * // this binding applies - * this.Line('Hello World') - * }) - */ - False(condition, callback) { - if (!condition) callback.call(this, this); - return this; - } - /** - * Update the newline lines - * - * Allows for the tree lines to be changed, but no modification applies to text. - */ - Tree(tree) { - if (tree === "error") { - this.line = Tree.red; - this.trim = Tree.redTrim; - this.dash = Tree.redDash; - } else if (tree === "warning") { - this.line = Tree.yellow; - this.trim = Tree.yellowTrim; - this.dash = Tree.yellowDash; - } else if (tree === "nil") { - this.line = ""; - this.trim = ""; - this.dash = ""; - } else { - this.line = Tree.line; - this.trim = Tree.trim; - this.dash = Tree.dash; - } - return this; - } - /** - * Each Iterator - * - * Acccepts a array and callback function. - * - * @example - * _.Each(['foo', 'bar'], item => _.Line(item)) - */ - Each(array, callback) { - for (let i = 0, s2 = array.length; i < s2; i++) callback.call(this, array[i], i); - return this; - } - /** - * Reset stack and track - * - * Empties the `stack[]` and clears the `track` map. - */ - Reset() { - this.stack = []; - this.track.clear(); - this.writes = 0; - if (this.id !== null && _Tui.store.has(this.id)) _Tui.store.delete(this.id); - } - /** - * is Empty - * - * Whether or not the message stack is empty - */ - get isEmpty() { - return this.stack.length > 0; - } - /** - * is Endline - * - * Whether or not the last item in the stack ends with a newline character - */ - get isEndline() { - if (this.stack.length > 0) { - const last = this.Get(); - return last[last.length - 1] === "\n"; - } - return false; - } - /** - * Get Line - * - * Returns a line at the specific index. Defaults to last known line - */ - Get(at = this.stack.length - 1) { - if (typeof at === "string" && this.track.has(at)) at = this.track.get(at).index; - return this.stack[at]; - } - /** - * Track Stack entry - * - * When called, an index in the stack is tracked. The message in the stack - * can then be referenced and updated at a later time using `Update`. If - * the stack is empty, no track applies. - * - * The function **must** be called following a write method and the last known - * entry index in the stack is what is saved. If a tacked reference exists - * with the `id` provided, it will be overwritten. - * - * All tracked references are cleared on `toString` or `toLine` - */ - Template(...input) { - const message = input.length === 2 ? input[0] : null; - const options = Object.assign({ - color: null, - prefix: false, - insert: false, - hidden: false, - id: null, - label: null, - message: null, - dash: false, - index: this.stack.length - }, message ? input[1] : input[0]); - if (typeof options.prefix === "string") { - options.label = options.prefix; - options.prefix = true; - } - if (message !== null) { - const write2 = Array.isArray(message) ? message : [message]; - if (options.hidden) { - options.message = write2; - this.stack.push(""); - } else { - if (options.prefix) { - this.stack.push( - Prefix( - typeof options.label === "string" ? options.label : options.id, - options.color ? options.color(g(write2)) : g(write2) - ) + NWL2 - ); - } else { - this.stack.push(Multiline(write2, { - color: options.color, - line: options.dash ? this.dash : this.line - }) + NWL2); - } - } - } else { - this.stack.push(""); - } - if (options.id !== null) { - if (options.index !== this.stack.length - 1) options.index = this.stack.length - 1; - this.track.set(options.id, options); - } - return this; - } - /** - * Tree Update - * - * Updates a stack entry at either a `Track()` identifier index or index (depending on `id`) - * parameter `type` provided. The stack will be augmented and updated, at the index provided. - * Passing an `string[]` input will result in spliced insertion. - * - * @example - * // Assuming Template('ref') was called during message creation - * - * // If ref was index 1 in the stack - * _.Update('ref', ['hello', 'world']) - * - * // Before - * ['│ foo\n', '│ bar\n', '│ baz\n'] - * // After - * ['│ foo\n', '│ hello\n', '│ world\n', '│ baz\n'] - */ - Update(id, input = null, newColor = null) { - let index = NaN; - let track; - if (typeof id === "string" && this.track.has(id)) { - track = this.track.get(id); - index = track.index; - } - if (isNaN(index) || typeof this.stack[index] !== "string") return this; - const lines = track.hidden ? input === null ? [...track.message] : [""] : typeof input === "string" ? [input] : Array.isArray(input) ? input : [`${input}`]; - const newline = lines.length > 1; - const replace = []; - const color = newColor || track.color; - const { prefix, insert, label, dash } = track; - const line = dash ? this.dash : this.line; - let tree = 0; - while (lines.length !== 0) { - const line2 = lines.shift(); - newline && tree > 0 && insert === false ? replace.push(line2 + (color ? color(line2) : line2)) : replace.push(color ? color(line2) : line2); - tree++; - } - const output = prefix ? Prefix(typeof label === "string" ? label : id, g(replace)) : newline ? g.nl(replace) : g(replace); - if (insert) { - this.stack.splice(index, 1, output); - } else { - this.stack.splice(index, 1, line + output + "\n"); - } - return this; - } - /** - * TUI Spinner - * - * Prints a spinning loading and persists within stack Calling `this.toUpdate()` each interval. - * Can be used with `this.Stop()`. Renders a `Header` entry. - * - * @example - * // Spinner will begin immediately - * _.Line('foo').Spinner('bar') - * - * // Stack input - notice how a header is applied - * ['│ foo\n', '│\n│ ◓ bar\n│\n'] - * - * // When we want to stop and clear spinner - * _.Stop() - */ - Spinner(message, options) { - options = Object.assign({ - style: "spinning", - color: neonTeal - }, { - color: this.spin.color, - style: this.spin.style - }, options); - if (this.spin.active === false) { - if (this.spin.stopOn === "done") { - this.update.clear(); - } - let frame = 0; - this.spin.style = options.style; - const spin = Spinner.loaders[this.spin.style]; - const frames = spin.frames; - const size = frames.length; - this.spin.index = this.stack.push("") - 1; - this.spin.color = options.color; - this.spin.label = message; - this.spin.active = true; - this.update(this.line + gray2.dim("...")); - this.spin.interval = setInterval(() => { - if (this.spin.active) { - this.update(g( - this.line, - this.spin.color(frames[++frame % size] + WSP2 + this.spin.label), - NWL2 - )); - } - }, spin.interval); - } else { - this.spin.label = message; - this.spin.color = options.color; - } - return this; - } - /** - * TUI Stop Spinner - * - * When spinner is active, calling this will stop and remove the spinner - * from the stack. Optionally update the spinner value to preserve. - * - * > **NOTE** Passing an update will render as line, not Header - */ - Stop(update2, color) { - if (this.spin.interval !== null) { - clearInterval(this.spin.interval); - } - if (this.spin.active === false) { - this.update.done(); - return this; - } - this.update.clear(); - this.spin.active = false; - this.spin.interval = null; - this.True(this.writes > 0, () => this.Remove(this.spin.index, Infinity)).True(update2, () => this.Line(update2, color)); - this.spin.index = NaN; - return this; - } - /** - * Checks if previous stack entry is tree line and pops it - * if determined to be true. - */ - Trim() { - const previous = this.stack[this.stack.length - 1] + "\n"; - if (!previous) return this; - if (previous === Tree.line || previous === Tree.trim || previous === Tree.red || previous === Tree.redTrim || previous === Tree.yellow || previous === Tree.yellowTrim) this.Pop(); - return this; - } - /** - * Remove Line - * - * Removes a line at specific index. Can apply a slice or splice. - * Passing a `deleteCount` value of `Infinity` will slice stack at the index. - * - * @example - * // Assuming the stack contains the following: - * [ - * '│ foo', - * '│ bar', - * '│ baz' - * ] - * - * // Calling .remove(0) will remove first index - * [ - * '│ bar', - * '│ baz' - * ] - */ - Remove(at, deleteCount = 1) { - let index; - if (typeof at === "string") { - if (!this.track.has(at)) return this; - index = this.track.get(at).index; - this.track.delete(at); - } else { - index = at; - } - if (deleteCount === Infinity) { - this.stack.splice(index); - for (const [otherId, data] of this.track.entries()) { - if (data.index >= index) { - this.track.delete(otherId); - } - } - this.stack = this.stack.slice(0, index); - } else { - let ender; - if (typeof deleteCount === "string") { - if (this.track.has(deleteCount)) { - ender = this.track.get(deleteCount).index; - this.track.delete(deleteCount); - } else { - ender = 1; - } - } else { - ender = deleteCount; - } - this.stack.splice(index, ender); - for (const [id, track] of this.track.entries()) { - if (track.index > index) { - this.track.get(id).index = track.index - ender; - } - } - } - return this; - } - /** - * Mark Stack - * - * Inserts a fake placeholder that is to be removed or replaced at a later time. - * The `track` Map will assign `insert` to `true` to prevent newline line insertion. - * - * @example - * _.Mark('xxx') - * - * // Before - * [ '│ foo', '│ bar' ] - * - * // After - * [ '│ foo', '│ bar', ''] - * - * // Later on - * _.Remove('xxx') - * - * // Use Infinity to slice at mark - * _.Remove('xxx', Infinity) - */ - Mark(id) { - this.track.set(id, { - id, - index: this.stack.length, - label: null, - prefix: false, - color: void 0, - insert: false, - dash: false, - hidden: false, - message: null - }); - this.stack.push(""); - return this; - } - /** - * Replace and persist - * - * Replaces an entry at the provided index. Line is prefixed and not required in `input` - * - * @example - * _.Replace(1, 'qux') - * - * // Before - * [ '│ foo', '│ bar', '│ baz' ] - * - * // After - * [ '│ foo', '│ qux', '│ baz' ] - */ - Replace(at, input, color) { - let index; - if (typeof at === "string") { - if (!this.track.has(at)) return this; - index = this.track.get(at).index; - } else { - index = at; - } - if (this.stack[index]) { - this.stack[index] = this.line + (color ? color(input) : input) + "\n"; - } - return this; - } - /** - * Tree Horizontal Line - * - * Prints a horizontal line separator which will default to - * spanning the `wrap` of the terminal pane. - * - * ```bash - * # When Tree is enabled - * │\n - * ├─────────────────────\n - * │\n - * - * # When Tree is disabled - * ──────────────────────\n - * ``` - */ - Ruler(width = void 0, { noLines = false } = {}) { - if (width === void 0) width = tsize().wrap; - if (this.tree) { - if (noLines) { - this.stack.push(lightGray(`\u251C${"\u2500".repeat(width)}`) + "\n"); - } else { - this.stack.push(Tree.trim + "\n" + lightGray(`\u251C${"\u2500".repeat(width)}`) + "\n" + Tree.trim + "\n"); - } - } else { - this.stack.push(lightGray("\u2500".repeat(width)) + "\n"); - } - return this; - } - /** - * Returns the current text index in the stack - */ - get index() { - return this.stack.length - 1; - } - get newlines() { - return this.stack.join("").split(NWL2).length; - } - /** - * Tree Newline - * - * Works the same as `Newline()` but is exposed as getter - * - * ```bash - * │\n - * ``` - */ - get NL() { - this.stack.push(this.trim + "\n"); - return this; - } - /** - * Newline only - * - * Pushed a newline into the stack - * - * ```bash - * \n - * ``` - */ - get BR() { - this.stack.push("\n"); - return this; - } - /** - * Newline only - * - * Pushes a single `\n` newline into the stack or - * multiple newlines if `repeat` parameter is provided. - * - * ```bash - * \n - * ``` - */ - Break(repeat) { - if (typeof repeat === "number") { - this.stack.push("\n".repeat(repeat)); - } else { - this.stack.push("\n"); - } - return this; - } - /** - * Tree Pop - * - * Removes the last entry in the message stack. Accepts - * a number parameter to increase the amount of removals - * to occur. - * - * ```bash - * │\n - * ``` - * - * @example - * // Assuming the stack contains the following: - * [ - * '│ foo', - * '│ bar', - * '│ baz' - * ] - * - * // Calling .pop() will remove the last entry: - * [ - * '│ foo', - * '│ bar' - * ] - */ - Pop(amount = 1) { - while (amount-- > 0) this.stack.pop(); - return this; - } - /** - * Tree Newline - * - * Returns a newline, accepts `addLines` parameter that accepts a `number` - * and when provided will generate multiple newlines. In addition (or optionally) - * a `color` can be provided, which expects a valid color string name. - * - * ```bash - * │\n - * ``` - * - * --- - * - * **Passing Color** - * - * Passing `Newlines('red')` will a line in red. - * - * ```bash - * │\n - * ``` - * - * --- - * - * **Passing Lines and Color** - * - * Passing `Newlines(2, 'red')` will generate the following string in red. - * - * ```bash - * │\n - * │\n - * ``` - */ - Newline(addLines, color) { - if (typeof addLines === "number") { - let input = this.trim + "\n"; - if (color) { - if (this.tree) { - if (color === "yellow") { - input = Tree.yellowTrim + "\n"; - } else if (color === "red") { - input = Tree.redTrim + "\n"; - } - } - } - for (let i = 0; i < addLines; i++) this.stack.push(input); - } else { - if (addLines === "") { - this.stack.push("\n"); - } else if (addLines === "line") { - this.stack.push(Tree.trim + "\n"); - } else if (addLines === "yellow") { - this.stack.push((this.tree ? Tree.yellowTrim : "") + "\n"); - } else if (addLines === "red") { - this.stack.push((this.tree ? Tree.redTrim : "") + "\n"); - } else if (typeof addLines === "string") { - this.stack.push(addLines + "\n"); - } else { - this.stack.push(this.trim + "\n"); - } - } - return this; - } - /** - * Tree Inline - * - * Appends to the previous entry. If no entries exist in the message, a new one is - * created with tree line prefix. - * - * > Use `Push()` method to insert entry without line prefix. - * - * @example - * _.Inline('baz qux') - * - * // Before - * [ '│ hello', '│ foo bar\n' ] - * - * // After - * [ '│ hello', '│ foo bar baz qux\n' ] - * - * // If the stack is empty, default behaviour applied - * - * // Before - * [] - * - * // After - * [ '│ baz qux' ] - */ - Inline(input, ...options) { - let index = this.stack.length > 0 ? this.stack.length - 1 : NaN; - let color = null; - if (options.length > 0) { - if (options.length === 2) { - index = options[0]; - color = options[1]; - } else if (options.length === 1) { - if (typeof options[0] === "number") { - index = options[0]; - } else { - color = options[0]; - } - } - } - if (index > -1) { - this.stack[index] = this.stack[index].trimEnd() + " " + (color ? color(input) : input) + "\n"; - } else { - this.stack.push(this.line + (color ? color(input) : input) + "\n"); - } - return this; - } - /** - * Tree Insert - * - * Pushes input onto the stack, but does not prefix line or append newline. - * Inserts the `input` as is, and accepts an optional `color` function. - * - * @example - * _.Insert('bar baz qux') - * - * // Before - * [ '│ hello', '│ foo' ] - * - * // After - * [ '│ hello', '│ foo', 'bar baz qux' ] - */ - Insert(input, color) { - this.stack.push(color ? color(input) : input); - return this; - } - /** - * Tree Line - * - * Pushes a string onto the message stack. Prefixes with a `│` and - * suffixes with newline `\n`. This is _typically_ the most common method. - * - * ```bash - * │ input\n - * ``` - * - * @example - * _.Line('world') - * - * // Before - * [ '│ hello\n' ] - * - * // After - * [ '│ hello\n', '│ world\n' ] - */ - Line(input, color) { - if (this.type === "error") { - return this.Error(input, color); - } - if (this.type === "warning") { - return this.Warn(input, color); - } - this.stack.push(this.line + (color ? color(input) : input) + "\n"); - return this; - } - /** - * Tree Prefix - * - * Applies the {@link Prefix} render on a line. - * - * Equally distributes whitespace following the `prefix` parameter. - * Optionally accepts a `suffix[]` string spread. Depending on the number - * of suffix appends passed, different output is produced. When passing - * `3 or 4` suffixes the last known suffix will apply `~` appenditure. - * - * See below examples: - * - * --- - * - * **Passing 0 `suffix` parameters** - * - * ```bash - * │ prefix - * ``` - * - * --- - * - * **Passing 1 `suffix` parameter** - * - * ```bash - * │ prefix » action - * ``` - * --- - * - * **Passing 2 `suffix` parameters** - * - * ```bash - * │ prefix » action → suffix - * ``` - * - * --- - * - * **Passing 3 `suffix` parameters** - * - * ```bash - * │ prefix » action → suffix ~ append - * ``` - * - * --- - * - * **Passing 4 `suffix` parameters** - * - * ```bash - * │ prefix » handle ⥂ joiner → action ~ append - * ``` - */ - Prefix(label, ...suffix) { - const color = typeof suffix[suffix.length - 1] === "function" ? suffix.pop() : null; - const text = color ? suffix.map((item) => color(item)) : suffix; - const input = Prefix(label, ...text); - this.stack.push(this.line + input + "\n"); - return this; - } - /** - * Prepend Line - * - * Pushes a string onto the message stack with a newline line prepended - * - * ```bash - * │\n - * │ input\n - * ``` - * - * @example - * _.Prepend('world') - * - * // Before - * [ '│ hello\n' ] - * - * // After - * [ '│ hello\n', '│\n│ world\n' ] - */ - Prepend(input, color) { - if (this.type === "error") { - return this.NL.Error(input, color); - } else if (this.type === "warning") { - return this.NL.Warn(input, color); - } - return this.NL.Line(input, color); - } - /** - * Append Line - * - * Pushes a string onto the message stack. Appended with a newline line `│` and - * suffixes with newline `\n`. - * - * ```bash - * │ input\n - * │\n - * ``` - * - * @example - * _.Append('world') - * - * // Before - * [ '│ hello\n' ] - * - * // After - * [ '│ hello\n', '│ world\n│\n' ] - */ - Append(input, color) { - if (this.type === "error") { - this.Error(input, color); - } else if (this.type === "warning") { - this.Warn(input, color); - } else { - this.Line(input, color); - } - return this.Newline(); - } - /** - * Tree Error Line (red) - * - * Same as `Line()` but tree line suffix is `red` - * - * ```bash - * │ input\n - * ``` - */ - Error(input, color) { - this.stack.push((this.tree ? Tree.red : "") + (color ? color(input) : redBright2(input)) + "\n"); - return this; - } - /** - * Tree Warn Line (yellow) - * - * Same as `Line()` but tree line suffix is `yellow` - * - * ```bash - * │ input\n - * ``` - */ - Warn(input, color) { - this.stack.push((this.tree ? Tree.yellow : "") + (color ? color(input) : yellowBright2(input)), "\n"); - return this; - } - /** - * Tree Line Break - * - * Appends and Prepends newlines, effectively wrapping the `input` in - * paragraphical format. - * - * ```js - * // When tree is enabled - * │\n - * │ input\n - * │\n - * - * // When tree is disabled - * \n - * input\n - * \n - * ``` - */ - Header(message, color) { - this.stack.push( - this.trim + "\n" + this.line + (color ? color(message) : message) + "\n" + this.trim + "\n" - ); - return this; - } - /** - * Tree Top - * - * ``` - * '\n┌─ Label ~ 01:59:20\n' - * ``` - */ - Top(label, timestamp = true) { - this.stack.push(Top(label, timestamp) + "\n"); - return this; - } - /** - * Tree End - * - * Returns a tree ender with optional timestamp suffix appended. - * Timestamp suffix defaults to `true` and will be applied. - * - * ```js - * '└─ input ~ 01:59:20\n' // Passing true to timestamp (default) - * // OR - * '└─ input\n' // Passing false to timestamp - * ``` - */ - End(input, timestamp = true) { - this.stack.push(End(input, timestamp)); - return this; - } - /** - * Tree Context - * - * Accepts a contextual model. The context will be parsed and - * pushed onto the stack. - * - * ``` - * │ - * │ code: 422 - * │ file: ~source/dir/filename.liquid - * │ status: Unprocessed Entity - * │ - * │ Type s and press enter to view stack trace - * ``` - */ - Context(data) { - if (!("tree" in data)) data.tree = this.line !== ""; - this.stack.push(Context(data) + "\n"); - return this; - } - /** - * Tree Dash - * - * Applies prefixed tree dash to input - * - * ```js - * // When tree is enabled - * ├─ input\n - * - * // When tree is disabled - * — input\n - * ``` - */ - Dash(input, color) { - this.stack.push((this.tree ? this.dash : `${DSH} `) + (color ? color(input) : input) + "\n"); - return this; - } - /** - * Tree Multiline - * - * Prefixes a multiline string with tree line. This method does - * not apply wrap, but instead applies a `.split('\n')` on string - * input (if single string is passed). The method accepts `...string` - * spread or `string[]` parameter value. - * - * ``` - * │ lorem ipsum lorem ipsum\n - * │ lorem ipsum lorem ipsum\n - * │ lorem ipsum lorem ipsum\n - * ``` - * - * @example - * // Passing a string with newlines - * _.Multline('hello\nworld') => [ '│ hello\n', '│ world\n' ] - * - * // Passing an array of strings - * _.Multline(['hello', 'world']) => [ '│ hello\n', '│ world\n' ] - * - * // Passing a spread - * _.Multline('hello', 'world') => [ '│ hello\n', '│ world\n' ] - */ - Multiline(...input) { - const lines = typeof input[0] === "string" ? input.length === 1 ? input[0].split("\n") : input : input[0]; - while (lines.length !== 0) { - this.stack.push(this.line + lines.shift() + "\n"); - } - return this; - } - /** - * Tree Unshift - * - * Inserts a string onto the message stack at index `0`. Prefixes with a `│` and - * suffixes with newline `\n`. - * - * > If `type` is `error` or `warning` and you want to prevent the red or yellow - * color highlighting, then pass a value of `null` to color parameter. - * - * ```bash - * │ input\n - * ``` - * - * @example - * _.Unshift('world', 0) - * - * // Before - * [ '│ hello\n' ] - * - * // After - * ['│ world\n', '│ hello\n' ] - */ - Unshift(input, color) { - if (!color) { - if (color !== null) { - if (this.type === "error") color = redBright2; - if (this.type === "warning") color = yellowBright2; - } - } - this.stack.push(this.line + (color ? color(input) : input) + "\n"); - return this; - } - /** - * Tree Wrap - * - * Accepts `string[]` or `...string[]` spread. The last entry accepts an - * optional Ansis color. The **input** will be passed to {@link Wrap} and the - * returning output will end with newline. - * - * ``` - * │ lorem ipsum lorem ipsum\n - * │ lorem ipsum lorem ipsum\n - * │ lorem ipsum lorem ipsum\n - * ``` - */ - Wrap(...input) { - let color = whiteBright2; - if (this.type === "error") { - color = redBright2; - } else if (this.type === "warning") { - color = yellowBright2; - } - if (typeof input[0] === "string") { - if (typeof input[input.length - 1] === "function") { - color = input.pop(); - } - this.stack.push(Wrap(input, { color, line: this.line }) + "\n"); - } else if (Array.isArray(input[0])) { - if (typeof input[1] === "function") color = input.pop(); - this.stack.push(Wrap(input[0], { color, line: this.line }) + "\n"); - } else if (typeof input[0] === "function") { - color = input.shift(); - this.stack.push(Wrap(input, { color, line: this.line }) + "\n"); - } else if (Array.isArray(input[1])) { - color = input[0]; - this.stack.push(Wrap(input[1], { color, line: this.line }) + "\n"); - } - return this; - } -}; -function Create(...params2) { - let id; - let options; - if (params2.length === 2) { - id = params2[0]; - options = params2[1]; - } else if (params2.length === 1) { - if (typeof params2[0] === "string") { - id = params2[0]; - } else { - options = params2[0]; - } - } - if (id) { - if (options) { - options.id = id; - } else { - options = { id }; - } - const instance = new Tui(options); - return Tui.store.set(id, instance).get(id); - } - return new Tui(options); -} -function TUI(id) { - if (Tui.store.has(id)) return Tui.store.get(id); - return Create(id); -} -function progress(total, opts = {}) { - const options = Object.assign({ - showPercentage: true, - barColor: "neonGreen", - prepend: Tree.line, - percentColor: "whiteBright", - barSize: 40, - clearOnComplete: false - }, opts); - let percent = 0; - const align = (output) => { - if (typeof options.prepend === "string") { - return options.prepend + output + " ".repeat(Math.max(0, options.barSize - output.length)); - } else { - return output + " ".repeat(Math.max(0, options.barSize - output.length)); - } - }; - const bar = (length, empty = false) => (empty ? "\u25B1" : "\u25B0").repeat(length); - const stop = () => { - if (options.clearOnComplete) console.clear(); - }; - const reset3 = (newTotal) => { - if (typeof newTotal === "number") total = newTotal; - if (percent !== 0) percent = 0; - }; - const increment = (incrementBy = 1) => { - const filled = percent + incrementBy; - percent = Math.min(filled, total); - if (percent === total) stop(); - }; - const decrement = (decrementBy = 1) => { - const filled = percent - decrementBy; - percent = Math.max(filled, 0); - }; - const render2 = (percentColor) => { - const progress2 = Math.round(percent / total * options.barSize); - const filled = bar(progress2); - const empty = bar(options.barSize - progress2, true); - let output = ansis_default[options.barColor](filled) + lightGray(empty); - if (options.showPercentage) { - output += (percentColor || whiteBright2)(` ${String(Math.round(percent / total * 100))}%`); - } - return align(output); - }; - return { - stop, - increment, - decrement, - render: render2, - reset: reset3, - /** - * Returns the percent filled amount - */ - get percent() { - return percent; - } - }; -} -var Scroller = class { - /** - * The lines of content in the scrollable area wrapped - * according to the specified {@link ScrollerOptions} and - * split into an array of lines. - */ - lines = []; - /** - * The maximum height - */ - maxHeight; - /** - * The content to display in the scrollable area. - * - * @default undefined - */ - content; - /** - * Whether or not each write to `stdout` should append `\n` - * character and simulate native `console.log`. - */ - newline; - /** - * The position of the first line to display in the scrollable area. - */ - position = 0; - /** - * The tree line prefix character - */ - prefix; - /** - * The line suffix, when `newline` is `true` this is `\n` otherwise empty string - */ - suffix; - /** - * An empty line - */ - empty; - /** - * Word Wrap options - */ - wrap = { - hard: false, - trim: true, - wordWrap: true - }; - /** - * The options for the Scroller instance. - */ - options = { - input: void 0, - newline: true, - height: process.stdout.rows - 20, - width: process.stdout.columns - 20, - wrap: false, - tree: false, - xPos: 0, - yPos: 0 - }; - /** - * The height of the content - */ - get height() { - return this.options.height; - } - /** - * The width of the content - */ - get width() { - return this.options.width; - } - /** - * X position of scroller - */ - get x() { - return this.options.xPos; - } - /** - * Set X position of scroller - */ - set x(x) { - this.options.xPos = x; - } - /** - * Y position of scroller - */ - get y() { - return this.options.yPos; - } - /** - * Set Y position of scroller - */ - set y(y) { - this.options.yPos = y; - } - /** - * Creates a new Scroller instance. - * @param options - The options for the Scroller instance. - */ - constructor(options) { - Object.assign(this.options, options); - this.prefix = this.options.tree ? Tree.line : ""; - this.suffix = this.options.newline ? "\n" : ""; - this.empty = g(Array(this.width).fill(WSP2)); - if (typeof this.options.input === "string") { - this.content = this.options.input; - } else { - this.content = g.nl(this.options.input); - this.lines = this.options.input; - } - this.options.height = "height" in options ? options.height : this.content.split("\n").length; - this.maxHeight = this.content.split("\n").length - this.options.height - 1; - } - setKeypress(y, max) { - process.stdin.setRawMode(true); - readline.emitKeypressEvents(process.stdin); - return process.stdin.on("keypress", (str, key) => { - if (key.sequence === "" || key.sequence === "" || key.sequence === "") { - process.exit(0); - } else if (key.name === "up") { - if (this.position === 0) return; - this.scroll(-2).print(); - process.stdout.cursorTo(0, y + 2); - } else if (key.name === "down") { - if (this.position >= max) return; - this.scroll(2).print(); - process.stdout.cursorTo(0, y + 2); - } - }); - } - /** - * Sets the content to display in the scrollable area. - */ - setContent(content) { - this.content = content; - this.resetLines(); - return this; - } - /** - * Sets the `x` and/or `y`position of the scrollable area. - */ - setPosition(position = {}) { - if ("x" in position) this.x = position.x; - if ("y" in position) this.y = position.y; - this.resetLines(); - return this; - } - /** - * Sets the size of the scroller area. - */ - setSize(size) { - if ("width" in size) this.options.width = size.width; - if ("height" in size) this.options.height = size.height; - this.resetLines(); - return this; - } - /** - * Sets the options for wrapping the content in the scrollable area. - */ - setWrap(wrapOptions) { - if (typeof wrapOptions === "boolean") { - this.options.wrap = wrapOptions; - } else { - if (!this.options.wrap) this.options.wrap = true; - Object.assign(this.wrap, wrapOptions); - } - if (this.options.wrap) this.resetLines(); - return this; - } - /** - * Prints the scrollable area to the console. - * @returns The Scroller instance. - */ - print() { - if (this.lines.length === 0) this.splitContentIntoLines(); - this.clear(); - process.stdout.cursorTo(this.x, this.y); - for (let i = 0; i < this.height; i++) { - const line = this.lines[i + this.position]; - process.stdout.write(this.prefix + (line ?? this.empty) + this.suffix); - } - return this; - } - /** - * Scrolls by the specified number of lines. - */ - scroll(lines) { - this.position += lines; - return this; - } - /** - * Clears the scrollable area. - */ - clear() { - process.stdout.cursorTo(this.x, this.y); - for (let i = 0; i < this.height; i++) { - process.stdout.cursorTo(this.x); - process.stdout.write(this.empty + "\n"); - } - return this; - } - resetLines() { - this.lines = []; - this.position = 0; - } - splitContentIntoLines() { - if (!this.content) return; - if (this.options.wrap) { - this.lines = wrapAnsi(this.content, this.width, this.wrap).split("\n"); - } else { - this.lines = this.content.split("\n"); - } - } -}; -function Scroll(options) { - return new Scroller(options); -} -var capture = function(regex2, input, fn) { - return detect(input) ? input.replace(/(?:\u001b\[[;\d]+m)([\s\S]*?)(?=\u001b)/g, function(match, group) { - const escape = group.trim().replace(/([^a-z0-9\s]+)/g, "\\$1"); - const regexp = new RegExp(`(${escape})`, "g"); - return match.replace(regexp, (text) => text === NIL2 ? text : text.replace(regex2, fn("$1"))); - }) : input.replace(regex2, fn("$1")); -}; -capture.stream = (input) => (...replacers) => { - let output = input; - for (const callback of replacers) { - output = callback(output); - } - return output; -}; -capture.quoted = (input, fn) => { - return capture.stream(input)( - (value) => value.replace(/\B'(?:(?!'\B).)+'/g, fn), - (value) => value.replace(/\B"(?:(?!"\B).)+"/g, fn) - ); -}; -capture.url = (input, fn) => { - return input.replace(/(https?:\/\/[^\s]+|www\.[^\s]+)/g, (match) => { - const url = strip("$1"); - return /^(https?:\/\/|www\.)[./:0-9A-Za-z-]+$/.test(url) ? fn(url) : match; - }); -}; -capture.punctuation = (input, fn) => capture(/([|$[\]{}<>:-]+)/, input, fn); -capture.numbers = (input, fn) => capture(/([\d]+)/g, input, fn); -capture.braces = (input, fn) => input.replace(/[{}]+/g, (m2) => fn(m2)); -capture.angles = (input, fn) => input.replace(/[<>]+/g, (m2) => fn(m2)); -capture.brackets = (input, fn) => capture(/([[\]]+)/g, input, fn); -capture.pipes = (input, fn) => input.replace(/[|]+/g, (m2) => fn(m2)); -capture.colons = (input, fn) => input.replace(/[:]+/g, (m2) => fn(m2)); -capture.dash = (input, fn) => input.replace(/[-]+/g, (m2) => fn(m2)); -capture.commas = (input, fn) => input.replace(/[,]+/g, (m2) => fn(m2)); -capture.dollar = (input, fn) => input.replace(/[$]+/g, (m2) => fn(m2)); -var LINUX = process8__default.default.platform === "linux"; -var WINDOWS = process8__default.default.platform === "win32"; -var SIGNALS = [ - "SIGABRT", - "SIGALRM", - "SIGHUP", - "SIGINT", - "SIGTERM" -]; -if (!WINDOWS) { - SIGNALS.push( - "SIGVTALRM", - "SIGXCPU", - "SIGXFSZ", - "SIGUSR2", - "SIGTRAP", - "SIGSYS", - "SIGQUIT", - "SIGIOT" - ); -} -if (LINUX) { - SIGNALS.push( - "SIGIO", - "SIGPOLL", - "SIGPWR", - "SIGSTKFLT", - "SIGUNUSED" - ); -} -var kill = function(callback) { - kill.hooks.add(callback); - if (!kill.setup) { - kill.setup = true; - process8__default.default.once("exit", () => hook()); - for (const signal of SIGNALS) { - try { - process8__default.default.once(signal, () => hook(signal)); - } catch { - } - } - } - return () => kill.hooks.delete(callback); -}; -kill.hooks = /* @__PURE__ */ new Set(); -kill.setup = false; -kill.fired = false; -kill.exit = function(code = 0) { - if (code > 0) { - kill.hooks.clear(); - process8__default.default.exit(code); - } - const done = () => { - if (kill.hooks.size > 0) kill.hooks.clear(); - process8__default.default.exit(code); - }; - const wait = []; - kill.hooks.forEach((hook2) => types.isAsyncFunction(hook2) ? wait.push(hook2()) : hook2()); - Promise.allSettled(wait).finally(done); -}; -function hook(signal) { - if (kill.fired === true) return; - const wait = []; - const done = () => { - if (signal) { - if (WINDOWS && (signal !== "SIGINT" && signal !== "SIGTERM" && signal !== "SIGKILL")) { - process8__default.default.kill(process8__default.default.pid, "SIGTERM"); - } else { - process8__default.default.kill(process8__default.default.pid, signal); - } - } - }; - kill.fired = true; - kill.hooks.forEach((cb) => types.isAsyncFunction(cb) ? wait.push(cb()) : cb()); - Promise.allSettled(wait).finally(done); -} -var prexit = function(...params2) { - let id; - let callback; - if (params2.length === 3) { - [id, callback, prexit.code] = params2; - } else if (params2.length === 2) { - if (typeof params2[0] === "string") { - [id, callback] = params2; - } else { - callback = params2[0]; - id = callback.name || Date.now().toString(); - prexit.code = params2[1]; - } - } else if (params2.length === 1) { - callback = params2[0]; - id = callback.name || Date.now().toString(); - } - if (callback) { - if (typeof callback !== "function") { - throw new Error("Callback must be a function"); - } - prexit.hooks.set(id, callback); - } - if (!prexit.setup) { - prexit.setup = true; - readline__default.default.emitKeypressEvents(process8__default.default.stdin); - if (process8__default.default.stdin.isTTY) process8__default.default.stdin.setRawMode(true); - process8__default.default.stdin.resume(); - process8__default.default.stdin.on("keypress", async (_, key) => { - if (prexit.fired) return; - if (prexit.intercept["escape"] && key.sequence === "\x1B" || prexit.intercept["ctrl+c"] && key.sequence === "" || prexit.intercept["ctrl+d"] && key.sequence === "" || prexit.intercept["ctrl+z"] && key.sequence === "") { - await hooks(); - } - }); - } - return id ? () => prexit.hooks.delete(id) : () => false; -}; -prexit.hooks = /* @__PURE__ */ new Map(); -prexit.code = 130; -prexit.setup = false; -prexit.fired = false; -prexit.intercept = { - "escape": true, - "ctrl+c": true, - "ctrl+d": false, - "ctrl+z": false -}; -prexit.listener = (handler) => { - if (!prexit.setup) { - prexit(); - } - process8__default.default.stdin.on("keypress", handler); -}; -async function hooks() { - if (prexit.fired) return; - prexit.fired = true; - const promises = []; - for (const [id, hook2] of prexit.hooks) { - try { - const result = hook2(); - if (types.isAsyncFunction(hook2)) { - promises.push(result); - } else if (result instanceof Promise) { - promises.push(result); - } - } catch (err) { - console.error(`Error in hook ${id}:`, err); - } - } - await Promise.allSettled(promises); - process8__default.default.exit(prexit.code); -} - -// syncify/utils/const.ts -var READ_WRITE_OWNER = 493; -var HOT_SNIPPET = "hot.js.liquid"; -var HOT_SOURCE = "hot-snippet"; -var HOT_SNIPPET_KEY = "snippets/hot.js.liquid"; -var JS_TS_CONFIGS = [ - "tsconfig.json", - "jsconfig.json" -]; -var COMMAND_MODES = /* @__PURE__ */ new Set([ - "init", - "create", - "build", - "watch", - "pack", - "push", - "pull", - "publish", - "version", - "keychain", - "projects", - "link", - "git", - "help", - "prune", - "doctor", - "inspect" -]); -var HOT_SOCKET_TOPICS = [ - "alias", - "script", - "stylesheet", - "section", - "svg", - "assets", - "reload", - "replace", - "connect", - "disconnect", - "connected" -]; -var SYNCIFY_CONFIG = [ - "syncify.config.ts", - "syncify.config.js", - "syncify.config.mjs", - "syncify.config.cjs", - "syncify.config.json" -]; -var TARGET_FILES = [ - "theme.toml", - "theme.yaml", - "theme.yml" -]; -var CACHE_FILES = [ - "checksum", - "metafields", - "pages", - "paths", - "schema", - "sections", - "settings", - "templates" -]; -var BASE_DIRS = [ - ["input", "source"], - ["output", "theme"], - ["config", "."] -]; -var PATH_PLUS_KEYS = [ - "blogs", - "files", - "metafields", - "navigation", - "pages", - "policies", - "schema" -]; -var PATH_THEME_KEYS = [ - "assets", - "config", - "layout", - "customers", - "locales", - "sections", - "blocks", - "snippets", - "templates", - "metaobject" -]; -var PATH_KEYS = [ - ...PATH_THEME_KEYS, - ...PATH_PLUS_KEYS -]; -var THEME_KEYS = [ - "assets", - "config", - "layout", - "customers", - "locales", - "sections", - "blocks", - "snippets", - "templates", - "metaobject" -]; -var BUILD_GROUPS = [ - "styles", - "scripts", - "svgs", - "sections", - "layouts", - "blocks", - "metaobject", - "templates", - "snippets", - "locales", - "configs", - "schema", - "pages", - "metafields", - "assets" -]; -var THEME_DIRS = [ - "templates", - "templates/customers", - "templates/metaobject", - "assets", - "blocks", - "config", - "layout", - "locales", - "sections", - "snippets" -]; -var CONFIG_FILE_EXT = [ - "js", - "cjs", - "mjs", - "ts" -]; -var UNITS = [ - "b", - "kb", - "mb", - "gb", - "tb" -]; -var STRAP_THEMES = [ - ["dusk", " Stripped down skeleton theme structure"], - ["dawn", " The official Shopify slop using Syncify"], - ["silk", " Advanced Hybrid with SPX and mithril.js", true], - ["hexx", " Intermediate starting point with basics", true] -]; -var STRAP_EXAMPLES = [ - ["using-paths", " Strap with paths usage"], - ["using-rename", " Strap with rename usage"], - ["using-sass", " Strap with sass transform"], - ["using-schema", " Strap using Shared Schema"], - ["using-tailwind", " Strap using Tailwind transform"], - ["using-typescript", " Strap using TypeScript transform"] -]; -var REGEX_HOT_SNIPPET = /{%-?\s*render\s*['"]hot\.js['"]\s*-?%}/; - -// syncify/model/defaults.ts -var defaults = () => ({ - input: "source", - output: "theme", - config: ".", - editor: null, - paths: { - assets: "assets/*", - config: "config/*.json", - layout: "layout/*.liquid", - locales: "locales/*.json", - templates: "templates/*", - customers: "templates/customers/*", - metaobject: "templates/metaobject/*", - snippets: "snippets/**/*.liquid", - sections: "sections/**/*.{liquid,json}", - blocks: "blocks/*.liquid", - files: "+/files/*", - metafields: "+/metafields/**/*.json", - blogs: "+/blogs/*.{html,md}", - navigation: "+/navigation/*.json", - policies: "+/policies/*.{html,md}", - schema: "+schema/*.{schema,json}", - pages: "+pages/*.{html,json}" - }, - transform: { - svg: null, - style: null, - script: null, - json: { - crlf: false, - indent: 2, - useTab: false, - stripComments: false, - sortArrays: false, - sortObjects: false, - noSortList: [], - terse: false - }, - liquid: { - terse: false - } - }, - hot: { - server: 41001, - socket: 51001, - method: "hot", - client: "inject", - label: true, - eject: true, - layouts: [ - "theme.liquid" - ], - flags: [ - "--no-preview-bar" - ] - }, - log: { - clear: true, - silent: false, - stats: true, - warnings: true - } -}); - -// syncify/model/extends.ts -var Stores = class _Stores extends Array { - static map = o(); - /** - * Returns the first store entry - */ - get default() { - return this[0]; - } - /** - * Extended implementation of `[].push()` which will allow store name querying. - */ - push(store) { - const index = super.push(store); - _Stores.map[store.name] = index - 1; - return index; - } - /** - * Update a store record by name - * - * @example - * // Assume a the following: - * [ - * { name: 'foo', domain: 'foo.myshopfy.com' }, - * { name: 'bar', domain: 'foo.myshopfy.com' } - * ] - * - * // We can query using name - * // - * $.stores.set('bar', { token: 'abcdefg' }) - */ - set(name, store) { - const index = _Stores.map[name]; - return index !== void 0 ? assign(this[index], store) : void 0; - } - /** - * Get store by name, e.g: - * - * @example - * // Assume a the following: - * [ - * { name: 'foo', domain: 'foo.myshopfy.com' }, - * { name: 'bar', domain: 'foo.myshopfy.com' } - * ] - * - * // We can query using name - * // - * $.stores.get('bar') // equivalent of $.stores[1] - */ - get(name) { - const index = _Stores.map[name]; - return index !== void 0 ? this[index] : void 0; - } - /** - * Does store exist by name - * - * @example - * // Assume a the following: - * [ - * { name: 'foo', domain: 'foo.myshopfy.com' }, - * { name: 'bar', domain: 'foo.myshopfy.com' } - * ] - * - * // We can query using name - * // - * $.stores.has('bar') // equivalent of $.stores[1] - */ - has(name) { - const index = _Stores.map[name]; - return index !== void 0 && this[index] !== void 0; - } -}; -var Targets = class _Targets extends Array { - static raw = o(); - static map = o(); - get raw() { - return _Targets.raw; - } - set raw(raw) { - _Targets.raw = raw; - } - /** - * Returns the first entry in the stack - */ - get default() { - return this[0]; - } - /** - * Generate a uid MurMur hash, can be used in isolation - */ - uid(storeName, themeId) { - return murmur(storeName, themeId); - } - /** - * Extends push and assigns the `Targets.map` name query helper. - */ - push(theme2) { - const index = super.push(theme2); - _Targets.map[theme2.uid] = index - 1; - return index; - } - /** - * Updates a theme target in the stack based - */ - set(uid, theme2) { - const index = _Targets.map[uid]; - return index !== void 0 ? assign(this[index], theme2) : void 0; - } - /** - * Get a theme target in the stack - */ - get(uid) { - const index = _Targets.map[uid]; - return index !== void 0 ? this[index] : void 0; - } - /** - * Whether or not theme exists in the stack - */ - has(uid) { - const index = _Targets.map[uid]; - return index !== void 0 && this[index] !== void 0; - } -}; - -// syncify/model/plugins.ts -var plugins = () => ({ - onDefine: [], - onBuild: [], - onChange: [], - onReload: [], - onTransform: [], - onWatch: [] -}); - -// syncify/model/processor.ts -var processor = () => ({ - tailwind: { - installed: false, - loaded: false, - file: false, - map: null, - config: null - }, - sass: { - installed: false, - loaded: false, - file: false, - config: { - warnings: true, - style: "compressed", - sourcemap: true, - quietDeps: false, - include: ["node_modules"] - } - }, - esbuild: { - tsconfig: void 0, - bundle: true, - format: "esm", - globalName: void 0, - target: "es2016", - metafile: true, - external: [], - platform: "browser", - splitting: false, - sourcemap: "linked", - write: false, - logLevel: "silent", - plugins: [] - }, - postcss: { - file: false, - config: [] - }, - svgo: { - multipass: true, - js2svg: { - indent: 2, - pretty: true - }, - plugins: [ - { - name: "preset-default", - params: { - overrides: { - removeViewBox: false - } - } - } - ] - } -}); - -// syncify/options/utils.ts -var import_anymatch = __toESM(require_anymatch()); - -// syncify/process/cache.ts -var import_write_file_atomic = __toESM(require_lib()); -var gunzipAsync = node_util.promisify(zlib__default.default.gunzip); -var gzipAsync = node_util.promisify(zlib__default.default.gzip); -async function decode(uri) { - const content = await fsExtra.readFile(uri); - const gunzip = await gunzipAsync(content); - return cbor__default.default.decode(gunzip); -} -function save(uri, data) { - return async () => { - if ($.file.project === null) { - throwError([ - "Project cache has not been created" - ]); - return; - } - if (!/[/]/.test(uri)) { - uri = $.cache.uri[uri]; - if (!data) data = $.cache[uri]; - } - const encoded = await cbor__default.default.encodeAsync(data, { omitUndefinedProperties: true, canonical: true }); - const gzip = await gzipAsync(encoded); - gzip[9] = 3; - await (0, import_write_file_atomic.default)(uri, gzip); - }; -} -function clearCache(id = null) { - if (id === null) { - for (const key of CACHE_FILES) { - if (!isEmpty($.cache[key])) { - $.cache[key] = {}; - q.cache.add(save($.cache.uri[key], $.cache[key])); - } - } - return q.cache.onIdle(); - } - $.cache[id] = {}; - return q.cache.add(save($.cache.uri[id], $.cache[id])); -} -function runChecksum(input, value) { - const hash = checksum(value); - if (has(input, $.cache.checksum) && $.cache.checksum[input] === hash) return true; - $.cache.checksum[input] = hash; - q.cache.add(save($.cache.uri.checksum, $.cache.checksum)); - return false; -} -function saveCache(id = null) { - if (id === null) { - for (const key of CACHE_FILES) { - if (!isEmpty($.cache[key])) { - q.cache.add(save($.cache.uri[key], $.cache[key])); - } - } - return q.cache.onIdle(); - } else { - return q.cache.add(save($.cache.uri[id], $.cache[id])); - } -} -function getPageCache(domain, pageId = NaN) { - const store = domain.endsWith(".myshopify.com") ? domain.slice(0, domain.indexOf(".myshopify.com")).toLowerCase() : domain.toLowerCase(); - if (isNaN(pageId) === false) { - if (hasPath(`${store}.${pageId}`, $.cache.pages)) { - return $.cache.pages[store][pageId]; - } - if (!has(store, $.cache.pages)) { - $.cache.pages[store] = { [pageId]: {} }; - } else { - $.cache.pages[store][pageId] = {}; - } - q.cache.add(save($.cache.uri.pages, $.cache.pages)); - return $.cache.pages[store][pageId]; - } else { - if (!has(store, $.cache.pages)) { - $.cache.pages[store] = {}; - q.cache.add(save($.cache.uri.pages, $.cache.pages)); - } - } - return $.cache.pages[store]; -} -function setPageCache(domain, data) { - const store = domain.endsWith(".myshopify.com") ? domain.slice(0, domain.indexOf(".myshopify.com")).toLowerCase() : domain.toLowerCase(); - if (!has(store, $.cache.pages)) { - $.cache.pages[store] = { [data.id]: data }; - } else { - $.cache.pages[store][data.id] = data; - } - q.cache.add(save($.cache.uri.pages, $.cache.pages)); - return $.cache.pages[store][data.id]; -} -function setTemplateCache(domain, themeId, path5, data) { - const store = domain.endsWith(".myshopify.com") ? domain.slice(0, domain.indexOf(".myshopify.com")).toLowerCase() : domain.toLowerCase(); - if (!has(store, $.cache.templates)) { - $.cache.templates[store] = { [themeId]: { [path5]: data } }; - } else if (!has(`${themeId}`, $.cache.templates[store])) { - $.cache.templates[store][themeId] = { [path5]: data }; - } else { - $.cache.templates[store][themeId][path5] = data; - } - q.cache.add(save($.cache.uri.templates, $.cache.templates)); - return $.cache.templates[store][themeId][path5]; -} -function setPathCache(input, output) { - let update = null; - if (!has("paths", $.cache)) { - $.cache.paths = {}; - } - if (!has(input, $.cache.paths)) { - update = $.cache.paths[input] = output; - } - if ($.cache.paths[input] !== output) { - update = $.cache.paths[input] = output; - } - if (!has(output, $.cache.paths)) { - update = $.cache.paths[output] = input; - } - if ($.cache.paths[output] !== input) { - update = $.cache.paths[output] = input; - } - if (update) { - q.cache.add(save($.cache.uri.paths, $.cache.paths)); - } -} -var File = class { - constructor(uri) { - assign(this, path2.parse(uri)); - } - /** - * Configuration reference. This will hold a reference to additional data. - * Typically, this is used for transforms, wherein it holds the indexed config. - * - * @default undefined // getter when required - */ - data = void 0; - /** - * File value is set in the final process cycle and will hold the file - * content after transforms conclude. - * - * @default '' - */ - value = ""; - /** - * Hash reference of the file contents, used for diffing comparison, couples with - * the caching datasets. - * - * @example - * - * 'aa11bb22cc33dd44ee55ff66gg77' - */ - hash; - /** - * A unique UUID reference for this file - This option can change - * where required and when dealing with multiple stores at the request level. - * - * @example - * - * 'ABD41WX' - */ - uuid; - /** - * The file type that was intercepted. This is an enum number value. - * The number value will infer on how the file should be handled and uses - * the `FileType` enum for checks. - * - * @example - * - * file.type === FileType.Template - * - */ - type; - /** - * The resource API endpoint to which the file will be synced. - * This will be passed to the request client. - * - * @example - * - * 'assets' - * 'redirects' - */ - resource; - /** - * The root of the file path - * - * > Value is obtained via the native `path.parse()` method - * - * @example - * - * '/' OR 'c:\' - */ - root; - /** - * The full directory path such. - * - * > Value is obtained via the native `path.parse()` method - * - * @example - * - * '/home/user/dir' OR 'c:\path\dir' - */ - dir; - /** - * The file name without extension (if any). - * - * > Value is obtained via the native `path.parse()` method - * - * @example - * - * 'filename' // filename.ext - */ - name; - /** - * The filename extension including the dot, eg: `.liquid` - * - * > Value is obtained via the native `path.parse()` method - * - * @example - * - * '.ext' - */ - ext; - /** - * The input base filename including file extension. - * - * > Value is obtained via the native `path.parse()` method - * - * @example - * - * 'filename.ext' - */ - base; - /** - * The input relative path location from current _root_ working directory - * - * @example - * - * 'source/views/sections/dir/file.liquid' - */ - relative; - /** - * The `key` value will be passed into the sync request. This - * will contain the namespace and base name and is used for - * uploading to Shopify stores. - * - * @example - * - * 'sections/file.liquid' - * 'snippets/file.liquid' - * 'templates/index.liquid' - */ - key; - /** - * The `namespace` value will typically refelect the output - * parent directory name reference, but sometimes this might - * be a unique value depending on the file type we are handling. - * - * @example - * - * 'snippets' - * 'sections' - * 'templates' - */ - namespace; - /** - * The file kind grouping. This is used internally and describes - * the type of file we are working with. - * - * @example - * - * 'json' - * 'liquid' - * 'sass' - * 'css' - * - * // etc etc - */ - kind; - /** - * The absolute passed path - this is full URI file path. - * - * @example - * - * 'User/name/project/source/dir/file.liquid' - */ - input; - /** - * The output path location which files will be written. Only theme specific files - * have an output path location, when a file writes from its source (like a metafield) or - * if the file is handled in an asset pipeline transform then this will have a `null` value. - * - * @example - * - * // When file is theme specific - * 'User/name/project/theme/dir/filename.liquid' - * - * // When file is not theme specific - * null - */ - output; - /** - * The file size in bytes before any augmentation is applied. This - * value will be assigned post-context, typically in a transform. - * - * @example - * - * 1024 // => 1.24kb - */ - size; -}; -var import_timer2 = __toESM(require_dist()); -var import_timer = __toESM(require_dist()); -function bulk() { - if ($.bulk.id === null) { - $.bulk.id = uuid(); - import_timer.timer.start($.bulk.id); - } - if ($.bulk.synced.size > 0) { - $.bulk.synced.clear(); - $.errors.clear(); - $.warnings.clear(); - } - if (bulk.tui === null) { - bulk.tui = Create().Template({ prefix: true, id: "changes", color: neonCyan }).Template({ prefix: true, id: "errors", color: gray2 }).Template({ prefix: true, id: "warnings", color: gray2 }).Template({ prefix: true, id: $.bulk.type, color: whiteBright2 }); - } - if (bulk.progress === null) { - bulk.progress = progress($.bulk.files, { - barSize: 30, - prepend: null, - barColor: $.bulk.type === "uploaded" ? "neonGreen" : "blueBright" - }); - } else { - bulk.progress.reset($.bulk.files); - } - bulk.tui.Update("changes", `${bold2($.bulk.files)} Files`).Update("errors", `${bold2($.errors.size)} Errors`).Update("warnings", `${bold2($.warnings.size)} Warnings`).Update($.bulk.type, bulk.progress.render()).toUpdate(); -} -bulk.notifier = (type2) => { - notifier2__default.default.notify({ - warnings: { - contentImage: $.file.notifier, - title: `Bulk ${plur("Warning", $.warnings.size)}`, - message: `${$.warnings.size} ${plur("warning", $.warnings.size)} encountered` - }, - errors: { - contentImage: $.file.notifier, - title: `Bulk ${plur("Error", $.errors.size)}`, - message: `${$.errors.size} ${plur("Error", $.errors.size)} encountered` - } - }[type2]); -}; -bulk.complete = () => { - if (!$.mode.bulk) return; - const color = $.bulk.type === "deleted" ? blueBright2 : neonGreen; - bulk.tui.Update($.bulk.type, `${bold2($.bulk.synced.size)} Files ${Append(import_timer.timer.stop($.bulk.id))}`, color).Newline(); - if ($.bulk.synced.size > 0) { - bulk.tui.Line(`Type ${bold2("i")} and press ${bold2("enter")} to view ${$.bulk.type}`, gray2); - } - if ($.warnings.size > 0) { - bulk.tui.Line(`Type ${bold2("w")} and press ${bold2("enter")} to view warnings`, gray2); - bulk.notifier("warnings"); - } - if ($.errors.size > 0) { - bulk.tui.Line(`Type ${bold2("e")} and press ${bold2("enter")} to view errors`, gray2); - bulk.notifier("errors"); - } - bulk.tui.toUpdate({ clear: true, trim: true }).done(); - bulk.tui = null; - bulk.progress = null; - $.mode.bulk = false; - $.bulk.files = 0; - $.bulk.id = null; -}; -bulk.synced = (filename, target, store) => { - const message = $.bulk.type === "uploaded" ? neonGreen(Prefix("uploaded", filename, bold2(target), store, import_timer.timer.stop())) : blueBright2(Prefix("deleted", filename, bold2(target), store)); - $.bulk.synced.add(Line(message)); -}; -bulk.progress = null; -bulk.tui = null; -var event = new class Event extends EventEmitter__default.default { - id; - /** - * Whether or not an event is listening with the provided name - */ - has(name) { - return this.listenerCount(name) > 0; - } - /** - * Changes the current event listening mode. Used for specific run-modes - * such a bulk operations or stdin debugs. - */ - mode(name) { - this.id = name; - return this; - } - /** - * Each Event - * - * Iterates over an array of arguments and emits to the provided event name. - */ - each(args) { - for (const arg of args) { - this.emit(this.id, arg); - } - } -}(); - -// syncify/cli/stdin.ts -var setStdin = stdin; -function stdin() { - stdin.errors = StdinError(); - if ($.mode.watch) { - stdin.watch = StdinWatch(); - stdin.warnings = StdinWarning(); - } -} -stdin.errors = void 0; -stdin.watch = void 0; -stdin.warnings = void 0; -stdin.ansi = { - footer: `USE ${Encase("SB", gray2("\u25C4"))} AND ${Encase("SB", gray2("\u25BA"))} ARROW KEYS TO NAVIGATE`, - legend: { - /** `[q] exit debug mode` */ - q: Encase("SB", gray2.bold("q")) + " exit debug mode", - /** `[s] skip error */ - s: Encase("SB", gray2.bold("s")) + " skip error", - /** `[w] view warnings */ - w: Encase("SB", gray2.bold("w")) + " view warnings", - /** `[e] view errors */ - e: Encase("SB", gray2.bold("e")) + " view errors", - /** `[p] print all errors and exit' */ - p: Encase("SB", gray2.bold("p")) + " print all" - } -}; -function StdinError() { - const state = { - index: 0, - isAttached: false, - write: [], - keypress: null, - skipped: null, - errors: null, - warnings: null, - get shown() { - return this.write[this.index]; - } - }; - function listen(write2) { - if (state.isAttached) return update(write2); - state.index = 0; - state.write = write2; - state.isAttached = true; - state.keypress = (_data, key) => { - if (key.name === "left") return prev(); - if (key.name === "right") return next(); - if (key.name === "q") return quit(); - if (key.name === "p") return print(); - if (key.name === "s") return event.emit("stdin:skip"); - if (key.name === "w") return event.emit("stdin:warn"); - if (key.name === "e") return event.emit("stdin:errors"); - }; - prexit.listener(state.keypress); - log.update(state.shown.toString({ clear: false })); - event.on("stdin:dispose", () => { - log.update.done(); - dispose(); - }); - } - function quit() { - } - function update(messages2) { - state.index = 0; - state.write = messages2; - log.update.clear(); - log.update(state.shown.toString({ clear: false })); - } - function dispose() { - if (!state.keypress) return; - state.shown.Remove("debug", Infinity); - log.update(state.shown.toString({ clear: false })); - log.update.done(); - process.stdin.removeListener("keypress", state.keypress); - state.keypress = void 0; - state.isAttached = false; - state.write = []; - state.index = 0; - if (state.skipped) event.off("stdin:skip", state.skipped); - if (state.warnings) event.off("stdin:warn", state.warnings); - if (state.errors) event.off("stdin:errors", state.errors); - event.off("stdin:dispose", dispose); - } - function skip(callback) { - if (!state.skipped) { - state.skipped = () => callback(state.index); - event.on("stdin:skip", state.skipped); - } - } - function errors(callback) { - if (!state.errors) { - state.errors = () => callback(state.index); - event.on("stdin:error", state.errors); - } - } - function warn2(callback) { - if (!state.warnings) { - state.warnings = () => callback(state.index); - event.on("stdin:warn", state.warnings); - } - } - function print() { - log.update.clear(); - log.update.done(); - log.nl(); - event.emit("stdin:view", state.index); - state.write.forEach((write2, index) => { - write2.Remove("legend", "debug").True(index !== state.write.length - 1, (tui) => tui.Pop()).True(index !== state.write.length - 1, (tui) => tui.Ruler()).toLog({ clear: true }); - }); - dispose(); - kill.exit(0); - } - function next() { - if (state.index < state.write.length - 1) { - state.index++; - log.update(state.shown.toString({ clear: false })); - } - } - function prev() { - if (state.index > 0) { - state.index--; - log.update(state.shown.toString({ clear: false })); - } - } - return { - get isAttached() { - return state.isAttached; - }, - listen, - dispose, - update, - skip, - warn: warn2, - errors - }; -} -function StdinWatch() { - const preview = $.target.map(({ preview: preview2 }) => preview2); - const editors = $.target.map(({ editor }) => editor); - const write2 = Create().Newline().Template(preview, { id: "p", hidden: true, color: gray2.underline }).Template(editors, { id: "a", hidden: true, color: gray2.underline }); - let keypress; - function listen() { - keypress = (_data, key) => { - if (key.name === "p") return write2.Update("p").toLog({ clear: "p", trim: false }); - if (key.name === "a") return write2.Update("c").toLog({ clear: "a", trim: false }); - }; - prexit.listener(keypress); - stdin.warnings.listen(); - } - function dispose() { - if (keypress) { - process.stdin.removeListener("keypress", keypress); - keypress = void 0; - } - } - return { listen, dispose }; -} -function StdinWarning() { - const state = { - index: 0, - isAttached: false, - write: [], - keypress: null, - get shown() { - return this.write[this.index]; - } - }; - function reset3() { - log.update.clear(); - state.write = []; - state.index = 0; - } - function listen() { - if (state.isAttached) return; - state.isAttached = true; - state.keypress = (_data, key) => { - if (key.name === "left") return prev(); - if (key.name === "right") return next(); - if (key.name === "v") return view(); - }; - prexit.listener(state.keypress); - event.on("warn:dispose", () => { - log.update.done(); - dispose(); - }); - } - function dispose() { - if (!state.keypress) return; - process.stdin.removeListener("keypress", state.keypress); - state.keypress = void 0; - state.isAttached = false; - state.write = []; - state.index = 0; - event.off("stdin:dispose", dispose); - } - function view() { - if (!$.warnings.has($.log.uri)) return; - state.write = []; - state.index = 0; - let count = 0; - $.warnings.get($.log.uri).values().forEach((stack) => count += stack.size); - for (const stack of $.warnings.get($.log.uri).values()) { - stack.forEach((value) => { - const tui = Create({ type: "warning " }); - if (count > 1) { - tui.Newline("line").Append(`WARNING ${state.write.length + 1} of ${count}`, bold2.yellowBright).Insert(value).Newline("line").End(stdin.ansi.footer); - } else { - tui.Insert(value); - } - state.write.push(tui); - }); - } - log.update(state.shown.toString({ clear: false })); - } - function next() { - if (state.write.length > 1 && state.index < state.write.length - 1) { - state.index++; - log.update(state.shown.toString({ clear: false })); - } - } - function prev() { - if (state.write.length > 1 && state.index > 0) { - state.index--; - log.update(state.shown.toString({ clear: false })); - } - } - return { - get isAttached() { - return state.isAttached; - }, - listen, - dispose, - view, - reset: reset3 - }; -} - -// syncify/model/console.ts -var console2 = new Log(); -var { stdout: stdout2, stderr: stderr2 } = Log; - -// syncify/cli/log.ts -function log(...message) { - forEach((line) => console2.write(line), message); - return log; -} -log.runtime = TUI("runtime"); -log.progress = progress; -log.update = log_update_default; -log.spinner = Spinner(); -log.line = console2.info; -log.header = console2.header; -log.bulk = bulk; -log.wrap = console2.wrap; -log.hline = (options = {}) => { - const { wrap } = $.terminal; - if (isEmpty(options)) { - options.width = wrap; - options.newlines = false; - } else { - const has2 = hasProp(options); - if (!has2("width")) options.width = wrap; - if (!has2("newlines")) options.newlines = false; - } - log( - Ruler( - options.width, - options.newlines - ) - ); -}; -log.nl = function(entry) { - entry === "" ? console2.break() : console2.tree(entry); - return this; -}; -log.clear = (clear2 = true) => clear2 ? log(clear) : log; -log.group = function(name) { - if ($.config.log.silent || $.env.tree === false) return; - if ($.mode.bulk) { - name = g("Bulk", CHV, toUpcase(name)); - if ($.log.group === name) return this; - $.log.group = name; - } - log.ender($.log.group); - if ($.config.log.clear && name !== false) log.clear(); - if (isString(name)) { - $.log.group = name; - log.begin($.log.group); - } - return this; -}; -log.task = (name, timestamp = true) => { - if ($.config.log.silent || $.env.tree === false) return; - if (isString(name)) { - console2.dash( - g.ws(gray2(name), timestamp ? Append(getTime2()) : "") - ); - } else { - log.clear()( - Tree.trim, - Dash(g.ws(gray2($.log.group), Append(getTime2()))) - ); - } -}; -log.process = (label, ...message) => { - if ($.mode.pack || $.mode.build || $.config.log.silent) return; - console2.info( - Prefix( - "process", - message.length === 2 ? g.ws(bold2(label), CHV, message[0], Append(message[1])) : g.ws(bold2(label), Append(message[0])) - ) - ); -}; -log.upsert = (upsert) => { - const { target, store } = upsert.target; - if ($.mode.bulk) { - forEach(({ filename }) => { - bulk.synced(filename, target, store.name); - bulk.progress.increment(); - bulk.tui.Update($.bulk.type, bulk.progress.render()).toUpdate(); - }, upsert.synced); - if (upsert.errors.length > 0) { - error.upsert(upsert.errors); - bulk.progress.increment(upsert.errors.length); - bulk.tui.Update($.bulk.type, bulk.progress.render()).Update("errors", `${bold2($.errors.size)} ${plur("Error", $.errors.size)}`, redBright2).toUpdate(); - } - } else { - forEach(({ filename }) => { - console2.info( - Prefix("uploaded", bold2(target), store.name, filename, import_timer2.timer.stop()), - neonGreen - ); - }, upsert.synced); - upsert.errors.length > 0 && error.upsert(upsert.errors); - } -}; -log.changed = (file) => { - if ($.errors.size > 0) $.errors.clear(); - if ($.warnings.size > 0) { - $.warnings.clear(); - stdin.warnings.reset(); - } - if ($.config.log.silent === true || $.mode.watch === false) return; - import_timer2.timer.start(); - const name = `${file.kind} ${CHV} ${toUpcase(file.namespace)}`; - const change = $.log.changes.has(file.relative) ? $.log.changes.get(file.relative) + 1 : 1; - $.log.changes.set(file.relative, change); - if ($.log.group !== name) { - log.group(name); - if ($.log.title !== file.namespace) $.log.title = file.namespace; - } else { - log.group(name); - } - if ($.log.uri !== file.input) $.log.uri = file.input; - console2.info( - Prefix("changed", `${file.relative} ${Append(`${change} ${plur("change", change)}`)}`), - neonCyan - ); -}; -log.syncing = (path5, { hot = false } = {}) => { - if ($.mode.pack || $.mode.bulk || $.mode.build || $.mode.debug || $.config.log.silent) return; - if ($.warnings.has(path5)) { - const { size } = $.warnings.get(path5); - log.warn(`${bold2(size)} ${plur("warning", size)}`, Suffix.warning); - } - console2.info( - magentaBright2( - Prefix( - "syncing", - path5.replace(/^(\d+)/, bold2("$1")) - ) - ) - ); - if (q.http.pending > (hot ? 0 : 2)) { - console2.info( - orange( - Prefix( - "queued", - g.ws( - path5, - TLD, - bold2(addSuffix(q.http.pending)), - "in queue" - ) - ) - ) - ); - } -}; -log.resource = (type2, store) => { - if ($.mode.watch) { - $.log.queue.add( - [ - type2, - store.domain, - import_timer2.timer.stop() - ] - ); - if ($.log.idle) return; - else $.log.idle = true; - q.http.onIdle().then(() => { - for (const [type3, store2, ctime] of $.log.queue) { - console2.info( - Line( - neonGreen( - Prefix( - "uploaded", - g.ws( - bold2(type3), - ARR, - store2, - Append(ctime) - ) - ) - ) - ) - ); - } - $.log.queue.clear(); - $.log.idle = false; - }); - } else { - console2.info( - Line( - neonGreen( - Prefix( - "uploaded", - g.ws( - bold2(type2), - ARR, - store.domain, - Append(import_timer2.timer.stop()) - ) - ) - ) - ) - ); - } -}; -log.invalid = (path5, message) => { - console2.error(Prefix("invalid", path5)); - notifier2__default.default.notify( - { - title: "Syncify Error", - sound: "Pop", - open: path5, - subtitle: path5, - message: "Invalid error" - } - ).notify(); - if (message) { - console2.error(Wrap(...message, { line: "red", color: redBright2 })); - } -}; -log.error = (input, { suffix = null, notify = null } = {}) => { - if ($.mode.bulk) return; - const message = capture.numbers(input, bold2); - console2.error(Prefix("failed", suffix ? `${message} ${Append(suffix)}` : message)); - if (notify !== null) { - notify.contentImage = $.file.notifier; - notifier2__default.default.notify(notify).notify(); - } -}; -log.transform = (label, ...suffix) => $.mode.build || $.mode.bulk || $.mode.debug || console2.info( - Prefix("transform", bold2(label), ...suffix), - whiteBright2 -); -log.minified = (...p) => $.mode.pack || $.mode.bulk || $.mode.build || console2.info( - Prefix("minified", bold2(p.shift()), ...p.slice(0, -1), `saved ${p.pop()}`), - whiteBright2 -); -log.begin = (message, { timestamp = true, clear: clear2 = true, group = false } = {}) => log.clear(clear2)( - NWL2, - Top(group ? $.log.group = message : message, timestamp), - Tree.next + NWL2 -); -log.ender = (message, { timestamp = true, clear: clear2 = true } = {}) => log.clear(clear2)( - Tree.trim + "\n", - End(message || $.log.group, timestamp), - NLR2 -); -log.skipped = (file, reason) => $.mode.pack || $.mode.build || $.mode.bulk || console2.info( - Prefix("skipped", `${isString(file) ? file : file.key} ${Append(reason)}`), - gray2 -); -log.deleted = (file, theme2) => console2.info( - Prefix("deleted", file, ...[$.mode.bulk ? (theme2.target, theme2.store.domain) : void 0]), - blueBright2 -); -log.zipped = (size, path5) => console2.info( - Prefix("zipped", `${bold2("ZIP")} ${size} ${Append(path5)}`), - whiteBright2 -); -log.ignored = (path5) => console2.info( - Prefix("ignored", path5), - yellowBright2 -); -log.rename = (from, to) => $.running === false || $.mode.watch || console2.info( - Prefix("renamed", bold2(from), bold2(to)), - whiteBright2 -); -log.warn = (message, suffix) => console2.info( - Prefix("warnings", suffix ? `${message} ${Append(suffix)}` : `${message}`), - yellowBright2 -); -log.hot = (id) => console2.info( - Prefix("reloaded", bold2("HOT RELOAD"), import_timer2.timer.now(id)), - neonRouge -); -log.exported = (from, to) => console2.info( - Prefix("exported", bold2(from), bold2(to)), - teal -); -log.retrying = (file, theme2) => console2.info( - Prefix("retrying", file, theme2.target, theme2.store.domain), - orange -); -log.reloaded = (path5, time) => console2.info( - Prefix("reloaded", path5, time), - whiteBright2 -); -log.version = (version, action) => console2.info( - Prefix("version", bold2(version.number), bold2(version.update.number), action), - whiteBright2 -); -function globPath(path5) { - return isArray(path5) ? path5.filter((uri) => /\*/.test(uri)) : /\*/.test(path5) ? path5 : null; -} -function lastPath(path5) { - if (isArray(path5)) return path5.map(lastPath); - if (path5.indexOf("/") === -1) return path5; - const dir = path5.endsWith("/") ? path2.dirname(path5.slice(0, -1)) : path2.dirname(path5); - const ender = dir.lastIndexOf("/") + 1; - return dir.slice(ender); -} -function parentPath(path5) { - if (isArray(path5)) return path5.map(parentPath); - const last = path5.lastIndexOf("/"); - if (last === -1) return path5; - const glob9 = path5.indexOf("*"); - return glob9 === -1 ? path5.slice(0, last) : path5.slice(0, glob9); -} -function normalPath(input, cwd2 = null) { - const regex2 = new RegExp(`^\\.?\\/?${input}\\/`); - const source = new RegExp(`^\\.?\\/?${path2.basename(input)}\\/`); - return function prepend(path5) { - if (isArray(path5)) return path5.map(prepend); - const ignore = path5.charCodeAt(0) === 33; - if (ignore) path5 = path5.slice(1); - if (regex2.test(path5)) return ignore ? "!" + path5 : path5; - if (path5.charCodeAt(0) === 46 && path5.charCodeAt(1) === 46 && path5.charCodeAt(2) === 47) { - throwError( - `Invalid path defined at: ${COL} ${yellowBright2(`"${path5}"`)}`, - ["Paths must be relative to the input directory"] - ); - } - if (cwd2 !== null) { - const exists2 = path2.join(cwd2, path5); - return (ignore ? "!" : "") + (exists2.startsWith(input) ? exists2 : path2.join(input, path5)); - } else { - return (ignore ? "!" : "") + path2.join(input, source.test(path5) ? path5.replace(source, "") : path5); - } - }; -} -var basePath = (cwd2) => (path5) => { - if (path5.indexOf("*") !== -1) { - throwError( - `Base directory path cannot contain glob${COL} ${yellowBright2(`"${path5}"`)}`, - ["Ensure that path you are resolving is correctly formed"] - ); - } - if (path5.charCodeAt(0) === 46) { - if (path5.length === 1) return cwd2 + "/"; - if (path5.charCodeAt(1) === 47) { - path5 = path5.slice(1); - } else { - throwError( - `Directory path is invalid at${COL} ${yellowBright2(`"${path5}"`)}`, - ["Ensure that the path you attempting to resolve is correctly formed"] - ); - } - } - if (path5.charCodeAt(0) === 47) { - if (path5.length === 1) { - return cwd2 + "/"; - } else { - path5 = path5.slice(1); - } - } - if (/^[a-zA-Z0-9_-]+/.test(path5)) { - path5 = path2.join(cwd2, path5); - return path5[path5.length - 1].charCodeAt(0) === 47 ? path5 : path5 + "/"; - } else { - throwError( - `Directory path is invalid at${COL} ${yellowBright2(`"${path5}"`)}`, - ["Ensure that the path you attempting to resolve is correctly formed"] - ); - } -}; - -// syncify/process/context.ts -function svg(file) { - const config = $.svg.filter((context) => { - if (context.input.has(file.input)) return true; - if (!context.match(file.input)) return false; - context.input.add(file.input); - return true; - }); - if (isUndefined(config)) return file; - defineProperty(file, "data", { - get() { - return config; - } - }); - return file; -} -function style(file) { - const config = $.style.find((x) => x.watch(file.input)); - if (isUndefined(config)) { - file.type = 16 /* Asset */; - return file; - } - defineProperty(file, "data", { - get() { - return config; - } - }); - if (config.snippet) { - file.namespace = "snippets" /* Snippets */; - file.key = path2.join("snippets", config.rename); - } else { - file.key = path2.join("assets", config.rename); - } - if (file.output) { - if (file.data.rename !== path2.basename(file.output)) { - if (config.snippet) { - file.output = path2.join($.dirs.output, file.key); - } else { - file.output = path2.join(parentPath(file.output), file.data.rename); - } - } - } else { - file.output = path2.join($.dirs.output, file.key); - } - return file; -} -function script(file) { - const config = $.script.filter((config2) => config2.watch.has(file.input)); - if (config.length === 0) return file; - defineProperty(file, "data", { get() { - return config; - } }); - return file; -} -function schema(parse10, file) { - defineProperty(file, "data", { get() { - return parse10; - } }); - return file; -} -function section(file) { - if ($.paths.sections.rename.length > 0) { - const path5 = file.input; - const find = $.paths.sections.rename.find(({ match }) => match(path5)); - if (isUndefined(find)) return file; - const oldName = file.base; - const rename = renameFileParse(file.input, find.pattern); - file.name = rename.name; - file.ext = rename.ext; - file.base = rename.base; - file.key = path2.join(file.namespace, rename.base); - file.output = path2.join(path2.dirname(file.output), rename.base); - if ($.mode.watch) log.rename(oldName, file.base); - } - return file; -} -function snippet(file) { - if ($.paths.snippets.rename.length > 0) { - const path5 = file.input; - const find = $.paths.snippets.rename.find(({ match }) => match(path5)); - if (isUndefined(find)) return file; - const oldName = file.base; - const rename = renameFileParse(file.input, find.pattern); - file.name = rename.name; - file.ext = rename.ext; - file.base = rename.base; - file.key = path2.join(file.namespace, rename.base); - file.output = path2.join(path2.dirname(file.output), rename.base); - if ($.mode.watch) log.rename(oldName, file.base); - } - return file; -} - -// syncify/process/files.ts -function renameFile({ name, dir, ext, namespace }, rename) { - let newName = rename; - if (/\[dir\]/.test(newName)) newName = newName.replace(/\[dir\]/g, dir); - if (/\[name\]/.test(newName)) newName = newName.replace(/\[name\]/g, name); - if (/\[file\]/.test(newName)) newName = newName.replace(/\[file\]/g, name); - if (/\[ext\]/.test(newName)) newName = newName.replace(/\[ext\]/g, ext); - if (namespace === "snippets" && rename.endsWith(".liquid") === false) return newName + ".liquid"; - if (!rename.endsWith(".[ext]") || !rename.endsWith(ext)) { - return /\.[a-z]+$/.test(rename) ? newName : newName + ext; - } - return newName; -} -function setFile(file, input, output) { - file.size = NaN; - return function(namespace, type2, kind) { - let key; - if (type2 === 17 /* Metafield */ || type2 === 18 /* Page */) { - key = path2.join(lastPath(file.dir), file.base); - output = null; - } else { - key = path2.join(namespace, file.base); - output = path2.join(output, key); - } - if (kind === -1) { - input = $.cache.paths[output]; - } else { - setPathCache(input, output); - } - file.uuid = uuid(); - file.type = type2; - file.key = key; - file.namespace = namespace; - file.kind = kind; - file.input = input; - file.output = output; - file.relative = input ? path2.relative($.cwd, input) : $.cwd; - return file; - }; -} -function parseProcessorConfigs(path5, namespace) { - const file = new File(path5); - file.namespace = namespace; - file.input = path5; - file.relative = path2.relative($.cwd, file.input); - switch (file.ext) { - case ".ts": - file.kind = "TypeScript" /* TypeScript */; - break; - case ".js": - case ".mjs": - case ".cjs": - file.kind = "JavaScript" /* JavaScript */; - break; - } - return file; -} -function parseSyncifyConfig(path5) { - const file = new File(path5); - file.namespace = "syncify" /* Syncify */; - file.input = path5; - file.type = 20 /* Syncify */; - file.relative = path2.relative($.cwd, file.input); - switch (file.ext) { - case ".ts": - file.kind = "TypeScript" /* TypeScript */; - break; - case ".js": - case ".mjs": - case ".cjs": - file.kind = "JavaScript" /* JavaScript */; - break; - } - return file; -} -function parse2(path5) { - const { paths } = $; - const file = new File(path5); - const define = setFile(file, path5, $.dirs.output); - if (file.ext === ".liquid") { - if (paths.sections.match(path5)) { - return section(define("sections" /* Sections */, 5 /* Section */, "Liquid" /* Liquid */)); - } else if (paths.snippets.match(path5)) { - return snippet(define("snippets" /* Snippets */, 4 /* Snippet */, "Liquid" /* Liquid */)); - } else if (paths.layout.match(path5)) { - return define("layout" /* Layout */, 2 /* Layout */, "Liquid" /* Liquid */); - } else if (paths.templates.match(path5)) { - return define("templates" /* Templates */, 1 /* Template */, "Liquid" /* Liquid */); - } else if (paths.customers.match(path5)) { - return define("templates/customers" /* Customers */, 1 /* Template */, "Liquid" /* Liquid */); - } else if (paths.metaobject.match(path5)) { - return define("templates/metaobject" /* Metaobject */, 1 /* Template */, "Liquid" /* Liquid */); - } - } else if (file.ext === ".schema" && paths.schema.match(path5)) { - return schema(parse2, define("schema" /* Schema */, 7 /* Schema */, "JSON" /* JSON */)); - } else if (file.ext === ".json") { - if (paths.metafields.match(path5)) { - return define("metafields" /* Metafields */, 17 /* Metafield */, "JSON" /* JSON */); - } else if (paths.sections.match(path5)) { - return define("sections" /* Sections */, 6 /* Group */, "JSON" /* JSON */); - } else if (paths.templates.match(path5)) { - return define("templates" /* Templates */, 1 /* Template */, "JSON" /* JSON */); - } else if (paths.config.match(path5)) { - return define("config" /* Config */, 9 /* Config */, "JSON" /* JSON */); - } else if (paths.locales.match(path5)) { - return define("locales" /* Locales */, 10 /* Locale */, "JSON" /* JSON */); - } else if (paths.customers.match(path5)) { - return define("templates/customers" /* Customers */, 1 /* Template */, "JSON" /* JSON */); - } else if (paths.metaobject.match(path5)) { - return define("templates/metaobject" /* Metaobject */, 8 /* Metaobject */, "JSON" /* JSON */); - } else if (paths.schema.match(path5)) { - return schema(parse2, define("schema" /* Schema */, 7 /* Schema */, "JSON" /* JSON */)); - } - } - if (paths.assets.match(path5)) { - switch (file.ext) { - case ".js": - case ".mjs": - return define("assets" /* Assets */, 16 /* Asset */, "JavaScript" /* JavaScript */); - case ".json": - return define("assets" /* Assets */, 16 /* Asset */, "JSON" /* JSON */); - case ".svg": - return define("assets" /* Assets */, 16 /* Asset */, "SVG" /* SVG */); - case ".css": - return define("assets" /* Assets */, 16 /* Asset */, "CSS" /* CSS */); - case ".ico": - case ".jpg": - case ".png": - case ".gif": - case ".webp": - case ".pjpg": - return define("assets" /* Assets */, 16 /* Asset */, "Image" /* Image */); - case ".mov": - case ".mp4": - case ".webm": - case ".ogg": - return define("assets" /* Assets */, 16 /* Asset */, "Video" /* Video */); - case ".pdf": - return define("assets" /* Assets */, 16 /* Asset */, "PDF" /* PDF */); - case ".eot": - case ".ttf": - case ".woff": - case ".woff2": - return define("assets" /* Assets */, 16 /* Asset */, "Font" /* Font */); - default: - return define("assets" /* Assets */, 16 /* Asset */, "Unknown" /* Unknown */); - } - } - switch (file.ext) { - case ".js": - case ".mjs": - return script(define("assets" /* Assets */, 12 /* Script */, "JavaScript" /* JavaScript */)); - case ".ts": - return script(define("assets" /* Assets */, 12 /* Script */, "TypeScript" /* TypeScript */)); - case ".tsx": - return script(define("assets" /* Assets */, 12 /* Script */, "TSX" /* TSX */)); - case ".jsx": - return script(define("assets" /* Assets */, 12 /* Script */, "JSX" /* JSX */)); - case ".svg": - return svg(define("assets" /* Assets */, 13 /* Svg */, "SVG" /* SVG */)); - case ".css": - return style(define("assets" /* Assets */, 11 /* Style */, "CSS" /* CSS */)); - case ".scss": - return style(define("assets" /* Assets */, 11 /* Style */, "SCSS" /* SCSS */)); - case ".sass": - return style(define("assets" /* Assets */, 11 /* Style */, "SASS" /* SASS */)); - case ".md": - return define("pages" /* Pages */, 18 /* Page */, "Markdown" /* Markdown */); - case ".html": - return define("pages" /* Pages */, 18 /* Page */, "HTML" /* HTML */); - } - return void 0; -} -var outputFile = (output) => (path5) => { - const file = new File(path5); - const define = setFile(file, path5, output); - switch (path2.basename(file.dir)) { - case "sections": - return define("sections" /* Sections */, 5 /* Section */, -1); - case "blocks": - return define("blocks" /* Blocks */, 3 /* Block */, -1); - case "snippets": - return define("snippets" /* Snippets */, 4 /* Snippet */, -1); - case "layout": - return define("layout" /* Layout */, 2 /* Layout */); - case "templates": - return define("templates" /* Templates */, 1 /* Template */, -1); - case "customers": - return define("templates/customers" /* Customers */, 1 /* Template */, -1); - case "metaobject": - return define("templates/metaobject" /* Metaobject */, 1 /* Template */, -1); - case "config": - return define("config" /* Config */, 9 /* Config */, -1); - case "locales": - return define("locales" /* Locales */, 10 /* Locale */, -1); - case "assets": - return define("assets" /* Assets */, 16 /* Asset */, -1); - } -}; - -// syncify/options/utils.ts -function createPathsState() { - const state = o(); - for (const path5 of PATH_KEYS) { - state[path5] = o({ - input: null, - match: null, - config: null, - stash: null, - rename: [] - }); - } - return state; -} -function getResolvedPaths(filePath, hook2) { - const match = isFunction(hook2) ? [] : false; - const warn2 = warnOption("Path Resolver"); - const getUri = normalPath($.dirs.input, $.cwd); - if (isArray(filePath)) { - const paths = []; - for (const item of filePath) { - const uri = getUri(item); - const resolved = glob__default.default.sync(uri, { - cwd: $.cwd, - absolute: true - }); - if (match !== false) { - const test = hook2(uri); - if (isString(test)) { - match.push(test); - } else if (isArray(test)) { - match.push(...test); - } - } - if (resolved.length === 0) { - warn2("No files can be resolved in", item); - } else { - paths.push(...resolved); - } - } - return match === false ? paths : { - paths, - match: (0, import_anymatch.default)(match) - }; - } - if (isString(filePath)) { - const uri = getUri(filePath); - const paths = glob__default.default.sync(uri, { cwd: $.cwd }); - if (paths.length === 0) { - warn2("No files can be resolved in", filePath); - } - if (match !== false) { - const test = hook2(uri); - if (isString(test)) { - match.push(test); - } else if (isArray(test)) { - match.push(...test); - } - } - return match === false ? paths : { - paths, - match: (0, import_anymatch.default)(match) - }; - } - typeError({ - option: "uri", - name: "uri/path", - provided: filePath, - expects: "string | string[]" - }); -} -function getTransform(transforms, opts) { - if (!has("assertSnippet", opts)) opts.snippet = true; - if (isString(transforms)) { - const { paths, match } = getResolvedPaths(transforms, (watch) => globPath(watch)); - return opts.flatten ? paths.map((input) => ({ input, rename: path2.basename(input), snippet: false })) : { input: paths, rename: "[name].[ext]", snippet: false, match }; - } else if (isArray(transforms)) { - if (transforms.every(isString)) { - const { paths, match } = getResolvedPaths(transforms, globPath); - opts.flatten ? paths.map((input) => ({ input, rename: path2.basename(input), snippet: false })) : { }; - } else if (transforms.every(isObject)) { - return transforms.map((option) => { - if (!has("input", option)) { - invalidError({ - option: "tranform", - name: "input", - value: option, - expects: "{ input: string | string[] }" - }); - } - const { paths, match } = getResolvedPaths(option.input, globPath); - option.match = match; - option.input = paths[0]; - option.snippet = has("snippet", option) ? option.snippet : false; - if (!has("rename", option)) { - option.rename = option.snippet ? "[name].liquid" : "[name].[ext]"; - } - return option; - }); - } - } else if (isObject(transforms)) { - const config = []; - if (has("input", transforms)) { - const record = merge(transforms); - const { paths, match } = getResolvedPaths(record.input, globPath); - if (!has("snippet", record)) { - record.snippet = false; - } - if (!has("rename", record)) { - record.rename = record.snippet ? "[name].liquid" : "[name].[ext]"; - } - if (opts.flatten) { - for (const input of paths) { - config.push({ ...record, input }); - } - } else { - record.input = paths; - record.match = match; - config.push(record); - } - } else { - for (const prop in transforms) { - const record = { snippet: prop.startsWith("snippets/") }; - const asset = prop.startsWith("assets/"); - const option = transforms[prop]; - const rename = asset || record.snippet; - if (isString(option)) { - if (rename) record.rename = asset ? prop.slice(7) : prop.slice(9); - const { paths, match } = getResolvedPaths(option, globPath); - if (opts.flatten) { - for (const input of paths) { - config.push({ ...record, input }); - } - } else { - config.push({ ...record, input: paths, match }); - } - } else if (isObject(option)) { - if (!has("input", option)) { - invalidError({ - option: "transform", - name: prop, - value: option, - expects: "{ input: string | string[] }" - }); - } - const { paths, match } = getResolvedPaths(option.input, globPath); - if (paths.length > 0) { - const merge2 = rename ? { ...option, ...record, rename: asset ? prop.slice(7) : prop.slice(9) } : { ...record, ...option }; - if (opts.flatten) { - for (const input of paths) { - config.push({ ...merge2, input }); - } - } else { - config.push({ ...merge2, input: paths, match }); - } - } - } else if (isArray(option)) { - if (option.every(isString)) { - const { paths, match } = getResolvedPaths(option, globPath); - if (hasRenameNamespace(prop)) record.rename = path2.basename(prop); - if (paths) { - if (opts.flatten) { - for (const input of paths) { - config.push({ ...record, input }); - } - } else { - config.push({ ...record, input: paths, match }); - } - } - } else { - typeError({ - option: "transform", - name: prop, - provided: option, - expects: "string[]" - }); - } - } - } - } - return config; - } -} -function getModules(pkg, name) { - if (has("devDependencies", pkg)) { - if (has(name, pkg.devDependencies)) return true; - } - if (has("dependencies", pkg)) { - if (has(name, pkg.dependencies)) return true; - } - if (has("peerDependencies", pkg)) { - if (has(name, pkg.peerDependencies)) return true; - } - if (has("optionalDependencies", pkg)) { - if (has(name, pkg.peerDependencies)) return true; - } - return false; -} -async function getConfigFilePath(filename) { - for (const ext of CONFIG_FILE_EXT) { - const filepath = `${filename}.${ext}`; - const fileExists = await fsExtra.pathExists(filepath); - if (fileExists) return filepath; - } - return null; -} -async function readConfigFile(path5, namespace, onRebuild) { - try { - const file = await getConfigFilePath(path5); - if (file !== null) { - const config = await acquire.acquire({ - file, - cwd: $.cwd, - tsconfig: false, - type: has("type", $.pkg) ? $.pkg.type : "commonjs", - onRebuild, - onError: (errors) => { - const p = parseProcessorConfigs(file, namespace); - Create({ type: "error" }).Append("BUILD ERROR", bold2).Wrap(`The ${yellowBright2(p.base)} file could not be processed.`).toLog({ clear: true }); - error.esbuild(p, errors); - } - }); - return { file, config }; - } - return null; - } catch (e) { - return null; - } -} -function hasRenameNamespace(rename) { - return /\[(?:file|name|dir|ext)\]/.test(rename); -} -function renameFileParse(src, pattern) { - let rename = pattern; - const dir = lastPath(src); - const ext = path2.extname(src); - const file = path2.basename(src, ext); - if (isUndefined(pattern)) return { dir, ext, file, name: file, base: file + ext }; - if (/(\[dir\])/.test(rename)) rename = rename.replace("[dir]", dir); - if (/(\[name\])/.test(rename)) rename = rename.replace("[name]", file); - if (/(\[file\])/.test(rename)) rename = rename.replace("[file]", file); - if (/(\.?\[ext\])/.test(rename)) rename = rename.replace(/\.?\[ext\]/, ext); - const name = pattern.replace(pattern, rename); - return { - ext, - file, - dir, - name, - base: name + ext - }; -} - -// node_modules/.pnpm/eventemitter3@5.0.1/node_modules/eventemitter3/index.mjs -var import_index2 = __toESM(require_eventemitter3(), 1); - -// node_modules/.pnpm/p-timeout@6.1.4/node_modules/p-timeout/index.js -var TimeoutError = class extends Error { - constructor(message) { - super(message); - this.name = "TimeoutError"; - } -}; -var AbortError = class extends Error { - constructor(message) { - super(); - this.name = "AbortError"; - this.message = message; - } -}; -var getDOMException = (errorMessage) => globalThis.DOMException === void 0 ? new AbortError(errorMessage) : new DOMException(errorMessage); -var getAbortedReason = (signal) => { - const reason = signal.reason === void 0 ? getDOMException("This operation was aborted.") : signal.reason; - return reason instanceof Error ? reason : getDOMException(reason); -}; -function pTimeout(promise, options) { - const { - milliseconds, - fallback, - message, - customTimers = { setTimeout, clearTimeout } - } = options; - let timer16; - let abortHandler; - const wrappedPromise = new Promise((resolve2, reject) => { - if (typeof milliseconds !== "number" || Math.sign(milliseconds) !== 1) { - throw new TypeError(`Expected \`milliseconds\` to be a positive number, got \`${milliseconds}\``); - } - if (options.signal) { - const { signal } = options; - if (signal.aborted) { - reject(getAbortedReason(signal)); - } - abortHandler = () => { - reject(getAbortedReason(signal)); - }; - signal.addEventListener("abort", abortHandler, { once: true }); - } - if (milliseconds === Number.POSITIVE_INFINITY) { - promise.then(resolve2, reject); - return; - } - const timeoutError = new TimeoutError(); - timer16 = customTimers.setTimeout.call(void 0, () => { - if (fallback) { - try { - resolve2(fallback()); - } catch (error2) { - reject(error2); - } - return; - } - if (typeof promise.cancel === "function") { - promise.cancel(); - } - if (message === false) { - resolve2(); - } else if (message instanceof Error) { - reject(message); - } else { - timeoutError.message = message ?? `Promise timed out after ${milliseconds} milliseconds`; - reject(timeoutError); - } - }, milliseconds); - (async () => { - try { - resolve2(await promise); - } catch (error2) { - reject(error2); - } - })(); - }); - const cancelablePromise = wrappedPromise.finally(() => { - cancelablePromise.clear(); - if (abortHandler && options.signal) { - options.signal.removeEventListener("abort", abortHandler); - } - }); - cancelablePromise.clear = () => { - customTimers.clearTimeout.call(void 0, timer16); - timer16 = void 0; - }; - return cancelablePromise; -} - -// node_modules/.pnpm/p-queue@8.1.0/node_modules/p-queue/dist/lower-bound.js -function lowerBound(array, value, comparator) { - let first = 0; - let count = array.length; - while (count > 0) { - const step = Math.trunc(count / 2); - let it = first + step; - if (comparator(array[it], value) <= 0) { - first = ++it; - count -= step + 1; - } else { - count = step; - } - } - return first; -} - -// node_modules/.pnpm/p-queue@8.1.0/node_modules/p-queue/dist/priority-queue.js -var _queue; -var PriorityQueue = class { - constructor() { - __privateAdd(this, _queue, []); - } - enqueue(run, options) { - options = { - priority: 0, - ...options - }; - const element = { - priority: options.priority, - id: options.id, - run - }; - if (this.size === 0 || __privateGet(this, _queue)[this.size - 1].priority >= options.priority) { - __privateGet(this, _queue).push(element); - return; - } - const index = lowerBound(__privateGet(this, _queue), element, (a, b) => b.priority - a.priority); - __privateGet(this, _queue).splice(index, 0, element); - } - setPriority(id, priority) { - const index = __privateGet(this, _queue).findIndex((element) => element.id === id); - if (index === -1) { - throw new ReferenceError(`No promise function with the id "${id}" exists in the queue.`); - } - const [item] = __privateGet(this, _queue).splice(index, 1); - this.enqueue(item.run, { priority, id }); - } - dequeue() { - const item = __privateGet(this, _queue).shift(); - return item == null ? void 0 : item.run; - } - filter(options) { - return __privateGet(this, _queue).filter((element) => element.priority === options.priority).map((element) => element.run); - } - get size() { - return __privateGet(this, _queue).length; - } -}; -_queue = new WeakMap(); - -// node_modules/.pnpm/p-queue@8.1.0/node_modules/p-queue/dist/index.js -var _carryoverConcurrencyCount, _isIntervalIgnored, _intervalCount, _intervalCap, _interval, _intervalEnd, _intervalId, _timeoutId, _queue2, _queueClass, _pending, _concurrency, _isPaused, _throwOnTimeout, _idAssigner, _PQueue_instances, doesIntervalAllowAnother_get, doesConcurrentAllowAnother_get, next_fn, onResumeInterval_fn, isIntervalPaused_get, tryToStartAnother_fn, initializeIntervalIfNeeded_fn, onInterval_fn, processQueue_fn, throwOnAbort_fn, onEvent_fn; -var PQueue = class extends import_index2.default { - // TODO: The `throwOnTimeout` option should affect the return types of `add()` and `addAll()` - constructor(options) { - var _a14, _b12; - super(); - __privateAdd(this, _PQueue_instances); - __privateAdd(this, _carryoverConcurrencyCount); - __privateAdd(this, _isIntervalIgnored); - __privateAdd(this, _intervalCount, 0); - __privateAdd(this, _intervalCap); - __privateAdd(this, _interval); - __privateAdd(this, _intervalEnd, 0); - __privateAdd(this, _intervalId); - __privateAdd(this, _timeoutId); - __privateAdd(this, _queue2); - __privateAdd(this, _queueClass); - __privateAdd(this, _pending, 0); - // The `!` is needed because of https://github.com/microsoft/TypeScript/issues/32194 - __privateAdd(this, _concurrency); - __privateAdd(this, _isPaused); - __privateAdd(this, _throwOnTimeout); - // Use to assign a unique identifier to a promise function, if not explicitly specified - __privateAdd(this, _idAssigner, 1n); - /** - Per-operation timeout in milliseconds. Operations fulfill once `timeout` elapses if they haven't already. - - Applies to each future operation. - */ - __publicField(this, "timeout"); - options = { - carryoverConcurrencyCount: false, - intervalCap: Number.POSITIVE_INFINITY, - interval: 0, - concurrency: Number.POSITIVE_INFINITY, - autoStart: true, - queueClass: PriorityQueue, - ...options - }; - if (!(typeof options.intervalCap === "number" && options.intervalCap >= 1)) { - throw new TypeError(`Expected \`intervalCap\` to be a number from 1 and up, got \`${((_a14 = options.intervalCap) == null ? void 0 : _a14.toString()) ?? ""}\` (${typeof options.intervalCap})`); - } - if (options.interval === void 0 || !(Number.isFinite(options.interval) && options.interval >= 0)) { - throw new TypeError(`Expected \`interval\` to be a finite number >= 0, got \`${((_b12 = options.interval) == null ? void 0 : _b12.toString()) ?? ""}\` (${typeof options.interval})`); - } - __privateSet(this, _carryoverConcurrencyCount, options.carryoverConcurrencyCount); - __privateSet(this, _isIntervalIgnored, options.intervalCap === Number.POSITIVE_INFINITY || options.interval === 0); - __privateSet(this, _intervalCap, options.intervalCap); - __privateSet(this, _interval, options.interval); - __privateSet(this, _queue2, new options.queueClass()); - __privateSet(this, _queueClass, options.queueClass); - this.concurrency = options.concurrency; - this.timeout = options.timeout; - __privateSet(this, _throwOnTimeout, options.throwOnTimeout === true); - __privateSet(this, _isPaused, options.autoStart === false); - } - get concurrency() { - return __privateGet(this, _concurrency); - } - set concurrency(newConcurrency) { - if (!(typeof newConcurrency === "number" && newConcurrency >= 1)) { - throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${newConcurrency}\` (${typeof newConcurrency})`); - } - __privateSet(this, _concurrency, newConcurrency); - __privateMethod(this, _PQueue_instances, processQueue_fn).call(this); - } - /** - Updates the priority of a promise function by its id, affecting its execution order. Requires a defined concurrency limit to take effect. - - For example, this can be used to prioritize a promise function to run earlier. - - ```js - import PQueue from 'p-queue'; - - const queue = new PQueue({concurrency: 1}); - - queue.add(async () => '🦄', {priority: 1}); - queue.add(async () => '🦀', {priority: 0, id: '🦀'}); - queue.add(async () => '🦄', {priority: 1}); - queue.add(async () => '🦄', {priority: 1}); - - queue.setPriority('🦀', 2); - ``` - - In this case, the promise function with `id: '🦀'` runs second. - - You can also deprioritize a promise function to delay its execution: - - ```js - import PQueue from 'p-queue'; - - const queue = new PQueue({concurrency: 1}); - - queue.add(async () => '🦄', {priority: 1}); - queue.add(async () => '🦀', {priority: 1, id: '🦀'}); - queue.add(async () => '🦄'); - queue.add(async () => '🦄', {priority: 0}); - - queue.setPriority('🦀', -1); - ``` - Here, the promise function with `id: '🦀'` executes last. - */ - setPriority(id, priority) { - __privateGet(this, _queue2).setPriority(id, priority); - } - async add(function_, options = {}) { - options.id ?? (options.id = (__privateWrapper(this, _idAssigner)._++).toString()); - options = { - timeout: this.timeout, - throwOnTimeout: __privateGet(this, _throwOnTimeout), - ...options - }; - return new Promise((resolve2, reject) => { - __privateGet(this, _queue2).enqueue(async () => { - var _a14; - __privateWrapper(this, _pending)._++; - __privateWrapper(this, _intervalCount)._++; - try { - (_a14 = options.signal) == null ? void 0 : _a14.throwIfAborted(); - let operation = function_({ signal: options.signal }); - if (options.timeout) { - operation = pTimeout(Promise.resolve(operation), { milliseconds: options.timeout }); - } - if (options.signal) { - operation = Promise.race([operation, __privateMethod(this, _PQueue_instances, throwOnAbort_fn).call(this, options.signal)]); - } - const result = await operation; - resolve2(result); - this.emit("completed", result); - } catch (error2) { - if (error2 instanceof TimeoutError && !options.throwOnTimeout) { - resolve2(); - return; - } - reject(error2); - this.emit("error", error2); - } finally { - __privateMethod(this, _PQueue_instances, next_fn).call(this); - } - }, options); - this.emit("add"); - __privateMethod(this, _PQueue_instances, tryToStartAnother_fn).call(this); - }); - } - async addAll(functions, options) { - return Promise.all(functions.map(async (function_) => this.add(function_, options))); - } - /** - Start (or resume) executing enqueued tasks within concurrency limit. No need to call this if queue is not paused (via `options.autoStart = false` or by `.pause()` method.) - */ - start() { - if (!__privateGet(this, _isPaused)) { - return this; - } - __privateSet(this, _isPaused, false); - __privateMethod(this, _PQueue_instances, processQueue_fn).call(this); - return this; - } - /** - Put queue execution on hold. - */ - pause() { - __privateSet(this, _isPaused, true); - } - /** - Clear the queue. - */ - clear() { - __privateSet(this, _queue2, new (__privateGet(this, _queueClass))()); - } - /** - Can be called multiple times. Useful if you for example add additional items at a later time. - - @returns A promise that settles when the queue becomes empty. - */ - async onEmpty() { - if (__privateGet(this, _queue2).size === 0) { - return; - } - await __privateMethod(this, _PQueue_instances, onEvent_fn).call(this, "empty"); - } - /** - @returns A promise that settles when the queue size is less than the given limit: `queue.size < limit`. - - If you want to avoid having the queue grow beyond a certain size you can `await queue.onSizeLessThan()` before adding a new item. - - Note that this only limits the number of items waiting to start. There could still be up to `concurrency` jobs already running that this call does not include in its calculation. - */ - async onSizeLessThan(limit) { - if (__privateGet(this, _queue2).size < limit) { - return; - } - await __privateMethod(this, _PQueue_instances, onEvent_fn).call(this, "next", () => __privateGet(this, _queue2).size < limit); - } - /** - The difference with `.onEmpty` is that `.onIdle` guarantees that all work from the queue has finished. `.onEmpty` merely signals that the queue is empty, but it could mean that some promises haven't completed yet. - - @returns A promise that settles when the queue becomes empty, and all promises have completed; `queue.size === 0 && queue.pending === 0`. - */ - async onIdle() { - if (__privateGet(this, _pending) === 0 && __privateGet(this, _queue2).size === 0) { - return; - } - await __privateMethod(this, _PQueue_instances, onEvent_fn).call(this, "idle"); - } - /** - Size of the queue, the number of queued items waiting to run. - */ - get size() { - return __privateGet(this, _queue2).size; - } - /** - Size of the queue, filtered by the given options. - - For example, this can be used to find the number of items remaining in the queue with a specific priority level. - */ - sizeBy(options) { - return __privateGet(this, _queue2).filter(options).length; - } - /** - Number of running items (no longer in the queue). - */ - get pending() { - return __privateGet(this, _pending); - } - /** - Whether the queue is currently paused. - */ - get isPaused() { - return __privateGet(this, _isPaused); - } -}; -_carryoverConcurrencyCount = new WeakMap(); -_isIntervalIgnored = new WeakMap(); -_intervalCount = new WeakMap(); -_intervalCap = new WeakMap(); -_interval = new WeakMap(); -_intervalEnd = new WeakMap(); -_intervalId = new WeakMap(); -_timeoutId = new WeakMap(); -_queue2 = new WeakMap(); -_queueClass = new WeakMap(); -_pending = new WeakMap(); -_concurrency = new WeakMap(); -_isPaused = new WeakMap(); -_throwOnTimeout = new WeakMap(); -_idAssigner = new WeakMap(); -_PQueue_instances = new WeakSet(); -doesIntervalAllowAnother_get = function() { - return __privateGet(this, _isIntervalIgnored) || __privateGet(this, _intervalCount) < __privateGet(this, _intervalCap); -}; -doesConcurrentAllowAnother_get = function() { - return __privateGet(this, _pending) < __privateGet(this, _concurrency); -}; -next_fn = function() { - __privateWrapper(this, _pending)._--; - __privateMethod(this, _PQueue_instances, tryToStartAnother_fn).call(this); - this.emit("next"); -}; -onResumeInterval_fn = function() { - __privateMethod(this, _PQueue_instances, onInterval_fn).call(this); - __privateMethod(this, _PQueue_instances, initializeIntervalIfNeeded_fn).call(this); - __privateSet(this, _timeoutId, void 0); -}; -isIntervalPaused_get = function() { - const now = Date.now(); - if (__privateGet(this, _intervalId) === void 0) { - const delay2 = __privateGet(this, _intervalEnd) - now; - if (delay2 < 0) { - __privateSet(this, _intervalCount, __privateGet(this, _carryoverConcurrencyCount) ? __privateGet(this, _pending) : 0); - } else { - if (__privateGet(this, _timeoutId) === void 0) { - __privateSet(this, _timeoutId, setTimeout(() => { - __privateMethod(this, _PQueue_instances, onResumeInterval_fn).call(this); - }, delay2)); - } - return true; - } - } - return false; -}; -tryToStartAnother_fn = function() { - if (__privateGet(this, _queue2).size === 0) { - if (__privateGet(this, _intervalId)) { - clearInterval(__privateGet(this, _intervalId)); - } - __privateSet(this, _intervalId, void 0); - this.emit("empty"); - if (__privateGet(this, _pending) === 0) { - this.emit("idle"); - } - return false; - } - if (!__privateGet(this, _isPaused)) { - const canInitializeInterval = !__privateGet(this, _PQueue_instances, isIntervalPaused_get); - if (__privateGet(this, _PQueue_instances, doesIntervalAllowAnother_get) && __privateGet(this, _PQueue_instances, doesConcurrentAllowAnother_get)) { - const job = __privateGet(this, _queue2).dequeue(); - if (!job) { - return false; - } - this.emit("active"); - job(); - if (canInitializeInterval) { - __privateMethod(this, _PQueue_instances, initializeIntervalIfNeeded_fn).call(this); - } - return true; - } - } - return false; -}; -initializeIntervalIfNeeded_fn = function() { - if (__privateGet(this, _isIntervalIgnored) || __privateGet(this, _intervalId) !== void 0) { - return; - } - __privateSet(this, _intervalId, setInterval(() => { - __privateMethod(this, _PQueue_instances, onInterval_fn).call(this); - }, __privateGet(this, _interval))); - __privateSet(this, _intervalEnd, Date.now() + __privateGet(this, _interval)); -}; -onInterval_fn = function() { - if (__privateGet(this, _intervalCount) === 0 && __privateGet(this, _pending) === 0 && __privateGet(this, _intervalId)) { - clearInterval(__privateGet(this, _intervalId)); - __privateSet(this, _intervalId, void 0); - } - __privateSet(this, _intervalCount, __privateGet(this, _carryoverConcurrencyCount) ? __privateGet(this, _pending) : 0); - __privateMethod(this, _PQueue_instances, processQueue_fn).call(this); -}; -/** -Executes all queued functions until it reaches the limit. -*/ -processQueue_fn = function() { - while (__privateMethod(this, _PQueue_instances, tryToStartAnother_fn).call(this)) { - } -}; -throwOnAbort_fn = async function(signal) { - return new Promise((_resolve, reject) => { - signal.addEventListener("abort", () => { - reject(signal.reason); - }, { once: true }); - }); -}; -onEvent_fn = async function(event2, filter) { - return new Promise((resolve2) => { - const listener = () => { - if (filter && !filter()) { - return; - } - this.off(event2, listener); - resolve2(); - }; - this.on(event2, listener); - }); -}; - -// syncify/model/queue.ts -var q = new class Enqueue { - /** - * Cache Queue - * - * Cache specific queue - */ - cache = new PQueue(); - /** - * Bulk Queue - * - * Used in `watch` mode for batch requests. - */ - bulk = new PQueue({ concurrency: 1 }); - /** - * Change Queue - * - * Used in `watch` mode for single file changes. - */ - change = new PQueue(); - /** - * Task Queue - * - * Holds various different operations that can be queue executed - */ - tasks = new PQueue(); - /** - * HTTP Queue - * - * HTTP Request Queue which performs requests in 1000ms (10 per-cap) intervals. This ensures - * that requests stay within bounds of limits imposed by Shopify. It does not take into - * account plan based usage limits, which needs to be addressed in later versions. - */ - http = new PQueue({ interval: 1e3, intervalCap: 10 }); -}(); - -// syncify/model/$.ts -var $ = new class Bundle { - /** - * The users configuration settings merged with defaults - */ - static config = defaults(); - /** - * Plugins - */ - static plugins = plugins(); - /** - * The processors configuration settings - */ - static processor = processor(); - /** - * The parsed contents of `package.json` file - * - * > When `null` there is no `package.json` file present in the project. - */ - static package = null; - /** - * The package manager used - */ - static pm = null; - /** - * Cache interface - */ - static cache = o(); - /** - * The user platform OS - */ - platform = node_os.platform(); - /** - * The Syncify Github Repository - */ - github = "https://github.com/panoply/syncify.git"; - /** - * The version of Syncify running - */ - version = "1.0.0-alpha.1"; - /** - * **READY AT RUNTIME** - * - * Home or temporary directory if home fails - * - * @example - * '/Users/sissel/.syncify' - */ - home = path2.join(node_os.homedir(), ".syncify"); - /** - * The provided command passed on the CLI. - * - * > The references sliced[2] copy of `process.argv` - */ - argv; - /** - * The path to node.js binary - */ - node; - /** - * The path to the script binary being run - */ - bin; - /** - * Model representing the shopify stores - */ - stores = new Stores(); - /** - * Model representing the shopify themes - * Each theme can access their associated {@link Stores} - */ - target = new Targets(); - /** - * Cache copy of the invoked commands in which syncify was started. - * By default, this structure will assign `target` and `filter` entries - * only, as they are parsed and handled in their own respective define - * operations. - */ - cmd = o({ - target: [], - filter: [], - batch: 16 - }); - /** - * Whether or not synicfy is running. - */ - running = false; - /** - * Event Name emitter reference - */ - event = null; - /** - * **READY AT RUNTIME** - * - * The current working directory - * - * @example - * '/Users/sissel/projects/site-name' - */ - cwd = process8.cwd(); - /** - * **READY AT RUNTIME** - * - * Encoded checksum of the CWD - * - * @example - * 'eb4e712f2f3970b7' - */ - hash = checksum(this.cwd); - /** - * **READY AT RUNTIME** - * - * Root directory base - * - * @example - * '/Users/sissel/.syncify/eb4e712f2f3970b7' - */ - root = path2.join(this.home, this.hash); - /** - * Base directory path references. These are fully resolved absolute URI - * paths pointing to all base directory locations, included cached locations. - */ - dirs = o({ - module: null, - input: null, - output: null, - config: this.cwd, - hot: path2.join(this.root, "hot"), - cache: path2.join(this.root, "cache"), - temp: path2.join(this.root, "temp"), - versions: path2.join(this.root, "versions"), - sourcemaps: { - root: path2.join(this.root, "sourcemaps"), - scripts: path2.join(this.root, "sourcemaps", "scripts"), - styles: path2.join(this.root, "sourcemaps", "styles") - } - }); - /** - * Configuration file path resolutions for `syncify.config` and `package.json` - * and other required files. - */ - file = o({ - keychain: path2.join(this.home, ".keychain"), - pkg: path2.join(this.cwd, "package.json"), - notifier: path2.join(this.home, "icon.png"), - project: null, - tsconfig: null, - targets: null, - env: null, - config: null, - githook: null - }); - /** - * Global keychain for store access tokens stored in home - */ - keychain = null; - /** - * The project store which references the parsed cache project file. This reference - * is a `Proxy` type and will apply atomic writes to the project cache file. - * The data this reference holds lives in the root project location of the users OS. - * - * > This will be `null` and populated at runtime in one of the first operations to occur. - */ - project = null; - /** - * The installation binary being used - */ - using = null; - /** - * Process Child - */ - process = null; - /** - * Whether or not to restart process - */ - restart = false; - /** - * Websockets HOT reloading instance - * - * @default null - */ - wss = null; - /** - * Stats information for the output directory - * - * @default null - */ - stats = o(); - /** - * CLI provided filters - * - * @default null - */ - filters = o(); - /** - * Error store, holds reference to errors. Map key is {@link File} - * and values are an array list of string error messages. - * - * @default Map - */ - errors = m(); - /** - * Error stack store. Used in some instances where stack-trace is - * required and reference is to exist. Stacks are temporary. - * - * @default Set - */ - stacks = s(); - /** - * Error store, holds reference to errors - * - * The file uri input path - The `Map` will hold - * process identifier and a `Set` of stack messages. - * - * @default - * {} - */ - warnings = m(); - /** - * Directory structure paths. - */ - paths = createPathsState(); - /** - * Execution options which describe the invocation and operation - * instructions Syncify was initialised. - * - * @default - * { - * cli: false, - * dev: true, - * prod: false - * sync: 0, - * vars: {} - * } - */ - env = o({ - dev: true, - cli: false, - tree: true, - // TODO - REMOVE THIS - prod: false, - ready: false, - sync: 0, - vars: null - }); - git = {}; - /** - * Version Control settings - */ - vc = o({ - cache: null, - source: 1, - dir: null, - number: null, - zip: null, - patch: 0, - major: 0, - minor: 0, - update: null - }); - /** - * Hot reload mode options - Use the `mode.hot` reference to - * determine whether or not HOT reloading is enabled. - */ - hot = o({ - source: null, - route: null, - ready: false, - server: 41001, - socket: 51001, - label: true, - eject: true, - method: "hot", - client: "inject", - alias: {}, - layouts: [ - "theme.liquid" - ], - version: o({ - source: null, - remote: null, - local: "0.4.9" - }), - flags: o({ - "no-preview-bar": true, - "no-checkout-preloads": false, - "no-perfkit": false, - "no-trekkie": false, - "no-shopify-features": false, - "no-web-pixels-manager": false - }), - cache: o({ - root: null, - snippet: null, - layouts: [] - }), - alive: o({ - snippet: false, - layouts: o() - }) - }); - /** - * Log state and console references - */ - log = o({ - idle: false, - group: "Syncify", - mode: null, - title: "", - uri: "", - queue: s(), - changes: m() - }); - /** - * Bulk batch model - used when performing bulk operations in `watch` mode. - */ - bulk = o({ - id: null, - group: "", - files: 0, - type: null, - synced: s() - }); - /** - * The operation mode executing - * - * @default false // all modes are false by default - */ - mode = o({ - _: null, - align: false, - bind: false, - build: false, - clean: false, - debug: false, - bulk: false, - create: false, - doctor: false, - dev: false, - pack: false, - force: false, - git: false, - help: false, - hot: false, - projects: false, - inspect: false, - keychain: false, - main: false, - metafields: false, - pages: false, - prod: false, - prompt: false, - prune: false, - publish: false, - pull: false, - push: false, - stash: false, - redirects: false, - liquid: false, - json: false, - script: false, - style: false, - svg: false, - init: false, - setup: false, - suggest: false, - terse: false, - link: false, - unpublished: false, - version: false, - watch: false - }); - /** - * Section sub-directory configuration - * - * @todo - * Allow anymatch global patterns - * - * @default - * { - * prefixDir: false, - * separator: '-', - * global: null - * } - */ - section = o({ - schema: null, - shared: m(), - template: o() - }); - /** - * Page transforms - * - * Populated during the setPages options generation - */ - page = null; - /** - * Script transforms - * - * @default [] - */ - script = []; - /** - * Style tranforms - * - * @default [] - */ - style = []; - /** - * SVG transforms - * - * @default [] - */ - svg = []; - /** - * Liquid Transforms - * - * @default [] - */ - liquid = o({ - terse: { - enabled: false, - exclude: null, - liquid: { - minifySchema: true - }, - markup: { - // EXPOSED - // - minifyCSS: true, - minifyJS: true, - collapseWhitespace: true, - removeComments: true, - // OVERRIDES - // - caseSensitive: false, - collapseBooleanAttributes: false, - collapseInlineTagWhitespace: false, - conservativeCollapse: false, - keepClosingSlash: false, - noNewlinesBeforeTagClose: false, - preventAttributesEscaping: false, - removeEmptyAttributes: false, - removeEmptyElements: false, - removeOptionalTags: false, - removeRedundantAttributes: false, - removeScriptTypeAttributes: true, - removeStyleLinkTypeAttributes: true, - useShortDoctype: false, - continueOnParseError: true, - trimCustomFragments: false, - ignoreCustomFragments: [ - /(?<=\bstyle\b=["']\s?)[\s\S]*?(?="[\s\n>]?)/, - //, - //, - /{%[\s\S]*?%}/ - ] - } - } - }); - /** - * Liquid Transforms - * - * @default [] - */ - json = o({ - crlf: false, - cache: null, - stripComments: false, - exclude: null, - indent: 2, - useTab: false, - sortObjects: false, - sortArrays: [], - noSortList: [], - options: { - indentSize: 2, - useTab: false, - crlf: false, - arrays: false, - objects: false, - removeComments: false, - exclude: [] - }, - terse: { - enabled: false, - exclude: null, - options: { - assets: true, - config: true, - locales: true, - metafields: true, - metaobject: true, - groups: true, - templates: true - } - } - }); - /** - * Returns the {@link Bundle.cache} static model - */ - get cache() { - return Bundle.cache; - } - /** - * Returns the {@link Bundle.cache.checksum} static model - */ - get checksum() { - return Bundle.cache.checksum; - } - /** - * Processor Configurations - */ - get processor() { - return Bundle.processor; - } - /** - * Merge users configuration with default - */ - set config(data) { - Bundle.config = merge(Bundle.config, data); - } - /** - * Returns the merged configuration of users syncify configuration with defaults - */ - get config() { - return Bundle.config; - } - /** - * Returns the `package.json` contents - */ - get pkg() { - return Bundle.package; - } - /** - * Set the `package.json` contents - */ - set pkg(pkg) { - Bundle.package = pkg; - } - /** - * Returns the `package.json` contents - */ - get pm() { - return Bundle.pm === null ? pm() : Bundle.pm; - } - /** - * Set the `package.json` contents - */ - set pm(manager) { - Bundle.pm = manager; - } - /** - * Plugins - */ - get plugins() { - return Bundle.plugins; - } - /** - * The terminal rows and columns size - */ - get terminal() { - return tsize(); - } -}(); - -// syncify/utils/utils.ts -var command = node_util.promisify(node_child_process.exec); -var NooP = () => { -}; -var assign = Object.assign; -var defineProperty = Object.defineProperty; -var keys = Object.keys; -var values = Object.values; -var toArray = Array.from; -var toBuffer = Buffer.from; -var { toString } = Object.prototype; -var isBuffer = Buffer.isBuffer; -function type(input) { - if (input === null) return "null"; - if (input === void 0) return "undefined"; - if (isNaN2(input)) return "NaN"; - if (isBuffer(input)) return "Buffer"; - const result = toString.call(input).slice(8, -1); - return result === "AsyncFunction" ? "Promise" : result; -} -function isNil(input) { - return input === void 0 || input === null; -} -function isEmptyString(input) { - if (isBuffer(input)) return input.toString().trim().length === 0; - return input.trim().length === 0; -} -function isEmpty(input) { - if (isObject(input)) { - for (const _ in input) return false; - return true; - } - if (isArray(input)) return input.length === 0; - if (isUndefined(input) || isNumber(input) || isNull(input) || isNaN2(input)) return true; - return !input; -} -function isArray(param) { - return Array.isArray(param); -} -function isObject(param) { - return toString.call(param).slice(8, -1) === "Object"; -} -function isString(param) { - return toString.call(param).slice(8, -1) === "String"; -} -function isRegex(param) { - return toString.call(param).slice(8, -1) === "RegExp"; -} -function isFunction(param) { - return typeof param === "function"; -} -function isBoolean(param) { - return typeof param === "boolean"; -} -function isNumber(param) { - return typeof param === "number"; -} -function isNaN2(param) { - return Number.isNaN(param); -} -function isNull(param) { - return param === null; -} -function isUndefined(param) { - return typeof param === "undefined" && param === void 0; -} -function pm() { - if (!process8.env.npm_config_user_agent) return "?"; - const userAgent = process8.env.npm_config_user_agent; - const pmSpec = userAgent.split(" ")[0]; - const separatorPos = pmSpec.lastIndexOf("/"); - const name = pmSpec.substring(0, separatorPos); - return name === "npminstall" ? "cnpm" : name; -} -function o(input) { - return input ? Object.assign(/* @__PURE__ */ Object.create(null), input) : /* @__PURE__ */ Object.create(null); -} -function s(value) { - return new Set(value); -} -function m(input) { - return new Map(input); -} -function checksum(input, outputLength = -1) { - const hash = outputLength > -1 ? node_crypto.createHash("shake256", { outputLength }) : node_crypto.createHash("md5"); - return hash.update(input).digest("hex"); -} -async function openInEditor(filePath) { - return new Promise((resolve2, reject) => { - try { - const process9 = node_child_process.spawn($.project.textEditor, [filePath], { - stdio: "ignore", - detached: true - }); - process9.unref(); - resolve2(true); - } catch (error2) { - reject(new Error(`Failed to open file: ${error2.message}`)); - } - }); -} -function getChunk(array, perChunk = 2) { - return array.reduce((acc, item, index) => { - const ci = Math.floor(index / perChunk); - if (!acc[ci]) acc[ci] = []; - acc[ci].push(item); - return acc; - }, []); -} -function includes(a, list) { - let index = -1; - const size = list.length; - while (++index < size) { - if (String(list[index]) === String(a)) return true; - } - return false; -} -function hasPath(path5, param) { - if (isNil(param)) return false; - if (isObject(param) === false) return false; - let object = param; - let counter = 0; - const props = path5.split("."); - while (counter < props.length) { - if (isNil(object)) return false; - if (object[props[counter]] === null) return false; - object = object[props[counter]]; - counter++; - } - return object !== void 0; -} -function has(prop, object) { - return isObject(object) ? prop in object : false; -} -function inProp(prop, object) { - return prop in object; -} -function hasProp(object) { - const isObj = isObject(object); - return (prop) => isObj ? prop in object : false; -} -function pathOr(object, path5, fallback) { - const keys2 = isString(path5) ? path5.split(".") : path5; - if (keys2.length === 0) return fallback(object); - let result = object; - for (const key of keys2) { - if (result == null || !(key in result)) return fallback(object); - result = result[key]; - } - return result; -} -function merge(source, ...patches) { - const arr = isArray(source); - return function apply(isArr, copy, patch) { - const type2 = typeof patch; - if (patch && type2 === "object") { - if (isArray(patch)) { - for (const p of patch) copy = apply(isArr, copy, p); - } else { - for (const k in patch) { - const val = patch[k]; - if (isFunction(val)) { - copy[k] = val(copy[k], merge); - } else if (val === void 0) { - if (isArr) { - copy.splice(k, 1); - } else { - delete copy[k]; - } - } else if (val === null || isObject(val) === false || isArray(val)) { - copy[k] = val; - } else if (typeof copy[k] === "object") { - copy[k] = val === copy[k] ? val : merge(copy[k], val); - } else { - copy[k] = apply(false, {}, val); - } - } - } - } else if (type2 === "function") { - copy = patch(copy, merge); - } - return copy; - }(arr, arr ? source.slice() : Object.assign({}, source), patches); -} -function forMap(cb, array) { - if (!isArray(array)) return []; - const s2 = array.length; - if (s2 === 0) return []; - const a = []; - let i = 0; - for (; i < s2; i++) { - const v2 = cb(array[i]); - if (!isNil(v2)) a.push(v2); - } - return a; -} -function reduce(array, cb, model) { - const s2 = array.length; - if (s2 === 0) return model; - let i = 0; - for (; i < s2; i++) cb(model, array[i]); - return model; -} -function forEach(cb, array) { - const s2 = array.length; - if (s2 === 0) return; - let i = 0; - for (; i < s2; i++) if (cb(array[i]) === false) break; -} -function forKeys(cb, object) { - for (const k in object) if (cb(k) === false) break; -} -function pNext() { - return new Promise((resolve2) => isFunction(setImmediate) ? setImmediate(resolve2) : setTimeout(resolve2)); -} -function delay(ms = 1e3) { - return new Promise((resolve2) => setTimeout(resolve2, ms)); -} -function eqWS(array, { prop = null, padding = 0 } = {}) { - let size = 0; - if (isArray(array)) { - for (let i = 0, s2 = array.length; i < s2; i++) { - if (prop) { - if (array[i][prop].length > size) { - size = array[i][prop].length; - } - } else { - if (array[i].length > size) { - size = array[i].length; - } - } - } - } else { - for (const item in array) { - if (item.length > size) size = item.length; - } - } - size = size + 1; - const p = padding > 0 ? " ".repeat(padding) : ""; - return (string) => { - const n = isString(string) ? size - string.length : size - string; - const s2 = n < 1 ? " " : " ".repeat(n); - return s2 + p; - }; -} -function murmur(str, seed) { - const string = new TextEncoder().encode(str); - let s2 = string.length; - let h = seed ^ s2; - let i = 0; - let k; - while (s2 >= 4) { - k = string[i] & 255 | (string[++i] & 255) << 8 | (string[++i] & 255) << 16 | (string[++i] & 255) << 24; - k = (k & 65535) * 1540483477 + (((k >>> 16) * 1540483477 & 65535) << 16); - k ^= k >>> 24; - k = (k & 65535) * 1540483477 + (((k >>> 16) * 1540483477 & 65535) << 16); - h = (h & 65535) * 1540483477 + (((h >>> 16) * 1540483477 & 65535) << 16) ^ k; - s2 -= 4; - ++i; - } - if (s2 === 3) h ^= (string[i + 2] & 255) << 16; - if (s2 === 2) h ^= (string[i + 1] & 255) << 8; - if (s2 === 1) { - h ^= string[i] & 255; - h = (h & 65535) * 1540483477 + (((h >>> 16) * 1540483477 & 65535) << 16); - } - h ^= h >>> 13; - h = (h & 65535) * 1540483477 + (((h >>> 16) * 1540483477 & 65535) << 16); - h ^= h >>> 15; - return h >>> 0; -} -function uuid() { - return Math.random().toString(36).slice(2); -} -function handleize(string) { - return string.toLowerCase().replace(/[^a-z0-9_:]+/g, "-").replace(/-$/, "").replace(/^-/, ""); -} -function toPascalCase(string) { - return string.replace(/[^a-zA-Z0-9_:]+(.)/g, (_, c) => c.toUpperCase()).replace(/^./, (c) => c.toUpperCase()); -} -function plur(word, size) { - if (size === 1) return word; - if (size >= 2 || size === 0) return word[word.length - 1] !== "s" ? `${word}s` : word; - return word[word.length - 1] !== "s" ? word : word.slice(0, -1); -} -function toUpcase(value) { - return value.charAt(0).toUpperCase() + value.slice(1); -} -function addSuffix(number) { - const a = number % 10; - const b = number % 100; - return number + (a === 1 && b !== 11 ? "st" : a === 2 && b !== 12 ? "nd" : a === 3 && b !== 13 ? "rd" : "th"); -} -function stringSize(value) { - return isNumber(value) ? byteConvert(value) : byteConvert(byteSize(value)); -} -function byteSize(string) { - return isString(string) ? Buffer.from(string).toString().length : string.toString().length; -} -function byteConvert(bytes) { - if (bytes === 0) return `${bold2("0")}b`; - const size = parseInt(String(Math.floor(Math.log(bytes) / Math.log(1024))), 10); - return size === 0 ? `${bold2(`${bytes}`)}${UNITS[size]}` : `${bold2((bytes / 1024 ** size).toFixed(1))}${UNITS[size]}`; -} -function sizeDiff(content, beforeSize) { - const size = byteSize(content); - return { - get isSmaller() { - return size > beforeSize || size === beforeSize; - }, - get brotli() { - return byteConvert(zlib__default.default.brotliCompressSync(content).length); - }, - get before() { - return byteConvert(beforeSize); - }, - get after() { - return byteConvert(size); - }, - get saved() { - return byteConvert(beforeSize - size); - } - }; -} -function getFuture(months) { - const current = new Date(Date.now()); - current.setMonth(current.getMonth() + months); - const d = current.getDate(); - current.setDate(1); - current.setDate(Math.min(d, new Date(current.getFullYear(), current.getMonth() + 1, 0).getDate())); - return current.getTime(); -} -function prettyDate(time) { - const date = new Date(time); - const locale = date.toLocaleDateString("en-GB", { - day: "numeric", - month: "long", - year: "numeric" - }); - return locale.replace(/\d+/, addSuffix(date.getDate())); -} -function getTime2() { - const now = /* @__PURE__ */ new Date(); - const hur = now.getHours(); - const min = now.getMinutes(); - const sec = now.getSeconds(); - return (hur < 10 ? `0${hur}` : hur) + ":" + (min < 10 ? `0${min}` : min) + ":" + (sec < 10 ? `0${sec}` : sec); -} - -// syncify/model/modules.ts -var IMPORT_MAP = o({ - "smol-toml": "toml", - "js-yaml": "yaml", - "svgo": "svgo", - "@tailwindcss/postcss": "tailwind", - "postcss": "postcss", - "sass-embedded": "sass", - "clean-css": "cleancss", - "markdown-it": "markdown", - "adm-zip": "admzip", - "gray-matter": "matter", - "html-minifier-terser": "terser" -}); -var $import = Object.assign(async function(name) { - const id = IMPORT_MAP[name]; - if ($import[id] !== null) return $import[id]; - try { - const resolve2 = await import(name); - $import[id] = resolve2.default || resolve2; - return $import[id]; - } catch (e) { - $import[id] = null; - throwError(`Module import failed for ${name}`, [ - "Please ensure the module is installed correctly. If this error persists, try", - "to reinstall Syncify or install the import in isolation." - ]); - } -}, { - toml: null, - yaml: null, - postcss: null, - svgo: null, - sass: null, - markdown: null, - cleancss: null, - tailwind: null, - terser: null, - admzip: null, - matter: null -}); - -// packages/codeframe/dist/index.mjs -var fe = Object.create; -var K = Object.defineProperty; -var _e2 = Object.getOwnPropertyDescriptor; -var xe = Object.getOwnPropertyNames; -var ye = Object.getPrototypeOf; -var he = Object.prototype.hasOwnProperty; -var ve = (e, t2) => () => (t2 || e((t2 = { exports: {} }).exports, t2), t2.exports); -var be = (e, t2, a, s2) => { - if (t2 && typeof t2 == "object" || typeof t2 == "function") for (let o2 of xe(t2)) !he.call(e, o2) && o2 !== a && K(e, o2, { get: () => t2[o2], enumerable: !(s2 = _e2(t2, o2)) || s2.enumerable }); - return e; -}; -var Se = (e, t2, a) => (a = e != null ? fe(ye(e)) : {}, be(!e || !e.__esModule ? K(a, "default", { value: e, enumerable: true }) : a, e)); -var re = ve((We, ie) => { - var ee, E, $2, J, P, X, L, R, w2, C2, te, j, k, z, q2, B, v2, ne, O, W; - z = /\/(?![*\/])(?:\[(?:[^\]\\\n\r\u2028\u2029]+|\\.)*\]?|[^\/[\\\n\r\u2028\u2029]+|\\.)*(\/[$_\u200C\u200D\p{ID_Continue}]*|\\)?/yu; - k = /--|\+\+|=>|\.{3}|\??\.(?!\d)|(?:&&|\|\||\?\?|[+\-%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2}|\/(?![\/*]))=?|[?~,:;[\](){}]/y; - E = /(\x23?)(?=[$_\p{ID_Start}\\])(?:[$_\u200C\u200D\p{ID_Continue}]+|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+/yu; - B = /(['"])(?:[^'"\\\n\r]+|(?!\1)['"]|\\(?:\r\n|[^]))*(\1)?/y; - j = /(?:0[xX][\da-fA-F](?:_?[\da-fA-F])*|0[oO][0-7](?:_?[0-7])*|0[bB][01](?:_?[01])*)n?|0n|[1-9](?:_?\d)*n|(?:(?:0(?!\d)|0\d*[89]\d*|[1-9](?:_?\d)*)(?:\.(?:\d(?:_?\d)*)?)?|\.\d(?:_?\d)*)(?:[eE][+-]?\d(?:_?\d)*)?|0[0-7]+/y; - v2 = /[`}](?:[^`\\$]+|\\[^]|\$(?!\{))*(`|\$\{)?/y; - W = /[\t\v\f\ufeff\p{Zs}]+/yu; - w2 = /\r?\n|[\r\u2028\u2029]/y; - C2 = /\/\*(?:[^*]+|\*(?!\/))*(\*\/)?/y; - q2 = /\/\/.*/y; - ee = /^#!.*/; - J = /[<>.:={}]|\/(?![\/*])/y; - $2 = /[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}-]*/yu; - P = /(['"])(?:[^'"]+|(?!\1)['"])*(\1)?/y; - X = /[^<>{}]+/y; - O = /^(?:[\/+-]|\.{3}|\?(?:InterpolationIn(?:JSX|Template)|NoLineTerminatorHere|NonExpressionParenEnd|UnaryIncDec))?$|[{}([,;<>=*%&|^!~?:]$/; - ne = /^(?:=>|[;\]){}]|else|\?(?:NoLineTerminatorHere|NonExpressionParenEnd))?$/; - L = /^(?:await|case|default|delete|do|else|instanceof|new|return|throw|typeof|void|yield)$/; - R = /^(?:return|throw|yield)$/; - te = RegExp(w2.source); - ie.exports = function* (e, { jsx: t2 = false } = {}) { - var a, s2, o2, i, r2, u, n, g2, _, f, x, p, y, d; - for ({ length: u } = e, i = 0, r2 = "", d = [{ tag: "JS" }], a = [], x = 0, p = false, (n = ee.exec(e)) && (yield { type: "HashbangComment", value: n[0] }, i = n[0].length); i < u; ) { - switch (g2 = d[d.length - 1], g2.tag) { - case "JS": - case "JSNonExpressionParen": - case "InterpolationInTemplate": - case "InterpolationInJSX": - if (e[i] === "/" && (O.test(r2) || L.test(r2)) && (z.lastIndex = i, n = z.exec(e))) { - i = z.lastIndex, r2 = n[0], p = true, yield { type: "RegularExpressionLiteral", value: n[0], closed: n[1] !== void 0 && n[1] !== "\\" }; - continue; - } - if (k.lastIndex = i, n = k.exec(e)) { - switch (y = n[0], _ = k.lastIndex, f = y, y) { - case "(": - r2 === "?NonExpressionParenKeyword" && d.push({ tag: "JSNonExpressionParen", nesting: x }), x++, p = false; - break; - case ")": - x--, p = true, g2.tag === "JSNonExpressionParen" && x === g2.nesting && (d.pop(), f = "?NonExpressionParenEnd", p = false); - break; - case "{": - k.lastIndex = 0, o2 = !ne.test(r2) && (O.test(r2) || L.test(r2)), a.push(o2), p = false; - break; - case "}": - switch (g2.tag) { - case "InterpolationInTemplate": - if (a.length === g2.nesting) { - v2.lastIndex = i, n = v2.exec(e), i = v2.lastIndex, r2 = n[0], n[1] === "${" ? (r2 = "?InterpolationInTemplate", p = false, yield { type: "TemplateMiddle", value: n[0] }) : (d.pop(), p = true, yield { type: "TemplateTail", value: n[0], closed: n[1] === "`" }); - continue; - } - break; - case "InterpolationInJSX": - if (a.length === g2.nesting) { - d.pop(), i += 1, r2 = "}", yield { type: "JSXPunctuator", value: "}" }; - continue; - } - } - p = a.pop(), f = p ? "?ExpressionBraceEnd" : "}"; - break; - case "]": - p = true; - break; - case "++": - case "--": - f = p ? "?PostfixIncDec" : "?UnaryIncDec"; - break; - case "<": - if (t2 && (O.test(r2) || L.test(r2))) { - d.push({ tag: "JSXTag" }), i += 1, r2 = "<", yield { type: "JSXPunctuator", value: y }; - continue; - } - p = false; - break; - default: - p = false; - } - i = _, r2 = f, yield { type: "Punctuator", value: y }; - continue; - } - if (E.lastIndex = i, n = E.exec(e)) { - switch (i = E.lastIndex, f = n[0], n[0]) { - case "for": - case "if": - case "while": - case "with": - r2 !== "." && r2 !== "?." && (f = "?NonExpressionParenKeyword"); - } - r2 = f, p = !L.test(n[0]), yield { type: n[1] === "#" ? "PrivateIdentifier" : "IdentifierName", value: n[0] }; - continue; - } - if (B.lastIndex = i, n = B.exec(e)) { - i = B.lastIndex, r2 = n[0], p = true, yield { type: "StringLiteral", value: n[0], closed: n[2] !== void 0 }; - continue; - } - if (j.lastIndex = i, n = j.exec(e)) { - i = j.lastIndex, r2 = n[0], p = true, yield { type: "NumericLiteral", value: n[0] }; - continue; - } - if (v2.lastIndex = i, n = v2.exec(e)) { - i = v2.lastIndex, r2 = n[0], n[1] === "${" ? (r2 = "?InterpolationInTemplate", d.push({ tag: "InterpolationInTemplate", nesting: a.length }), p = false, yield { type: "TemplateHead", value: n[0] }) : (p = true, yield { type: "NoSubstitutionTemplate", value: n[0], closed: n[1] === "`" }); - continue; - } - break; - case "JSXTag": - case "JSXTagEnd": - if (J.lastIndex = i, n = J.exec(e)) { - switch (i = J.lastIndex, f = n[0], n[0]) { - case "<": - d.push({ tag: "JSXTag" }); - break; - case ">": - d.pop(), r2 === "/" || g2.tag === "JSXTagEnd" ? (f = "?JSX", p = true) : d.push({ tag: "JSXChildren" }); - break; - case "{": - d.push({ tag: "InterpolationInJSX", nesting: a.length }), f = "?InterpolationInJSX", p = false; - break; - case "/": - r2 === "<" && (d.pop(), d[d.length - 1].tag === "JSXChildren" && d.pop(), d.push({ tag: "JSXTagEnd" })); - } - r2 = f, yield { type: "JSXPunctuator", value: n[0] }; - continue; - } - if ($2.lastIndex = i, n = $2.exec(e)) { - i = $2.lastIndex, r2 = n[0], yield { type: "JSXIdentifier", value: n[0] }; - continue; - } - if (P.lastIndex = i, n = P.exec(e)) { - i = P.lastIndex, r2 = n[0], yield { type: "JSXString", value: n[0], closed: n[2] !== void 0 }; - continue; - } - break; - case "JSXChildren": - if (X.lastIndex = i, n = X.exec(e)) { - i = X.lastIndex, r2 = n[0], yield { type: "JSXText", value: n[0] }; - continue; - } - switch (e[i]) { - case "<": - d.push({ tag: "JSXTag" }), i++, r2 = "<", yield { type: "JSXPunctuator", value: "<" }; - continue; - case "{": - d.push({ tag: "InterpolationInJSX", nesting: a.length }), i++, r2 = "?InterpolationInJSX", p = false, yield { type: "JSXPunctuator", value: "{" }; - continue; - } - } - if (W.lastIndex = i, n = W.exec(e)) { - i = W.lastIndex, yield { type: "WhiteSpace", value: n[0] }; - continue; - } - if (w2.lastIndex = i, n = w2.exec(e)) { - i = w2.lastIndex, p = false, R.test(r2) && (r2 = "?NoLineTerminatorHere"), yield { type: "LineTerminatorSequence", value: n[0] }; - continue; - } - if (C2.lastIndex = i, n = C2.exec(e)) { - i = C2.lastIndex, te.test(n[0]) && (p = false, R.test(r2) && (r2 = "?NoLineTerminatorHere")), yield { type: "MultiLineComment", value: n[0], closed: n[1] !== void 0 }; - continue; - } - if (q2.lastIndex = i, n = q2.exec(e)) { - i = q2.lastIndex, p = false, yield { type: "SingleLineComment", value: n[0] }; - continue; - } - s2 = String.fromCodePoint(e.codePointAt(i)), i += s2.length, r2 = s2, p = false, yield { type: g2.tag.startsWith("JSX") ? "JSXInvalid" : "Invalid", value: s2 }; - } - }; -}); -var I = /\r\n|[\n\r\u2028\u2029]/; -var G = /^[()[\]{}]$/; -var Z = /\(line \d+\):/; -var Q = /* @__PURE__ */ new Set(["as", "async", "from", "get", "of", "set"]); -var Y = /* @__PURE__ */ new Set(["implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"]); -var M = /* @__PURE__ */ new Set(["console", "break", "constructor", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete"]); -var oe = Se(re()); -function ke(e, t2) { - return t2 && e === "await" || e === "enum" || Y.has(e); -} -var ae = function(e) { - if (e.type === "IdentifierName") { - if (M.has(e.value) || ke(e.value, true) || Q.has(e.value)) return "keyword"; - if (e.value[0] !== e.value[0].toLowerCase()) return "capitalized"; - } - if (e.type === "Punctuator" && G.test(e.value)) return "uncolored"; - if (e.type === "Invalid" && e.value === "@") return "punctuator"; - switch (e.type) { - case "NumericLiteral": - return "number"; - case "StringLiteral": - case "JSXString": - case "NoSubstitutionTemplate": - return "string"; - case "RegularExpressionLiteral": - return "regex"; - case "Punctuator": - case "JSXPunctuator": - return "punctuator"; - case "MultiLineComment": - case "SingleLineComment": - return "comment"; - case "Invalid": - case "JSXInvalid": - return "invalid"; - case "JSXIdentifier": - return "jsx_identifier"; - default: - return "uncolored"; - } -}; -function we(e) { - let t2 = Array.from((0, oe.default)(e, { jsx: true })), a = [], s2 = /* @__PURE__ */ new Set(), o2 = 0, i = false; - for (let r2 = 0, u = t2.length; r2 < u; r2++) { - let n = t2[r2]; - if (n.type === "RegularExpressionLiteral" && s2.has(n.value)) { - let g2 = n.value[0], _ = n.value.slice(1, -1), f = n.value[n.value.length - 1]; - a.push({ type: "punctuator", value: g2 }), a.push({ type: "jsx_element", value: _ }), a.push({ type: "punctuator", value: f }); - } else n.type === "TemplateHead" ? (a.push({ type: "string", value: n.value.slice(0, -2) }), a.push({ type: "punctuator", value: "${" })) : n.type === "TemplateMiddle" ? (a.push({ type: "punctuator", value: "}" }), a.push({ type: "string", value: n.value.slice(1, -2) }), a.push({ type: "punctuator", value: "${" })) : n.type === "TemplateTail" ? (a.push({ type: "punctuator", value: "}" }), a.push({ type: "string", value: n.value.slice(1) })) : i ? (n.value === "}" || n.value === "%") && t2[r2 + 1].value === "}" ? (i = false, a.push({ type: "liquid", value: n.value }), a.push({ type: "liquid", value: t2[r2 + 1].value }), r2 = r2 + 1) : a.push({ type: "liquid", value: n.value }) : n.type === "JSXIdentifier" ? t2[r2 - 1].value === "<" ? (a.push({ type: "jsx_element", value: n.value }), s2.add(`/${n.value}>`)) : r2 >= 2 && t2[r2 - 2].value === "<" && t2[r2 - 1].value === "/" ? a.push({ type: "jsx_element", value: n.value }) : a.push({ type: ae(n), value: n.value }) : n.value === "{" && (t2[r2 + 1].value === "{" || t2[r2 + 1].value === "%") ? (i = true, a.push({ type: "liquid", value: "{" }), a.push({ type: "liquid", value: t2[r2 + 1].value }), r2 = r2 + 1) : u >= r2 + 2 && n.type === "Punctuator" && n.value === "." && t2[r2 + 1].type === "IdentifierName" && t2[r2 + 2].type === "Punctuator" && t2[r2 + 2].value === "(" ? (a.push({ type: "punctuator", value: n.value }, { type: "function", value: t2[r2 + 1].value }, { type: "punctuator", value: "(" }), o2 = o2 + 1, r2 = r2 + 2) : n.type === "Punctuator" && n.value === ")" && o2 > 0 ? (o2 = o2 - 1, a.push({ type: "punctuator", value: n.value })) : a.push({ type: ae(n), value: n.value }); - } - return a; -} -function se(e, t2) { - if (e === "") return ""; - let a = Te(t2), s2 = we(e), o2 = ""; - for (let { type: i, value: r2 } of s2) i in a ? o2 += g.nl(r2.split(I).map(a[i])) : o2 += r2; - return o2; -} -function Te(e) { - return e === "json" ? { keyword: neonCyan, capitalized: greenBright2, liquid_open: gray2, liquid_close: gray2, jsx_element: neonRouge, jsx_attribute: pink, jsx_identifier: teal, punctuator: neonRouge, function: greenBright2, number: yellowBright2, string: neonCyan, regex: neonTeal, comment: gray2, invalid: red2.bold, reset: reset2 } : { keyword: neonCyan, capitalized: greenBright2, liquid_open: gray2, liquid_close: gray2, jsx_element: neonRouge, jsx_attribute: pink, jsx_identifier: teal, punctuator: e === "markup" ? lavender : gray2, function: greenBright2, number: neonMagenta, string: yellowBright2, regex: neonTeal, comment: gray2, invalid: red2.bold, reset: reset2 }; -} -function Ne(e, t2, a) { - let s2 = { column: 0, line: -1, ...e.start }, o2 = { ...s2, ...e.end }, { linesAbove: i = 2, linesBelow: r2 = 3 } = a || {}, u = s2.line, n = s2.column, g2 = o2.line, _ = o2.column, f = Math.max(u - (i + 1), 0), x = Math.min(t2.length, g2 + r2); - u === -1 && (f = 0), g2 === -1 && (x = t2.length); - let p = g2 - u, y = {}; - if (p) for (let d = 0; d <= p; d++) { - let h = d + u; - if (!n) y[h] = true; - else if (d === 0) { - let S = t2[h - 1].length; - y[h] = [n, S - n + 1]; - } else if (d === p) y[h] = [0, _]; - else { - let S = t2[h - d].length; - y[h] = [0, S]; - } - } - else n === _ ? y[u] = n ? [n, 0] : true : y[u] = [n, _ - n]; - return { start: f, end: x, markerLines: y }; -} -function le(e, t2, a) { - let s2 = e.split(I), { start: o2, end: i, markerLines: r2 } = Ne(t2, s2, a), u = String(i).length, n = a.highlight ? se(e, a.language) : e, g2 = a.type === "error" ? Tree.red : a.type === "warning" ? Tree.yellow : Tree.line, _ = a.type === "error" ? Tree.redTrim : a.type === "warning" ? Tree.yellowTrim : Tree.trim, f = n.split(I, i).slice(o2, i).map((x, p) => { - let y = o2 + 1 + p, d = ` ${y}`.slice(-u), h = r2[y]; - if (h) { - let S = ` ${redBright2(d)} ${Tree.trim}`, H = ""; - if (Array.isArray(h)) { - let me = x.slice(0, Math.max(h[0] - 1, 0)).replace(/[^\t]/g, WSP2), ge = h[1] || 1; - H = g(NWL2, g2, WSP2.repeat(d.length), BAD, WSP2, Tree.trim, WSP2, me, redBright2("^").repeat(ge)); - } - return g(redBright2("\u27A4"), S, x.length > 0 ? ` ${x}` : "", H); - } else return g(WSR2, blueBright2(d), WSP2, Tree.trim, x.length > 0 ? ` ${x}` : ""); - }); - return g.nl(f.map((x) => _ + WSP2 + x)) + NWL2; -} -var ue = (e) => e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); -function N(e, t2) { - if (!e || t2 < 1) return { lineNumber: -1, lineStart: -1, nextLineNumber: -1, nextLineStart: -1 }; - let a = (e.match(/\n/g) || []).length + 1; - if (t2 > a) return { lineNumber: -1, lineStart: -1, nextLineNumber: -1, nextLineStart: -1 }; - let s2 = 0, o2 = 1, i = 0; - for (; o2 < t2 && i < e.length && (i = e.indexOf(` -`, i), i !== -1); ) s2 = i + 1, i++, o2++; - if (o2 < t2) return { lineNumber: -1, lineStart: -1, nextLineNumber: -1, nextLineStart: -1 }; - let r2 = t2, u = e.indexOf(` -`, s2); - return u === -1 ? u = e.length : u++, t2 < a && r2++, { lineNumber: t2, lineStart: s2, nextLineNumber: r2, nextLineStart: u }; -} -function Ee(e, t2, a) { - let s2 = N(e, t2); - if (s2.lineStart < 0 && s2.nextLineStart < 0) return null; - let o2 = e.slice(s2.lineStart), i = o2.match(a), r2 = s2.lineStart; - if (!i) { - let h = t2; - for (; h > 1 && !i; ) if (h--, s2 = N(e, h), o2 = e.slice(s2.lineStart), i = o2.match(a), i && i.index >= 0) { - r2 = s2.lineStart; - break; - } - if (!i) return s2; - } - let u = i[0], n = i.index, g2 = r2 + n, _ = g2 + u.length, f = (u.match(/\n/g) || []).length; - if (f === 0) return { lineNumber: t2, lineStart: g2, nextLineNumber: t2, nextLineStart: _, token: u }; - let p = (e.slice(0, g2).match(/\n/g) || []).length + 1, y = p + f; - return { lineNumber: p, lineStart: g2, nextLineNumber: y, nextLineStart: _, token: u }; -} -function T(e, t2, a) { - let s2 = e instanceof RegExp ? Ee(t2, a, e) : N(t2, a); - if (!s2 || s2.lineStart < 0 && s2.nextLineStart < 0) return null; - let o2 = typeof e == "string" ? e : s2.token; - if (!o2) { - let _ = t2.slice(s2.lineStart, s2.nextLineStart); - return { token: _, range: { start: { line: s2.lineNumber, column: 1 }, ender: { line: s2.nextLineNumber, column: _.length || 1 } } }; - } - let i = N(t2, s2.lineNumber).lineStart, r2 = s2.lineStart >= i ? s2.lineStart - i + 1 : s2.lineStart - N(t2, s2.lineNumber - 1).lineStart + 1; - if (r2 <= 0) { - let _ = t2.slice(s2.lineStart, s2.nextLineStart); - return { token: _, range: { start: { line: s2.lineNumber, column: 1 }, ender: { line: s2.nextLineNumber, column: _.length || 1 } } }; - } - let u = o2.includes(` -`) ? s2.nextLineNumber : s2.lineNumber, n; - if (o2.includes(` -`)) { - let _ = o2.lastIndexOf(` -`); - n = o2.slice(_ + 1).length; - } else n = r2 + o2.length; - let g2 = { start: { line: s2.lineNumber, column: r2 }, ender: { line: u, column: n } }; - return { token: o2, range: g2 }; -} -function ce(e, t2, a) { - for (let o2 of [/^Syntax Error in '([a-z_]+)(?:\s[a-z]+)?'/i, /^Syntax Error in tag '([a-z_]+)(?:\s[a-z]+)?'/i, /^Syntax Error in tag '(#)'/i, /^in tag '([a-z_]+)(?:\s[a-z]+)?'/i, /^'([a-z_]+)' is not a valid delimiter for (?:[a-z_]+) tags\. use/i, /^Error in tag '([a-z_]+)(?:\s[a-z]+)?'/i, /^'?([a-z_]+)'? tag was never closed/i, /^(For) loops require an 'in' clause/i, /^Invalid attribute in (for) loop. Valid attributes are limit and offset/i, /^'?[a-z]+'? is not a valid delimiter for '?([a-z_]+)'? tags/i, /^Unexpected outer '{%-?\s*([a-z_]+)/i, /^Unknown tag '([a-z_]+)/i, /^Tag '{%-?\s*([a-z_]+)/i]) { - let i = t2.trimStart().match(o2); - if (i === null) continue; - let u = i[1].toLowerCase().replace(/_/g, ""), n = new RegExp(`{%-?\\s*${u}[\\s\\S]*?%}`); - return T(n, e, a); - } - for (let o2 of [/^Variable '(.*?)' was not properly terminated with regexp/i, /^\[:[a-z_]+, ".+"\] is not a valid expression in "({{.*?}})/i, /^Expected (?:[a-z_]+) but found (?:.*?) in "(.*?)"/i, /^Tag '({{.*?}})/i]) { - let i = t2.trimStart().match(o2); - if (i === null) continue; - let r2 = new RegExp(ue(i[1])); - return T(r2, e, a); - } - for (let o2 of [/^Unexpected character (?:.+?) in "([\S\s]+)/i]) { - let i = t2.trimStart().match(o2); - if (i !== null) if (/\n/.test(i[2])) { - let r2 = ue(i[2].slice(0, i.indexOf(` -`))); - return T(r2, e, a); - } else return T(i[2], e, a); - } - let s2 = t2.trimStart().match(/({{[\s\S]*?}}|{%[\s\S]*?%})/); - return s2 !== null ? T(s2[1], e, a) : null; -} -function V(e) { - let t2 = e; - for (let [a, s2] of [[/- Valid syntax: (.*?)/i, Ce], [/'(.*?)' is not a valid delimiter for/, $e], [/^For loops require an 'in' clause/, Je], [/Unexpected character (.*?) in "/, Pe], [/was not properly terminated with regexp:/, Xe], [/\[:([a-z_]+), "(.+)"\] is not a valid expression/, je]]) a.test(t2) && (t2 = s2(t2)); - return t2; -} -function $e(e) { - let t2 = e.match(/'(.*?)' is not a valid delimiter for ([a-z_]+) tags\. use ([a-z_]+)/i); - return t2 === null ? e : g.ws(`Unterminated "${t2[2]}" tag due to an "${t2[1]}" tag name. This is not a valid ender,`, `you need to use: "${t2[3]}"`); -} -function Je() { - return 'The "for" loop tag requires an "in" clause operator be provided.'; -} -function Pe(e) { - let t2 = e.match(/Unexpected character (\S+) in "([\S\s]*)/i); - return t2 === null ? e : /\n/.test(t2[2]) ? `Unexpected character occurrence "${t2[1]}" detected` : `Unexpected character occurrence "${t2[1]}" detected in "${t2[2]}"`; -} -function Xe(e) { - return /(regexp: )((?:\/\\}|\\}\/)|(?:\/\\\$|\\}\/))/.test(e) ? e.replace(/(')(.*?)(')/, '"$2"').replace(/regexp: /, "closing delimiter token: ").replace(/[/\\]+/g, NIL2) : e; -} -function D(e) { - return /\(line (\d+)\):/.test(e) ? e.replace(/\(line (\d+)\):/, "on line $1") : e; -} -function Ce(e) { - let t2 = /^in tag '([a-z_]+)(?:\s[a-z]+)?'/, a = e.match(t2), s2 = a !== null ? `Invalid "${a[1]}" tag,` : "An invalid or incomplete expression provided"; - if (e.match(/- Valid syntax: (.*?)/i) === null) return a !== null ? e.replace(t2, s2) : e; - let r2 = e.slice(e.indexOf("- Valid syntax:") + 15).trim().replace(/[[\]]/g, ""); - return g.ws(`${s2} likely due to a missing operator or keyword.`, `Expected syntax: {% ${r2} %}`); -} -function je(e) { - let t2 = e.match(/\[:([a-z_]+), "(.+)"\] is not a valid expression in "({{.*?}})"/i); - return t2 === null ? e : g.ws(`Invalid "${bold2(t2[2])}" (${t2[1].replace(/_/g, WSP2)}) placement detected in liquid expression.`, `This is not a valid output tag: ${t2[3]}`); -} -function ze(e) { - return capture.stream(e)((t2) => capture(/(<\/?|>)/g, t2, gray2), (t2) => capture.quoted(t2, bold2), (t2) => capture.colons(t2, gray2), (t2) => capture.pipes(t2, gray2), (t2) => capture.url(t2, gray2), (t2) => t2.replace(/(?<=Filename\s)([\w._-]+)(?=\salready)/, neonCyan.bold("$1")), (t2) => t2.replace(/({[{%]-?)([\s\S]*?)(-?%}})/g, (a, s2, o2, i) => { - let r2 = capture.stream(strip(o2))((u) => capture.quoted(u, magentaBright2), (u) => capture.colons(u, gray2), (u) => capture.pipes(u, gray2), (u) => u.replace(/(?<=\s)(=|==|!=|>=|>|<|<=|in)(?=\s)/g, blueBright2("$1")), (u) => u.replace(/^\s*([a-z]+)(?=\s)/g, WSP2 + neonTeal("$1")), (u) => capture(/(\d+)/g, u, pink)); - return capture.dash(neonCyan(s2), gray2) + r2 + capture.dash(neonCyan(i), gray2); - })); -} -function qe(e, t2) { - let a = NIL2, s2 = NIL2, o2 = NIL2; - return t2.indexOf("- Valid syntax:") > -1 ? (s2 = D(e.replace(/(Syntax Error)/, "Syntax error")), a = V(t2.trim()), o2 = g(bold2(s2), COL, NLR2, capture.stream(a)((r2) => capture.colons(r2, gray2)))) : (s2 = D(e), a = V(t2.trim()), o2 = g(bold2(s2), COL, NLR2, a)), { summary: s2, details: a, message: o2 }; -} -function de(e, t2, a = {}) { - let s2 = { type: "error", language: "liquid", highlight: true, linesAbove: 2, linesBelow: 2, ...a }, o2 = {}; - if (Z.test(t2)) { - let i = t2.indexOf("(line") + 6, r2 = t2.indexOf("):"), u = Number(t2.slice(i, r2)), n = r2 + 2, g2 = t2.slice(n), { summary: _, details: f, message: x } = qe(t2.slice(0, n), t2.slice(n)); - o2.line = u, o2.summary = _, o2.details = f, o2.message = Wrap(ze(x), { color: redBright2 }); - let p = ce(e, g2, u); - p !== null ? (o2.hasFrame = true, o2.column = p.range.start.column, o2.frame = U(e, { start: p.range.start, language: "liquid", end: p.range.ender, ...s2 })) : (o2.hasFrame = false, o2.column = 0, o2.frame = null); - } else o2.hasFrame = false, o2.summary = NIL2, o2.details = NIL2, o2.message = Wrap(t2, { color: redBright2, line: Tree.red }) + NWL2, o2.line = NaN, o2.column = NaN, o2.frame = null; - return o2; -} -function U(e, t2) { - return le(e, { start: t2.start, end: t2.end }, { language: "javascript", type: "error", highlight: true, linesAbove: 2, linesBelow: 2, ...t2 }); -} -U.shopify = de; - -// syncify/cli/errors.ts -function error(...message) { - forEach((line) => stderr2.write(line), message); -} -error.upsert = (failed) => { - const isWatch = $.mode.bulk || $.mode.push; - const record = {}; - const errors = []; - const write2 = Create({ type: "error" }); - for (const { code, file, message, summary, graph: graph2 } of failed) { - const index = file.key in record ? record[file.key] : null; - if (index === null) { - record[file.key] = errors.length; - errors.push({ code, file, summary, graph: graph2, messages: [message] }); - } else { - errors[index].messages.push(message); - } - } - let notifier3 = isWatch; - let heading = ""; - let context; - for (const { code, file, messages: messages2, summary, graph: graph2 } of errors) { - heading = ""; - const issue = $.errors.has(file) ? $.errors.get(file) : $.errors.set(file, []).get(file); - for (const message of messages2) { - const cf = U.shopify(file.value, message); - if (cf.hasFrame) { - isWatch ? write2.Header(cf.summary, red2.bold) : write2.Prepend(cf.summary, red2.bold); - write2.Wrap(cf.details, redBright2).NL.Insert(cf.frame, gray2).Context({ - entries: { - line: cf.line, - column: cf.column, - input: file.input, - output: file.output, - code: neonMagenta(code), - graph: pink(graph2) - } - }); - if (notifier3 === false) { - notifier3 = true; - log.error(file.relative, { - notify: { - title: `Error in ${file.key}`, - message: cf.summary - } - }); - } - if (issue.length === 1) { - write2.NL.Unshift(`Type ${bold2("i")} and press ${bold2("enter")} to view all file erros`, gray2); - } - write2.toString((message2) => issue.push(message2)); - } else { - context = { - entries: { - input: file.input, - output: file.output, - namespace: file.namespace, - code: neonMagenta(code), - graph: pink(graph2) - } - }; - if (notifier3 === false) { - notifier3 = true; - log.error(`${failed.length} ${plur("error", failed.length)} detected`, { - notify: { - title: "Request Failed", - message: `Rejected by Shopify with ${failed.length} ${plur("Error", failed.length)}` - } - }); - } - if (heading === summary) { - write2.Insert(cf.message, gray2); - } else { - if (heading !== "") { - write2.Context(context).NL.toString(issue.push); - } - heading = summary; - write2.Header(summary, bold2).Insert(cf.message, gray2); - } - } - } - if (heading !== "") { - issue.push( - write2.Context(context).NL.toString() - ); - } - if (write2.isEmpty) issue.push(write2.toString()); - } - if (isWatch === false) { - for (const [file, messages2] of $.errors) { - error(messages2.shift()); - if (messages2.length > 0) $.errors.delete(file); - break; - } - } -}; -error.graph = (e) => { - const count = e.errors.length; - const write2 = Create({ type: "error" }).Header(`${count} GRAPHQL ${plur("ERROR", count)}`, bold2.redBright); - for (const item of e.errors) { - write2.Wrap(item.message.replace(/(\s+'.*?'\s*)/g, bold2("$1"))); - if (has("path", item)) { - write2.Newline(); - let indent = ""; - const max = item.path.length - 1; - item.path.forEach((path5, i) => { - if (i !== 0) indent += " "; - if (max !== i) { - write2.Line(`${indent}${path5} ${gray2("{")}`, yellow2); - } else { - write2.Line(`${indent}${path5}`, red2.bold); - indent = indent.slice(2); - } - }); - item.path.forEach((path5, i) => { - if (max !== i) { - write2.Line(`${indent}${gray2("}")}`); - indent = indent.slice(2); - } - }); - } - write2.Newline(); - } - write2.Context({ - entries: { - target: e.target.target, - domain: e.target.store.domain, - graph: neonMagenta(e.graph) - } - }); - write2.NL.End($.log.group).Break().toLog(); - kill.exit(0); -}; -error.request = (e) => { - if ($.running) { - log.spinner.stop(); - } else { - log.error("Request failed", { - suffix: e.graph, - notify: { - message: `An error was thrown when attempting to interface with ${e.target.store.domain} store.` - } - }); - } - if (e instanceof TypeError) { - Create({ type: "error" }).Header("TYPE ERROR", bold2.redBright).Wrap(e.message).Context({ - stack: e.stack, - cleanStack: true, - entries: { - name: e.name, - graph: e.graph, - detail: "POSSIBLY INTERNAL" - } - }).NL.End($.log.group).Break().toLog(); - kill.exit(0); - } else if (e.isGraphError) { - return error.graph(e); - } else if (e.isGraphError) { - Create({ type: "error" }).Header("REQUEST ERROR", bold2.redBright).Wrap(e.message).Context({ - entries: { - cause: e.cause, - status: e.response.status, - graph: e.name - } - }).NL.toLog({ clear: true }); - } -}; -error.toml = (file, e) => { - if (e instanceof $import.toml.TomlError) { - const context = { - entries: { - location: `${e.line}${COL}${e.column}`, - input: file, - cause: e.cause, - processor: neonMagenta("TOML") - } - }; - const code = e.codeblock.replace(/\[/g, magenta2("[")).replace(/=/g, magentaBright2("=")).replace(/("[\s\S]*")/g, yellowBright2("$1")).replace(/(\d+)(:)/g, `${blue2("$1")} ${Tree.line}`).replace(/(\^)/, "$1 " + Tree.line); - Create({ type: "error" }).Append(`TOML Error on Line ${e.line}`, bold2).Wrap(e.message.replace(e.codeblock, "").trim()).NL.Wrap(code).NL.Context(context).NL.toLog({ clear: true }); - } -}; -error.throw = (e, entries) => { - const context = { - stack: false, - entries: { ...entries } - }; - const message = e.message.replace(/(OnlineStoreThemeFileReadResult)/, bold2("$1")); - if (has("stack", e)) context.stack = e.stack; - if (has("code", e)) context.entries.code = e.code; - if (has("name", e)) context.entries.name = e.name; - const tui = Create({ type: "error" }); - if (context.stack === false) { - error(tui.Wrap(message, redBright2).Context(context).toString()); - kill.exit(0); - } else { - $.stacks.add(tui.Wrap(message).Context(context).toString()); - } -}; -error.write = (message, context) => (e) => { - Create({ type: "error" }).NL.Wrap(e.message).Context({ stack: e.stack, entries: { ...context, code: e.code, name: e.name, details: message } }).NL.toLog({ clear: true }); -}; -error.read = (details, entries) => { - return function(e) { - Create({ type: "error" }).Header("FILE ERROR").Wrap(e.message).NL.Context({ - stack: e.stack, - entries: { - code: e.code, - details, - ...entries, - name: e.name - } - }).toLog({ clear: true }); - }; -}; -error.json = (err, file, ...contexts) => { - let details = "JSON Parse Error"; - let lineOffset = 0; - let message; - if (contexts.length > 0) { - if (typeof contexts[0] === "string") details = contexts[0]; - if (typeof contexts[0] === "number") lineOffset = contexts[0]; - if (contexts.length > 1) { - if (typeof contexts[1] === "string") details = contexts[1]; - if (typeof contexts[1] === "number") lineOffset = contexts[1]; - } - } - const frame = U(err.source, { - language: "json", - start: { - line: err.line + lineOffset, - column: err.column - } - }); - if (lineOffset > 0) { - message = err.message.replace(/(line number:?|line:?) (\d+)/i, `$1 ${err.line + lineOffset}`).replace(/Line \d+:\s+/, ""); - } else { - message = err.message.replace(/Line \d+:\s+/, ""); - } - Create({ type: "error" }).Prepend(details, bold2).Wrap(capture.numbers(message, bold2), redBright2).NL.Insert(frame).Context({ - entries: { - line: err.line + lineOffset, - column: err.column, - input: isString(file) ? path2.relative($.cwd, file) : file.relative, - processor: neonMagenta("JSON") - } - }).toLog({ clear: true }); -}; -error.sass = (file, e) => { - const entries = {}; - const write2 = Create({ type: "error" }).NL.Wrap(e.sassMessage, red2.bold).Newline(); - const { span } = e; - const source = node_fs.readFileSync(span.url.pathname, "utf8"); - const frame = U(source, { - start: { - line: span.start.line + 1, - column: span.start.column - } - }); - write2.Insert(frame); - const uri = TLD + path2.relative($.cwd, span.url.pathname); - entries.line = span.start.line + 1; - entries.column = span.start.column; - entries.input = TLD + file.relative; - if (entries.input !== uri) entries.source = uri; - if (/\/node_modules\//.test(span.url.pathname)) { - entries.module = pink(span.url.pathname.match(/(?:.*?\/node_modules\/)((?:@[^/]+\/)?[^/]+)/)[1]); - } - entries.cause = e.cause; - entries.processor = neonMagenta("SASS Dart"); - write2.NL.Context({ entries }).toLog(); -}; -error.terser = (file, e) => { - Create({ type: "error" }).Header("Terse minification error").Wrap(e.message, red2.bold).NL.Context({ - entries: { - input: file.input, - cause: e.cause, - processor: neonMagenta("html-minifier-terser") - } - }).NL.toLog(); -}; -error.esbuild = (file, errors) => { - if (errors.length === 0) return; - const { length } = errors; - const multiple = length > 1; - const isSyncifyConfig = file.type === 20 /* Syncify */; - if (!isSyncifyConfig) { - log.error(file.relative, { - suffix: "transform failed", - notify: { - title: `${length} ${file.kind} ${plur("Error", length)}`, - message: `${file.key || file.base}` - } - }); - } - if (errors.length > 1) log.nl("red"); - file.value = node_fs.readFileSync(file.input, "utf8"); - const issues = errors.map(({ - location, - text, - pluginName - }, no) => { - const write2 = Create({ type: "error" }).Template({ id: "errors" }).True(multiple, (tui) => tui.Update("errors", `${bold2("ERROR")} ${bold2(no + 1)} of ${bold2(length)}`)).Header(multiple ? white2(file.input) : bold2.redBright(`${file.kind} Error`)); - if (location === null) { - const context = { entries: {} }; - if (pluginName === "acquire") { - context.entries.internal = "@syncify/acquire"; - } else { - context.entries.plugin = pluginName; - } - context.entries.namespace = file.namespace; - context.entries.processor = neonMagenta("ESBuild"); - if (/Require stack:\n/.test(text)) { - text = text.replace(/Require stack:\n/, "\nRequire stack:\n"); - } - write2.Wrap(text, redBright2).NL.Context(context).Newline(); - } else { - const frame = U(file.value, { - language: "javascript", - highlight: true, - start: { - line: location.line, - column: location.column - } - }); - write2.Wrap(`${text} on line ${location.line}`, redBright2).NL.Insert(frame).Context({ - entries: { - line: location.line, - column: location.column, - file: location.file, - plugin: pluginName, - namespace: location.namespace, - processor: neonMagenta("ESBuild") - } - }); - } - if (multiple) { - write2.Mark("legend").Tree("info").NL.Dash(stdin.ansi.legend.e, gray2).NL.End(stdin.ansi.footer, false); - } - return write2; - }); - if (isSyncifyConfig) { - issues.forEach((message) => message.Newline().End("Error").toLog({ clear: true })); - kill.exit(0); - } else if (issues.length > 1) { - stdin.errors.listen(issues); - } else { - issues[0].toLog({ clear: true }); - } -}; -error.postcss = (file, e) => { - const stack = []; - const trace = cleanStack(e.stack, { pretty: true, basePath: $.cwd }).split("\n"); - while (trace.length !== 0) stack.push(Tree.red + trace.shift()); - $.stacks.add(stack.join("\n")); - ({ - entries: { - line: e.line, - column: e.column, - source: file.input, - file: file.input === e.file ? void 0 : e.file, - plugin: blue2(e.plugin), - processor: neonMagenta("PostCSS") - } - }); - Create({ type: "error" }).NL.Wrap(`${e.name}${COL} ${e.reason}`, red2.bold).NL.Wrap(e.details).toLog(); -}; -error.acquire = (e) => { - Create({ type: "error" }).Append(e.type.toUpperCase(), bold2.red).True(e.summary, (tui) => tui.Header(e.summary, bold2.red)).Wrap(e.message, redBright2).Context({ entries: { ...e.context } }).Tree("info").NL.End("Error").Break().toLog({ clear: true }); - kill.exit(1); -}; - -// syncify/cli/throws.ts -var warnings = o(); -var severities = o(); -function warnOption(group) { - if (!has(group, warnings)) warnings[group] = []; - return (message, value) => { - if (isUndefined(value)) { - warnings[group].push(yellowBright2(message)); - } else { - warnings[group].push(yellowBright2(message + COL + " " + bold2(value))); - } - }; -} -function warnSevere(group) { - if (!has(group, severities)) severities[group] = []; - return (message, value) => { - if (isUndefined(value)) { - severities[group].push(Tree.red + red2(message)); - } else { - severities[group].push(Tree.red + red2(message + COL + " " + bold2(value))); - } - }; -} -function internalError(e) { - const message = Create({ type: "error" }).Line("INTERNAL ERROR ~ Thrown during define()", bold2).Header(e.message).Wrap(cleanStack(e.stack)).Newline().Line("Submit Issue", gray2.bold).Line("This is an internal error thrown by Syncify. Please report to the", gray2).Line("Github repository and provide re-production information", gray2).Newline().Line(CHV + " " + underline2.gray("https://github.com/panoply/syncify/issues")).Newline().End($.log.group).Break().toString(); - error(message); - $.running ? kill.exit(0) : process.exit(0); -} -function typeError({ option, name, provided, expects }) { - const base = path2.basename($.file.config); - error( - Create({ type: "error" }).Line("TYPE ERROR", bold2).Newline().Line(`An invalid ${cyan2(option)} type value was provided within your ${bold2(base)} file.`).Line(`The ${cyan2(name)} option has an incorrect type. Syncify will not intialize until this is fixed.`).Newline().Line(`provided${COL} ${yellowBright2(type(provided).toLowerCase())}`).Line(`expected${COL} ${blue2(expects.replace(/([|,])/g, gray2("$1")))}`).Line(`location${COL} ${TLD}${gray2.underline(base)}`).Newline().Line("How to fix?", gray2.bold).Line(`You need to change the option value to use the ${blue2("expected")} type.`, gray2).Line(`Use the ${white2("defineConfig")} named export for type checking`, gray2).End($.log.group).Break().toString() - ); - $.running ? kill.exit(0) : process.exit(0); -} -function invalidCommand({ - message, - expected, - provided = void 0, - fix -}) { - if (!provided) { - provided = g.ws($.argv); - expected = whiteBright2(`sy ${provided} ${cyan2(expected.replace(/([|,-])/g, gray2("$1")))}`); - } else { - expected = whiteBright2(`sy ${expected}`); - } - error( - Create({ type: "error" }).Line("COMMAND ERROR", bold2).Newline().Wrap(message).Newline().Line(`provided${COL} ${whiteBright2("$")} ${provided}`).Line(`expected${COL} ${whiteBright2("$")} ${expected}`).Newline().Line("How to fix?", gray2.bold).Wrap(fix, gray2).Newline().End($.log.group).Break().toString() - ); - $.running ? kill.exit(0) : process.exit(0); -} -function enoentError({ - type: type2, - path: path5, - message, - task -}) { - error( - Create({ type: "error" }).Line("ENOENT ERROR", bold2).Newline().Wrap(`Failed to resolve ${cyan2(path5)} ${type2}.`, ...message).Newline().Line(`task${COL} ${yellowBright2(task)}`).Line(`path${COL} ${blue2(path5)}`).Newline().End($.log.group).Break().toString() - ); - $.running ? kill.exit(0) : process.exit(0); -} -function missingDependency(deps) { - log.runtime.Stop(); - const tui = Create({ type: "error" }).Line("DEPENDENCY ERROR", bold2).Newline(); - if (isString(deps)) { - const message = g.ws( - `Missing ${cyan2(deps)} dependency. You need to install ${cyan2(deps)} to use it as`, - "a processor or remove the reference to it within your transform/s." - ); - tui.Wrap(message).Newline().Line("How to fix?", gray2.bold).Line("Install the above module as a development dependency, for example:", gray2).Newline().Line(`$ pnpm add ${deps} -D`, whiteBright2); - } else { - const message = g.ws( - `Missing ${cyan2(`${deps.length}`)} dependencies. You are attempting to use a processor`, - "transform that is not yet installed in your project. Install the below module/s as", - "development dependencies or disable the transform:" - ); - tui.Wrap(message).Newline(); - for (const dep of deps) { - tui.Line(`$ pnpm add ${dep} -D`, whiteBright2); - } - } - error( - tui.Newline().End($.log.group).Break().toString() - ); - $.running ? kill.exit(0) : process.exit(0); -} -function missingOption({ option, key, expects, reason }) { - const base = path2.basename($.file.config); - if (option.indexOf(".") > -1) { - option = option.split(".").filter(Boolean).join(gray2(" \u2192 ")); - } - error( - Create({ type: "error" }).Line("MISSING OPTION", bold2).Newline().Line(`Missing ${Encase("CB", cyan2(option), { spaced: true })} config option.`).Line(`The ${cyan2(key)} option must be defined`).Newline().Line(`expected${COL} ${blue2(expects.replace(/([|,])/g, gray2("$1")))}`).Line(`location${COL} ${gray2.underline(base)}`).Newline().Line("Why?", gray2.bold).Wrap(reason, gray2).Newline("line").End($.log.group).Break().toString() - ); - $.running ? kill.exit(0) : process.exit(0); -} -function invalidError({ - option, - name, - value, - expects, - reason = [""] -}) { - if (option.indexOf(".") > -1) { - option = option.split(".").filter(Boolean).join(gray2(" \u2192 ")); - } - error( - Create({ type: "error" }).Line("INVALID ERROR", bold2).Newline().Wrap(`Invalid ${cyan2(option)} configuration. The ${cyan2(name)} option is invalid. `, ...reason).Newline().Line(`provided${COL} ${yellowBright2(value)}`).Line(`expected${COL} ${blue2(expects.replace(/([|,])/g, gray2("$1")))}`).Newline().Line("How to fix?", gray2.bold).Line("You need to update the option and use one of the expected values.", gray2).Line(`Use the ${white2("defineConfig")} named export for type checking`, gray2).Newline().End($.log.group).Break().toString({ color: red2 }) - ); - $.running ? kill.exit(0) : process.exit(0); -} -function unknownProject() { - const message = g.ws( - "Syncify cannot run from this location as it is unknown. The necessary files", - "and references that would auto-confirm this directory as a valid project could", - "not be located." - ); - const write2 = Create({ type: "error" }).Line("UNKNOWN PROJECT", bold2).Newline().Wrap(message).Header(`${underline2.redBright($.cwd)}`); - let _stores = false; - let _credential = false; - let _config = false; - if ($.project.credentials === null) { - write2.Line(`${BAD} no credentials`, bold2); - } else { - _credential = true; - } - if ($.stores.length === 0) { - write2.Line(`${BAD} no targets`, bold2); - } else { - _stores = true; - } - if ($.file.config === null) { - write2.Line(`${BAD} no config file`, bold2); - } else { - _config = true; - } - if (_config) write2.Line(`${CHK} ${path2.basename($.file.config)}`, neonGreen); - if (_stores) write2.Line(`${CHK} stores defined`, neonGreen); - if (_credential) { - if ($.project.credentials === "env") { - write2.Line(`${CHK} .env file`, neonGreen); - } else { - write2.Line(`${CHK} using keychain`, neonGreen); - } - } - const suggest = g.ws( - `Run the ${neonCyan("sy init")} command if you would like to make this directory a Syncify project.`, - "You can alternatively provide the necessary files/references. For more information", - `visit the setup guide: ${underline2("https://syncify.sh/setup/")}` - ); - error( - write2.Newline().Line("How to fix?", gray2.bold).Wrap(suggest, gray2).Newline("line").End($.log.group).Break().toString({ color: red2 }) - ); - $.running ? kill.exit(0) : process.exit(0); -} -function missingEnv() { - const message = g.ws( - `Missing ${cyan2(".env")} credentials. Syncify could not resolve credentials within the workspace.`, - `Check you have ${cyan2(".env")} file present in the root of your project` - ); - error( - Create({ type: "error" }).Line("MISSING ENV", bold2).Newline().Wrap(message).Newline().End($.log.group).Break().toString({ color: red2 }) - ); - $.running ? kill.exit(0) : process.exit(0); -} -function invalidCredentials() { - const message = g.ws( - "The project's authorization access failed due to missing or invalid credentials.", - "Syncify could not obtain the store access tokens. Check that you have correctly", - `provided API access within your ${cyan2(".env")} file.` - ); - const suggest = g.ws( - "Credentials are expected to adhere to a specific format and can be expressed", - 'in either uppercase or lowercase. The store name must be is appended with "_api_token".', - `If the Shopify store (domain) name is ${white2("foo-store.myshopify.com")}:` - ); - error( - Create({ type: "error" }).Line("BAD CREDENTIALS", bold2).Newline().Wrap(message).Newline().Line($.file.env, underline2.redBright).Newline().Line("How to fix?", gray2.bold).Wrap(suggest, gray2).Newline().Line("FOO-STORE_API_TOKEN = 'shpat_abcdefghijklmnopqrstuvwz'", gray2).Newline().End($.log.group).Break().toString({ color: red2 }) - ); - $.running ? kill.exit(0) : process.exit(0); -} -function errorRuntime(e, options) { - const message = e instanceof Error ? has("message", e) ? e.message : e.toString() : e; - if (has("code", e)) options.entries.code = e.code; - if (has("name", e)) options.entries.name = e.name; - log.runtime.Tree("error").Header("ERROR", bold2.red).Wrap(options.message, redBright2).Newline().Wrap(message, redBright2.bold).Newline().Line("How to fix?", gray2.bold).Wrap(options.solution, gray2).Newline().Context({ entries: options.entries }).Newline().End($.log.group).Break().toWrite({ clear: true }); - $.running ? kill.exit(0) : process.exit(0); -} -function throwError(message, solution, errName) { - if (!errName) errName = "ERROR"; - const tui = Create({ type: "error" }).Line(errName.toUpperCase(), bold2).Newline().Wrap(message); - if (solution && solution.length > 0) { - tui.Line("How to fix?", gray2.bold).Wrap(solution, gray2); - } - error( - tui.Newline(Tree.trim).End($.log.group).Break().toString() - ); - $.running ? kill.exit(0) : process.exit(0); -} -function throwCommand(message) { - Create({ type: "error" }).Top(`Syncify ${CHV} Error`, false).Newline(Tree.trim).Line("COMMAND LINE ERROR", bold2).Newline().Wrap(message).Newline().Line("Need Help?", gray2.bold).Line("Refer to the usage documentation for more information:", gray2).Line(underline2("https://syncify.sh/usage/syncify-cli"), gray2).Newline(Tree.trim).End(`Syncify ${CHV} Error`, false).toLog(); - $.running ? kill.exit(0) : process.exit(0); -} -function unknownError(option, value) { - if (option.indexOf(".") > -1) { - const opts = option.split(".").filter(Boolean).join(" " + ARR + " "); - const join29 = g.ws(opts, ARR, red2.bold(value)); - option = Encase("CB", join29, { spaced: true }); - } - const base = path2.basename($.file.config); - const file = base === "package.json" ? `${blue2("syncify")} config in the ${blue2("package.json")} file.` : `${blue2(base)} file.`; - error( - Create({ type: "error" }).Line("ERROR", bold2).Newline().Line(`Unknown ${cyan2(option)} option provided.`).Newline().Line("How to fix?", gray2.bold).Line(`The ${cyan2(value)} option is invalid or unsupported.`).Line(`You need to remove it from the ${file}`).Newline().End($.log.group).Break().toString() - ); - $.running ? kill.exit(0) : process.exit(0); -} - -// syncify/mode/build.ts -var import_anymatch2 = __toESM(require_anymatch()); - -// node_modules/.pnpm/p-map@7.0.3/node_modules/p-map/index.js -async function pMap(iterable, mapper, { - concurrency = Number.POSITIVE_INFINITY, - stopOnError = true, - signal -} = {}) { - return new Promise((resolve_, reject_) => { - if (iterable[Symbol.iterator] === void 0 && iterable[Symbol.asyncIterator] === void 0) { - throw new TypeError(`Expected \`input\` to be either an \`Iterable\` or \`AsyncIterable\`, got (${typeof iterable})`); - } - if (typeof mapper !== "function") { - throw new TypeError("Mapper function is required"); - } - if (!(Number.isSafeInteger(concurrency) && concurrency >= 1 || concurrency === Number.POSITIVE_INFINITY)) { - throw new TypeError(`Expected \`concurrency\` to be an integer from 1 and up or \`Infinity\`, got \`${concurrency}\` (${typeof concurrency})`); - } - const result = []; - const errors = []; - const skippedIndexesMap = /* @__PURE__ */ new Map(); - let isRejected = false; - let isResolved = false; - let isIterableDone = false; - let resolvingCount = 0; - let currentIndex = 0; - const iterator = iterable[Symbol.iterator] === void 0 ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator](); - const signalListener = () => { - reject(signal.reason); - }; - const cleanup = () => { - signal == null ? void 0 : signal.removeEventListener("abort", signalListener); - }; - const resolve2 = (value) => { - resolve_(value); - cleanup(); - }; - const reject = (reason) => { - isRejected = true; - isResolved = true; - reject_(reason); - cleanup(); - }; - if (signal) { - if (signal.aborted) { - reject(signal.reason); - } - signal.addEventListener("abort", signalListener, { once: true }); - } - const next = async () => { - if (isResolved) { - return; - } - const nextItem = await iterator.next(); - const index = currentIndex; - currentIndex++; - if (nextItem.done) { - isIterableDone = true; - if (resolvingCount === 0 && !isResolved) { - if (!stopOnError && errors.length > 0) { - reject(new AggregateError(errors)); - return; - } - isResolved = true; - if (skippedIndexesMap.size === 0) { - resolve2(result); - return; - } - const pureResult = []; - for (const [index2, value] of result.entries()) { - if (skippedIndexesMap.get(index2) === pMapSkip) { - continue; - } - pureResult.push(value); - } - resolve2(pureResult); - } - return; - } - resolvingCount++; - (async () => { - try { - const element = await nextItem.value; - if (isResolved) { - return; - } - const value = await mapper(element, index); - if (value === pMapSkip) { - skippedIndexesMap.set(index, value); - } - result[index] = value; - resolvingCount--; - await next(); - } catch (error2) { - if (stopOnError) { - reject(error2); - } else { - errors.push(error2); - resolvingCount--; - try { - await next(); - } catch (error3) { - reject(error3); - } - } - } - })(); - }; - (async () => { - for (let index = 0; index < concurrency; index++) { - try { - await next(); - } catch (error2) { - reject(error2); - break; - } - if (isIterableDone || isRejected) { - break; - } - } - })(); - }); -} -var pMapSkip = Symbol("skip"); - -// syncify/mode/build.ts -var import_timer10 = __toESM(require_dist()); -function http(domain, token) { - if (domain in http.tokens) { - return http.client[domain]; - } else if (domain && token) { - http.tokens[domain] = token; - http.client[domain] = xior__default.default.create({ - baseURL: `https://${domain}.myshopify.com/admin/api/${http.VERSION}`, - url: "graphql.json", - responseType: "json", - // @ts-ignore - method: "POST", - headers: { - "X-Shopify-Access-Token": http.tokens[domain], - "Content-Type": "application/json" - } - }); - http.client[domain].interceptors.response.use( - (response) => response.data && response.data.data ? response.data : response.data, - (error2) => Promise.reject(error2) - ); - } else { - throwError(domain ? [ - `Xior instance cannot be found for ${domain}` - ] : [ - "Xior instance could not be created" - ], []); - } -} -http.request = (domain, token) => { - const client = xior__default.default.create({ - baseURL: `https://${domain}.myshopify.com/admin/api/${http.VERSION}`, - url: "graphql.json", - responseType: "json", - // @ts-ignore - method: "POST", - headers: token ? { - "X-Shopify-Access-Token": token, - "Content-Type": "application/json" - } : { - "Content-Type": "application/json" - } - }); - client.interceptors.response.use( - (response) => response.data && response.data.data ? response.data : response.data, - (error2) => Promise.reject(error2) - ); - return (data) => client.request(data); -}; -http.chain = (path5, reject) => (object) => pathOr(object, path5, (reason) => { - reason.isGraphError = true; - reject(reason); -}); -http.client = o(); -http.tokens = o(); -http.VERSION = "2025-01"; - -// syncify/http/utils.ts -function graph(object, path5, reject) { - if (!isObject(object)) return reject(Object.assign(object, { isGraphError: true })); - const keys2 = isString(path5) ? path5.split(".").filter(Boolean) : path5; - if (keys2.length === 0) { - object.isGraphError = true; - return reject(object); - } - let result = object; - for (const key of keys2) { - if (result == null || !(key in result)) { - reject(Object.assign(object, { isGraphError: true })); - } else { - result = result[key]; - } - } - return result; -} -function params(parameters) { - let files = null; - let query = parameters[0]; - let target; - let onError = null; - let onNext = null; - if (isObject(query)) { - const has2 = hasProp(query); - target = has2("target") ? query.target : $.target.default; - if (has2("onError")) onError = query.onError; - if (has2("onNext")) onNext = query.onNext; - if (has2("input")) { - if (isArray(query.input)) { - const [first] = query.input; - if (isObject(first) && "key" in query.input) { - files = query.input; - query = files.map(({ key, value }) => ({ - filename: key, - body: { - type: "TEXT", - value - } - })); - } else { - query = query.input; - } - } else if (isObject(query.input)) { - if ("key" in query.input) { - files = [query.input]; - query = [{ filename: query.input.key, body: { type: "TEXT", value: query.input.value } }]; - } else { - query = [query.input]; - } - } else if (isString(query.input)) { - query = [query.input]; - } - } - } else { - target = parameters.length === 2 ? parameters[1] : $.target.default; - if (isArray(query)) { - const [first] = query; - if (isObject(first) && "key" in first) { - files = query; - query = files.map(({ key, value }) => ({ - filename: key, - body: { - type: "TEXT", - value - } - })); - } - } else if (isObject(query)) { - if ("key" in query) { - files = [query]; - query = [ - { - filename: query.key, - body: { type: "TEXT", value: query.value } - } - ]; - } else { - query = [query]; - } - } else if (isString(query)) { - query = [query]; - } - } - return { - query, - target, - files, - onError, - onNext - }; -} -params.upsert = function(parameters) { - let files = null; - let query = parameters[0]; - let target; - let onError = null; - let onNext = null; - if (isObject(query)) { - const has2 = hasProp(query); - if (has2("onError")) onError = query.onError; - if (has2("onNext")) onNext = query.onNext; - target = has2("target") ? query.target : $.target.default; - if (has2("input")) { - if (isArray(query.input)) { - if (query.input.length > 0) { - const [first] = query.input; - if (isObject(first) && "key" in query.input) { - files = query.input; - query = forMap(({ - key, - value - }) => ({ - filename: key, - body: { - type: "TEXT", - value - } - }), files); - } else { - query = query.input; - } - } - } else if (isObject(query.input)) { - if ("key" in query.input) { - files = [query.input]; - query = [ - { - filename: query.input.key, - body: { - type: "TEXT", - value: query.input.value - } - } - ]; - } else { - query = [query.input]; - } - } else if (isString(query.input)) { - query = [query.input]; - } - } - } else { - target = parameters.length === 2 ? parameters[1] : $.target.default; - if (isArray(query)) { - const [first] = query; - if (isObject(first) && "key" in first) { - files = query; - query = forMap(({ key, value }) => ({ - filename: key, - body: { - type: "TEXT", - value - } - }), files); - } - } else if (isObject(query)) { - if ("key" in query) { - files = [query]; - query = [ - { - filename: query.key, - body: { - type: "TEXT", - value: query.value - } - } - ]; - } else { - query = [query]; - } - } else if (isString(query)) { - query = [query]; - } - } - return { - query, - target, - files, - onError, - onNext - }; -}; - -// syncify/http/themeFiles/themeFilesMap.ts -function themeFilesMap(target, callback = null) { - return new Promise((resolve2, reject) => (async () => { - let after = null; - let hasNextPage = true; - const files = { files: {}, total: 0 }; - while (hasNextPage) { - await http(target.store.name).request({ - data: { - query: `query ThemeFilesMap($gid:ID!,$after:String){theme(id:$gid){files(first:180,after:$after){nodes{filename}pageInfo{hasNextPage endCursor}}}}`, - variables: { - gid: target.gid, - after - } - } - }).then((response) => { - const { nodes, pageInfo } = graph(response.data, "theme.files", reject); - files.total += nodes.length; - hasNextPage = pageInfo.hasNextPage; - after = pageInfo.endCursor; - callback && callback(files.total); - forEach(({ filename }) => { - const directory = filename.slice(0, filename.lastIndexOf("/")); - has(directory, files.files) ? files.files[directory].push(filename) : files.files[directory] = [filename]; - }, nodes); - }).catch((e) => { - e.target = target; - e.graph = "OnlineStoreThemeFile"; - error.request(e); - hasNextPage = false; - }); - } - resolve2(files); - })()); -} - -// syncify/http/enums.ts -var OnlineStoreThemeFileReadResult = (code) => ({ - BAD_REQUEST: "Operation was malformed or invalid.", - CONFLICT: "Operation faced a conflict with the current state of the file.", - ERROR: "Operation encountered an error.", - NOT_FOUND: "Operation file could not be found.", - SUCCESS: "Operation was successful.", - TIMEOUT: "Operation timed out.", - UNPROCESSABLE_ENTITY: "Operation could not be processed due to issues with input data.", - _: null -})[code || "__UNKNOWN__"]; -var OnlineStoreThemeFilesUserErrors = (code) => ({ - ACCESS_DENIED: "Access denied.", - DUPLICATE_FILE_INPUT: "There are files with the same filename.", - ERROR: "Error.", - FILE_VALIDATION_ERROR: "The file is invalid.", - LESS_THAN_OR_EQUAL_TO: "The input value should be less than or equal to the maximum value allowed.", - NOT_FOUND: "The record with the ID used as the input value couldn't be found.", - THEME_FILES_CONFLICT: "There are theme files with conflicts.", - THEME_LIMITED_PLAN: "This action is not available on your current plan. Please upgrade to access theme editing features.", - _: null -})[code || "_"]; - -// syncify/http/themeFiles/themeFilesDelete.ts -function themeFilesDelete(...input) { - const { query, target, files, onError } = params(input); - return new Promise((resolve2, reject) => { - http(target.store.name).request({ - data: { - query: `mutation ThemeFilesDelete($gid:ID!,$query:[String!]!){themeFilesDelete(themeId:$gid,files:$query){deletedThemeFiles{filename}userErrors{message filename code}}}`, - variables: { - gid: target.gid, - query - } - } - }).then((response) => { - const { deletedThemeFiles, userErrors } = graph(response.data, "themeFilesDelete", reject); - resolve2( - { - target, - synced: deletedThemeFiles, - errors: forMap((userError) => ({ - message: userError.message, - filename: userError.filename, - code: userError.code.replace(/_/g, " "), - summary: OnlineStoreThemeFilesUserErrors(userError.code), - graph: "MutationThemeFilesDelete", - file: files.find((file) => file.key === userError.filename) || null - }), userErrors) - } - ); - }).catch((e) => { - e.target = target; - e.files = files; - e.graph = "OnlineStoreThemeFileOperationResult"; - onError ? onError(e) : reject(e); - }); - }); -} -async function themeFilesDeleteMap(file) { - const files = isArray(file) ? file : [file]; - await q.http.add(async () => { - try { - const targets = await pMap($.target, (target) => themeFilesDelete(files, target)); - event.each(targets); - } catch (e) { - error.request(e); - } - }); -} - -// syncify/http/themeFiles/themeFilesUpsert.ts -function themeFilesUpsert(...input) { - const { query, target, files, onError } = params.upsert(input); - return new Promise((resolve2, reject) => { - http(target.store.name).request({ - data: { - query: `mutation ThemeFilesUpsert($query:[OnlineStoreThemeFilesUpsertFileInput!]!,$gid:ID!){themeFilesUpsert(files:$query,themeId:$gid){upsertedThemeFiles{filename}userErrors{code,field,filename,message,}}}`, - variables: { - gid: target.gid, - query - } - } - }).then((response) => { - const { upsertedThemeFiles, userErrors } = graph(response.data, "themeFilesUpsert", reject); - resolve2( - { - target, - synced: upsertedThemeFiles, - errors: forMap((userError) => ({ - message: userError.message, - filename: userError.filename, - code: userError.code.replace(/_/g, " "), - graph: "OnlineStoreThemeFilesUpsertFileInput", - summary: OnlineStoreThemeFilesUserErrors(userError.code), - file: files.find((file) => file.key === userError.filename) || null - }), userErrors) - } - ); - }).catch((e) => { - e.target = target; - e.files = files; - e.graph = "OnlineStoreThemeFilesUpsertFileInput"; - onError ? onError(e) : reject(e); - }); - }); -} -async function themeFilesUpsertMap(file) { - const files = isArray(file) ? file : [file]; - await q.http.add(async () => { - try { - const targets = await pMap($.target, (target) => themeFilesUpsert(files, target)); - event.each(targets); - } catch (e) { - error.request(e); - } - }); -} - -// syncify/http/themeFiles/themeFilesList.ts -function themeFilesList(...input) { - const { query, target, onError, onNext } = params(input); - return new Promise((resolve2, reject) => (async () => { - let after = null; - let hasNextPage = true; - let files = []; - let errors = []; - while (hasNextPage) { - await http(target.store.name).request({ - data: { - query: `query ThemeFilesList($gid:ID!,$query:[String!]!$after:String){theme(id:$gid){files(first:100,after:$after,filenames:$query){nodes{filename,size,createdAt,updatedAt,checksumMd5,body{...on OnlineStoreThemeFileBodyText{content}}}userErrors{code filename},pageInfo{hasNextPage endCursor}}}}`, - variables: { - gid: target.gid, - query, - after - } - } - }).then((response) => { - const { nodes, pageInfo, userErrors } = graph(response.data, "theme.files", reject); - hasNextPage = pageInfo.hasNextPage; - after = pageInfo.endCursor; - files = files.concat(nodes); - if (onNext) onNext(files.length); - if (userErrors.length > 0) { - errors = errors.concat(forMap(({ filename, code }) => ({ - filename, - code: code.replace(/_/g, " "), - graph: "QueryOnlineStoreThemeFile", - message: OnlineStoreThemeFileReadResult(code) - }), userErrors)); - } - }).catch((e) => { - e.target = target; - e.files = files; - e.graph = "OnlineStoreThemeFile"; - onError ? onError(e) : error.request(e); - hasNextPage = false; - }); - } - resolve2( - { - get target() { - return target; - }, - get files() { - return files; - }, - get errors() { - return errors; - } - } - ); - })()); -} - -// syncify/http/themeFiles/themeFilesGet.ts -function themeFilesGet(...input) { - const { query, target, files, onError } = params(input); - return new Promise((resolve2, reject) => { - http(target.store.name).request({ - data: { - query: `query ThemeFilesGet($gid:ID!,$query:[String!]!){theme(id:$gid){files(filenames:$query){userErrors{code filename},nodes{filename,size,createdAt,updatedAt,body{...on OnlineStoreThemeFileBodyText{content}}}}}}`, - variables: { - gid: target.gid, - query - } - } - }).then((response) => { - const { nodes, userErrors } = graph(response.data, "theme.files", reject); - resolve2( - { - get target() { - return target; - }, - file: nodes.length === 1 ? nodes[0] : null, - errors: forMap(({ filename, code }) => ({ - filename, - code: code.replace(/_/g, " "), - graph: "QueryOnlineStoreThemeFile", - message: OnlineStoreThemeFileReadResult(code) - }), userErrors) - } - ); - }).catch((e) => { - e.target = target; - e.files = files; - e.graph = "QueryOnlineStoreThemeFile"; - onError ? onError(e) : error.request(e); - }); - }); -} -function themesList(store) { - return new Promise((resolve2, reject) => { - http(store.name).request({ - data: `query ThemeList{themes(first:100){nodes{id createdAt name prefix role themeStoreId updatedAt}}}` - }).then(({ - data: { - themes: { - nodes - } - } - }) => { - resolve2(nodes.map((theme2) => ({ ...theme2, id: path2.basename(theme2.id) }))); - }).catch((failed) => { - const e = {}; - e.failed = failed; - e.store = store; - reject(e); - }); - }); -} - -// syncify/transform/asset.ts -async function passthrough(file) { - await fsExtra.writeFile(file.output, file.value).catch( - error.write("Error writing asset to output directory", { - input: file.input, - output: file.output - }) - ); - if ($.mode.hot) { - log.syncing(file.key, { hot: $.mode.hot }); - if (file.kind === "JavaScript" /* JavaScript */) { - $.wss.script(file.uuid, file.base); - } else if (file.kind === "CSS" /* CSS */) { - $.wss.stylesheet(file.uuid, file.base); - } - } - if ($.mode.build === false) { - await themeFilesUpsertMap(file); - } -} -async function AssetTransform(file) { - const value = await fsExtra.readFile(file.input, "utf8").catch( - error.write("Error reading asset file", { - input: file.input, - output: file.output - }) - ); - if (isString(value)) { - file.value = value; - if (isEmptyString(value)) { - if ($.mode.watch) log.skipped(file, "empty file"); - return null; - } - await passthrough(file); - } - return null; -} - -// syncify/transform/json.ts -var import_timer4 = __toESM(require_dist()); -var theme = { - pointer(choice, index) { - const line = this.state.index === index ? Tree.dash : Tree.line; - return index === 0 ? Tree.trim + "\n" + line : line; - }, - prefix: Tree.trim + " ", - styles: { - primary: neonGreen, - success: neonGreen, - danger: red2, - warning: yellowBright2, - muted: gray2, - disabled: gray2, - typing: whiteBright2 - }, - symbols: { - ellipsis: bold2("?"), - prefix: { - pending: "", - submitted: "\u2713", - cancelled: "\u2715" - }, - separator: { - pending: "", - submitted: "\u2794 ", - cancelled: `${redBright2("\u2715")} ` - } - } -}; -function cancel() { - kill(() => { - log.nl().line("PROCESS EXIT WITH CODE 0", neonRouge); - log.ender("Prompt Exit", { clear: false }); - }); - kill.exit(0); - return null; -} -function labels({ - prompts: prompts2, - padding = 2 -}) { - const space = eqWS(prompts2, { padding }); - const model = o(); - for (let i = 0, size = prompts2.length, name = ""; i < size; i++) { - name = prompts2[i]; - model[toPascalCase(name)] = bold2(name + COL + space(name)); - } - return model; -} -function intercept() { - const native = process.stdout.write; - process8.stdout.write = function(chunk, encoding, callback) { - let modified = chunk.toString(); - if (/ERROR|INVALID|MISSING|REQUIRED/i.test(modified)) { - modified = modified.replace(/\n/, "\n" + Tree.trim).replace(/(?<=\u001b\[31m) /, "").replace(/(?<=\[39m)\n? +(?=\u001b\[38;2;42;42;46m)/, "").replace(/( (?:ERROR|INVALID|MISSING|REQUIRED))/i, "$1"); - } - native.call(process8.stdout, modified, encoding, callback); - }; - return () => { - process8.stdout.write = native; - }; -} - -// syncify/prompts/enquirer/snippet.ts -async function render() { - const { index, keys: keys2 = [], submitted, size } = this.state; - const newline = [this.options.newline].find((v2) => v2 != null); - const prefix = await this.prefix(); - const separator = await this.separator(); - const message = await this.message(); - let prompt2 = [ - prefix, - message, - separator - ].filter(Boolean).join(" "); - this.state.prompt = prompt2; - const header = await this.header(); - const error2 = await this.error() || ""; - const hint = await this.hint() || ""; - const body = submitted ? "" : await this.interpolate(this.state); - const key = this.state.key = keys2[index] || ""; - const input = await this.format(key); - const footer = await this.footer(); - if (input) prompt2 += " " + input; - if (hint && !input && this.state.completed === 0) prompt2 += " " + hint; - this.clear(size); - const lines = [ - header, - prompt2, - body.split("\n").join(Tree.next), - footer, - error2.trim() - ]; - this.write(lines.filter(Boolean).join(newline)); - this.restore(); -} -var import_timer3 = __toESM(require_dist()); -function warn(...message) { - forEach((line) => stderr2.write(line), message); -} -warn.count = () => { - let total = 0; - $.warnings.get($.log.uri).values().forEach((stack) => total += stack.size); - return total; -}; -function messages(processor2, uri) { - if ($.warnings.has(uri)) { - const file = $.warnings.get(uri); - return file.has(processor2) ? file.get(processor2) : file.set(processor2, s()).get(processor2); - } - return $.warnings.set(uri, m([[processor2, s()]])).get(uri).get(processor2); -} -warn.schema = (file, options) => { - const stack = messages("Shared Schema", file.input); - const tui = Create({ type: "warning" }).Newline().Wrap(options.message, yellowBright2).Newline().Context({ - stack: false, - type: "warning", - entries: { - reference: options.$ref, - schema: options.schema, - section: file.relative, - shared: options.shared - } - }); - stack.add(tui.toString()); -}; -warn.sass = (file) => (message, options) => { - const stack = messages("sass", file.input); - const text = capture.url(message.replace(/\n+/g, " "), (text2) => underline2(text2)); - const tui = Create({ type: "warning" }).Wrap(text, yellowBright2); - const location = {}; - if (has("span", options)) { - if (isObject(options.span)) { - const { span } = options; - const source = fsExtra.readFileSync(span.url.pathname, "utf8"); - const frame = U(source, { - type: "warning", - start: { - line: span.start.line + 1, - column: span.start.column - } - }); - tui.Newline().Insert(frame); - location.line = span.start.line + 1; - location.column = span.start.column; - location.input = TLD + file.relative; - location.source = TLD + path2.relative($.cwd, options.span.url.pathname); - if (/\/node_modules\//.test(span.url.pathname)) { - location.module = pink(span.url.pathname.match(/(?:.*?\/node_modules\/)((?:@[^/]+\/)?[^/]+)/)[1]); - } - } else { - location.input = TLD + file.relative; - } - } else { - location.input = TLD + file.relative; - } - location.processor = neonMagenta("SASS Dart"); - if (options.deprecation) { - location.details = "DEPRECATION WARNING"; - } - tui.Newline().Context({ - stack: false, - type: "warning", - entries: { - ...location, - processor: neonMagenta("SASS Dart") - } - }); - const context = tui.toString({ trim: false }); - if (!stack.has(context)) stack.add(context); -}; -warn.esbuild = (data) => { -}; -warn.postcss = (file, data) => { - const stack = messages("postcss", file.input); - function Sample(code, { - line = Tree.line, - span = null - } = {}) { - if (line === "red") { - line = Tree.red; - } else if (line === "yellow") { - line = Tree.yellow; - } - if (span !== null) { - const end = has("end", span) ? span.end : span.start + 1; - return line + "\n" + g.nl( - line + blue2(`${span.start - 1}`) + COL, - line + blue2(`${span.start}`) + COL + code, - line + blue2(`${end}`) + COL - ); - } - return line + "\n" + line + code; - } - const output = g( - Sample( - data.node.toString(), - { - line: "yellow", - span: isNumber(data.endLine) ? { - start: data.line, - end: data.endLine - } : { - start: data.line, - end: data.endLine - } - } - ), - Context({ - stack: false, - entries: { - column: data.column, - file: file.relative, - plugin: data.plugin - } - }) - ); - if (!stack.has(output)) { - stack.add(output); - } -}; - -// syncify/transform/style.ts -function write(file, { noUpsert = false } = {}) { - return async (data) => { - if (isNil(data)) return null; - runChecksum(file.input, data); - fsExtra.writeFile(file.output, data).catch(error.write("Error writing stylesheet to output", { - input: file.relative, - output: path2.relative($.cwd, file.output) - })); - file.value = data; - const size = sizeDiff(file.value, file.size); - if (size.isSmaller) { - if (file.kind === "SCSS" /* SCSS */ || file.kind === "SASS" /* SASS */ || file.kind === "Tailwind" /* Tailwind */) { - log.transform(file.kind, bold2("CSS"), size.before, import_timer3.timer.stop(file.uuid)); - } else { - log.transform("CSS", size.before, `brotli ${size.brotli}`); - } - } else { - if (file.kind === "Tailwind" /* Tailwind */) { - log.minified("Tailwind" /* Tailwind */, size.before, size.after, size.saved); - } else { - log.minified("CSS", size.before, size.after, size.saved); - } - } - if ($.mode.hot) { - $.wss.stylesheet(file.uuid, path2.basename(file.key)); - } - if (file.kind !== "Tailwind" /* Tailwind */) { - log.syncing(file.key); - } - if ($.mode.watch && !noUpsert) { - await themeFilesUpsertMap(file); - if (!$.mode.build) { - if ($.warnings.size > 0) { - const size2 = warn.count(); - log.warn(`${bold2(size2)} Compiler ${plur("Warning", size2)}`, `Press ${bold2("v")} to view all warning/s`); - } - } - } - return file.value; - }; -} -async function sassProcess(file) { - if (isUndefined(file.data) || isBoolean(file.data.sass) && file.data.sass === false) { - return readStyleFile(file); - } - const options = isObject(file.data.sass) ? merge($.processor.sass.config, file.data.sass) : $.processor.sass.config; - if (file.ext === ".scss" || file.ext === ".sass") { - $.mode.watch && import_timer3.timer.start(); - try { - const { css, sourceMap } = await $import.sass.compileAsync(file.data.input, { - loadPaths: options.include, - sourceMapIncludeSources: file.data.postcss, - sourceMap: options.sourcemap, - style: options.style, - alertColor: false, - alertAscii: false, - quietDeps: options.quietDeps, - charset: file.data.snippet === false, - logger: { - debug: (msg) => console.log("DEBUG", msg), - warn: warn.sass(file) - } - }); - if (options.sourcemap) { - const map = path2.join($.dirs.sourcemaps.styles, file.base + ".map"); - fsExtra.writeFile(map, JSON.stringify(sourceMap)).catch( - error.write("Error writing SASS Source Map file to the cache directory", { - file: path2.relative($.cwd, map), - source: file.relative - }) - ); - } - log.process("SASS Dart", import_timer3.timer.stop()); - file.size = byteSize(css); - return { - css, - map: sourceMap - }; - } catch (e) { - if ($.mode.watch) { - import_timer3.timer.clear(); - log.error(file.relative, { - notify: { - title: `Error in ${file.base}`, - message: "SASS style transform failed, SCSS was not complied." - } - }); - error.sass(file, e); - } - return null; - } - } - return readStyleFile(file); -} -async function tailwindParse(file) { - const files = []; - for (const map in $.processor.tailwind.map) { - if ($.processor.tailwind.map[map].has(file.input)) { - const file2 = parse2($.style[map].input); - if (isUndefined(file2)) continue; - import_timer3.timer.start(file2.uuid); - file2.kind = "Tailwind" /* Tailwind */; - file2.value = await tailwindProcess(file2, { noUpsert: true }); - if (isString(file2.value)) { - files.push(file2); - } - } - } - files.push(file); - files.length > 1 ? log.syncing(`${files.length} files processed`, { hot: $.mode.hot }) : log.syncing(files[0].key, { hot: $.mode.hot }); - return files; -} -async function tailwindProcess(file, upsert) { - if ($.mode.hot) import_timer3.timer.start(file.uuid); - const output = write(file, upsert); - const read = await readStyleFile(file); - const post = await postcssProcess(file, read.css, read.map); - if (post === null) return null; - file.hash = checksum(post); - if ($.checksum[file.input] === file.hash) { - log.skipped(file, "no changes"); - return null; - } - $.checksum[file.input] = file.hash; - if (file.data.snippet) { - return output(createSnippet(post, file.data.attrs)); - } else { - return output(post); - } -} -async function readStyleFile(file) { - try { - const css = await fsExtra.readFile(file.input, "utf8"); - file.size = byteSize(css); - return { css, map: null }; - } catch (e) { - import_timer3.timer.clear(); - log.error(file.relative, { - notify: { - title: "Read Error", - message: `File ${file.base} could not be read` - } - }); - error.throw(e, { - source: file.relative, - transform: "style" - }); - return null; - } -} -async function postcssProcess(file, css, map) { - const { data } = file; - const isTWCSS = isBoolean(data.tailwind) === false; - const plugins2 = isTWCSS && data.tailwind ? [$import.tailwind(data.tailwind)].concat(data.postcss) : data.postcss; - try { - if ($.mode.watch && file.kind !== "Tailwind" /* Tailwind */) import_timer3.timer.start(); - const result = await $import.postcss(plugins2).process(css, { - from: data.rename, - to: data.rename, - map: map ? { - prev: map, - inline: false, - absolute: true - } : null - }); - if ($.mode.watch && file.kind !== "Tailwind" /* Tailwind */) { - log.process("PostCSS", import_timer3.timer.stop()); - } - const issues = result.warnings(); - if (issues.length > 0) { - for (const warning of issues) { - warn.postcss(file, warning); - } - } - return result.css.toString(); - } catch (e) { - if ($.mode.watch) { - import_timer3.timer.clear(); - log.error(file.relative, { - notify: { - title: `Error in ${file.base}`, - message: "PostCSS Transform Error, file failed to process" - } - }); - console.log(e); - } - return null; - } -} -function createSnippet(string, attrs) { - return attrs.length > 0 ? `` : ``; -} -async function StyleTransform(file) { - if ($.mode.watch) import_timer3.timer.start(); - if ($.mode.hot) import_timer3.timer.start(file.uuid); - const output = write(file); - try { - if (isUndefined(file.data)) return readStyleFile(file); - const out = await sassProcess(file); - if (out === null) return null; - if (isNil($import.postcss) || isUndefined(file.data) || !file.data.postcss && !file.data.snippet) { - return output(out.css); - } - if (file.data.postcss) { - const post = await postcssProcess(file, out.css, out.map); - if (post === null) return null; - if (file.data.snippet) { - return output(createSnippet(post, file.data.attrs)); - } else { - return output(post); - } - } - return file.data.snippet ? output(createSnippet(out.css, file.data.attrs)) : output(out.css); - } catch (e) { - console.log(e); - return null; - } -} - -// syncify/transform/json.ts -function parseJson(file, actual, expected) { - try { - return expected ? json.evaluate(actual, expected, $.json.options) : json.evaluate(actual, $.json.options); - } catch (e) { - log.error(file.relative, { - notify: { - title: `Error in ${file.base}`, - message: "JSON Parse error occurred due to invalid syntax" - } - }); - error.json(e, file, "JSON Parse Error"); - return null; - } -} -async function jsonCompile(file, json$1) { - const { parsed, string } = isString(json$1) ? parseJson(file, json$1) : json$1; - const indent = $.json.terse.enabled ? indentSize(file.type) : $.json.indent; - const output = indent === 0 ? json.stringify(parsed, { - removeComments: true, - indentSize: 0, - arrays: $.json.options.arrays, - objects: $.json.options.objects, - exclude: $.json.options.exclude - }) : string; - if (isNil(output)) { - if ($.mode.watch) import_timer4.timer.stop(); - return output; - } - if (indent === 0) { - const { before, after, saved } = sizeDiff(output, file.size); - log.minified("JSON", before, after, saved); - } else { - log.transform("JSON", file.namespace, byteConvert(file.size), import_timer4.timer.now()); - } - if (file.type === 17 /* Metafield */) return output; - fsExtra.writeFile(file.output, output).catch( - error.write("Error writing JSON", { - file: file.input - }) - ); - return output; -} -async function jsonCompare(file, local) { - const json = []; - for (const theme2 of $.target) { - const remote = await themeFilesGet(file.key, theme2); - if (remote.file !== null) { - const data = parseJson(file, local, remote.file.body.content); - if (data === null) return null; - json.push(data); - } - } - if (json.length > 0) { - log.error(file.key, { - suffix: "version mismatch", - notify: { - title: "Version Mismatch", - message: `Local and remote versions do not align on ${file.key}` - } - }); - log.nl(); - const { action } = await enquirer.prompt({ - name: "action", - type: "select", - multiple: false, - message: "action", - theme, - choices: [ - { - name: "open", - hint: "View the remote version in your editor" - }, - { - name: "push", - hint: "Replaces the remote version with local version" - }, - { - name: "pull", - hint: "Replaces the local version with the remote version" - }, - { - name: "stash", - hint: "Stash the remote version and push the local version" - }, - { - name: "cancel", - hint: "Cancel the sync operation" - } - ] - }); - if (action === "open") { - const uri = path2.join($.dirs.temp, file.key); - await fsExtra.writeFile(uri, json[0].string); - openInEditor(uri); - return null; - } else if (action === "push") { - return json[0].string; - } else if (action === "pull") { - await fsExtra.writeFile(file.input, json[0].string); - return null; - } - } - return json[0].string; -} -function indentSize(type2) { - const { options } = $.json.terse; - switch (type2) { - case 6 /* Group */: - if (options.groups) return 0; - break; - case 16 /* Asset */: - if (options.assets) return 0; - break; - case 10 /* Locale */: - if (options.locales) return 0; - break; - case 1 /* Template */: - if (options.templates) return 0; - break; - case 9 /* Config */: - if (options.config) return 0; - break; - case 17 /* Metafield */: - if (options.metafields) return 0; - break; - case 8 /* Metaobject */: - if (options.metaobject) return 0; - break; - } - return $.json.useTab ? " ".repeat(Math.floor($.json.indent / 2)) : $.json.indent; -} -var isDiff = (type2) => type2 === 9 /* Config */ || type2 === 1 /* Template */ || type2 === 8 /* Metaobject */ || type2 === 10 /* Locale */ || type2 === 6 /* Group */; -async function JsonTransform(file) { - $.mode.watch && import_timer4.timer.start(); - const read = await fsExtra.readFile(file.input, "utf8").catch( - error.write("Error reading JSON file", { - input: file.input, - output: file.output - }) - ); - if (!isString(read)) return; - const local = read.trim(); - file.size = byteSize(local); - if (local.length === 0) return log.skipped(file, "empty file"); - if ($.mode.build === false && isDiff(file.type)) { - file.value = await jsonCompare(file, local); - } else { - file.value = await jsonCompile(file, local); - } - if ($.mode.build) return file.value; - if (runChecksum(file.input, file.value)) { - log.skipped(file.key, "no changes"); - await themeFilesUpsertMap(file); - } else { - if (file.type !== 11 /* Style */ && $.processor.tailwind.map !== null) { - await tailwindParse(file).then(themeFilesUpsertMap); - } else { - log.syncing(file.key); - await themeFilesUpsertMap(file); - } - if ($.mode.hot && $.mode.bulk === false) { - await q.http.onIdle().then(() => $.wss.replace()); - } - return file.value; - } -} -var import_timer7 = __toESM(require_dist()); - -// syncify/hot/socket.ts -var import_timer6 = __toESM(require_dist()); -var import_timer5 = __toESM(require_dist()); - -// packages/update/dist/index.mjs -var w = /^(\d+)\.(\d+)\.(\d+)(-([a-z]+)(?:\.(\d+))?)?$/i; -function C(o2, a, n) { - let i = (s2) => { - let e = s2.match(w); - if (!e) throw new Error(`Invalid version format: ${s2}`); - return { parts: [parseInt(e[1], 10), parseInt(e[2], 10), parseInt(e[3], 10)], release: e[5] || "latest", preRelease: e[5] ? `${e[5]}${e[6] ? `.${e[6]}` : ""}` : void 0, stage: e[5] ? parseInt(e[6] || "0", 10) : null }; - }, p = (s2, e) => { - if (!s2 && !e) return { comparison: 0, step: false }; - if (!s2) return { comparison: 1, step: false }; - if (!e) return { comparison: -1, step: false }; - let [u, h = "0"] = s2.split("."), [$2, y = "0"] = e.split("."), m2 = n[u.toLowerCase()] || 0, g2 = n[$2.toLowerCase()] || 0; - if (m2 !== g2) return { comparison: m2 - g2, step: false }; - let f = Number(h) - Number(y); - return { comparison: f, step: f !== 0 }; - }, r2 = i(o2), t2 = i(a), d = () => { - for (let e = 0; e < 3; e++) if (r2.parts[e] - t2.parts[e] !== 0) return e === 0 ? "major" : e === 1 ? "minor" : "patch"; - return p(r2.preRelease, t2.preRelease).comparison !== 0, "patch"; - }; - if (r2.preRelease === t2.preRelease) { - if (r2.parts.every((s2, e) => s2 === t2.parts[e])) return false; - if (Number(r2.parts.join("")) > Number(t2.parts.join(""))) throw new Error(`Current version is greater than registry version: ${o2} > ${a}`); - } - let l = d(), c = p(r2.preRelease, t2.preRelease), b = l === "major" || (n[r2.release.toLowerCase()] || 0) < (n[t2.release.toLowerCase()] || 0) || c.comparison > 0 || t2.stage > r2.stage, R = r2.preRelease && t2.preRelease ? r2.release === t2.release ? `${r2.release}.${r2.stage} \u2192 ${t2.release}.${t2.stage}` : `${r2.release} \u2192 ${t2.release}` : r2.preRelease ? `${r2.release} \u2192 latest` : `latest \u2192 ${t2.release}`; - return { change: l, bump: R, release: t2.release, breaking: b, step: c.step, current: o2, registry: a, parse: { get current() { - return { major: r2.parts[0], minor: r2.parts[1], patch: r2.parts[2], release: r2.release, stage: r2.stage }; - }, get registry() { - return { major: t2.parts[0], minor: t2.parts[1], patch: t2.parts[2], release: t2.release, stage: t2.stage }; - } } }; -} -async function I2(o2) { - let a = new AbortController(); - kill(() => a.abort()); - try { - return (await (await fetch(`https://registry.npmjs.org/${o2}`, { signal: a.signal })).json()).version; - } catch { - return null; - } -} -async function v(o2, a, { tag: n = "latest", priorities: i = void 0 } = {}) { - var _a14; - if (!((_a14 = process == null ? void 0 : process.stdout) == null ? void 0 : _a14.isTTY)) return; - let p = await I2(`${o2}/${n}`); - return p === null ? false : C(a, p, { alpha: 1, beta: 2, rc: 3, ...i }); -} -var N2 = v; - -// syncify/cli/runtime.ts -function runtime() { - if ($.config.log.silent || $.running) return; - import_timer5.timer.start("runtime"); -} -runtime.startup = function() { - if ($.running) { - return null; - } else { - log.runtime.Break().Top("Syncify").Newline().Template(white2.dim(`v${$.version}`), { id: "v" }).True($.terminal.cols < 80, function() { - this.Header("TERMINAL WIDTH WARNING", bold2.red).Wrap( - red2, - `Your terminal width is below ${bold2(80)} columns (currently ${bold2($.terminal.cols)})`, - "This is not recommended for usage with Syncify (size matters).", - "Expand your terminal width wider for an optimal console experience." - ); - }).Newline().toWrite(); - N2("@syncify/cli", $.version).then((version) => { - if (version !== false) { - const latest = `${neonGreen(`${bold2(version.registry)} (available)`)}`; - log.runtime.Update("v", `${red2.dim($.version)} ${ARL} ${latest}`); - } - }); - } -}; -runtime.time = () => { - if ($.running) return; - log.runtime.Prepend(`${NXT} Runtime ~ ${import_timer5.timer.stop("runtime")}`, gray2.dim).toWrite({ trim: true }).Reset(); -}; -runtime.modes = function() { - if ($.mode.link) { - log.wrap( - "Select theme target/s to be inserted into your package.json file.", - "You will be given a code example after selecting where you will define", - "a custom target name. If you would like to create a new theme, then run", - `the ${cyan2("publish")} resource`, - gray2 - ); - } else { - if (!isEmpty($.filters)) { - const tui = Create().Newline().Line(`Filters${COL}`, white2.bold); - const space = eqWS($.filters); - for (const group in $.filters) { - const join29 = white2($.filters[group].map((k) => path2.relative($.cwd, k)).join(", ")); - tui.Line(` ${TLD} ${group}${COL}${space(group)}${join29}`, neonCyan); - } - tui.Newline().toLog({ clear: true }); - } - } -}; -runtime.stores = function() { - if (!$.mode.watch) return; - for (const url of ["editor", "preview"]) { - const width = $.target.reduce((size, { target, store }) => { - if (store.name.length > size.store) size.store = store.name.length; - if (target.length > size.theme) size.theme = target.length; - return size; - }, { - store: 0, - theme: 0 - }); - log.runtime.Line(plur(toUpcase(url), $.target.length) + COL, bold2.white).Each($.target, function({ target, store, editor, preview }) { - this.Line( - g.ws( - " ", - TLD, - pink(store.name), - WSP2.repeat(width.store - store.name.length), - ARR, - pink.bold(target), - WSP2.repeat(width.theme - target.length), - ARR, - WSP2, - gray2.underline(url === "editor" ? editor : preview) - ) - ); - }).True(url === "editor", (tui) => tui.Newline()); - } - log.runtime.NL.toWrite(); - if ($.mode.hot) { - if ($.mode.align) { - log.runtime.Spinner(`remote ${ARL} local merges`, { color: whiteBright2 }); - } else { - log.runtime.Spinner("configuring HOT Reloads", { color: whiteBright2 }); - } - } else if ($.mode.align) { - log.runtime.Spinner(`remote ${ARL} local merges`, { color: whiteBright2 }); - } -}; -runtime.hot = ({ isError = false } = {}) => { - log.runtime.Stop(); - if (isError) { - log.runtime.Line("Reloads" + COL, whiteBright2.bold).Line(` ${BAD} ${redBright2("server")} ${ARR} ${redBright2("FAILED")}`).Line(` ${BAD} ${redBright2("socket")} ${ARR} ${redBright2("FAILED")}`); - } else { - log.runtime.Line("Reloads" + COL, whiteBright2.bold).Line(` ${TLD} ${neonMagenta("method")} ${ARR} ${neonMagenta.bold(`${$.hot.method.toUpperCase()}`)}`).Line(` ${TLD} ${neonMagenta("server")} ${ARR} ${neonMagenta(`${$.hot.server}`)}`).Line(` ${TLD} ${neonMagenta("socket")} ${ARR} ${neonMagenta(`${$.hot.socket}`)}`); - } -}; -runtime.warnings = () => { - if (!$.config.log.warnings) return; - const props = keys(warnings); - const amount = props.reduce((n, k) => n = n + warnings[k].length, 0); - if (amount === 0) return; - log.runtime.Tree("warning").Line(`${amount} ${plur("Runtime Warning", amount)}`, bold2); - for (const key of props) { - const item = warnings[key]; - if (item.length > 0) { - const condition = item.length === amount; - log.runtime.True(condition, (tui) => tui.Line(`${key} ${plur("Warning", item.length)}${COL}`, bold2)).False(condition, (tui) => tui.Prepend(`${item.length} ${key} ${plur("Warning", item.length)}`, bold2)).Each(item, function(message) { - this.Line(` \uD800\uDD02 ${message}`, yellowBright2); - }); - } - } - log.runtime.Tree("info").Newline().toLog({ clear: true }); -}; -function server() { - const assets = path2.join($.dirs.output, "assets"); - const app = uws.uWS.App(); - app.get("/*", (response, request2) => { - const key = request2.getUrl(); - if (key === "/") { - response.endWithoutBody(); - } else { - const uri = path2.join(assets, key); - response.writeHeader("Access-Control-Allow-Origin", "*"); - response.writeHeader("Cache-Control", "public, max-age=0"); - switch (path2.extname(key)) { - case ".js": - case ".mjs": - response.writeHeader("Content-Type", "application/javascript"); - break; - case "css": - response.writeHeader("Content-Type", "text/css"); - break; - case "json": - response.writeHeader("Content-Type", "application/json"); - break; - } - if (fsExtra.existsSync(uri) && fsExtra.ensureFile(uri)) { - response.end(fsExtra.readFileSync(uri)); - } else { - response.endWithoutBody(); - } - } - }).listen($.hot.server, (token) => { - if (token === false) { - console.log("Failed to listen to port " + $.hot.server); - } - }); - return app; -} - -// syncify/hot/socket.ts -var wss = function wss2() { - const app = server(); - let listener; - const ws = app.ws("/ws", { - compression: uws.uWS.SHARED_COMPRESSOR, - maxPayloadLength: 16 * 1024 * 1024, - idleTimeout: 32, - sendPingsAutomatically: false, - open(ws2) { - HOT_SOCKET_TOPICS.forEach((topic) => ws2.subscribe(topic)); - }, - message(ws2, message, isBinary) { - const string = Buffer.from(message).toString(isBinary ? "binary" : "utf8"); - if (string.startsWith("ROUTE:")) { - $.hot.route = JSON.parse(string.slice(6)); - } else { - log.hot(string); - } - } - }); - $.wss = defineProperty(o(), "http", { get() { - return ws; - } }); - $.wss.alias = (json) => ws.publish("alias", `alias|${json}`); - $.wss.script = (uuid2, src) => ws.publish("script", `script,${src},${uuid2}`); - $.wss.stylesheet = (uuid2, href) => ws.publish("stylesheet", `stylesheet,${href},${uuid2}`); - $.wss.section = (id) => ws.publish("section", `section,${id}`); - $.wss.svg = (id) => ws.publish("svg", `svg,${id}`); - $.wss.assets = () => ws.publish("assets", "assets"); - $.wss.reload = () => ws.publish("reload", "reload"); - $.wss.replace = () => ws.publish("replace", "replace"); - $.wss.disconnect = () => ws.publish("disconnect", "disconnect"); - ws.publish("connected", "connected"); - ws.listen($.hot.socket, (token) => { - listener = token; - event.emit("hot:socket"); - token === false && log.error("Websocket connection failed", { suffix: "HOT" }); - }); - event.on("hot:socket", () => { - $.wss.alias(JSON.stringify($.hot.alias)); - }); - event.on("hot:failed", () => { - ws.close(); - app.close(); - uws.uWS.us_listen_socket_close(listener); - prexit.hooks.delete("hot:eject"); - runtime.hot({ isError: true }); - }); - if ($.hot.eject) { - prexit("hot:eject", async function() { - import_timer6.timer.start(); - log.ender($.log.group); - log.begin(`HOT ${CHV} Ejection`, { group: true }); - log.spinner("HOT snippet ejection", { style: "brielle", color: neonCyan }); - await removeSnippetInjections().then((layouts) => { - log.spinner.stop(); - forEach((layout) => log.line(`${magenta2(layout)} ${Append("HOT Snippet Removed")}`), layouts); - log.nl(); - log.line(gray2.dim(`${NXT} Exit took ~ ${import_timer6.timer.stop()}`)); - log.ender($.log.group, { clear: false }); - log.nl(""); - kill(() => { - ws.close(); - uws.uWS.us_listen_socket_close(listener); - }); - }); - }); - } -}; - -// syncify/hot/snippet.ts -function setHotOptions(injection) { - const { hot } = $; - return injection.replace("# inject@options", g.nl( - `assign server = ${hot.server}`, - ` assign socket = ${hot.socket}`, - ` assign method = '${hot.method}'`, - ` assign no-preview-bar = ${hot.flags["no-preview-bar"]}`, - ` assign no-web-pixels-manager = ${hot.flags["no-web-pixels-manager"]}`, - ` assign no-shopify-features = ${hot.flags["no-shopify-features"]}`, - ` assign no-checkout-preloads = ${hot.flags["no-checkout-preloads"]}`, - ` assign no-trekkie = ${hot.flags["no-trekkie"]}`, - ` assign no-perfkit = ${hot.flags["no-perfkit"]}` - )); -} -function getSnippetVersion(content) { - const source = content || fsExtra.readFileSync($.hot.source, "utf8"); - const start = source.indexOf("# v") + 3; - if (start > 2) { - const ender = source.indexOf("\n", start); - if (ender > -1) return source.slice(start, ender); - } - return null; -} -function removeRenderTag(content) { - const render2 = content.search(REGEX_HOT_SNIPPET); - if (render2 > -1) { - const start = content.slice(0, render2); - const slice = content.slice(content.indexOf("%}") + 2); - return start.replace(/\n$/, "") + slice.replace(/^\n/, ""); - } - return content; -} -function injectRenderSnippet(content) { - const ender = content.indexOf("") + 6; - const start = content.slice(0, ender); - return start + "\n{%- render 'hot.js' -%}\n" + content.slice(ender); -} -function hasSnippetInjection(content) { - return REGEX_HOT_SNIPPET.test(content); -} -function removeSnippetInjections() { - const request2 = forMap((key) => ({ - filename: `layout/${path2.basename(key)}`, - body: { - type: "TEXT", - value: fsExtra.readFileSync(key, "utf8") - } - }), $.hot.cache.layouts); - return new Promise((resolve2) => { - themeFilesUpsert(request2).then(({ synced }) => { - resolve2(forMap(({ filename }) => filename, synced)); - }); - }); -} -async function snippet2(theme2) { - const input = [HOT_SNIPPET_KEY, ...$.hot.layouts.map((layout) => `layout/${layout}`)]; - const promise = new Promise((resolve2, reject) => { - themeFilesList({ input, onError: reject }).then(({ files, errors }) => { - if (errors.length > 0) { - const warn2 = warnOption("HOT"); - forEach(({ filename, message }) => warn2(message, filename), errors); - } - const match = m(files.map((file) => [file.filename, file.body.content])); - const upsert = forMap((filename) => { - if (filename === HOT_SNIPPET_KEY) { - $.hot.alive.snippet = match.has(filename); - if (match.has(filename)) { - const content = match.get(filename); - $.hot.alive.snippet = true; - $.hot.version.remote = getSnippetVersion(content); - q.cache.add(() => fsExtra.writeFile($.hot.cache.snippet, content)); - } - const source = fsExtra.readFileSync($.hot.source, "utf8"); - return { - filename, - body: { - type: "TEXT", - value: setHotOptions(source) - } - }; - } else if (match.has(filename)) { - const cache = path2.join($.hot.cache.root, path2.basename(filename)); - const content = match.get(filename); - const exists2 = $.hot.alive.layouts[filename] = hasSnippetInjection(content); - $.hot.cache.layouts.push(cache); - q.cache.add(() => fsExtra.writeFile(cache, exists2 ? removeRenderTag(content) : content)); - return exists2 ? void 0 : { - filename, - body: { - type: "TEXT", - value: injectRenderSnippet(content) - } - }; - } else { - $.hot.alive.layouts[filename] = false; - } - }, input); - themeFilesUpsert({ input: upsert, onError: reject }).then(() => { - if ($.mode.align) { - resolve2("hot:active"); - } else { - resolve2("hot:active"); - } - }); - }); - }).then(wss); - await promise; -} - -// syncify/transform/terser/liquid.ts -function minifySchema(schema2) { - if ($.liquid.terse.liquid.minifySchema === false) { - if ($.json.useTab) { - return JSON.stringify(schema2, null, " ".repeat($.json.indent)); - } else { - return JSON.stringify(schema2, null, $.json.indent); - } - } - return JSON.stringify(schema2, null, 0); -} - -// syncify/transform/schema.ts -var SCHEMA_REGEX = /{%-?\s*schema/; -function SkipSchemaWithinComments(content) { - const length = content.length; - let searchFrom = 0; - do { - searchFrom = content.indexOf("endcomment", searchFrom); - if (searchFrom === -1) return 0; - const from = content.lastIndexOf("{%", searchFrom) + 2; - if (from > -1) { - const to = content.indexOf("%}", searchFrom + 10); - if (from > -1 && /-?endcomment-?/.test(content.slice(from, to).trim())) return to + 2; - } - } while (searchFrom < length); - return 0; -} -function GetSchemaTagLine(content) { - return content.split("\n").length - 1; -} -function GetSchemaIndices(content) { - if (!SCHEMA_REGEX.test(content)) return null; - const fromIndex = SkipSchemaWithinComments(content); - let start = -1; - if (fromIndex > -1) { - start = fromIndex + content.slice(fromIndex).search(SCHEMA_REGEX); - if (start < 0) return null; - } - const begin = content.indexOf("%}", start) + 2; - const ender = begin + content.slice(begin).search(/{%-?\s*endschema/); - return { start, begin, ender }; -} -async function ExtractSchema(file) { - const content = await fsExtra.readFile(file.input, "utf-8"); - const indices = GetSchemaIndices(content); - if (indices === null) return [content, null, null]; - const { begin, ender } = indices; - if (ender < 0) { - log.error("Missing {% endschema %} tag in file.", { - suffix: file.relative, - notify: { - title: `Error in ${file.base}`, - message: "Liquid schema tag in section is missing an endschema token" - } - }); - return null; - } - try { - const schema2 = json.parse(content.slice(begin, ender)); - return [ - content.slice(0, begin), - schema2, - content.slice(ender) - ]; - } catch (err) { - log.error(file.relative, { - notify: { - title: `Error in ${file.base}`, - message: "JSON Parse error occurred in the section schema tag" - } - }); - err.source = content; - error.json(err, file, GetSchemaTagLine(content.slice(0, begin))); - return null; - } -} -function InjectSettings(file, schema2) { - const settings = []; - for (let i = 0, s2 = schema2.length; i < s2; i++) { - if (!has("$ref", schema2[i])) { - settings.push(schema2[i]); - continue; - } - const [key, prop] = schema2[i].$ref.split("."); - if ($.section.shared.has(key)) { - const shared = $.section.shared.get(key); - if (has(prop, shared.schema)) { - if (isArray(shared.schema[prop])) { - settings.push(...shared.schema[prop]); - } else if (isObject(shared.schema[prop])) { - if (has("settings", shared.schema[prop])) { - settings.push(...shared.schema[prop].settings); - } else { - settings.push(shared.schema[prop]); - } - } - } else { - if ($.mode.build) { - warn.schema(file, { - shared: shared.uri, - $ref: schema2[i].$ref, - schema: "settings", - message: [ - `An unknown Shared Schema reference key of ${bold2(schema2[i].$ref)} was provided.`, - `There is no such key ${bold2(prop)} within the shared schema.` - ] - }); - } else { - log.warn(`undefined $ref ${bold2(prop)} in ${bold2(key)} `, file.base); - } - } - } else { - if ($.mode.build) { - warn.schema(file, { - shared: prop, - $ref: schema2[i].$ref, - schema: "settings", - message: [ - `An unknown Shared Schema file reference ${bold2(schema2[i].$ref)} was provided`, - `to ${bold2("settings")} within section file ${bold2(file.base)}. There is no known shared`, - "schema file using that name." - ] - }); - } else { - log.warn(`unknown $ref ${bold2(schema2[i].$ref)} `, file.base); - } - } - } - return settings; -} -function InjectBlocks(file, schema2) { - const blocks = []; - for (let i = 0, s2 = schema2.length; i < s2; i++) { - if (has("$ref", schema2[i])) { - const [key, prop] = schema2[i].$ref.split("."); - if ($.section.shared.has(key)) { - const shared = $.section.shared.get(key); - if (has(prop, shared.schema)) { - if (isArray(shared.schema[prop])) { - blocks.push(...shared.schema[prop]); - } else { - blocks.push(shared.schema[prop]); - } - } else { - if ($.mode.build) { - warn.schema(file, { - shared: prop, - $ref: schema2[i].$ref, - schema: "blocks", - message: [ - `An unknown Shared Schema key reference of ${bold2(schema2[i].$ref)} was provided`, - `to the ${bold2("blocks")} within section file ${bold2(file.base)}. The shared schema`, - `file exists, but the key ${bold2(prop)} does not.` - ] - }); - } else { - log.warn(`undefined $ref ${bold2(prop)} in ${bold2(key)} `, file.base); - } - } - } else { - if ($.mode.build) { - warn.schema(file, { - shared: prop, - $ref: schema2[i].$ref, - schema: "blocks", - message: [ - `An unknown Shared Schema file reference ${bold2(schema2[i].$ref)} was provided`, - `to ${bold2("blocks")} within section file ${bold2(file.base)}. There is no known shared`, - "schema file using that name." - ] - }); - } else { - log.warn(`unknown $ref ${bold2(schema2[i].$ref)} `, file.base); - } - } - } else { - const block = {}; - for (const prop in schema2[i]) { - if (prop !== "settings") block[prop] = schema2[i][prop]; - } - if (block.type === "@app") { - blocks.push(block); - continue; - } - block.settings = []; - if (has("settings", schema2[i])) { - for (const setting of schema2[i].settings) { - if (has("$ref", setting)) { - const [key, prop] = setting.$ref.split("."); - if ($.section.shared.has(key)) { - const shared = $.section.shared.get(key); - if (has(prop, shared.schema)) { - if (isArray(shared.schema[prop])) { - block.settings.push(...shared.schema[prop]); - } else if (isObject(shared.schema[prop])) { - if (has("settings", shared.schema[prop])) { - block.settings.push(...shared.schema[prop].settings); - } else { - block.settings.push(shared.schema[prop]); - } - } - } else { - if ($.mode.build) { - warn.schema(file, { - shared: prop, - $ref: schema2[i].$ref, - schema: `blocks ${ARR} settings`, - message: [ - `An unknown Shared Schema key reference of ${bold2(schema2[i].$ref)} was provided`, - `to the ${bold2("blocks")} schema id ${bold2(setting.id)} within section file`, - `${bold2(file.base)}. The shared schema file exists, but the key ${bold2(prop)} does not.` - ] - }); - } else { - log.warn(`undefined $ref ${bold2(prop)} in ${bold2(key)} `, file.base); - } - } - } else { - if ($.mode.build) { - warn.schema(file, { - shared: prop, - $ref: schema2[i].$ref, - schema: `blocks ${ARR} settings`, - message: [ - `An unknown Shared Schema file reference ${bold2(schema2[i].$ref)} was provided`, - `to ${bold2("blocks")} schema id ${bold2(setting.id)} within section file ${bold2(file.base)}.`, - "There is no known shared schema file using that name." - ] - }); - } else { - log.warn(`unknown $ref ${bold2(setting.$ref)} `, file.base); - } - } - } else { - block.settings.push(setting); - } - } - } - blocks.push(block); - } - } - return blocks; -} -async function ParseSharedSchema(file) { - try { - const read = await fsExtra.readFile(file.input); - const hash = checksum(read); - if (has(file.input, $.cache.schema) && $.cache.checksum[file.input] === hash && $.section.shared.has(file.name)) { - return $.section.shared.get(file.name); - } - ; - $.cache.checksum[file.input] = hash; - const data = read.toString(); - if (data.trim().length === 0) { - log.warn("empty file", "no shared schema defined"); - return null; - } - const schema2 = json.parse(data.toString()); - if (has("$schema", schema2)) delete schema2.$schema; - if (has("$description", schema2)) delete schema2.$description; - for (const prop in schema2) { - if (isObject(schema2[prop])) { - if (has("$description", schema2[prop])) { - delete schema2[prop].$description; - } - } else if (isArray(schema2[prop])) { - for (const setting of schema2[prop]) { - if (has("$description", setting)) delete setting.$description; - } - } - } - return $.section.shared.set(file.name, { uri: file.input, schema: schema2 }).get(file.name); - } catch (e) { - log.error(file.relative, { - notify: { - title: `Error in ${file.base}`, - message: "JSON Syntax error in shared schema file" - } - }); - error.json(e, file); - return null; - } -} -async function CreateSection(file) { - const read = await ExtractSchema(file); - if (read === null) return null; - const [before, schema2, after] = read; - if (schema2 === null) return before; - const schemaProp = hasProp(schema2); - if (schemaProp("settings")) { - schema2.settings = InjectSettings(file, schema2.settings); - } - if (schemaProp("blocks")) { - schema2.blocks = InjectBlocks(file, schema2.blocks); - } - return g(before.trimEnd(), "\n", minifySchema(schema2), "\n", after.trimStart()); -} -async function getSchemaFiles(sections) { - for (let i = 0, s2 = sections.length; i < s2; i++) { - sections[i].value = await CreateSection(sections[i]); - } - return sections; -} -async function SchemaTransform(file) { - const shared = await ParseSharedSchema(file); - if (shared === null) return null; - const schemas = toArray($.cache.schema[shared.uri]); - const sections = await pMap(schemas, (p) => { - return defineProperty(file.data(p), "data", { - get() { - return $.cache.sections[p]; - } - }); - }); - log.process("Shared Schema", `${sections.length} ${plur("section", sections.length)}`); - const files = await getSchemaFiles(sections); - if (files.length > 1) { - log.syncing(`${files.length} files`); - } else { - log.syncing(files[0].key); - } - await themeFilesUpsertMap(files); - if ($.mode.hot && $.mode.bulk === false) { - for (const section2 of files) { - if (file.type === 5 /* Section */) { - $.wss.section(section2.name); - } else if (section2.type !== 12 /* Script */ && section2.type !== 11 /* Style */) { - await q.http.onIdle().then(() => $.wss.replace()); - } - } - } -} - -// syncify/transform/liquid.ts -var LiquidLineComments = /{%-?\s*#[\s\S]+?%}/g; -var LiquidBlockComments = /{%-?\s*comment\s*-?%}[\s\S]+?{%-?\s*endcomment\s*-?%}/g; -var LiquidTag = /{%-?\s*liquid[\s\S]+?%}/g; -var ScriptJsonWhitespace = /[^,:'"a-zA-Z0-9=] +[^'"a-zA-Z0-9=}{]/g; -function removeComments(content) { - return $.liquid.terse.markup.removeComments ? content.replace(LiquidBlockComments, "").replace(LiquidLineComments, "") : content; -} -function minifyLiquidTag(content) { - return content.replace(LiquidTag, (tag) => "\n" + tag.replace(/#.*?$/gm, "") + "\n"); -} -function minifySchema2(file, content) { - if (!$.liquid.terse.liquid.minifySchema) return removeComments(content); - const open = content.search(/{%-?\s*schema/); - if (open > -1) { - const begin = content.indexOf("%}", open + 2) + 2; - const start = content.slice(begin); - const ender = begin + start.search(/{%-?\s*endschema/); - if (ender > -1) { - const parse10 = JSON.parse(content.slice(begin, ender)); - const minified = JSON.stringify(parse10, null, 0); - const schema2 = content.slice(0, begin) + minified + content.slice(ender); - return removeComments(schema2); - } - log.invalid(file.relative); - } - return removeComments(content); -} -function removeDashes(content) { - if (!$.liquid.terse.liquid.stripTrims) return content; - return content; -} -async function htmlMinify(file, content) { - try { - const htmlmin = await $import.terser.minify(content, $.liquid.terse.markup); - return htmlmin; - } catch (e) { - log.error(file.relative, { - notify: { - title: "Parse Error", - message: `Terse minification error in ${file.base}` - } - }); - error.terser(file, e); - return null; - } -} -async function transform(file, data) { - if (!$.mode.terse) { - fsExtra.writeFile(file.output, data).catch( - error.write("Error writing liquid file to output", { - input: file.relative, - output: path2.relative($.cwd, file.output) - }) - ); - log.transform( - toUpcase(file.namespace), - file.kind, - byteConvert(file.size), - import_timer7.timer.now() - ); - return data; - } - let htmlmin; - if (file.base.endsWith(".js.liquid")) { - htmlmin = data.replace(ScriptJsonWhitespace, "").replace(/(?<=[:,]) +(?=['"{[])/g, "").replace(/{{%/g, "{ {%").replace(/%}}/g, "%} }").replace(/(?<=[%}]})\s+(?=[\]}])/g, " ").replace(/>\s+(?=[{[])/, ">").replace(/(?<=[}\]])\s<\//g, " $.wss.replace()); - } - } - return file.value; -} -var import_timer8 = __toESM(require_dist()); -async function esbuildBundle(bundle) { - bundle.watch.clear(); - const result = await esbuild__default.default.build(bundle.esbuild); - if ($.mode.terse && $.mode.build) { - bundle.size = byteSize(result.outputFiles[0].text); - } - if ($.mode.watch) { - await getWatchPaths(bundle, result.metafile.inputs); - } else { - if (!bundle.watch.has(bundle.input)) { - bundle.watch.add(bundle.input); - } - } -} -async function getWatchPaths(bundle, inputs) { - const { cwd: cwd2, mode } = $; - for (const file in inputs) { - if (file.indexOf("/node_modules/") > -1) continue; - const path5 = path2.join(cwd2, file); - if (!bundle.watch.has(path5)) bundle.watch.add(path5); - if (mode.watch) ; - } - if (mode.watch) { - await pNext().then(() => { - for (const path5 of bundle.watch) { - if (path5.indexOf("/node_modules/") > -1) continue; - if (bundle.watchCustom !== null && bundle.watchCustom(path5)) continue; - if (!has(path5.slice(cwd2.length + 1), inputs)) bundle.watch.delete(path5); - } - }); - } -} -function createSnippet2(string, attrs) { - return attrs.length > 0 ? `` : ``; -} -async function ScriptTransform(file) { - if (!file.data) return; - const { hot, watch, terse, bulk: bulk2, build } = $.mode; - if (watch) import_timer8.timer.start(); - if (hot) import_timer8.timer.start(file.uuid); - const files = await pMap(file.data, async (bundle) => { - const { key, input, output, snippet: snippet3, attrs, esbuild: { format: format2 } } = bundle; - const { metafile, outputFiles, warnings: warnings2 } = await esbuild__default.default.build(bundle.esbuild); - if (file.data.length > 1) { - log.nl().write(path2.relative($.cwd, input)); - } - if ($.mode.watch) { - await getWatchPaths(bundle, metafile.inputs); - } - if (warnings2.length > 0) { - warn.esbuild(warnings2); - } - for (const { text, path: path5 } of outputFiles) { - if (path5.endsWith(".map")) { - const map = path2.join($.dirs.sourcemaps.scripts, `${file.base}.map`); - q.tasks.add(() => fsExtra.writeFile(map, text).catch( - error.write("Error writing JavaScript Source Map to cache", { - output: $.dirs.sourcemaps.scripts, - source: file.relative - }) - )); - } else { - if (terse) { - if (isNaN(bundle.size)) { - log.transform(file.kind, `${bold2(format2.toUpperCase())} bundle`); - log.minified(stringSize(text)); - } else { - const size = sizeDiff(text, bundle.size); - log.transform(`${bold2(format2.toUpperCase())} bundle ${ARR} ${bold2(stringSize(text))}`); - log.minified(null, size.before, size.after, size.saved); - } - } else { - log.transform(`${bold2(format2.toUpperCase())} bundle ${ARR} ${bold2(stringSize(text))}`); - } - if (snippet3) { - bundle.value = createSnippet2(text, attrs); - await fsExtra.writeFile(output, bundle.value).catch( - error.write("Error writing inline