UNPKG

@wix/cli

Version:

CLI tool for building Wix sites and applications

816 lines (801 loc) 25 kB
import { createRequire as _createRequire } from 'node:module'; const require = _createRequire(import.meta.url); import { wixAstroConfigSchema } from "./chunk-KCDAY54L.js"; import { stripAnsi } from "./chunk-AFPDHQYI.js"; import { getWixConfigFilePath } from "./chunk-4UTFAKA5.js"; import { pathExists } from "./chunk-TLLAD5LU.js"; import { CliError, CliErrorCode } from "./chunk-CO5A7CZG.js"; import { init_esm_shims } from "./chunk-EXLZF52D.js"; // ../cli-command-contract/src/index.ts init_esm_shims(); var NO_TTY_JSON_OUTPUT_OPTION = "--json"; // ../cli-plugin-config/src/parse-stderr.ts init_esm_shims(); var hasStringStderr = (maybeError) => { return typeof maybeError === "object" && maybeError != null && "stderr" in maybeError && typeof maybeError.stderr === "string"; }; var SECTION_MARKERS = { "Hint:": "hint", "Error reference:": "errorReference", "Location:": "location", "Stack trace:": "stacktrace" }; var TIMESTAMPED_LOG_LINE = /^\d{2}:\d{2}:\d{2}\s/; var PACKAGE_MANAGER_NOISE_LINE = /^(npm (warn|notice)\b|warning |➤ YN\d+)/i; var FILE_LINE_COLUMN = /^(.+):(\d+):(\d+)$/; var joinLines = (lines) => { return lines.join("\n") || void 0; }; var isNoise = (line) => PACKAGE_MANAGER_NOISE_LINE.test(line); var dropEdgeNoise = (lines) => { const first = lines.findIndex((line) => !isNoise(line)); const last = lines.findLastIndex((line) => !isNoise(line)); return first === -1 ? lines : lines.slice(first, last + 1); }; var parseLocationLine = (line) => { const match = FILE_LINE_COLUMN.exec(line); const [, file, lineNumber, column] = match ?? []; if (file == null || lineNumber == null || column == null) { return { file: line }; } return { file, line: Number(lineNumber), column: Number(column) }; }; var parseSections = (stderr) => { const sections = { message: [], hint: [], errorReference: [], location: [], stacktrace: [] }; let section = "message"; for (const line of stderr.split("\n")) { const trimmed = line.trim(); if (!trimmed || TIMESTAMPED_LOG_LINE.test(trimmed)) { continue; } const nextSection = SECTION_MARKERS[trimmed]; if (nextSection != null) { section = nextSection; continue; } sections[section].push(trimmed); } const [locationLine] = sections.location; return { message: joinLines(dropEdgeNoise(sections.message)), location: locationLine != null ? parseLocationLine(locationLine) : void 0, stack: joinLines(dropEdgeNoise(sections.stacktrace)) }; }; var parseStdErr = (e) => { let stderr; try { stderr = hasStringStderr(e) ? stripAnsi(e.stderr) : void 0; } catch { return void 0; } if (stderr == null || stderr === "") { return void 0; } try { return { raw: stderr, ...parseSections(stderr) }; } catch { return { raw: stderr }; } }; // ../cli-plugin-config/src/index.ts init_esm_shims(); // ../cli-plugin-config/src/plugins/hooks.ts init_esm_shims(); var USER_HOOK_NAMES = ["cli:setup"]; // ../cli-plugin-config/src/plugins/plugins-interface.ts init_esm_shims(); // ../../node_modules/emittery/index.js init_esm_shims(); // ../../node_modules/emittery/maps.js init_esm_shims(); var anyMap = /* @__PURE__ */ new WeakMap(); var eventsMap = /* @__PURE__ */ new WeakMap(); var producersMap = /* @__PURE__ */ new WeakMap(); // ../../node_modules/emittery/index.js var anyProducer = Symbol("anyProducer"); var resolvedPromise = Promise.resolve(); var listenerAdded = Symbol("listenerAdded"); var listenerRemoved = Symbol("listenerRemoved"); var canEmitMetaEvents = false; var isGlobalDebugEnabled = false; var isEventKeyType = (key) => typeof key === "string" || typeof key === "symbol" || typeof key === "number"; function assertEventName(eventName) { if (!isEventKeyType(eventName)) { throw new TypeError("`eventName` must be a string, symbol, or number"); } } function assertListener(listener) { if (typeof listener !== "function") { throw new TypeError("listener must be a function"); } } function getListeners(instance, eventName) { const events = eventsMap.get(instance); if (!events.has(eventName)) { return; } return events.get(eventName); } function getEventProducers(instance, eventName) { const key = isEventKeyType(eventName) ? eventName : anyProducer; const producers = producersMap.get(instance); if (!producers.has(key)) { return; } return producers.get(key); } function enqueueProducers(instance, eventName, eventData) { const producers = producersMap.get(instance); if (producers.has(eventName)) { for (const producer of producers.get(eventName)) { producer.enqueue(eventData); } } if (producers.has(anyProducer)) { const item = Promise.all([eventName, eventData]); for (const producer of producers.get(anyProducer)) { producer.enqueue(item); } } } function iterator(instance, eventNames) { eventNames = Array.isArray(eventNames) ? eventNames : [eventNames]; let isFinished = false; let flush = () => { }; let queue = []; const producer = { enqueue(item) { queue.push(item); flush(); }, finish() { isFinished = true; flush(); } }; for (const eventName of eventNames) { let set = getEventProducers(instance, eventName); if (!set) { set = /* @__PURE__ */ new Set(); const producers = producersMap.get(instance); producers.set(eventName, set); } set.add(producer); } return { async next() { if (!queue) { return { done: true }; } if (queue.length === 0) { if (isFinished) { queue = void 0; return this.next(); } await new Promise((resolve) => { flush = resolve; }); return this.next(); } return { done: false, value: await queue.shift() }; }, async return(value) { queue = void 0; for (const eventName of eventNames) { const set = getEventProducers(instance, eventName); if (set) { set.delete(producer); if (set.size === 0) { const producers = producersMap.get(instance); producers.delete(eventName); } } } flush(); return arguments.length > 0 ? { done: true, value: await value } : { done: true }; }, [Symbol.asyncIterator]() { return this; } }; } function defaultMethodNamesOrAssert(methodNames) { if (methodNames === void 0) { return allEmitteryMethods; } if (!Array.isArray(methodNames)) { throw new TypeError("`methodNames` must be an array of strings"); } for (const methodName of methodNames) { if (!allEmitteryMethods.includes(methodName)) { if (typeof methodName !== "string") { throw new TypeError("`methodNames` element must be a string"); } throw new Error(`${methodName} is not Emittery method`); } } return methodNames; } var isMetaEvent = (eventName) => eventName === listenerAdded || eventName === listenerRemoved; function emitMetaEvent(emitter, eventName, eventData) { if (!isMetaEvent(eventName)) { return; } try { canEmitMetaEvents = true; emitter.emit(eventName, eventData); } finally { canEmitMetaEvents = false; } } var Emittery = class _Emittery { static mixin(emitteryPropertyName, methodNames) { methodNames = defaultMethodNamesOrAssert(methodNames); return (target) => { if (typeof target !== "function") { throw new TypeError("`target` must be function"); } for (const methodName of methodNames) { if (target.prototype[methodName] !== void 0) { throw new Error(`The property \`${methodName}\` already exists on \`target\``); } } function getEmitteryProperty() { Object.defineProperty(this, emitteryPropertyName, { enumerable: false, value: new _Emittery() }); return this[emitteryPropertyName]; } Object.defineProperty(target.prototype, emitteryPropertyName, { enumerable: false, get: getEmitteryProperty }); const emitteryMethodCaller = (methodName) => function(...args) { return this[emitteryPropertyName][methodName](...args); }; for (const methodName of methodNames) { Object.defineProperty(target.prototype, methodName, { enumerable: false, value: emitteryMethodCaller(methodName) }); } return target; }; } static get isDebugEnabled() { if (typeof globalThis.process?.env !== "object") { return isGlobalDebugEnabled; } const { env } = globalThis.process ?? { env: {} }; return env.DEBUG === "emittery" || env.DEBUG === "*" || isGlobalDebugEnabled; } static set isDebugEnabled(newValue) { isGlobalDebugEnabled = newValue; } constructor(options = {}) { anyMap.set(this, /* @__PURE__ */ new Set()); eventsMap.set(this, /* @__PURE__ */ new Map()); producersMap.set(this, /* @__PURE__ */ new Map()); producersMap.get(this).set(anyProducer, /* @__PURE__ */ new Set()); this.debug = options.debug ?? {}; if (this.debug.enabled === void 0) { this.debug.enabled = false; } if (!this.debug.logger) { this.debug.logger = (type, debugName, eventName, eventData) => { try { eventData = JSON.stringify(eventData); } catch { eventData = `Object with the following keys failed to stringify: ${Object.keys(eventData).join(",")}`; } if (typeof eventName === "symbol" || typeof eventName === "number") { eventName = eventName.toString(); } const currentTime = /* @__PURE__ */ new Date(); const logTime = `${currentTime.getHours()}:${currentTime.getMinutes()}:${currentTime.getSeconds()}.${currentTime.getMilliseconds()}`; console.log(`[${logTime}][emittery:${type}][${debugName}] Event Name: ${eventName} data: ${eventData}`); }; } } logIfDebugEnabled(type, eventName, eventData) { if (_Emittery.isDebugEnabled || this.debug.enabled) { this.debug.logger(type, this.debug.name, eventName, eventData); } } on(eventNames, listener, { signal } = {}) { assertListener(listener); eventNames = Array.isArray(eventNames) ? eventNames : [eventNames]; for (const eventName of eventNames) { assertEventName(eventName); let set = getListeners(this, eventName); if (!set) { set = /* @__PURE__ */ new Set(); const events = eventsMap.get(this); events.set(eventName, set); } set.add(listener); this.logIfDebugEnabled("subscribe", eventName, void 0); if (!isMetaEvent(eventName)) { emitMetaEvent(this, listenerAdded, { eventName, listener }); } } const off = () => { this.off(eventNames, listener); signal?.removeEventListener("abort", off); }; signal?.addEventListener("abort", off, { once: true }); if (signal?.aborted) { off(); } return off; } off(eventNames, listener) { assertListener(listener); eventNames = Array.isArray(eventNames) ? eventNames : [eventNames]; for (const eventName of eventNames) { assertEventName(eventName); const set = getListeners(this, eventName); if (set) { set.delete(listener); if (set.size === 0) { const events = eventsMap.get(this); events.delete(eventName); } } this.logIfDebugEnabled("unsubscribe", eventName, void 0); if (!isMetaEvent(eventName)) { emitMetaEvent(this, listenerRemoved, { eventName, listener }); } } } once(eventNames, predicate) { if (predicate !== void 0 && typeof predicate !== "function") { throw new TypeError("predicate must be a function"); } let off_; const promise = new Promise((resolve) => { off_ = this.on(eventNames, (data) => { if (predicate && !predicate(data)) { return; } off_(); resolve(data); }); }); promise.off = off_; return promise; } events(eventNames) { eventNames = Array.isArray(eventNames) ? eventNames : [eventNames]; for (const eventName of eventNames) { assertEventName(eventName); } return iterator(this, eventNames); } async emit(eventName, eventData) { assertEventName(eventName); if (isMetaEvent(eventName) && !canEmitMetaEvents) { throw new TypeError("`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`"); } this.logIfDebugEnabled("emit", eventName, eventData); enqueueProducers(this, eventName, eventData); const listeners = getListeners(this, eventName) ?? /* @__PURE__ */ new Set(); const anyListeners = anyMap.get(this); const staticListeners = [...listeners]; const staticAnyListeners = isMetaEvent(eventName) ? [] : [...anyListeners]; await resolvedPromise; await Promise.all([ ...staticListeners.map(async (listener) => { if (listeners.has(listener)) { return listener(eventData); } }), ...staticAnyListeners.map(async (listener) => { if (anyListeners.has(listener)) { return listener(eventName, eventData); } }) ]); } async emitSerial(eventName, eventData) { assertEventName(eventName); if (isMetaEvent(eventName) && !canEmitMetaEvents) { throw new TypeError("`eventName` cannot be meta event `listenerAdded` or `listenerRemoved`"); } this.logIfDebugEnabled("emitSerial", eventName, eventData); enqueueProducers(this, eventName, eventData); const listeners = getListeners(this, eventName) ?? /* @__PURE__ */ new Set(); const anyListeners = anyMap.get(this); const staticListeners = [...listeners]; const staticAnyListeners = isMetaEvent(eventName) ? [] : [...anyListeners]; await resolvedPromise; for (const listener of staticListeners) { if (listeners.has(listener)) { await listener(eventData); } } for (const listener of staticAnyListeners) { if (anyListeners.has(listener)) { await listener(eventName, eventData); } } } onAny(listener, { signal } = {}) { assertListener(listener); this.logIfDebugEnabled("subscribeAny", void 0, void 0); anyMap.get(this).add(listener); emitMetaEvent(this, listenerAdded, { listener }); const offAny = () => { this.offAny(listener); signal?.removeEventListener("abort", offAny); }; signal?.addEventListener("abort", offAny, { once: true }); if (signal?.aborted) { offAny(); } return offAny; } anyEvent() { return iterator(this); } offAny(listener) { assertListener(listener); this.logIfDebugEnabled("unsubscribeAny", void 0, void 0); emitMetaEvent(this, listenerRemoved, { listener }); anyMap.get(this).delete(listener); } clearListeners(eventNames) { eventNames = Array.isArray(eventNames) ? eventNames : [eventNames]; for (const eventName of eventNames) { this.logIfDebugEnabled("clear", eventName, void 0); if (isEventKeyType(eventName)) { const set = getListeners(this, eventName); if (set) { set.clear(); } const producers = getEventProducers(this, eventName); if (producers) { for (const producer of producers) { producer.finish(); } producers.clear(); } } else { anyMap.get(this).clear(); for (const [eventName2, listeners] of eventsMap.get(this).entries()) { listeners.clear(); eventsMap.get(this).delete(eventName2); } for (const [eventName2, producers] of producersMap.get(this).entries()) { for (const producer of producers) { producer.finish(); } producers.clear(); producersMap.get(this).delete(eventName2); } } } } listenerCount(eventNames) { eventNames = Array.isArray(eventNames) ? eventNames : [eventNames]; let count = 0; for (const eventName of eventNames) { if (isEventKeyType(eventName)) { count += anyMap.get(this).size + (getListeners(this, eventName)?.size ?? 0) + (getEventProducers(this, eventName)?.size ?? 0) + (getEventProducers(this)?.size ?? 0); continue; } if (eventName !== void 0) { assertEventName(eventName); } count += anyMap.get(this).size; for (const value of eventsMap.get(this).values()) { count += value.size; } for (const value of producersMap.get(this).values()) { count += value.size; } } return count; } bindMethods(target, methodNames) { if (typeof target !== "object" || target === null) { throw new TypeError("`target` must be an object"); } methodNames = defaultMethodNamesOrAssert(methodNames); for (const methodName of methodNames) { if (target[methodName] !== void 0) { throw new Error(`The property \`${methodName}\` already exists on \`target\``); } Object.defineProperty(target, methodName, { enumerable: false, value: this[methodName].bind(this) }); } } }; var allEmitteryMethods = Object.getOwnPropertyNames(Emittery.prototype).filter((v) => v !== "constructor"); Object.defineProperty(Emittery, "listenerAdded", { value: listenerAdded, writable: false, enumerable: true, configurable: false }); Object.defineProperty(Emittery, "listenerRemoved", { value: listenerRemoved, writable: false, enumerable: true, configurable: false }); // ../cli-plugin-config/src/plugins/events-wrapper.ts init_esm_shims(); var UserEventWrapper = class { constructor(pluginsInterface, pluginName) { this.pluginsInterface = pluginsInterface; this.pluginName = pluginName; } on(key, callback) { return this.pluginsInterface.eventsEmitter.on(key, async (data) => { try { await callback(data); } catch (e) { this.pluginsInterface.onPluginError?.(e, { handlerName: key, pluginName: this.pluginName }); } }); } }; // ../cli-plugin-config/src/plugins/assertions.ts init_esm_shims(); var MIN_PLUGIN_NAME_LENGTH = 3; var normalizePluginName = (name) => { return name.trim().toLowerCase(); }; function throwInvalidConfigDefinition(reason) { throw new CliError({ code: CliErrorCode.InvalidConfigDefinition({ reason }), cause: null }); } function assertRecord(value, reason) { if (typeof value !== "object" || value == null || Array.isArray(value)) { throwInvalidConfigDefinition(reason); } } function assertPluginsProp(plugins) { if (plugins !== void 0 && !Array.isArray(plugins)) { throwInvalidConfigDefinition("`plugins` must be an array."); } } function assertPluginName(plugin, index) { assertRecord(plugin, `"plugins[${index}]" must be an object.`); if (typeof plugin.name !== "string" || normalizePluginName(plugin.name).length < MIN_PLUGIN_NAME_LENGTH) { throwInvalidConfigDefinition( `"plugins[${index}].name" must be a string at least ${MIN_PLUGIN_NAME_LENGTH} characters long.` ); } } function assertPluginHooksShape(plugin, name) { if (plugin.hooks !== void 0) { assertRecord( plugin.hooks, `"hooks" property in plugin "${name}" must be an object.` ); } } function assertUserHookName(key, pluginName) { if (!USER_HOOK_NAMES.includes(key)) { throw new CliError({ code: CliErrorCode.PluginUnknownHook({ hook: key, supportedHooks: [...USER_HOOK_NAMES], pluginName }), cause: null }); } } function assertUserHookHandler(entry, pluginName) { const [key, value] = entry; assertUserHookName(key, pluginName); if (typeof value !== "function") { throw new CliError({ code: CliErrorCode.PluginInvalidHookHandler({ hook: key, pluginName }), cause: null }); } } // ../cli-plugin-config/src/plugins/plugins-interface.ts function registerCliSetupHook(pluginsInterface, pluginName, hook, handler) { pluginsInterface.hooksEmitter.on(hook, async (data) => { try { await handler({ ...data, emitter: new UserEventWrapper(pluginsInterface, pluginName) }); } catch (e) { pluginsInterface.onPluginError?.(e, { handlerName: hook, pluginName }); } }); } function createPluginsInterface(plugins) { assertPluginsProp(plugins); const pluginsInterface = { hooksEmitter: new Emittery(), eventsEmitter: new Emittery() }; const seenPluginNameIndexes = /* @__PURE__ */ new Map(); for (const [index, plugin] of (plugins ?? []).entries()) { assertPluginName(plugin, index); const normalizedName = normalizePluginName(plugin.name); const firstIndex = seenPluginNameIndexes.get(normalizedName); if (firstIndex !== void 0) { throw new CliError({ code: CliErrorCode.PluginDuplicateName({ name: normalizedName, firstIndex, duplicateIndex: index }), cause: null }); } seenPluginNameIndexes.set(normalizedName, index); assertPluginHooksShape(plugin, plugin.name); const pluginHooks = plugin.hooks; if (pluginHooks === void 0) { continue; } for (const entry of Object.entries(pluginHooks)) { assertUserHookHandler(entry, plugin.name); const [hook, handler] = entry; registerCliSetupHook(pluginsInterface, plugin.name, hook, handler); } } return pluginsInterface; } // ../cli-plugin-config/src/import-config.ts init_esm_shims(); import { pathToFileURL } from "node:url"; // ../cli-plugin-config/src/wix-config.ts init_esm_shims(); import { join } from "node:path"; var DYNAMIC_WIX_CONFIG_FILENAME = "wix.config.mjs"; var getExistingWixConfigPaths = async (projectFolder) => { const dynamicConfigPath = join(projectFolder, DYNAMIC_WIX_CONFIG_FILENAME); const legacyConfigPath = getWixConfigFilePath(projectFolder); const [dynamicConfigExists, legacyConfigExists] = await Promise.all([ pathExists(dynamicConfigPath), pathExists(legacyConfigPath) ]); return { dynamicConfigPath: dynamicConfigExists ? dynamicConfigPath : void 0, legacyConfigPath: legacyConfigExists ? legacyConfigPath : void 0 }; }; var validateWixConfig = (value, configPath) => { const config = wixAstroConfigSchema.safeParse(value); if (config.success) { return config.data; } throw new CliError({ code: CliErrorCode.InvalidConfigSchemaError({ configPath, zodError: config.error }), cause: config.error }); }; // ../cli-plugin-config/src/import-config.ts function validateDefinedWixConfig(value, configPath) { if (typeof value !== "object" || value == null || Array.isArray(value)) { throw new CliError({ code: CliErrorCode.InvalidConfigDefinition({ reason: "`defineWixConfig` expects a configuration object." }), cause: null }); } if (!Object.hasOwn(value, "config")) { throw new CliError({ code: CliErrorCode.InvalidConfigDefinition({ reason: "`defineWixConfig` expects a `config` property." }), cause: null }); } return { config: validateWixConfig( value.config, configPath ), pluginsInterface: createPluginsInterface( value.plugins ) }; } var importWixConfig = async (projectFolder) => { const { dynamicConfigPath, legacyConfigPath } = await getExistingWixConfigPaths(projectFolder); const allConfigPaths = [ ...dynamicConfigPath != null ? [dynamicConfigPath] : [], ...legacyConfigPath != null ? [legacyConfigPath] : [] ]; if (allConfigPaths.length > 1) { throw new CliError({ code: CliErrorCode.MultipleConfigFiles({ paths: allConfigPaths }), cause: null }); } if (dynamicConfigPath == null) { throw new CliError({ code: CliErrorCode.InvalidConfigDefinition({ reason: `This project expected to have dynamic wix config in "${DYNAMIC_WIX_CONFIG_FILENAME}"` }), cause: null }); } let importedConfig; const pathToConfig = pathToFileURL(dynamicConfigPath).href; try { importedConfig = await import(pathToConfig); } catch (error) { throw new CliError({ code: CliErrorCode.InvalidConfigDefinition({ reason: `Failed to import wix config from "${pathToConfig}"` }), cause: error }); } if (!Object.hasOwn(importedConfig, "default")) { throw new CliError({ code: CliErrorCode.ConfigNoDefaultExport({ path: dynamicConfigPath }), cause: null }); } return validateDefinedWixConfig(importedConfig.default, dynamicConfigPath); }; export { NO_TTY_JSON_OUTPUT_OPTION, getExistingWixConfigPaths, validateWixConfig, importWixConfig, parseStdErr }; //# sourceMappingURL=chunk-RJAXCJJK.js.map