UNPKG

@shopify/cli

Version:

A CLI tool to build for the Shopify platform

204 lines (199 loc) • 8.39 kB
import { fetch, jsonOutputEnabled, z } from "./chunk-Q76H7OUL.js"; import { CLI_KIT_VERSION } from "./chunk-Z2AIGIVT.js"; import { cacheRetrieve, cacheStore, versionSatisfies } from "./chunk-KDFL67TE.js"; import { AbortSilentError, exec, isTruthy, outputDebug, renderError, renderInfo, renderWarning } from "./chunk-4NC2NVYY.js"; import { init_cjs_shims } from "./chunk-PKR7KJ6P.js"; // ../cli-kit/dist/public/node/notifications-system.js init_cjs_shims(); // ../cli-kit/dist/public/node/global-context.js init_cjs_shims(); var _globalContext; function getGlobalContext() { return _globalContext || (_globalContext = { currentCommandId: "" }), _globalContext; } function getCurrentCommandId() { return getGlobalContext().currentCommandId; } function setCurrentCommandId(commandId) { getGlobalContext().currentCommandId = commandId; } // ../cli-kit/dist/public/node/notifications-system.js var URL = "https://cdn.shopify.com/static/cli/notifications.json", EMPTY_CACHE_MESSAGE = "Cache is empty", COMMANDS_TO_SKIP = [ "notifications:list", "notifications:generate", "init", "app:init", "theme:init", "hydrogen:init", "cache:clear" ]; function url() { return process.env.SHOPIFY_CLI_NOTIFICATIONS_URL ?? URL; } var NotificationSchema = z.object({ id: z.string(), message: z.string(), type: z.enum(["info", "warning", "error"]), frequency: z.enum(["always", "once", "once_a_day", "once_a_week"]), ownerChannel: z.string(), cta: z.object({ label: z.string(), url: z.string().url() }).optional(), title: z.string().optional(), minVersion: z.string().optional(), maxVersion: z.string().optional(), minDate: z.string().optional(), maxDate: z.string().optional(), commands: z.array(z.string()).optional(), surface: z.string().optional() }), NotificationsSchema = z.object({ notifications: z.array(NotificationSchema) }); async function showNotificationsIfNeeded(currentSurfaces, environment = process.env) { try { let commandId = getCurrentCommandId(); if (skipNotifications(commandId, environment) || jsonOutputEnabled(environment)) return; let notifications = await getNotifications(), notificationsToShow = filterNotifications(notifications.notifications, commandId, currentSurfaces); outputDebug(`Notifications to show: ${notificationsToShow.length}`), await renderNotifications(notificationsToShow); } catch (error) { if (error.message === EMPTY_CACHE_MESSAGE) { outputDebug("Notifications to show: 0 (Cache is empty)"); return; } if (error.message === "abort") throw new AbortSilentError(); let errorMessage = `Error showing notifications: ${error.message}`; outputDebug(errorMessage); let { sendErrorToBugsnag } = await import("./error-handler-WBLMZ6OH.js"); await sendErrorToBugsnag(errorMessage, "unexpected_error"); } } function skipNotifications(currentCommand, environment = process.env) { return isTruthy(environment.CI) || isTruthy(environment.SHOPIFY_UNIT_TEST) || COMMANDS_TO_SKIP.includes(currentCommand); } async function renderNotifications(notifications) { notifications.slice(0, 2).forEach((notification) => { let content = { headline: notification.title, body: notification.message.replaceAll("\\n", ` `), link: notification.cta }; switch (notification.type) { case "info": { renderInfo(content); break; } case "warning": { renderWarning(content); break; } case "error": throw renderError(content), new Error("abort"); } cacheStore(`notification-${notification.id}`, (/* @__PURE__ */ new Date()).getTime().toString()); }); } async function getNotifications() { let cacheKey = `notifications-${url()}`, rawNotifications = cacheRetrieve(cacheKey)?.value; if (!rawNotifications) throw new Error(EMPTY_CACHE_MESSAGE); let notifications = JSON.parse(rawNotifications); return NotificationsSchema.parse(notifications); } async function fetchNotifications() { outputDebug("Fetching notifications..."); let response = await fetch(url(), void 0, { useNetworkLevelRetry: !1, useAbortSignal: !0, timeoutMs: 3 * 1e3 }); if (response.status !== 200) throw new Error(`Failed to fetch notifications: ${response.statusText}`); let rawNotifications = await response.text(), notifications = JSON.parse(rawNotifications), result = NotificationsSchema.parse(notifications); return await cacheNotifications(rawNotifications), result; } async function cacheNotifications(notifications) { cacheStore(`notifications-${url()}`, notifications), outputDebug(`Notifications from ${url()} stored in the cache`); } function fetchNotificationsInBackground(currentCommand, argv = process.argv, environment = process.env) { if (skipNotifications(currentCommand, environment) || !argv[0] || !argv[1]) return; let nodeBinary = argv[0], args = [argv[1], "notifications", "list", "--ignore-errors"]; exec(nodeBinary, args, { background: !0, env: { ...process.env, SHOPIFY_CLI_NO_ANALYTICS: "1" }, externalErrorHandler: async (error) => { outputDebug(`Failed to fetch notifications in background: ${error.message}`); } }); } function filterNotifications(notifications, commandId, currentSurfaces, today = new Date((/* @__PURE__ */ new Date()).setUTCHours(0, 0, 0, 0)), currentVersion = CLI_KIT_VERSION) { return notifications.filter((notification) => filterByVersion(notification, currentVersion)).filter((notifications2) => filterByDate(notifications2, today)).filter((notification) => filterByCommand(notification, commandId)).filter((notification) => filterBySurface(notification, commandId, currentSurfaces)).filter((notification) => filterByFrequency(notification)); } function filterByVersion(notification, currentVersion) { let minVersion = !notification.minVersion || versionSatisfies(currentVersion, `>=${notification.minVersion}`), maxVersion = !notification.maxVersion || versionSatisfies(currentVersion, `<=${notification.maxVersion}`); return minVersion && maxVersion; } function filterByDate(notification, today) { let minDate = !notification.minDate || new Date(notification.minDate) <= today, maxDate = !notification.maxDate || new Date(notification.maxDate) >= today; return minDate && maxDate; } function filterByCommand(notification, commandId) { return commandId === "" ? !0 : !notification.commands || notification.commands.includes(commandId); } function filterBySurface(notification, commandId, surfacesFromContext) { let surfaceFromCommand = commandId.split(":")[0] ?? "all", notificationSurface = notification.surface ?? "all"; return surfacesFromContext ? surfacesFromContext.includes(notificationSurface) : notificationSurface === surfaceFromCommand || notificationSurface === "all"; } function filterByFrequency(notification) { if (!notification.frequency) return !0; let cacheKey = `notification-${notification.id}`, lastShown = cacheRetrieve(cacheKey)?.value; if (!lastShown) return !0; switch (notification.frequency) { case "always": return !0; case "once": return !1; case "once_a_day": return (/* @__PURE__ */ new Date()).getTime() - Number(lastShown) > 24 * 3600 * 1e3; case "once_a_week": return (/* @__PURE__ */ new Date()).getTime() - Number(lastShown) > 7 * 24 * 3600 * 1e3; } } function stringifyFilters(notification) { let filters = []; return notification.minDate && filters.push(`from ${notification.minDate}`), notification.maxDate && filters.push(`to ${notification.maxDate}`), notification.minVersion && filters.push(`from v${notification.minVersion}`), notification.maxVersion && filters.push(`to v${notification.maxVersion}`), notification.frequency === "once" && filters.push("show only once"), notification.frequency === "once_a_day" && filters.push("show once a day"), notification.frequency === "once_a_week" && filters.push("show once a week"), notification.surface && filters.push(`surface = ${notification.surface}`), notification.commands && filters.push(`commands = ${notification.commands.join(", ")}`), filters.join(` `); } export { setCurrentCommandId, showNotificationsIfNeeded, getNotifications, fetchNotifications, fetchNotificationsInBackground, stringifyFilters }; //# sourceMappingURL=chunk-JLITATNF.js.map