@shopify/create-app
Version:
A CLI tool to create a new Shopify app.
180 lines (175 loc) • 6.42 kB
JavaScript
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