UNPKG

@shopify/create-app

Version:

A CLI tool to create a new Shopify app.

180 lines (175 loc) • 6.42 kB
import { require_lib } from "./chunk-E43EDJOG.js"; import { TokenizedString, stringifyMessage, tokenItemToString } from "./chunk-PK2M5CKS.js"; import { normalizePath } from "./chunk-C3J4HVUN.js"; import { __toESM, init_cjs_shims } from "./chunk-3XNI6LP4.js"; // ../cli-kit/dist/public/node/error.js init_cjs_shims(); // ../cli-kit/dist/private/node/analytics/graphql-error-codes.js init_cjs_shims(); var RATE_LIMIT_CODES = /* @__PURE__ */ new Set(["THROTTLED", "429"]), PERMISSION_CODES = /* @__PURE__ */ new Set(["ACCESS_DENIED", "access_denied"]); function graphQLErrorCodes(errors) { return Array.isArray(errors) ? errors.flatMap((entry) => { let found = [], error = entry, code = error?.extensions?.code; typeof code == "string" && found.push(code); let appErrors = error?.extensions?.app_errors?.errors; if (Array.isArray(appErrors)) for (let appError of appErrors) { let category = appError?.category; typeof category == "string" && found.push(category); } return found; }) : []; } function isRateLimitCode(code) { return code !== void 0 && RATE_LIMIT_CODES.has(code); } function isPermissionCode(code) { return code !== void 0 && PERMISSION_CODES.has(code); } function hasRateLimitCode(errors) { return graphQLErrorCodes(errors).some(isRateLimitCode); } // ../cli-kit/dist/public/node/error.js var import_core = __toESM(require_lib(), 1), FatalErrorType; (function(FatalErrorType2) { FatalErrorType2[FatalErrorType2.Abort = 0] = "Abort", FatalErrorType2[FatalErrorType2.AbortSilent = 1] = "AbortSilent", FatalErrorType2[FatalErrorType2.Bug = 2] = "Bug"; })(FatalErrorType || (FatalErrorType = {})); var CancelExecution = class extends Error { }, FatalError = class extends Error { tryMessage; type; nextSteps; formattedMessage; customSections; skipOclifErrorHandling; /** * Creates a new FatalError error. * * @param message - The error message. * @param type - The type of fatal error. * @param tryMessage - The message that recommends next steps to the user. * You can pass a string a {@link TokenizedString} or a {@link TokenItem} * if you need to style the message inside the error Banner component. * @param nextSteps - Message to show as "next steps" with suggestions to solve the issue. * @param customSections - Custom sections to show in the error banner. To be used if nextSteps is not enough. */ constructor(message, type, tryMessage = null, nextSteps, customSections) { let messageIsOutputMessage = typeof message == "string" || "value" in message; super(messageIsOutputMessage ? stringifyMessage(message) : tokenItemToString(message)), tryMessage ? tryMessage instanceof TokenizedString ? this.tryMessage = stringifyMessage(tryMessage) : this.tryMessage = tryMessage : this.tryMessage = null, this.type = type, this.nextSteps = nextSteps, this.customSections = customSections, this.skipOclifErrorHandling = !0, messageIsOutputMessage || (this.formattedMessage = message); } }, AbortError = class extends FatalError { constructor(message, tryMessage = null, nextSteps, customSections) { super(message, FatalErrorType.Abort, tryMessage, nextSteps, customSections); } }, ExternalError = class extends FatalError { command; args; constructor(message, command, args, tryMessage = null) { super(message, FatalErrorType.Abort, tryMessage), this.command = command, this.args = args; } }, AbortSilentError = class extends FatalError { constructor() { super("", FatalErrorType.AbortSilent); } }, BugError = class extends FatalError { constructor(message, tryMessage = null) { super(message, FatalErrorType.Bug, tryMessage); } }; async function handler(error) { let fatal; if (isFatal(error)) fatal = error; else if (typeof error == "string") fatal = new BugError(error); else if (error instanceof Error) fatal = new BugError(error.message), fatal.stack = error.stack; else { let maybeError = error; fatal = new BugError(maybeError?.message ?? "Unknown error"), maybeError?.stack && (fatal.stack = maybeError?.stack); } let { renderFatalError } = await import("./ui-UAVSRCJ7.js"); return renderFatalError(fatal), Promise.resolve(error); } function errorMapper(error) { if (error instanceof import_core.Errors.CLIError) { let mappedError = new AbortError(error.message); return mappedError.stack = error.stack, Promise.resolve(mappedError); } else return Promise.resolve(error); } function isFatal(error) { try { return Object.prototype.hasOwnProperty.call(error, "type"); } catch { return !1; } } function shouldReportErrorAsUnexpected(error) { if (!isFatal(error)) { if (error instanceof Error) { if (isExpectedApiError(error)) return !1; let message = error.message; return !errorMessageImpliesEnvironmentIssue(message); } return !0; } return error.type === FatalErrorType.Bug; } function isExpectedApiError(error) { let candidate = error; if (typeof candidate.response != "object" || candidate.response === null || candidate.request === void 0) return !1; let status = candidate.response.status; return status === 401 || status === 429 ? !0 : hasRateLimitCode(candidate.response.errors); } function cleanSingleStackTracePath(filePath) { return normalizePath(filePath).replace("file:/", "/").replace(/^\/?[A-Z]:/, ""); } function errorMessageImpliesEnvironmentIssue(message) { return [ "EPERM: operation not permitted, scandir", "EPERM: operation not permitted, rename", "EACCES: permission denied", "EPERM: operation not permitted, symlink", "This version of npm supports the following node versions", "EBUSY: resource busy or locked", "ENOTEMPTY: directory not empty", "getaddrinfo ENOTFOUND", "Client network socket disconnected before secure TLS connection was established", "spawn EPERM", "socket hang up", "The user aborted a request.", "write EPIPE", "Unsupported platform" ].some((issueMessage) => message.includes(issueMessage)); } export { graphQLErrorCodes, isRateLimitCode, isPermissionCode, hasRateLimitCode, CancelExecution, FatalError, AbortError, ExternalError, AbortSilentError, BugError, handler, errorMapper, shouldReportErrorAsUnexpected, cleanSingleStackTracePath }; //# sourceMappingURL=chunk-LEQAULOW.js.map