@nextlyhq/storage-vercel-blob 0.0.2-alpha.64 → 0.0.2-alpha.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -4,7 +4,7 @@ var blob = require('@vercel/blob');
4
4
 
5
5
  // src/adapter.ts
6
6
 
7
- // ../nextly/dist/chunk-HJ5IQPOY.mjs
7
+ // ../nextly/dist/chunk-IAZJNA2U.mjs
8
8
  function isDbError(err) {
9
9
  if (!err || typeof err !== "object") return false;
10
10
  const obj = err;
@@ -107,6 +107,13 @@ var NEXTLY_ERROR_STATUS = {
107
107
  // Plugin platform (P4) — contributes.routes collection (D25).
108
108
  NEXTLY_ROUTE_COLLISION: 409,
109
109
  NEXTLY_ROUTE_INVALID_PATH: 400,
110
+ // A root-mounted route declared where the request pipeline never reaches the
111
+ // root pass. 400 like an invalid path and not 409: nothing else claims the
112
+ // address, the declaration simply cannot be served from there.
113
+ NEXTLY_ROUTE_UNREACHABLE_ROOT: 400,
114
+ // A `mount` outside the declared union, which only an untyped caller can
115
+ // produce. 400 for the same reason: the declaration itself is unserveable.
116
+ NEXTLY_ROUTE_INVALID_MOUNT: 400,
110
117
  // An email transport whose library is an optional peer dependency the host
111
118
  // has not installed. 503 rather than 500: the request is not malformed and
112
119
  // nothing is broken, the install simply cannot carry it out yet, and the
@@ -444,7 +451,7 @@ var NextlyError = class _NextlyError extends Error {
444
451
  }
445
452
  };
446
453
 
447
- // ../nextly/dist/chunk-W77AQUUQ.mjs
454
+ // ../nextly/dist/chunk-T3OVIJZM.mjs
448
455
  var StorageReadTooLargeError = class extends NextlyError {
449
456
  constructor(path, maxBytes, size) {
450
457
  super({
@@ -462,7 +469,7 @@ var StorageReadTooLargeError = class extends NextlyError {
462
469
  }
463
470
  };
464
471
 
465
- // ../nextly/dist/chunk-C2VHLQKK.mjs
472
+ // ../nextly/dist/chunk-YGE6AGZG.mjs
466
473
  var IPV4_RE = /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/;
467
474
  var PRIVATE_IPV4_CIDRS = [
468
475
  "0.0.0.0/8",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../nextly/dist/chunk-HJ5IQPOY.mjs","../../nextly/dist/chunk-W77AQUUQ.mjs","../../nextly/dist/chunk-C2VHLQKK.mjs","../src/adapter.ts","../src/plugin.ts","../src/index.ts"],"names":["put","del","head","BlobNotFoundError","list"],"mappings":"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","file":"index.cjs","sourcesContent":["// src/database/errors.ts\nvar DbError = class extends Error {\n kind;\n dialect;\n code;\n meta;\n cause;\n constructor(args) {\n super(args.message);\n this.name = \"DbError\";\n this.kind = args.kind;\n this.dialect = args.dialect;\n this.code = args.code;\n this.meta = args.meta;\n this.cause = args.cause;\n }\n};\nfunction isDbError(err) {\n if (!err || typeof err !== \"object\") return false;\n const obj = err;\n return obj.name === \"DbError\" && typeof obj.kind === \"string\";\n}\nfunction toDbError(dialect, error, meta) {\n if (isDbError(error)) return error;\n const code = safeCode(error);\n const rawMsg = error != null && typeof error === \"object\" && \"message\" in error ? error.message : void 0;\n const message = typeof rawMsg === \"string\" ? rawMsg : \"Database error\";\n let kind = \"internal\";\n switch (dialect) {\n case \"postgresql\":\n kind = mapPostgresCodeToKind(code);\n break;\n case \"mysql\":\n kind = mapMySqlCodeToKind(code);\n break;\n case \"sqlite\":\n kind = mapSqliteCodeToKind(code);\n break;\n }\n if ((dialect === \"mysql\" || dialect === \"sqlite\") && (kind === \"constraint\" || kind === \"internal\") && isLikelyUniqueViolationMessage(dialect, message)) {\n kind = \"unique-violation\";\n }\n if (kind === \"internal\" && code) {\n const c = code.toUpperCase();\n if (c === \"ECONNRESET\" || c.includes(\"PROTOCOL_CONNECTION_LOST\"))\n kind = \"connection-lost\";\n else if (c === \"ETIMEDOUT\") kind = \"timeout\";\n }\n return new DbError({ message, kind, dialect, code, meta, cause: error });\n}\nfunction safeCode(error) {\n if (!error || typeof error !== \"object\") return void 0;\n const e = error;\n let c = e.code ?? e.sqlState ?? e.state ?? e.errno ?? void 0;\n if (!c && typeof e.originalError?.code === \"string\") c = e.originalError.code;\n if (!c && typeof e.cause?.code === \"string\") c = e.cause.code;\n if (!c && typeof e.severity === \"string\" && typeof e.code === \"string\")\n c = e.code;\n if (typeof c === \"number\") return String(c);\n if (typeof c === \"string\" && c.length > 0) return c;\n return void 0;\n}\nfunction mapPostgresCodeToKind(code) {\n if (!code) return \"internal\";\n const c = code.toUpperCase();\n if (c === \"40P01\") return \"deadlock\";\n if (c === \"40001\") return \"serialization-failure\";\n if (c === \"57014\") return \"timeout\";\n if (c === \"23505\") return \"unique-violation\";\n if (c === \"23503\") return \"fk-violation\";\n if (c === \"23502\") return \"not-null-violation\";\n if (c === \"42601\") return \"syntax\";\n if (c.startsWith(\"08\") || c === \"57P01\") return \"connection-lost\";\n if (c.startsWith(\"23\")) return \"constraint\";\n return \"internal\";\n}\nfunction mapMySqlCodeToKind(code) {\n if (!code) return \"internal\";\n const c = code.toUpperCase();\n if (c === \"1213\" || c === \"ER_LOCK_DEADLOCK\") return \"deadlock\";\n if (c === \"1205\" || c === \"ER_LOCK_WAIT_TIMEOUT\") return \"timeout\";\n if (c === \"1062\" || c === \"ER_DUP_ENTRY\") return \"unique-violation\";\n if (c === \"23000\") return \"constraint\";\n if (c === \"1064\" || c === \"ER_PARSE_ERROR\") return \"syntax\";\n if (c === \"1452\" || c === \"ER_NO_REFERENCED_ROW_2\") return \"fk-violation\";\n if (c === \"1451\" || c === \"ER_ROW_IS_REFERENCED_2\") return \"fk-violation\";\n if (c === \"ECONNRESET\" || c.includes(\"PROTOCOL_CONNECTION_LOST\"))\n return \"connection-lost\";\n if (c === \"ETIMEDOUT\") return \"timeout\";\n return \"internal\";\n}\nfunction mapSqliteCodeToKind(code) {\n if (!code) return \"internal\";\n const c = code.toUpperCase();\n if (c === \"SQLITE_BUSY\" || c === \"SQLITE_LOCKED\") return \"deadlock\";\n if (c === \"SQLITE_CONSTRAINT_UNIQUE\") return \"unique-violation\";\n if (c === \"SQLITE_CONSTRAINT_PRIMARYKEY\") return \"unique-violation\";\n if (c === \"SQLITE_CONSTRAINT_FOREIGNKEY\") return \"fk-violation\";\n if (c === \"SQLITE_CONSTRAINT_NOTNULL\") return \"not-null-violation\";\n if (c === \"SQLITE_INTERRUPT\") return \"timeout\";\n if (c === \"SQLITE_ERROR\") return \"syntax\";\n if (c.startsWith(\"SQLITE_CONSTRAINT\")) return \"constraint\";\n return \"internal\";\n}\nfunction isLikelyUniqueViolationMessage(dialect, message) {\n const m = message.toLowerCase();\n if (dialect === \"mysql\") {\n return m.includes(\"duplicate entry\") || m.includes(\"duplicate key\");\n }\n if (dialect === \"sqlite\") {\n return m.includes(\"unique constraint failed\");\n }\n return false;\n}\n\n// src/errors/error-codes.ts\nvar NEXTLY_ERROR_STATUS = {\n VALIDATION_ERROR: 400,\n INVALID_INPUT: 400,\n AUTH_REQUIRED: 401,\n AUTH_INVALID_CREDENTIALS: 401,\n TOKEN_EXPIRED: 401,\n FORBIDDEN: 403,\n // The schema builder is off in this environment (production by default).\n // Separate from FORBIDDEN: the caller's permissions are not the problem.\n BUILDER_DISABLED: 403,\n NOT_FOUND: 404,\n CONFLICT: 409,\n DUPLICATE: 409,\n RATE_LIMITED: 429,\n PAYLOAD_TOO_LARGE: 413,\n UNSUPPORTED_MEDIA_TYPE: 415,\n // 422: understood, well-formed, and refused on a rule the caller can act on.\n // Deliberately NOT added to CANONICAL_CODE_FOR_STATUS -- that list drives the\n // status -> code direction, where 422 stays mapped to INVALID_INPUT.\n BUSINESS_RULE_VIOLATION: 422,\n INTERNAL_ERROR: 500,\n DATABASE_ERROR: 500,\n EXTERNAL_SERVICE_ERROR: 502,\n SERVICE_UNAVAILABLE: 503,\n // Outbound-fetch safety (utils/validate-external-url): a URL refused for SSRF\n // safety, and a fetch that timed out / exceeded the size cap / failed to decode.\n EXTERNAL_URL_BLOCKED: 400,\n EXTERNAL_REQUEST_FAILED: 502,\n FILENAME_INVALID: 400,\n EXTENSION_BLOCKED: 400,\n MIME_BLOCKED: 415,\n MIME_NOT_ALLOWED: 415,\n SIZE_EXCEEDED: 413,\n // A stored object exceeded the cap a READ was given, which is a different\n // question from SIZE_EXCEEDED above: that one refuses an upload the caller\n // is sending, this one refuses to buffer an object already stored. Kept\n // apart so a caller discriminating on the code cannot match both.\n STORAGE_READ_TOO_LARGE: 413,\n // A stored object did not answer within the deadline the read was given. 504\n // rather than 500 because the failure is the BACKEND not answering, and a\n // caller can act on that difference: a gateway timeout is worth retrying, an\n // internal error is not.\n STORAGE_READ_TIMEOUT: 504,\n // The store answered, and answered badly. 502 rather than 500 because the\n // fault is UPSTREAM of this process: a caller can retry it, and an operator\n // reading the log needs to look at the bucket rather than at this service.\n // Distinct from the timeout above, which never got an answer at all.\n STORAGE_READ_UNREACHABLE: 502,\n MAGIC_BYTE_MISMATCH: 400,\n SVG_SANITIZATION_FAILED: 400,\n UNSUPPORTED_FOR_BACKEND: 415,\n // Plan B — schema bookkeeping consolidation.\n NEXTLY_LEGACY_BOOKKEEPING_DETECTED: 409,\n NEXTLY_UPGRADE_TABLE_NAME_COLLISION: 409,\n NEXTLY_UPGRADE_IN_PROGRESS: 409,\n // Plan C2 — nextly migrate phases.\n NEXTLY_MIGRATE_LOCK_BUSY: 409,\n NEXTLY_BASELINE_LOCK_NOT_HELD: 409,\n NEXTLY_RESOLVE_LOCK_NOT_HELD: 409,\n // Boot refused to serve: the migrate lock stayed held past the wait deadline,\n // so this process never established whether the schema matches the code. 503\n // rather than 409 — a load balancer should take the instance out of rotation\n // and retry it, which is exactly the recovery this refusal wants.\n NEXTLY_BOOT_MIGRATIONS_NOT_RUN: 503,\n // Still running rather than refused. 503 for the same reason: retry shortly.\n NEXTLY_BOOT_MIGRATIONS_PENDING: 503,\n NEXTLY_CORE_DESTRUCTIVE_REFUSED: 409,\n NEXTLY_MIGRATION_DRIFT: 409,\n NEXTLY_MIGRATION_APPLY_FAILED: 500,\n // Plan C3 — migrate:resolve recovery command.\n NEXTLY_MIGRATION_FILE_MISSING: 404,\n NEXTLY_MIGRATION_SNAPSHOT_MISSING: 404,\n NEXTLY_MIGRATION_RESOLVE_DRIFT: 409,\n NEXTLY_MIGRATION_RESOLVE_PRECONDITION: 409,\n // Plan D — UI schema support.\n NEXTLY_UI_SCHEMA_INVALID: 400,\n NEXTLY_SCHEMA_SLUG_COLLISION: 409,\n NEXTLY_SCHEMA_RELATION_TARGET_MISSING: 400,\n // Plugin platform (P2b) — schema extend (contributes.extend) + relations (D15).\n NEXTLY_SCHEMA_EXTEND_TARGET_UNKNOWN: 400,\n NEXTLY_SCHEMA_EXTEND_FIELD_DUPLICATE: 409,\n NEXTLY_SCHEMA_CROSS_PLUGIN_RELATION: 409,\n // Plugin platform (P2c) — framework remap (.rename()).\n NEXTLY_SCHEMA_RENAME_UNKNOWN_TARGET: 400,\n // Plugin platform — a declared admin.clientConfig that cannot be delivered\n // to the browser, refused at boot rather than serialized mangled.\n NEXTLY_PLUGIN_CLIENT_CONFIG_INVALID: 500,\n // Plugin platform — a contributed admin widget that cannot be delivered to\n // the browser. Refused at boot because it is serialized into the ONE\n // `/api/admin-meta/workspace` payload: a value `JSON.stringify` throws on\n // fails that request for every admin, not just the widget's own card.\n NEXTLY_PLUGIN_ADMIN_WIDGET_INVALID: 500,\n // Plugin platform (P0) — boot-time plugin dependency/version resolution.\n PLUGIN_RESOLUTION_ERROR: 500,\n // Plugin platform (P4) — contributes.routes collection (D25).\n NEXTLY_ROUTE_COLLISION: 409,\n NEXTLY_ROUTE_INVALID_PATH: 400,\n // An email transport whose library is an optional peer dependency the host\n // has not installed. 503 rather than 500: the request is not malformed and\n // nothing is broken, the install simply cannot carry it out yet, and the\n // remedy is one command on the server rather than a change by the caller.\n NEXTLY_EMAIL_TRANSPORT_UNAVAILABLE: 503,\n // The tooling that compiles `nextly.config.ts` is an optional peer the host\n // has not installed. 503 rather than 500 for the same reason as the mail\n // transport above: nothing is broken and the request is not malformed, the\n // install simply cannot carry it out until one command is run.\n NEXTLY_CONFIG_TOOLING_UNAVAILABLE: 503\n};\nvar CANONICAL_CODE_FOR_STATUS = [\n \"VALIDATION_ERROR\",\n \"AUTH_REQUIRED\",\n \"FORBIDDEN\",\n \"NOT_FOUND\",\n \"CONFLICT\",\n \"PAYLOAD_TOO_LARGE\",\n \"UNSUPPORTED_MEDIA_TYPE\",\n \"RATE_LIMITED\",\n \"EXTERNAL_SERVICE_ERROR\",\n \"SERVICE_UNAVAILABLE\"\n];\nvar LEGACY_UNPROCESSABLE_STATUS = 422;\nvar STATUS_TO_CODE = {\n ...Object.fromEntries(\n CANONICAL_CODE_FOR_STATUS.map((code) => [NEXTLY_ERROR_STATUS[code], code])\n ),\n [LEGACY_UNPROCESSABLE_STATUS]: \"INVALID_INPUT\"\n};\nfunction statusToErrorCode(statusCode) {\n return STATUS_TO_CODE[statusCode] ?? \"INTERNAL_ERROR\";\n}\nvar GENERIC_PUBLIC_MESSAGE = {\n VALIDATION_ERROR: \"Validation failed.\",\n INVALID_INPUT: \"The request could not be processed.\",\n AUTH_REQUIRED: \"Authentication required.\",\n FORBIDDEN: \"You don't have permission to perform this action.\",\n NOT_FOUND: \"Not found.\",\n CONFLICT: \"The resource has changed since you last loaded it. Please refresh and try again.\",\n DUPLICATE: \"Resource already exists.\",\n PAYLOAD_TOO_LARGE: \"The request is too large.\",\n UNSUPPORTED_MEDIA_TYPE: \"That file type is not supported.\",\n RATE_LIMITED: \"Too many requests. Please try again later.\",\n EXTERNAL_SERVICE_ERROR: \"An upstream service failed.\",\n SERVICE_UNAVAILABLE: \"The service is temporarily unavailable.\",\n INTERNAL_ERROR: \"An unexpected error occurred.\"\n};\nfunction genericPublicMessage(code) {\n return GENERIC_PUBLIC_MESSAGE[code] ?? GENERIC_PUBLIC_MESSAGE.INTERNAL_ERROR;\n}\n\n// src/errors/nextly-error.ts\nvar DB_ERROR_MAPPING = {\n \"unique-violation\": {\n code: \"DUPLICATE\",\n statusCode: 409,\n publicMessage: \"Resource already exists.\"\n },\n \"fk-violation\": {\n code: \"VALIDATION_ERROR\",\n statusCode: 400,\n publicMessage: \"Referenced record does not exist.\"\n },\n \"not-null-violation\": {\n code: \"VALIDATION_ERROR\",\n statusCode: 400,\n publicMessage: \"A required field is missing.\"\n },\n constraint: {\n code: \"VALIDATION_ERROR\",\n statusCode: 400,\n publicMessage: \"The provided data violates a constraint.\"\n },\n deadlock: {\n code: \"CONFLICT\",\n statusCode: 409,\n publicMessage: \"The operation could not be completed. Please retry.\"\n },\n \"serialization-failure\": {\n code: \"CONFLICT\",\n statusCode: 409,\n publicMessage: \"The operation could not be completed. Please retry.\"\n },\n timeout: {\n code: \"DATABASE_ERROR\",\n statusCode: 500,\n publicMessage: \"The operation timed out. Please try again.\"\n },\n \"connection-lost\": {\n code: \"DATABASE_ERROR\",\n statusCode: 500,\n publicMessage: \"A temporary database error occurred. Please try again.\"\n },\n syntax: {\n code: \"INTERNAL_ERROR\",\n statusCode: 500,\n publicMessage: \"An unexpected error occurred.\"\n },\n internal: {\n code: \"INTERNAL_ERROR\",\n statusCode: 500,\n publicMessage: \"An unexpected error occurred.\"\n }\n};\nvar NEXTLY_ERROR_BRAND = Symbol.for(\"nextly/NextlyError\");\nfunction hasBrand(value) {\n if (value === null || typeof value !== \"object\" && typeof value !== \"function\") {\n return false;\n }\n return value[NEXTLY_ERROR_BRAND] === true;\n}\nvar NextlyError = class _NextlyError extends Error {\n code;\n statusCode;\n publicMessage;\n publicData;\n messageKey;\n logMessage;\n logContext;\n cause;\n timestamp;\n constructor(opts) {\n super(opts.publicMessage);\n this.name = \"NextlyError\";\n this.code = opts.code;\n this.publicMessage = opts.publicMessage;\n this.publicData = opts.publicData;\n this.messageKey = opts.messageKey;\n this.logMessage = opts.logMessage;\n this.logContext = opts.logContext;\n this.cause = opts.cause;\n this.timestamp = /* @__PURE__ */ new Date();\n this.statusCode = _NextlyError.resolveStatusCode(opts);\n Error.captureStackTrace?.(this, _NextlyError);\n }\n static {\n _NextlyError.prototype[NEXTLY_ERROR_BRAND] = true;\n }\n static resolveStatusCode(opts) {\n if (typeof opts.statusCode === \"number\") return opts.statusCode;\n if (opts.code in NEXTLY_ERROR_STATUS) {\n return NEXTLY_ERROR_STATUS[opts.code];\n }\n return 500;\n }\n /** HTTP-safe JSON. Strips logMessage / logContext / cause / stack. */\n toResponseJSON(requestId) {\n const json = {\n code: String(this.code),\n message: this.publicMessage,\n requestId\n };\n if (this.messageKey) json.messageKey = this.messageKey;\n if (this.publicData !== void 0) json.data = this.publicData;\n return json;\n }\n /** Operator-facing JSON for log lines. Includes everything. */\n toLogJSON(requestId) {\n return {\n code: this.code,\n statusCode: this.statusCode,\n publicMessage: this.publicMessage,\n messageKey: this.messageKey,\n logMessage: this.logMessage,\n logContext: this.logContext,\n cause: this.cause ? {\n name: this.cause.name,\n message: this.cause.message,\n stack: this.cause.stack\n } : void 0,\n timestamp: this.timestamp.toISOString(),\n requestId\n };\n }\n // ────────────────────────────────────────────────────────────────────\n // Static factories — the recommended throw site for every common case.\n // Public messages here follow the §13.8 rubric: complete sentence,\n // generic, no identifiers, no value echoing, no policy hints.\n // ────────────────────────────────────────────────────────────────────\n static invalidCredentials(opts) {\n return new _NextlyError({\n code: \"AUTH_INVALID_CREDENTIALS\",\n publicMessage: \"Invalid email or password.\",\n logMessage: \"Login failed\",\n logContext: opts?.logContext\n });\n }\n static authRequired(opts) {\n return new _NextlyError({\n code: \"AUTH_REQUIRED\",\n publicMessage: \"Authentication required.\",\n logContext: opts?.logContext\n });\n }\n /**\n * Distinct from `authRequired`: the caller was authenticated but the\n * session token expired. Clients key on the TOKEN_EXPIRED *code* to\n * silently refresh and retry rather than redirecting to login; the public\n * message stays the generic spec §13.6 string (\"Authentication required.\")\n * so the wire never reveals the session state — same as `authRequired`.\n */\n static tokenExpired(opts) {\n return new _NextlyError({\n code: \"TOKEN_EXPIRED\",\n publicMessage: \"Authentication required.\",\n logContext: opts?.logContext\n });\n }\n static notFound(opts) {\n return new _NextlyError({\n code: \"NOT_FOUND\",\n publicMessage: opts?.message ?? \"Not found.\",\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n static forbidden(opts) {\n return new _NextlyError({\n code: \"FORBIDDEN\",\n publicMessage: \"You don't have permission to perform this action.\",\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n /**\n * A call the caller got wrong, where naming the mistake IS the value of the\n * error.\n *\n * The only factory that takes its public message from the caller. The\n * generic messages elsewhere exist so an HTTP response cannot leak internal\n * detail; this one is for arguments and configuration a developer controls\n * and must be told about — a missing option, an unusable combination — where\n * `internal()` would reduce the one useful sentence to \"An unexpected error\n * occurred.\" Do not pass user-supplied data through it.\n */\n static invalidInput(opts) {\n return new _NextlyError({\n code: \"INVALID_INPUT\",\n publicMessage: opts.message,\n logContext: opts.logContext\n });\n }\n static validation(opts) {\n return new _NextlyError({\n code: \"VALIDATION_ERROR\",\n publicMessage: \"Validation failed.\",\n publicData: { errors: opts.errors },\n cause: opts.cause,\n logContext: opts.logContext\n });\n }\n static conflict(opts) {\n return new _NextlyError({\n code: \"CONFLICT\",\n publicMessage: opts?.message ?? \"The resource has changed since you last loaded it. Please refresh and try again.\",\n cause: opts?.cause,\n logContext: { reason: opts?.reason, ...opts?.logContext }\n });\n }\n static duplicate(opts) {\n return new _NextlyError({\n code: \"DUPLICATE\",\n publicMessage: \"Resource already exists.\",\n logContext: opts?.logContext\n });\n }\n static rateLimited(opts) {\n return new _NextlyError({\n code: \"RATE_LIMITED\",\n publicMessage: \"Too many requests. Please try again later.\",\n publicData: opts?.retryAfterSeconds !== void 0 ? { retryAfterSeconds: opts.retryAfterSeconds } : void 0,\n logContext: opts?.logContext\n });\n }\n static internal(opts) {\n return new _NextlyError({\n code: \"INTERNAL_ERROR\",\n publicMessage: \"An unexpected error occurred.\",\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n // Accepts an optional `logMessage` override so callers (e.g. the health\n // route) can record a specific operator narrative (\"Health check failed\")\n // while the public message stays canonical per spec §13.8.5.\n static serviceUnavailable(opts) {\n return new _NextlyError({\n code: \"SERVICE_UNAVAILABLE\",\n publicMessage: opts?.publicMessage ?? \"Service unavailable. Please try again later.\",\n logMessage: opts?.logMessage,\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n /**\n * Convert a DbError (or arbitrary unknown thrown by the DB layer) to a\n * NextlyError with a generic public message and rich logContext. Used by\n * `withDbErrors` for auto-conversion (Pattern A) and by services that\n * catch DB errors at boundaries (Pattern B). Spec §8.2 mapping table.\n *\n * Never leaks DB driver text, constraint names, or table names into\n * `publicMessage`. All DB context goes into `logContext`. The original\n * DbError is preserved as `cause`.\n */\n static fromDatabaseError(error) {\n if (isDbError(error)) {\n const mapping = DB_ERROR_MAPPING[error.kind];\n const logContext = {\n dbKind: error.kind,\n dialect: error.dialect\n };\n if (error.code !== void 0) logContext.dbCode = error.code;\n if (error.meta !== void 0) logContext.meta = error.meta;\n return new _NextlyError({\n code: mapping.code,\n statusCode: mapping.statusCode,\n publicMessage: mapping.publicMessage,\n logMessage: \"Database error\",\n logContext,\n cause: error\n });\n }\n return new _NextlyError({\n code: \"INTERNAL_ERROR\",\n statusCode: 500,\n publicMessage: \"An unexpected error occurred.\",\n logMessage: \"Non-DbError passed to fromDatabaseError\",\n cause: error instanceof Error ? error : void 0,\n logContext: error instanceof Error ? void 0 : { value: String(error) }\n });\n }\n // ────────────────────────────────────────────────────────────────────\n // Type guards. Structural rather than `instanceof` so they survive\n // package-boundary mismatches (one consumer's NextlyError is a\n // different module instance from another's).\n // ────────────────────────────────────────────────────────────────────\n static is(err) {\n return hasBrand(err);\n }\n static isCode(err, code) {\n return hasBrand(err) && err.code === code;\n }\n static isNotFound(err) {\n return _NextlyError.isCode(err, \"NOT_FOUND\");\n }\n static isValidation(err) {\n return _NextlyError.isCode(err, \"VALIDATION_ERROR\");\n }\n static isAuthRequired(err) {\n return _NextlyError.isCode(err, \"AUTH_REQUIRED\");\n }\n static isForbidden(err) {\n return _NextlyError.isCode(err, \"FORBIDDEN\");\n }\n static isConflict(err) {\n return _NextlyError.isCode(err, \"CONFLICT\");\n }\n static isRateLimited(err) {\n return _NextlyError.isCode(err, \"RATE_LIMITED\");\n }\n};\n\nexport {\n DbError,\n isDbError,\n toDbError,\n safeCode,\n NEXTLY_ERROR_STATUS,\n statusToErrorCode,\n genericPublicMessage,\n NextlyError\n};\n","import {\n NextlyError\n} from \"./chunk-HJ5IQPOY.mjs\";\n\n// src/storage/read-errors.ts\nvar StorageReadTooLargeError = class extends NextlyError {\n constructor(path, maxBytes, size) {\n super({\n code: \"STORAGE_READ_TOO_LARGE\",\n publicMessage: \"The stored file is larger than the limit for this read.\",\n logContext: {\n path,\n maxBytes,\n ...size === void 0 ? {} : { size }\n }\n });\n this.path = path;\n this.maxBytes = maxBytes;\n this.size = size;\n }\n};\nfunction isStorageReadTooLarge(error) {\n return NextlyError.is(error) && error.code === \"STORAGE_READ_TOO_LARGE\";\n}\nvar StorageReadTimeoutError = class extends NextlyError {\n constructor(path, timeoutMs) {\n super({\n code: \"STORAGE_READ_TIMEOUT\",\n publicMessage: \"The stored file could not be read in time.\",\n logContext: { path, timeoutMs }\n });\n this.path = path;\n this.timeoutMs = timeoutMs;\n }\n};\nfunction isStorageReadTimeout(error) {\n return NextlyError.is(error) && error.code === \"STORAGE_READ_TIMEOUT\";\n}\n\nexport {\n StorageReadTooLargeError,\n isStorageReadTooLarge,\n StorageReadTimeoutError,\n isStorageReadTimeout\n};\n","import {\n StorageReadTimeoutError,\n StorageReadTooLargeError\n} from \"./chunk-W77AQUUQ.mjs\";\nimport {\n NextlyError\n} from \"./chunk-HJ5IQPOY.mjs\";\n\n// src/utils/validate-external-url.ts\nvar IPV4_RE = /^(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)$/;\nvar PRIVATE_IPV4_CIDRS = [\n \"0.0.0.0/8\",\n // RFC1122 \"this network\" / wildcard\n \"10.0.0.0/8\",\n // RFC1918\n \"100.64.0.0/10\",\n // RFC6598 CGNAT\n \"127.0.0.0/8\",\n // RFC1122 loopback\n \"169.254.0.0/16\",\n // RFC3927 link-local + AWS/GCP metadata\n \"172.16.0.0/12\",\n // RFC1918\n \"192.0.0.0/24\",\n // RFC6890 IETF protocol assignments\n \"192.0.2.0/24\",\n // RFC5737 documentation\n \"192.168.0.0/16\",\n // RFC1918\n \"198.18.0.0/15\",\n // RFC2544 benchmarking\n \"198.51.100.0/24\",\n // RFC5737 documentation\n \"203.0.113.0/24\",\n // RFC5737 documentation\n \"224.0.0.0/4\",\n // RFC5771 multicast\n \"240.0.0.0/4\"\n // RFC1112 reserved\n];\nvar CLOUD_METADATA_HOSTS = /* @__PURE__ */ new Set([\n \"metadata.google.internal\",\n \"metadata.googleapis.com\",\n \"metadata\"\n // GCP short form\n]);\nvar ExternalUrlError = class extends NextlyError {\n constructor(message, url) {\n super({\n code: \"EXTERNAL_URL_BLOCKED\",\n publicMessage: message,\n logContext: { url }\n });\n this.url = url;\n this.name = \"ExternalUrlError\";\n }\n};\nasync function validateExternalUrl(rawUrl, options = {}) {\n let parsed;\n try {\n parsed = new URL(rawUrl);\n } catch {\n throw new ExternalUrlError(\"Invalid URL\", rawUrl);\n }\n const hostname = parsed.hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n const isLocalhostHostname = hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"::1\";\n const baseProtocols = options.allowedProtocols ?? [\"https:\"];\n const protocols = options.allowLocalhost && isLocalhostHostname ? [...baseProtocols, \"http:\"] : baseProtocols;\n if (!protocols.includes(parsed.protocol)) {\n throw new ExternalUrlError(\n `Protocol ${parsed.protocol} not allowed (allowed: ${protocols.join(\", \")})`,\n rawUrl\n );\n }\n if (CLOUD_METADATA_HOSTS.has(hostname)) {\n throw new ExternalUrlError(\n `Cloud-metadata hostname rejected: ${parsed.hostname}`,\n rawUrl\n );\n }\n if (IPV4_RE.test(hostname)) {\n if (!isPublicIpv4(\n hostname,\n options.allowLocalhost === true && hostname === \"127.0.0.1\"\n )) {\n throw new ExternalUrlError(\n `Resolved to non-public IP: ${hostname}`,\n rawUrl\n );\n }\n return { url: parsed, pinnedIp: hostname, family: 4 };\n }\n if (hostname.includes(\":\")) {\n if (!isPublicIpv6(\n hostname,\n options.allowLocalhost === true && hostname === \"::1\"\n )) {\n throw new ExternalUrlError(\n `Resolved to non-public IP: ${hostname}`,\n rawUrl\n );\n }\n return { url: parsed, pinnedIp: hostname, family: 6 };\n }\n const { lookup } = await import(\"dns/promises\");\n let addresses;\n try {\n addresses = await lookup(hostname, { all: true });\n } catch (err) {\n throw new ExternalUrlError(\n `DNS lookup failed: ${err.message}`,\n rawUrl\n );\n }\n if (addresses.length === 0) {\n throw new ExternalUrlError(\"No IPs returned for host\", rawUrl);\n }\n for (const { address, family } of addresses) {\n const allow = options.allowLocalhost === true && isLocalhostHostname && family === 4;\n const ok = family === 4 ? isPublicIpv4(address, allow) : isPublicIpv6(address, allow);\n if (!ok) {\n throw new ExternalUrlError(\n `Resolved to non-public IP: ${address}`,\n rawUrl\n );\n }\n }\n const first = addresses[0];\n return {\n url: parsed,\n pinnedIp: first.address,\n family: first.family === 6 ? 6 : 4\n };\n}\nvar DEFAULT_MAX_RESPONSE_BYTES = 10 * 1024 * 1024;\nvar DEFAULT_TIMEOUT_MS = 3e4;\nvar SafeFetchError = class extends NextlyError {\n constructor(message, url, reason, status) {\n super({\n code: \"EXTERNAL_REQUEST_FAILED\",\n publicMessage: message,\n logContext: { url, reason }\n });\n this.url = url;\n this.reason = reason;\n this.status = status;\n this.name = \"SafeFetchError\";\n }\n};\nfunction createPinnedLookup(ip, family) {\n return (_hostname, options, callback) => {\n if (options && options.all) {\n callback(null, [{ address: ip, family }]);\n } else {\n callback(null, ip, family);\n }\n };\n}\nasync function safeFetch(rawUrl, options = {}) {\n const {\n allowLocalhost,\n allowedProtocols,\n method,\n headers,\n body,\n signal,\n maxResponseBytes = DEFAULT_MAX_RESPONSE_BYTES,\n timeoutMs = DEFAULT_TIMEOUT_MS\n } = options;\n const controller = new AbortController();\n const forwardAbort = () => controller.abort(signal?.reason);\n if (signal) {\n if (signal.aborted) controller.abort(signal.reason);\n else signal.addEventListener(\"abort\", forwardAbort, { once: true });\n }\n const timer = setTimeout(\n () => controller.abort(\n new SafeFetchError(`Request exceeded ${timeoutMs}ms`, rawUrl, \"timeout\")\n ),\n timeoutMs\n );\n try {\n const validated = await abortable(\n validateExternalUrl(rawUrl, { allowLocalhost, allowedProtocols }),\n controller.signal\n );\n return await pinnedFetch(validated, {\n method,\n headers,\n body,\n signal: controller.signal,\n maxResponseBytes\n });\n } finally {\n clearTimeout(timer);\n if (signal) signal.removeEventListener(\"abort\", forwardAbort);\n }\n}\nfunction abortError(signal) {\n const reason = signal.reason;\n if (reason instanceof Error) return reason;\n return new DOMException(\"The operation was aborted\", \"AbortError\");\n}\nfunction abortable(promise, signal) {\n if (signal.aborted) return Promise.reject(abortError(signal));\n let onAbort;\n const aborted = new Promise((_resolve, reject) => {\n onAbort = () => reject(abortError(signal));\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n return Promise.race([promise, aborted]).finally(\n () => signal.removeEventListener(\"abort\", onAbort)\n );\n}\nasync function pinnedFetch(validated, init) {\n const { url, pinnedIp, family } = validated;\n const httpMod = url.protocol === \"https:\" ? await import(\"https\") : await import(\"http\");\n const zlib = await import(\"zlib\");\n const lookup = createPinnedLookup(pinnedIp, family);\n const outHeaders = toOutgoingHeaders(init.headers);\n if (init.body != null) {\n delete outHeaders[\"transfer-encoding\"];\n outHeaders[\"content-length\"] = String(\n typeof init.body === \"string\" ? Buffer.byteLength(init.body) : init.body.byteLength\n );\n }\n return new Promise((resolve, reject) => {\n let settled = false;\n const settle = (fn) => {\n if (settled) return;\n settled = true;\n fn();\n };\n const failure = (err) => init.signal.aborted ? abortError(init.signal) : err;\n const req = httpMod.request(\n url,\n {\n method: init.method ?? \"GET\",\n headers: outHeaders,\n lookup,\n // Fresh socket per request so a pooled connection can't reuse a\n // differently-resolved address, and so the pinned lookup always runs.\n agent: false,\n // The combined deadline/caller signal aborts the request in flight.\n signal: init.signal\n },\n (res) => {\n const chunks = [];\n let received = 0;\n res.on(\"data\", (chunk) => {\n received += chunk.length;\n if (received > init.maxResponseBytes) {\n res.destroy();\n req.destroy();\n settle(\n () => reject(\n new SafeFetchError(\n `Response body exceeded ${init.maxResponseBytes} bytes`,\n url.href,\n \"response-too-large\",\n res.statusCode\n )\n )\n );\n return;\n }\n chunks.push(chunk);\n });\n res.on(\"end\", () => {\n const decoded = decodeBody(\n Buffer.concat(chunks),\n res.headers[\"content-encoding\"],\n zlib,\n init.maxResponseBytes,\n url.href,\n res.statusCode\n );\n if (decoded instanceof SafeFetchError) {\n settle(() => reject(decoded));\n return;\n }\n settle(\n () => resolve(toWhatwgResponse(res, decoded.body, decoded.decoded))\n );\n });\n res.on(\"error\", (err) => settle(() => reject(failure(err))));\n }\n );\n req.on(\"error\", (err) => settle(() => reject(failure(err))));\n if (!req.destroyed) {\n if (init.body != null) req.write(init.body);\n req.end();\n }\n });\n}\nfunction toOutgoingHeaders(headers) {\n const out = {};\n if (!headers) return out;\n const add = (rawKey, value) => {\n const key = rawKey.toLowerCase();\n if (key === \"host\") return;\n const existing = out[key];\n out[key] = existing === void 0 ? value : [].concat(existing, value);\n };\n if (headers instanceof Headers) {\n headers.forEach((value, key) => add(key, value));\n } else if (Array.isArray(headers)) {\n for (const [key, value] of headers) add(key, value);\n } else {\n for (const [key, value] of Object.entries(headers)) add(key, value);\n }\n return out;\n}\nfunction toWhatwgResponse(res, body, stripContentHeaders) {\n const headers = new Headers();\n for (const [key, value] of Object.entries(res.headers)) {\n if (value == null) continue;\n const lower = key.toLowerCase();\n if (stripContentHeaders && (lower === \"content-encoding\" || lower === \"content-length\")) {\n continue;\n }\n const values = Array.isArray(value) ? value : [value];\n for (const v of values) {\n try {\n headers.append(key, v);\n } catch {\n }\n }\n }\n const raw = res.statusCode ?? 502;\n const status = raw >= 200 && raw <= 599 ? raw : 502;\n const nullBody = status === 204 || status === 205 || status === 304;\n const bytes = new Uint8Array(body.byteLength);\n bytes.set(body);\n return new Response(nullBody ? null : bytes, {\n status,\n statusText: res.statusMessage ?? \"\",\n headers\n });\n}\nfunction decodeBody(buf, encoding, zlib, cap, url, status) {\n if (!encoding) return { body: buf, decoded: false };\n if (buf.length === 0) return { body: buf, decoded: true };\n const layers = encoding.split(\",\").map((e) => e.trim().toLowerCase()).filter(Boolean);\n const opts = { maxOutputLength: cap };\n let current = buf;\n let decoded = false;\n try {\n for (let i = layers.length - 1; i >= 0; i--) {\n const enc = layers[i];\n if (enc === \"identity\") continue;\n if (enc === \"gzip\" || enc === \"x-gzip\") {\n current = zlib.gunzipSync(current, opts);\n } else if (enc === \"br\") {\n current = zlib.brotliDecompressSync(current, opts);\n } else if (enc === \"deflate\") {\n try {\n current = zlib.inflateSync(current, opts);\n } catch (inflateErr) {\n if (errorCode(inflateErr) === \"ERR_BUFFER_TOO_LARGE\")\n throw inflateErr;\n current = zlib.inflateRawSync(current, opts);\n }\n } else {\n if (decoded) {\n return new SafeFetchError(\n `Cannot fully decode content-encoding \"${encoding}\"`,\n url,\n \"decode-failed\",\n status\n );\n }\n return { body: buf, decoded: false };\n }\n decoded = true;\n }\n return { body: current, decoded };\n } catch (err) {\n const tooLarge = errorCode(err) === \"ERR_BUFFER_TOO_LARGE\";\n return new SafeFetchError(\n tooLarge ? `Decoded ${encoding} response body exceeded the size cap` : `Failed to decode ${encoding} response body`,\n url,\n tooLarge ? \"response-too-large\" : \"decode-failed\",\n status\n );\n }\n}\nfunction errorCode(err) {\n if (err != null && typeof err === \"object\" && \"code\" in err) {\n const code = err.code;\n return typeof code === \"string\" ? code : void 0;\n }\n return void 0;\n}\nfunction ipv4ToInt(ip) {\n const parts = ip.split(\".\");\n if (parts.length !== 4) return null;\n let acc = 0;\n for (const p of parts) {\n const n = Number(p);\n if (!Number.isInteger(n) || n < 0 || n > 255) return null;\n acc = acc << 8 | n;\n }\n return acc >>> 0;\n}\nfunction isIpv4InCidr(intIp, cidr) {\n const [addr, prefixRaw] = cidr.split(\"/\");\n const intCidr = ipv4ToInt(addr);\n if (intCidr === null) return false;\n const prefix = Number(prefixRaw);\n if (!Number.isInteger(prefix) || prefix < 0 || prefix > 32) return false;\n const mask = prefix === 0 ? 0 : -1 >>> 32 - prefix << 32 - prefix;\n return (intIp & mask) >>> 0 === (intCidr & mask) >>> 0;\n}\nfunction isPublicIpv4(addr, allowLoopback) {\n const intIp = ipv4ToInt(addr);\n if (intIp === null) return false;\n if (allowLoopback && addr === \"127.0.0.1\") return true;\n for (const cidr of PRIVATE_IPV4_CIDRS) {\n if (isIpv4InCidr(intIp, cidr)) return false;\n }\n return true;\n}\nfunction mappedIpv4(lower) {\n const dotted = lower.match(/^::ffff:(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})$/);\n if (dotted) return dotted[1];\n const hex = lower.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);\n if (hex) {\n const hi = parseInt(hex[1], 16);\n const lo = parseInt(hex[2], 16);\n return [hi >> 8, hi & 255, lo >> 8, lo & 255].join(\".\");\n }\n return null;\n}\nfunction isPublicIpv6(addr, allowLoopback) {\n const lower = addr.toLowerCase();\n if (allowLoopback && lower === \"::1\") return true;\n const mapped = mappedIpv4(lower);\n if (mapped) {\n return isPublicIpv4(mapped, allowLoopback);\n }\n if (lower === \"::\" || lower === \"::1\") return false;\n const firstHextet = lower.split(\":\")[0] || \"\";\n if (firstHextet.startsWith(\"fc\") || firstHextet.startsWith(\"fd\"))\n return false;\n if (firstHextet.startsWith(\"fe8\") || firstHextet.startsWith(\"fe9\"))\n return false;\n if (firstHextet.startsWith(\"fea\") || firstHextet.startsWith(\"feb\"))\n return false;\n if (firstHextet.startsWith(\"ff\")) return false;\n return true;\n}\n\n// src/storage/fetch-stored-bytes.ts\nasync function fetchStoredBytes(url, context, label, options, signal) {\n let response;\n try {\n response = await safeFetch(url, {\n ...options?.maxBytes === void 0 ? {} : { maxResponseBytes: options.maxBytes },\n /*\n * A caller's signal REPLACES the deadline rather than joining it.\n *\n * These adapters look the object's address up before fetching it, and\n * that lookup can stall too. Starting a fresh timer here would give the\n * fetch its own full budget on top of however long the lookup took, so a\n * read could outlive the deadline the caller was told applied — by\n * roughly double. One signal begun before the lookup governs both phases.\n */\n ...signal !== void 0 ? { signal } : options?.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs }\n });\n } catch (error) {\n const verdict = classifyFetchFailure(error);\n if (verdict === \"absent\") return null;\n if (verdict === \"oversized\") {\n throw new StorageReadTooLargeError(\n context,\n resolveReadBounds(options).maxBytes\n );\n }\n throw error;\n }\n if (response.status === 404) return null;\n if (!response.ok) {\n throw NextlyError.internal({\n logContext: {\n service: label,\n path: context,\n status: response.status,\n statusText: response.statusText\n }\n });\n }\n return Buffer.from(await response.arrayBuffer());\n}\nfunction classifyFetchFailure(error) {\n if (!(error instanceof SafeFetchError)) return \"unknown\";\n if (error.status === 404) return \"absent\";\n const successful = error.status !== void 0 && error.status >= 200 && error.status < 300;\n return error.reason === \"response-too-large\" && successful ? \"oversized\" : \"unknown\";\n}\nvar DEFAULT_READ_TIMEOUT_MS = DEFAULT_TIMEOUT_MS;\nvar DEFAULT_READ_MAX_BYTES = DEFAULT_MAX_RESPONSE_BYTES;\nfunction resolveReadBounds(options) {\n return {\n maxBytes: options?.maxBytes ?? DEFAULT_READ_MAX_BYTES,\n timeoutMs: options?.timeoutMs ?? DEFAULT_READ_TIMEOUT_MS\n };\n}\nfunction deadlineSignal(timeoutMs, context) {\n const controller = new AbortController();\n const timer = setTimeout(() => {\n controller.abort(new StorageReadTimeoutError(context, timeoutMs));\n }, timeoutMs);\n timer.unref?.();\n return {\n signal: controller.signal,\n /*\n * Called once the read has settled, whichever way it went. `unref` only\n * stops a pending timer holding the process open; it still sits on the\n * timer heap retaining the controller and the path, so a server doing a\n * thousand reads a second keeps thirty seconds of them alive and then runs\n * a thousand aborts that answer nobody.\n */\n cancel: () => {\n clearTimeout(timer);\n }\n };\n}\nasync function withDeadline(work, signal) {\n if (signal === void 0) return await work;\n return await Promise.race([\n work,\n new Promise((_, reject) => {\n if (signal.aborted) {\n reject(signal.reason);\n return;\n }\n signal.addEventListener(\"abort\", () => reject(signal.reason), {\n once: true\n });\n })\n ]);\n}\n\nexport {\n ExternalUrlError,\n validateExternalUrl,\n SafeFetchError,\n safeFetch,\n fetchStoredBytes,\n classifyFetchFailure,\n DEFAULT_READ_TIMEOUT_MS,\n DEFAULT_READ_MAX_BYTES,\n resolveReadBounds,\n deadlineSignal,\n withDeadline\n};\n","/**\n * Vercel Blob Storage Adapter\n *\n * Stores files on Vercel Blob Storage, a globally distributed object storage\n * service powered by Cloudflare R2. Optimized for Vercel deployments with\n * built-in CDN distribution.\n *\n * Features:\n * - Globally distributed CDN-backed storage\n * - Automatic file management with unique filenames\n * - Token-based authentication\n * - Client-side upload support (via handleUpload API)\n * - Serverless-friendly (no filesystem access required)\n *\n * @example Basic usage\n * ```typescript\n * const adapter = new VercelBlobStorageAdapter({\n * token: process.env.BLOB_READ_WRITE_TOKEN,\n * collections: { media: true }\n * });\n *\n * const result = await adapter.upload(buffer, {\n * filename: 'photo.jpg',\n * mimeType: 'image/jpeg'\n * });\n * // result.url: \"https://abc123.public.blob.vercel-storage.com/photo-xyz.jpg\"\n * ```\n */\n\nimport { put, del, head, list, BlobNotFoundError } from \"@vercel/blob\";\nimport { NextlyError } from \"nextly/errors\";\nimport type {\n IStorageAdapter,\n UploadOptions,\n UploadResult,\n StorageAdapterInfo,\n ClientUploadData,\n FileMetadata,\n BulkDeleteResult,\n StorageReadOptions,\n} from \"nextly/storage\";\nimport {\n fetchStoredBytes,\n DEFAULT_READ_TIMEOUT_MS,\n} from \"nextly/storage/fetch-stored-bytes\";\n\nimport type {\n VercelBlobStorageConfig,\n ResolvedVercelBlobConfig,\n} from \"./types\";\n\n// ============================================================\n// Vercel Blob Storage Adapter\n// ============================================================\n\n/**\n * Vercel Blob Storage Adapter\n *\n * Implements the IStorageAdapter interface for Vercel Blob Storage.\n * Provides file upload, deletion, existence checks, and metadata retrieval.\n */\nexport class VercelBlobStorageAdapter implements IStorageAdapter {\n private resolvedConfig: ResolvedVercelBlobConfig;\n\n /**\n * Create a new Vercel Blob storage adapter.\n *\n * @param config - Vercel Blob storage configuration\n * @throws Error if token is not provided\n */\n constructor(private config: VercelBlobStorageConfig) {\n // Resolve token from config or environment\n const token = config.token || process.env.BLOB_READ_WRITE_TOKEN || \"\";\n\n if (!token) {\n throw new Error(\n \"@nextly/storage-vercel-blob: token is required.\\n\\n\" +\n \"Either set the BLOB_READ_WRITE_TOKEN environment variable or pass token in config.\\n\" +\n \"Get your token from: Vercel Dashboard > Storage > Blob > Tokens\"\n );\n }\n\n // Resolve config with defaults\n this.resolvedConfig = {\n token,\n addRandomSuffix: config.addRandomSuffix ?? true,\n cacheControlMaxAge: config.cacheControlMaxAge ?? 31536000,\n access: config.access ?? \"public\",\n storeId: config.storeId,\n allowOverwrite: config.allowOverwrite ?? false,\n multipartThreshold: config.multipartThreshold ?? 5 * 1024 * 1024, // 5MB\n };\n }\n\n // ============================================================\n // Core IStorageAdapter Methods\n // ============================================================\n\n /**\n * Upload file to Vercel Blob.\n *\n * Files are stored with globally distributed CDN backing.\n * By default, a random suffix is added to prevent filename collisions.\n *\n * @param buffer - File content as Buffer\n * @param options - Upload options (filename, mimeType, folder, collection)\n * @returns Upload result with URL and storage path\n */\n async upload(buffer: Buffer, options: UploadOptions): Promise<UploadResult> {\n const mimeType = (options.contentType || options.mimeType || \"\")\n .toLowerCase()\n .trim();\n const filename = (options.filename || \"\").toLowerCase();\n const ext = filename.includes(\".\")\n ? filename.slice(filename.lastIndexOf(\".\") + 1)\n : \"\";\n const isHtml =\n mimeType === \"text/html\" ||\n mimeType === \"application/xhtml+xml\" ||\n ext === \"html\" ||\n ext === \"htm\" ||\n ext === \"xhtml\";\n // HTML stays unconditionally rejected. The `downloadUrl` trick that\n // makes SVG safe (see below) doesn't help HTML — a downloaded HTML\n // file is still a usable XSS vector when opened from disk, and\n // Vercel Blob has no equivalent of `Content-Security-Policy` to\n // defang it.\n if (isHtml) {\n throw NextlyError.validation({\n errors: [\n {\n path: \"file\",\n code: \"UNSUPPORTED_FOR_BACKEND\",\n message:\n \"HTML files cannot be hosted on Vercel Blob. Use the S3 or R2 adapter, or upload as another format.\",\n },\n ],\n logContext: {\n adapter: \"vercel-blob\",\n claimedMimeType: options.mimeType,\n reason: \"vercel-blob-rejects-html\",\n filename: options.filename,\n },\n });\n }\n\n const isSvg =\n mimeType === \"image/svg+xml\" || ext === \"svg\" || ext === \"svgz\";\n\n const pathname = this.buildPathname(options.filename, options.folder);\n\n const result = await put(pathname, buffer, {\n access: this.resolvedConfig.access,\n token: this.resolvedConfig.token,\n contentType: options.contentType || options.mimeType,\n addRandomSuffix: this.resolvedConfig.addRandomSuffix,\n cacheControlMaxAge: this.resolvedConfig.cacheControlMaxAge,\n });\n\n // SVGs are served via Vercel Blob's `downloadUrl` (the same URL with\n // `?download=1` appended) so direct top-level navigation forces an\n // attachment download instead of rendering. `<img src>` ignores the\n // `Content-Disposition` header, so legitimate inline rendering still\n // works. The `@vercel/blob` SDK has no `contentDisposition` input\n // option on `put()`, so this query-param-driven approach is the\n // supported mechanism. Caller is responsible for sanitizing SVG\n // contents upstream (handled by `upload-validation`).\n const url =\n isSvg && options.contentDisposition === \"attachment\"\n ? result.downloadUrl\n : result.url;\n\n return {\n url,\n path: result.url,\n };\n }\n\n /**\n * Delete file from Vercel Blob.\n *\n * @param filePath - Full blob URL to delete\n */\n async delete(filePath: string): Promise<void> {\n await del(filePath, {\n token: this.resolvedConfig.token,\n });\n }\n\n /**\n * Delete multiple files from Vercel Blob in chunked batches.\n *\n * Processes deletions in chunks of 10 concurrent calls using Promise.allSettled,\n * collecting successes and failures without short-circuiting.\n *\n * @param filePaths - Array of full blob URLs to delete\n * @returns BulkDeleteResult with successful and failed arrays\n */\n async bulkDelete(filePaths: string[]): Promise<BulkDeleteResult> {\n const successful: string[] = [];\n const failed: Array<{ filePath: string; error: string }> = [];\n const chunkSize = 10;\n\n for (let i = 0; i < filePaths.length; i += chunkSize) {\n const chunk = filePaths.slice(i, i + chunkSize);\n const results = await Promise.allSettled(\n chunk.map(fp => del(fp, { token: this.resolvedConfig.token }))\n );\n\n results.forEach((result, idx) => {\n const fp = chunk[idx];\n if (result.status === \"fulfilled\") {\n successful.push(fp);\n } else {\n failed.push({\n filePath: fp,\n error:\n result.reason instanceof Error\n ? result.reason.message\n : String(result.reason),\n });\n }\n });\n }\n\n return { successful, failed };\n }\n\n /**\n * Check if file exists in Vercel Blob.\n *\n * Uses the head() function which is efficient for existence checks.\n *\n * @param filePath - Full blob URL to check\n * @returns true if file exists, false otherwise\n */\n async exists(filePath: string): Promise<boolean> {\n try {\n await head(filePath, {\n token: this.resolvedConfig.token,\n });\n return true;\n } catch {\n // Vercel Blob throws an error if the blob doesn't exist\n return false;\n }\n }\n\n /**\n * Read a stored blob back as bytes, or `null` when it is not there.\n *\n * A NETWORK round trip, unlike the local adapter's disk read, because the\n * bytes live on Vercel's CDN and there is no other way to reach them. That\n * cost is the reason a caller serving these from its own origin has to cache:\n * the privacy rule that forces same-origin serving does not also make the\n * fetch free, and an uncached proxy pays it on every request.\n *\n * The URL is taken from `head` rather than assembled from `filePath`,\n * because a blob's address is issued by the service — it carries a random\n * suffix this adapter never chose — so deriving one here would be guessing at\n * a string another system owns.\n *\n * `null` for a missing blob rather than a throw, matching {@link exists}.\n *\n * @param filePath - Blob path/key\n * @returns The blob's bytes, or `null` when it does not exist\n */\n async read(\n filePath: string,\n options?: StorageReadOptions\n ): Promise<Buffer | null> {\n /*\n * ONE deadline for both phases, started before the lookup.\n *\n * `head` can stall exactly as the fetch can, and it runs first — so a\n * deadline that begins only at the fetch leaves the lookup unbounded and\n * the read can outlive what the caller was promised. Created here and\n * handed to both.\n *\n * ALWAYS, not only when the caller named a timeout. `safeFetch` applies a\n * default deadline of its own, so a caller stating none was still bounded\n * for the fetch and unbounded for the lookup — which is the commonest call,\n * the email path among them, since it supplies only a byte cap. The default\n * comes from the same constant `safeFetch` uses rather than being restated.\n */\n const deadline = AbortSignal.timeout(\n options?.timeoutMs ?? DEFAULT_READ_TIMEOUT_MS\n );\n\n let target: string;\n try {\n const meta = await head(filePath, {\n token: this.resolvedConfig.token,\n abortSignal: deadline,\n });\n target = meta.downloadUrl ?? meta.url;\n } catch (error: unknown) {\n /*\n * ONLY the not-found class becomes `null`. `head` also rejects for an\n * expired token, a suspended or missing store, an aborted request and a\n * plain network failure, and every one of those says nothing about\n * whether the blob exists. Catching them all reports an outage as a\n * deletion, which a caller may act on by writing a replacement over a\n * file that is still there.\n *\n * Identified by the CLASS the SDK exports rather than by matching the\n * message, because the message is prose this package does not own.\n */\n if (error instanceof BlobNotFoundError) return null;\n throw error;\n }\n\n /*\n * OUTSIDE the catch above, deliberately, and through the shared helper so\n * that separation is stated once rather than in each adapter. A failed\n * fetch of a blob whose metadata just resolved is a transport failure\n * rather than an absence, and folding it into `null` would report a\n * network outage as a deleted file.\n */\n return await fetchStoredBytes(\n target,\n filePath,\n \"Vercel Blob\",\n options,\n deadline\n );\n }\n\n /**\n * Get public URL for Vercel Blob file.\n *\n * Vercel Blob paths ARE the public URLs - they're already full HTTPS URLs\n * with CDN distribution.\n *\n * @param filePath - Full blob URL\n * @returns The same URL (Vercel Blob paths are already public URLs)\n */\n getPublicUrl(filePath: string): string {\n // Vercel Blob paths are already full URLs\n return filePath;\n }\n\n /**\n * Get storage type identifier.\n */\n getType(): \"vercel-blob\" {\n return \"vercel-blob\";\n }\n\n // ============================================================\n // Optional IStorageAdapter Methods\n // ============================================================\n\n /**\n * Get adapter info including capabilities.\n *\n * @returns Adapter info with type, name, and capability flags\n */\n getInfo(): StorageAdapterInfo {\n return {\n type: \"vercel-blob\",\n name: \"VercelBlobStorageAdapter\",\n supportsSignedUrls: false, // Vercel Blob URLs are public by default\n supportsClientUploads: true, // Via handleUpload API\n };\n }\n\n /**\n * Get file metadata from Vercel Blob.\n *\n * Retrieves file information including size, content type, and upload date.\n *\n * @param filePath - Full blob URL\n * @returns File metadata or null if file not found\n */\n async getMetadata(filePath: string): Promise<FileMetadata | null> {\n try {\n const result = await head(filePath, {\n token: this.resolvedConfig.token,\n });\n\n // Extract filename from pathname\n const filename = result.pathname.split(\"/\").pop() || result.pathname;\n\n return {\n id: filePath,\n filename,\n originalFilename: filename,\n mimeType: result.contentType,\n size: result.size,\n url: result.url,\n createdAt: result.uploadedAt.toISOString(),\n };\n } catch {\n // File not found\n return null;\n }\n }\n\n /**\n * Generate pre-signed URL for client-side uploads.\n *\n * Vercel Blob uses a different pattern for client uploads - they require\n * the handleUpload API which handles token generation server-side.\n *\n * This method is not implemented because Vercel Blob's client upload flow\n * requires server-side route handlers with handleUpload().\n *\n * @see https://vercel.com/docs/storage/vercel-blob/client-upload\n * @throws Error always - client uploads require handleUpload API\n */\n getPresignedUploadUrl(\n _key: string,\n _mimeType: string,\n _expiresIn?: number\n ): Promise<ClientUploadData> {\n return Promise.reject(\n new Error(\n \"@nextly/storage-vercel-blob: Client uploads require the handleUpload API.\\n\\n\" +\n \"Vercel Blob uses a different pattern for client-side uploads that involves:\\n\" +\n \"1. A server-side route handler with handleUpload()\\n\" +\n \"2. The @vercel/blob/client upload() function\\n\\n\" +\n \"See: https://vercel.com/docs/storage/vercel-blob/client-upload\\n\\n\" +\n \"For server-side uploads, use the standard upload() method instead.\"\n )\n );\n }\n\n // ============================================================\n // Additional Methods\n // ============================================================\n\n /**\n * List blobs with optional prefix filter.\n *\n * Useful for browsing or batch operations on stored files.\n *\n * @param prefix - Optional prefix to filter results\n * @param options - List options (limit, cursor)\n * @returns List of blob metadata\n */\n async listBlobs(\n prefix?: string,\n options?: { limit?: number; cursor?: string }\n ): Promise<{\n blobs: Array<{\n url: string;\n pathname: string;\n size: number;\n uploadedAt: Date;\n }>;\n hasMore: boolean;\n cursor?: string;\n }> {\n const result = await list({\n token: this.resolvedConfig.token,\n prefix,\n limit: options?.limit,\n cursor: options?.cursor,\n });\n\n return {\n blobs: result.blobs.map(blob => ({\n url: blob.url,\n pathname: blob.pathname,\n size: blob.size,\n uploadedAt: blob.uploadedAt,\n })),\n hasMore: result.hasMore,\n cursor: result.cursor,\n };\n }\n\n // ============================================================\n // Helper Methods\n // ============================================================\n\n /**\n * Build pathname for Vercel Blob upload.\n *\n * Creates pathname in format: {folder}/{filename}\n * If no folder is provided, uses the filename directly.\n *\n * @param filename - Original filename (will be sanitized)\n * @param folder - Optional folder/prefix for organizing uploads\n * @returns Generated pathname\n * @throws Error if folder fails sanitization\n */\n private buildPathname(filename: string, folder?: string): string {\n const sanitized = this.sanitizeFilename(filename);\n if (!folder) return sanitized;\n return `${this.sanitizeFolder(folder)}/${sanitized}`;\n }\n\n /**\n * Sanitize filename to prevent path traversal issues.\n *\n * @param filename - Original filename\n * @returns Sanitized filename\n */\n private sanitizeFilename(filename: string): string {\n const basename = filename.split(/[/\\\\]/).pop() || filename;\n return basename.replace(/[^a-zA-Z0-9._-]/g, \"-\");\n }\n\n /**\n * Reject folder values that would let a caller\n * escape the configured prefix via path traversal or weird\n * separators. Vercel Blob is flat-keyed so `/` is just part of the\n * pathname, but an attacker who controls `folder` could still:\n *\n * - Use `..` to chain a relative-traversal-style key.\n * - Use `\\` (Windows separator) to confuse downstream tooling.\n * - Use control chars / null bytes to truncate the key.\n * - Use a leading `/` to look like an absolute path.\n *\n * Internal `/` segments stay allowed because callers legitimately\n * use nested folders (`docs/2026/...`); a leading `/`, empty\n * segments (`docs//x`), or `..` segments are rejected.\n *\n * @throws Error with a stable message so the storage facade can\n * surface a 400 instead of a 500.\n */\n private sanitizeFolder(folder: string): string {\n const trimmed = folder.replace(/\\/+$/, \"\"); // tolerate one trailing `/`\n if (!trimmed) {\n throw new Error(\"Folder must be a non-empty string.\");\n }\n // eslint-disable-next-line no-control-regex -- the whole point is to reject control chars\n if (/[\\\\\\0\\x01-\\x1f\\x7f]/.test(trimmed)) {\n throw new Error(\n \"Folder contains forbidden characters (backslash, control chars, or null bytes).\"\n );\n }\n if (trimmed.startsWith(\"/\")) {\n throw new Error(\"Folder must not start with `/`.\");\n }\n const segments = trimmed.split(\"/\");\n for (const segment of segments) {\n if (segment === \"\") {\n throw new Error(\"Folder must not contain empty segments (`//`).\");\n }\n if (segment === \"..\") {\n throw new Error(\"Folder must not contain `..` segments.\");\n }\n }\n return trimmed;\n }\n\n // ============================================================\n // Public Accessors\n // ============================================================\n\n /**\n * Get the configured token (masked for logging).\n */\n getTokenMasked(): string {\n const token = this.resolvedConfig.token;\n if (token.length <= 8) return \"****\";\n return `${token.slice(0, 4)}...${token.slice(-4)}`;\n }\n\n /**\n * Check if random suffix is enabled.\n */\n hasRandomSuffix(): boolean {\n return this.resolvedConfig.addRandomSuffix;\n }\n\n /**\n * Get configured cache control max age.\n */\n getCacheControlMaxAge(): number {\n return this.resolvedConfig.cacheControlMaxAge;\n }\n}\n","/**\n * Vercel Blob Storage Plugin\n *\n * Factory function that creates a storage plugin for Vercel Blob Storage.\n * Returns a StoragePlugin that can be registered with MediaStorage.\n *\n * @example Basic usage\n * ```typescript\n * import { vercelBlobStorage } from '@nextly/storage-vercel-blob'\n * import { defineConfig } from 'nextly/config'\n *\n * export default defineConfig({\n * storage: [\n * vercelBlobStorage({\n * token: process.env.BLOB_READ_WRITE_TOKEN,\n * collections: {\n * media: true\n * }\n * })\n * ]\n * })\n * ```\n *\n * @example With client uploads (recommended for Vercel)\n * ```typescript\n * vercelBlobStorage({\n * collections: {\n * media: {\n * clientUploads: true // Bypass 4.5MB serverless limit\n * }\n * }\n * })\n * ```\n *\n * @example With collection-specific configuration\n * ```typescript\n * vercelBlobStorage({\n * addRandomSuffix: true,\n * cacheControlMaxAge: 86400, // 1 day\n * collections: {\n * // Simple enable with defaults\n * media: true,\n *\n * // Full configuration\n * documents: {\n * prefix: 'docs/',\n * addRandomSuffix: false,\n * allowOverwrite: true\n * }\n * }\n * })\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { StoragePlugin, ClientUploadData } from \"nextly/storage\";\n\nimport { VercelBlobStorageAdapter } from \"./adapter\";\nimport type { VercelBlobStorageConfig } from \"./types\";\n\n// ============================================================\n// Plugin Factory Function\n// ============================================================\n\n/**\n * Create a Vercel Blob storage plugin for Nextly.\n *\n * This factory function creates a StoragePlugin that can be added to\n * the `storage` array in `nextly.config.ts`. Vercel Blob is optimized\n * for Vercel deployments with:\n *\n * - Global CDN distribution\n * - Simple token-based authentication\n * - Client-side upload support (via handleUpload API)\n * - Automatic file management\n *\n * @param config - Vercel Blob storage configuration\n * @returns A StoragePlugin that MediaStorage can register\n *\n * @throws Error if token is not provided (via adapter)\n */\nexport function vercelBlobStorage(\n config: VercelBlobStorageConfig\n): StoragePlugin {\n // Handle disabled plugin\n // When disabled, return a plugin with no collections and null adapter\n // MediaStorage.registerPlugin() checks for null adapter and skips registration\n if (config.enabled === false) {\n return {\n name: \"vercel-blob-storage\",\n type: \"vercel-blob\",\n collections: {},\n adapter: null as unknown as StoragePlugin[\"adapter\"],\n };\n }\n\n // Create the Vercel Blob adapter\n // Adapter constructor validates required config (token)\n const adapter = new VercelBlobStorageAdapter(config);\n\n // Build and return the plugin\n const plugin: StoragePlugin = {\n name: \"vercel-blob-storage\",\n type: \"vercel-blob\",\n collections: config.collections,\n adapter,\n\n /**\n * Generate upload URL for client-side uploads.\n *\n * Note: Vercel Blob uses a different pattern for client uploads.\n * Instead of pre-signed URLs, it uses the handleUpload() API which\n * requires server-side route handlers.\n *\n * This method throws an error explaining the correct approach.\n *\n * @see https://vercel.com/docs/storage/vercel-blob/client-upload\n */\n getClientUploadUrl(\n _filename: string,\n _mimeType: string,\n _collection: string\n ): Promise<ClientUploadData> {\n // Vercel Blob doesn't use pre-signed URLs like S3\n // Instead, it requires using the handleUpload API with @vercel/blob/client\n return Promise.reject(\n new Error(\n \"@nextly/storage-vercel-blob: Client uploads require the handleUpload API.\\n\\n\" +\n \"Vercel Blob uses a different pattern than S3 for client-side uploads:\\n\\n\" +\n \"1. Create a server-side route handler with handleUpload()\\n\" +\n \"2. Use upload() from @vercel/blob/client on the frontend\\n\\n\" +\n \"See: https://vercel.com/docs/storage/vercel-blob/client-upload\"\n )\n );\n },\n\n /**\n * Get signed download URL for file access.\n *\n * Note: Vercel Blob URLs are public by default and do not support\n * signed/temporary URLs. All uploaded blobs are accessible via their\n * public URL.\n *\n * @param path - Storage path (full blob URL)\n * @returns The same URL (Vercel Blob URLs are public)\n */\n getSignedDownloadUrl(path: string): Promise<string> {\n // Vercel Blob URLs are public by default\n // No signed URL support - just return the public URL\n return Promise.resolve(path);\n },\n };\n\n return plugin;\n}\n","/**\n * @nextly/storage-vercel-blob\n *\n * Vercel Blob storage adapter for Nextly CMS.\n * Optimized for Vercel deployments with client-side upload support\n * to bypass serverless function size limits (4.5MB).\n *\n * @example Basic usage\n * ```typescript\n * import { vercelBlobStorage } from '@nextly/storage-vercel-blob'\n * import { defineConfig } from 'nextly/config'\n *\n * export default defineConfig({\n * storage: [\n * vercelBlobStorage({\n * token: process.env.BLOB_READ_WRITE_TOKEN,\n * collections: {\n * media: true\n * }\n * })\n * ]\n * })\n * ```\n *\n * @example With client uploads (recommended for Vercel)\n * ```typescript\n * vercelBlobStorage({\n * collections: {\n * media: {\n * clientUploads: true // Bypass 4.5MB serverless limit\n * }\n * }\n * })\n * ```\n *\n * @packageDocumentation\n */\n\n// ============================================================\n// Vercel Blob Storage Plugin Export (Primary API)\n// ============================================================\n\nexport { vercelBlobStorage } from \"./plugin\";\n\n// ============================================================\n// Vercel Blob Storage Adapter Export\n// ============================================================\n\nexport { VercelBlobStorageAdapter } from \"./adapter\";\n\n// ============================================================\n// Vercel Blob Types Export\n// ============================================================\n\nexport type {\n VercelBlobStorageConfig,\n VercelBlobCollectionConfig,\n VercelBlobCollectionStorageMap,\n ResolvedVercelBlobConfig,\n} from \"./types\";\n\n// ============================================================\n// Package Metadata\n// ============================================================\n\nexport const PACKAGE_NAME = \"@nextly/storage-vercel-blob\";\nexport const PACKAGE_VERSION = \"0.1.0\";\n"]}
1
+ {"version":3,"sources":["../../nextly/dist/chunk-IAZJNA2U.mjs","../../nextly/dist/chunk-T3OVIJZM.mjs","../../nextly/dist/chunk-YGE6AGZG.mjs","../src/adapter.ts","../src/plugin.ts","../src/index.ts"],"names":["put","del","head","BlobNotFoundError","list"],"mappings":"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","file":"index.cjs","sourcesContent":["// src/database/errors.ts\nvar DbError = class extends Error {\n kind;\n dialect;\n code;\n meta;\n cause;\n constructor(args) {\n super(args.message);\n this.name = \"DbError\";\n this.kind = args.kind;\n this.dialect = args.dialect;\n this.code = args.code;\n this.meta = args.meta;\n this.cause = args.cause;\n }\n};\nfunction isDbError(err) {\n if (!err || typeof err !== \"object\") return false;\n const obj = err;\n return obj.name === \"DbError\" && typeof obj.kind === \"string\";\n}\nfunction toDbError(dialect, error, meta) {\n if (isDbError(error)) return error;\n const code = safeCode(error);\n const rawMsg = error != null && typeof error === \"object\" && \"message\" in error ? error.message : void 0;\n const message = typeof rawMsg === \"string\" ? rawMsg : \"Database error\";\n let kind = \"internal\";\n switch (dialect) {\n case \"postgresql\":\n kind = mapPostgresCodeToKind(code);\n break;\n case \"mysql\":\n kind = mapMySqlCodeToKind(code);\n break;\n case \"sqlite\":\n kind = mapSqliteCodeToKind(code);\n break;\n }\n if ((dialect === \"mysql\" || dialect === \"sqlite\") && (kind === \"constraint\" || kind === \"internal\") && isLikelyUniqueViolationMessage(dialect, message)) {\n kind = \"unique-violation\";\n }\n if (kind === \"internal\" && code) {\n const c = code.toUpperCase();\n if (c === \"ECONNRESET\" || c.includes(\"PROTOCOL_CONNECTION_LOST\"))\n kind = \"connection-lost\";\n else if (c === \"ETIMEDOUT\") kind = \"timeout\";\n }\n return new DbError({ message, kind, dialect, code, meta, cause: error });\n}\nfunction safeCode(error) {\n if (!error || typeof error !== \"object\") return void 0;\n const e = error;\n let c = e.code ?? e.sqlState ?? e.state ?? e.errno ?? void 0;\n if (!c && typeof e.originalError?.code === \"string\") c = e.originalError.code;\n if (!c && typeof e.cause?.code === \"string\") c = e.cause.code;\n if (!c && typeof e.severity === \"string\" && typeof e.code === \"string\")\n c = e.code;\n if (typeof c === \"number\") return String(c);\n if (typeof c === \"string\" && c.length > 0) return c;\n return void 0;\n}\nfunction mapPostgresCodeToKind(code) {\n if (!code) return \"internal\";\n const c = code.toUpperCase();\n if (c === \"40P01\") return \"deadlock\";\n if (c === \"40001\") return \"serialization-failure\";\n if (c === \"57014\") return \"timeout\";\n if (c === \"23505\") return \"unique-violation\";\n if (c === \"23503\") return \"fk-violation\";\n if (c === \"23502\") return \"not-null-violation\";\n if (c === \"42601\") return \"syntax\";\n if (c.startsWith(\"08\") || c === \"57P01\") return \"connection-lost\";\n if (c.startsWith(\"23\")) return \"constraint\";\n return \"internal\";\n}\nfunction mapMySqlCodeToKind(code) {\n if (!code) return \"internal\";\n const c = code.toUpperCase();\n if (c === \"1213\" || c === \"ER_LOCK_DEADLOCK\") return \"deadlock\";\n if (c === \"1205\" || c === \"ER_LOCK_WAIT_TIMEOUT\") return \"timeout\";\n if (c === \"1062\" || c === \"ER_DUP_ENTRY\") return \"unique-violation\";\n if (c === \"23000\") return \"constraint\";\n if (c === \"1064\" || c === \"ER_PARSE_ERROR\") return \"syntax\";\n if (c === \"1452\" || c === \"ER_NO_REFERENCED_ROW_2\") return \"fk-violation\";\n if (c === \"1451\" || c === \"ER_ROW_IS_REFERENCED_2\") return \"fk-violation\";\n if (c === \"ECONNRESET\" || c.includes(\"PROTOCOL_CONNECTION_LOST\"))\n return \"connection-lost\";\n if (c === \"ETIMEDOUT\") return \"timeout\";\n return \"internal\";\n}\nfunction mapSqliteCodeToKind(code) {\n if (!code) return \"internal\";\n const c = code.toUpperCase();\n if (c === \"SQLITE_BUSY\" || c === \"SQLITE_LOCKED\") return \"deadlock\";\n if (c === \"SQLITE_CONSTRAINT_UNIQUE\") return \"unique-violation\";\n if (c === \"SQLITE_CONSTRAINT_PRIMARYKEY\") return \"unique-violation\";\n if (c === \"SQLITE_CONSTRAINT_FOREIGNKEY\") return \"fk-violation\";\n if (c === \"SQLITE_CONSTRAINT_NOTNULL\") return \"not-null-violation\";\n if (c === \"SQLITE_INTERRUPT\") return \"timeout\";\n if (c === \"SQLITE_ERROR\") return \"syntax\";\n if (c.startsWith(\"SQLITE_CONSTRAINT\")) return \"constraint\";\n return \"internal\";\n}\nfunction isLikelyUniqueViolationMessage(dialect, message) {\n const m = message.toLowerCase();\n if (dialect === \"mysql\") {\n return m.includes(\"duplicate entry\") || m.includes(\"duplicate key\");\n }\n if (dialect === \"sqlite\") {\n return m.includes(\"unique constraint failed\");\n }\n return false;\n}\n\n// src/errors/error-codes.ts\nvar NEXTLY_ERROR_STATUS = {\n VALIDATION_ERROR: 400,\n INVALID_INPUT: 400,\n AUTH_REQUIRED: 401,\n AUTH_INVALID_CREDENTIALS: 401,\n TOKEN_EXPIRED: 401,\n FORBIDDEN: 403,\n // The schema builder is off in this environment (production by default).\n // Separate from FORBIDDEN: the caller's permissions are not the problem.\n BUILDER_DISABLED: 403,\n NOT_FOUND: 404,\n CONFLICT: 409,\n DUPLICATE: 409,\n RATE_LIMITED: 429,\n PAYLOAD_TOO_LARGE: 413,\n UNSUPPORTED_MEDIA_TYPE: 415,\n // 422: understood, well-formed, and refused on a rule the caller can act on.\n // Deliberately NOT added to CANONICAL_CODE_FOR_STATUS -- that list drives the\n // status -> code direction, where 422 stays mapped to INVALID_INPUT.\n BUSINESS_RULE_VIOLATION: 422,\n INTERNAL_ERROR: 500,\n DATABASE_ERROR: 500,\n EXTERNAL_SERVICE_ERROR: 502,\n SERVICE_UNAVAILABLE: 503,\n // Outbound-fetch safety (utils/validate-external-url): a URL refused for SSRF\n // safety, and a fetch that timed out / exceeded the size cap / failed to decode.\n EXTERNAL_URL_BLOCKED: 400,\n EXTERNAL_REQUEST_FAILED: 502,\n FILENAME_INVALID: 400,\n EXTENSION_BLOCKED: 400,\n MIME_BLOCKED: 415,\n MIME_NOT_ALLOWED: 415,\n SIZE_EXCEEDED: 413,\n // A stored object exceeded the cap a READ was given, which is a different\n // question from SIZE_EXCEEDED above: that one refuses an upload the caller\n // is sending, this one refuses to buffer an object already stored. Kept\n // apart so a caller discriminating on the code cannot match both.\n STORAGE_READ_TOO_LARGE: 413,\n // A stored object did not answer within the deadline the read was given. 504\n // rather than 500 because the failure is the BACKEND not answering, and a\n // caller can act on that difference: a gateway timeout is worth retrying, an\n // internal error is not.\n STORAGE_READ_TIMEOUT: 504,\n // The store answered, and answered badly. 502 rather than 500 because the\n // fault is UPSTREAM of this process: a caller can retry it, and an operator\n // reading the log needs to look at the bucket rather than at this service.\n // Distinct from the timeout above, which never got an answer at all.\n STORAGE_READ_UNREACHABLE: 502,\n MAGIC_BYTE_MISMATCH: 400,\n SVG_SANITIZATION_FAILED: 400,\n UNSUPPORTED_FOR_BACKEND: 415,\n // Plan B — schema bookkeeping consolidation.\n NEXTLY_LEGACY_BOOKKEEPING_DETECTED: 409,\n NEXTLY_UPGRADE_TABLE_NAME_COLLISION: 409,\n NEXTLY_UPGRADE_IN_PROGRESS: 409,\n // Plan C2 — nextly migrate phases.\n NEXTLY_MIGRATE_LOCK_BUSY: 409,\n NEXTLY_BASELINE_LOCK_NOT_HELD: 409,\n NEXTLY_RESOLVE_LOCK_NOT_HELD: 409,\n // Boot refused to serve: the migrate lock stayed held past the wait deadline,\n // so this process never established whether the schema matches the code. 503\n // rather than 409 — a load balancer should take the instance out of rotation\n // and retry it, which is exactly the recovery this refusal wants.\n NEXTLY_BOOT_MIGRATIONS_NOT_RUN: 503,\n // Still running rather than refused. 503 for the same reason: retry shortly.\n NEXTLY_BOOT_MIGRATIONS_PENDING: 503,\n NEXTLY_CORE_DESTRUCTIVE_REFUSED: 409,\n NEXTLY_MIGRATION_DRIFT: 409,\n NEXTLY_MIGRATION_APPLY_FAILED: 500,\n // Plan C3 — migrate:resolve recovery command.\n NEXTLY_MIGRATION_FILE_MISSING: 404,\n NEXTLY_MIGRATION_SNAPSHOT_MISSING: 404,\n NEXTLY_MIGRATION_RESOLVE_DRIFT: 409,\n NEXTLY_MIGRATION_RESOLVE_PRECONDITION: 409,\n // Plan D — UI schema support.\n NEXTLY_UI_SCHEMA_INVALID: 400,\n NEXTLY_SCHEMA_SLUG_COLLISION: 409,\n NEXTLY_SCHEMA_RELATION_TARGET_MISSING: 400,\n // Plugin platform (P2b) — schema extend (contributes.extend) + relations (D15).\n NEXTLY_SCHEMA_EXTEND_TARGET_UNKNOWN: 400,\n NEXTLY_SCHEMA_EXTEND_FIELD_DUPLICATE: 409,\n NEXTLY_SCHEMA_CROSS_PLUGIN_RELATION: 409,\n // Plugin platform (P2c) — framework remap (.rename()).\n NEXTLY_SCHEMA_RENAME_UNKNOWN_TARGET: 400,\n // Plugin platform — a declared admin.clientConfig that cannot be delivered\n // to the browser, refused at boot rather than serialized mangled.\n NEXTLY_PLUGIN_CLIENT_CONFIG_INVALID: 500,\n // Plugin platform — a contributed admin widget that cannot be delivered to\n // the browser. Refused at boot because it is serialized into the ONE\n // `/api/admin-meta/workspace` payload: a value `JSON.stringify` throws on\n // fails that request for every admin, not just the widget's own card.\n NEXTLY_PLUGIN_ADMIN_WIDGET_INVALID: 500,\n // Plugin platform (P0) — boot-time plugin dependency/version resolution.\n PLUGIN_RESOLUTION_ERROR: 500,\n // Plugin platform (P4) — contributes.routes collection (D25).\n NEXTLY_ROUTE_COLLISION: 409,\n NEXTLY_ROUTE_INVALID_PATH: 400,\n // A root-mounted route declared where the request pipeline never reaches the\n // root pass. 400 like an invalid path and not 409: nothing else claims the\n // address, the declaration simply cannot be served from there.\n NEXTLY_ROUTE_UNREACHABLE_ROOT: 400,\n // A `mount` outside the declared union, which only an untyped caller can\n // produce. 400 for the same reason: the declaration itself is unserveable.\n NEXTLY_ROUTE_INVALID_MOUNT: 400,\n // An email transport whose library is an optional peer dependency the host\n // has not installed. 503 rather than 500: the request is not malformed and\n // nothing is broken, the install simply cannot carry it out yet, and the\n // remedy is one command on the server rather than a change by the caller.\n NEXTLY_EMAIL_TRANSPORT_UNAVAILABLE: 503,\n // The tooling that compiles `nextly.config.ts` is an optional peer the host\n // has not installed. 503 rather than 500 for the same reason as the mail\n // transport above: nothing is broken and the request is not malformed, the\n // install simply cannot carry it out until one command is run.\n NEXTLY_CONFIG_TOOLING_UNAVAILABLE: 503\n};\nvar CANONICAL_CODE_FOR_STATUS = [\n \"VALIDATION_ERROR\",\n \"AUTH_REQUIRED\",\n \"FORBIDDEN\",\n \"NOT_FOUND\",\n \"CONFLICT\",\n \"PAYLOAD_TOO_LARGE\",\n \"UNSUPPORTED_MEDIA_TYPE\",\n \"RATE_LIMITED\",\n \"EXTERNAL_SERVICE_ERROR\",\n \"SERVICE_UNAVAILABLE\"\n];\nvar LEGACY_UNPROCESSABLE_STATUS = 422;\nvar STATUS_TO_CODE = {\n ...Object.fromEntries(\n CANONICAL_CODE_FOR_STATUS.map((code) => [NEXTLY_ERROR_STATUS[code], code])\n ),\n [LEGACY_UNPROCESSABLE_STATUS]: \"INVALID_INPUT\"\n};\nfunction statusToErrorCode(statusCode) {\n return STATUS_TO_CODE[statusCode] ?? \"INTERNAL_ERROR\";\n}\nvar GENERIC_PUBLIC_MESSAGE = {\n VALIDATION_ERROR: \"Validation failed.\",\n INVALID_INPUT: \"The request could not be processed.\",\n AUTH_REQUIRED: \"Authentication required.\",\n FORBIDDEN: \"You don't have permission to perform this action.\",\n NOT_FOUND: \"Not found.\",\n CONFLICT: \"The resource has changed since you last loaded it. Please refresh and try again.\",\n DUPLICATE: \"Resource already exists.\",\n PAYLOAD_TOO_LARGE: \"The request is too large.\",\n UNSUPPORTED_MEDIA_TYPE: \"That file type is not supported.\",\n RATE_LIMITED: \"Too many requests. Please try again later.\",\n EXTERNAL_SERVICE_ERROR: \"An upstream service failed.\",\n SERVICE_UNAVAILABLE: \"The service is temporarily unavailable.\",\n INTERNAL_ERROR: \"An unexpected error occurred.\"\n};\nfunction genericPublicMessage(code) {\n return GENERIC_PUBLIC_MESSAGE[code] ?? GENERIC_PUBLIC_MESSAGE.INTERNAL_ERROR;\n}\n\n// src/errors/nextly-error.ts\nvar DB_ERROR_MAPPING = {\n \"unique-violation\": {\n code: \"DUPLICATE\",\n statusCode: 409,\n publicMessage: \"Resource already exists.\"\n },\n \"fk-violation\": {\n code: \"VALIDATION_ERROR\",\n statusCode: 400,\n publicMessage: \"Referenced record does not exist.\"\n },\n \"not-null-violation\": {\n code: \"VALIDATION_ERROR\",\n statusCode: 400,\n publicMessage: \"A required field is missing.\"\n },\n constraint: {\n code: \"VALIDATION_ERROR\",\n statusCode: 400,\n publicMessage: \"The provided data violates a constraint.\"\n },\n deadlock: {\n code: \"CONFLICT\",\n statusCode: 409,\n publicMessage: \"The operation could not be completed. Please retry.\"\n },\n \"serialization-failure\": {\n code: \"CONFLICT\",\n statusCode: 409,\n publicMessage: \"The operation could not be completed. Please retry.\"\n },\n timeout: {\n code: \"DATABASE_ERROR\",\n statusCode: 500,\n publicMessage: \"The operation timed out. Please try again.\"\n },\n \"connection-lost\": {\n code: \"DATABASE_ERROR\",\n statusCode: 500,\n publicMessage: \"A temporary database error occurred. Please try again.\"\n },\n syntax: {\n code: \"INTERNAL_ERROR\",\n statusCode: 500,\n publicMessage: \"An unexpected error occurred.\"\n },\n internal: {\n code: \"INTERNAL_ERROR\",\n statusCode: 500,\n publicMessage: \"An unexpected error occurred.\"\n }\n};\nvar NEXTLY_ERROR_BRAND = Symbol.for(\"nextly/NextlyError\");\nfunction hasBrand(value) {\n if (value === null || typeof value !== \"object\" && typeof value !== \"function\") {\n return false;\n }\n return value[NEXTLY_ERROR_BRAND] === true;\n}\nvar NextlyError = class _NextlyError extends Error {\n code;\n statusCode;\n publicMessage;\n publicData;\n messageKey;\n logMessage;\n logContext;\n cause;\n timestamp;\n constructor(opts) {\n super(opts.publicMessage);\n this.name = \"NextlyError\";\n this.code = opts.code;\n this.publicMessage = opts.publicMessage;\n this.publicData = opts.publicData;\n this.messageKey = opts.messageKey;\n this.logMessage = opts.logMessage;\n this.logContext = opts.logContext;\n this.cause = opts.cause;\n this.timestamp = /* @__PURE__ */ new Date();\n this.statusCode = _NextlyError.resolveStatusCode(opts);\n Error.captureStackTrace?.(this, _NextlyError);\n }\n static {\n _NextlyError.prototype[NEXTLY_ERROR_BRAND] = true;\n }\n static resolveStatusCode(opts) {\n if (typeof opts.statusCode === \"number\") return opts.statusCode;\n if (opts.code in NEXTLY_ERROR_STATUS) {\n return NEXTLY_ERROR_STATUS[opts.code];\n }\n return 500;\n }\n /** HTTP-safe JSON. Strips logMessage / logContext / cause / stack. */\n toResponseJSON(requestId) {\n const json = {\n code: String(this.code),\n message: this.publicMessage,\n requestId\n };\n if (this.messageKey) json.messageKey = this.messageKey;\n if (this.publicData !== void 0) json.data = this.publicData;\n return json;\n }\n /** Operator-facing JSON for log lines. Includes everything. */\n toLogJSON(requestId) {\n return {\n code: this.code,\n statusCode: this.statusCode,\n publicMessage: this.publicMessage,\n messageKey: this.messageKey,\n logMessage: this.logMessage,\n logContext: this.logContext,\n cause: this.cause ? {\n name: this.cause.name,\n message: this.cause.message,\n stack: this.cause.stack\n } : void 0,\n timestamp: this.timestamp.toISOString(),\n requestId\n };\n }\n // ────────────────────────────────────────────────────────────────────\n // Static factories — the recommended throw site for every common case.\n // Public messages here follow the §13.8 rubric: complete sentence,\n // generic, no identifiers, no value echoing, no policy hints.\n // ────────────────────────────────────────────────────────────────────\n static invalidCredentials(opts) {\n return new _NextlyError({\n code: \"AUTH_INVALID_CREDENTIALS\",\n publicMessage: \"Invalid email or password.\",\n logMessage: \"Login failed\",\n logContext: opts?.logContext\n });\n }\n static authRequired(opts) {\n return new _NextlyError({\n code: \"AUTH_REQUIRED\",\n publicMessage: \"Authentication required.\",\n logContext: opts?.logContext\n });\n }\n /**\n * Distinct from `authRequired`: the caller was authenticated but the\n * session token expired. Clients key on the TOKEN_EXPIRED *code* to\n * silently refresh and retry rather than redirecting to login; the public\n * message stays the generic spec §13.6 string (\"Authentication required.\")\n * so the wire never reveals the session state — same as `authRequired`.\n */\n static tokenExpired(opts) {\n return new _NextlyError({\n code: \"TOKEN_EXPIRED\",\n publicMessage: \"Authentication required.\",\n logContext: opts?.logContext\n });\n }\n static notFound(opts) {\n return new _NextlyError({\n code: \"NOT_FOUND\",\n publicMessage: opts?.message ?? \"Not found.\",\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n static forbidden(opts) {\n return new _NextlyError({\n code: \"FORBIDDEN\",\n publicMessage: \"You don't have permission to perform this action.\",\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n /**\n * A call the caller got wrong, where naming the mistake IS the value of the\n * error.\n *\n * The only factory that takes its public message from the caller. The\n * generic messages elsewhere exist so an HTTP response cannot leak internal\n * detail; this one is for arguments and configuration a developer controls\n * and must be told about — a missing option, an unusable combination — where\n * `internal()` would reduce the one useful sentence to \"An unexpected error\n * occurred.\" Do not pass user-supplied data through it.\n */\n static invalidInput(opts) {\n return new _NextlyError({\n code: \"INVALID_INPUT\",\n publicMessage: opts.message,\n logContext: opts.logContext\n });\n }\n static validation(opts) {\n return new _NextlyError({\n code: \"VALIDATION_ERROR\",\n publicMessage: \"Validation failed.\",\n publicData: { errors: opts.errors },\n cause: opts.cause,\n logContext: opts.logContext\n });\n }\n static conflict(opts) {\n return new _NextlyError({\n code: \"CONFLICT\",\n publicMessage: opts?.message ?? \"The resource has changed since you last loaded it. Please refresh and try again.\",\n cause: opts?.cause,\n logContext: { reason: opts?.reason, ...opts?.logContext }\n });\n }\n static duplicate(opts) {\n return new _NextlyError({\n code: \"DUPLICATE\",\n publicMessage: \"Resource already exists.\",\n logContext: opts?.logContext\n });\n }\n static rateLimited(opts) {\n return new _NextlyError({\n code: \"RATE_LIMITED\",\n publicMessage: \"Too many requests. Please try again later.\",\n publicData: opts?.retryAfterSeconds !== void 0 ? { retryAfterSeconds: opts.retryAfterSeconds } : void 0,\n logContext: opts?.logContext\n });\n }\n static internal(opts) {\n return new _NextlyError({\n code: \"INTERNAL_ERROR\",\n publicMessage: \"An unexpected error occurred.\",\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n // Accepts an optional `logMessage` override so callers (e.g. the health\n // route) can record a specific operator narrative (\"Health check failed\")\n // while the public message stays canonical per spec §13.8.5.\n static serviceUnavailable(opts) {\n return new _NextlyError({\n code: \"SERVICE_UNAVAILABLE\",\n publicMessage: opts?.publicMessage ?? \"Service unavailable. Please try again later.\",\n logMessage: opts?.logMessage,\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n /**\n * Convert a DbError (or arbitrary unknown thrown by the DB layer) to a\n * NextlyError with a generic public message and rich logContext. Used by\n * `withDbErrors` for auto-conversion (Pattern A) and by services that\n * catch DB errors at boundaries (Pattern B). Spec §8.2 mapping table.\n *\n * Never leaks DB driver text, constraint names, or table names into\n * `publicMessage`. All DB context goes into `logContext`. The original\n * DbError is preserved as `cause`.\n */\n static fromDatabaseError(error) {\n if (isDbError(error)) {\n const mapping = DB_ERROR_MAPPING[error.kind];\n const logContext = {\n dbKind: error.kind,\n dialect: error.dialect\n };\n if (error.code !== void 0) logContext.dbCode = error.code;\n if (error.meta !== void 0) logContext.meta = error.meta;\n return new _NextlyError({\n code: mapping.code,\n statusCode: mapping.statusCode,\n publicMessage: mapping.publicMessage,\n logMessage: \"Database error\",\n logContext,\n cause: error\n });\n }\n return new _NextlyError({\n code: \"INTERNAL_ERROR\",\n statusCode: 500,\n publicMessage: \"An unexpected error occurred.\",\n logMessage: \"Non-DbError passed to fromDatabaseError\",\n cause: error instanceof Error ? error : void 0,\n logContext: error instanceof Error ? void 0 : { value: String(error) }\n });\n }\n // ────────────────────────────────────────────────────────────────────\n // Type guards. Structural rather than `instanceof` so they survive\n // package-boundary mismatches (one consumer's NextlyError is a\n // different module instance from another's).\n // ────────────────────────────────────────────────────────────────────\n static is(err) {\n return hasBrand(err);\n }\n static isCode(err, code) {\n return hasBrand(err) && err.code === code;\n }\n static isNotFound(err) {\n return _NextlyError.isCode(err, \"NOT_FOUND\");\n }\n static isValidation(err) {\n return _NextlyError.isCode(err, \"VALIDATION_ERROR\");\n }\n static isAuthRequired(err) {\n return _NextlyError.isCode(err, \"AUTH_REQUIRED\");\n }\n static isForbidden(err) {\n return _NextlyError.isCode(err, \"FORBIDDEN\");\n }\n static isConflict(err) {\n return _NextlyError.isCode(err, \"CONFLICT\");\n }\n static isRateLimited(err) {\n return _NextlyError.isCode(err, \"RATE_LIMITED\");\n }\n};\n\nexport {\n DbError,\n isDbError,\n toDbError,\n safeCode,\n NEXTLY_ERROR_STATUS,\n statusToErrorCode,\n genericPublicMessage,\n NextlyError\n};\n","import {\n NextlyError\n} from \"./chunk-IAZJNA2U.mjs\";\n\n// src/storage/read-errors.ts\nvar StorageReadTooLargeError = class extends NextlyError {\n constructor(path, maxBytes, size) {\n super({\n code: \"STORAGE_READ_TOO_LARGE\",\n publicMessage: \"The stored file is larger than the limit for this read.\",\n logContext: {\n path,\n maxBytes,\n ...size === void 0 ? {} : { size }\n }\n });\n this.path = path;\n this.maxBytes = maxBytes;\n this.size = size;\n }\n};\nfunction isStorageReadTooLarge(error) {\n return NextlyError.is(error) && error.code === \"STORAGE_READ_TOO_LARGE\";\n}\nvar StorageReadTimeoutError = class extends NextlyError {\n constructor(path, timeoutMs) {\n super({\n code: \"STORAGE_READ_TIMEOUT\",\n publicMessage: \"The stored file could not be read in time.\",\n logContext: { path, timeoutMs }\n });\n this.path = path;\n this.timeoutMs = timeoutMs;\n }\n};\nfunction isStorageReadTimeout(error) {\n return NextlyError.is(error) && error.code === \"STORAGE_READ_TIMEOUT\";\n}\n\nexport {\n StorageReadTooLargeError,\n isStorageReadTooLarge,\n StorageReadTimeoutError,\n isStorageReadTimeout\n};\n","import {\n StorageReadTimeoutError,\n StorageReadTooLargeError\n} from \"./chunk-T3OVIJZM.mjs\";\nimport {\n NextlyError\n} from \"./chunk-IAZJNA2U.mjs\";\n\n// src/utils/validate-external-url.ts\nvar IPV4_RE = /^(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)$/;\nvar PRIVATE_IPV4_CIDRS = [\n \"0.0.0.0/8\",\n // RFC1122 \"this network\" / wildcard\n \"10.0.0.0/8\",\n // RFC1918\n \"100.64.0.0/10\",\n // RFC6598 CGNAT\n \"127.0.0.0/8\",\n // RFC1122 loopback\n \"169.254.0.0/16\",\n // RFC3927 link-local + AWS/GCP metadata\n \"172.16.0.0/12\",\n // RFC1918\n \"192.0.0.0/24\",\n // RFC6890 IETF protocol assignments\n \"192.0.2.0/24\",\n // RFC5737 documentation\n \"192.168.0.0/16\",\n // RFC1918\n \"198.18.0.0/15\",\n // RFC2544 benchmarking\n \"198.51.100.0/24\",\n // RFC5737 documentation\n \"203.0.113.0/24\",\n // RFC5737 documentation\n \"224.0.0.0/4\",\n // RFC5771 multicast\n \"240.0.0.0/4\"\n // RFC1112 reserved\n];\nvar CLOUD_METADATA_HOSTS = /* @__PURE__ */ new Set([\n \"metadata.google.internal\",\n \"metadata.googleapis.com\",\n \"metadata\"\n // GCP short form\n]);\nvar ExternalUrlError = class extends NextlyError {\n constructor(message, url) {\n super({\n code: \"EXTERNAL_URL_BLOCKED\",\n publicMessage: message,\n logContext: { url }\n });\n this.url = url;\n this.name = \"ExternalUrlError\";\n }\n};\nasync function validateExternalUrl(rawUrl, options = {}) {\n let parsed;\n try {\n parsed = new URL(rawUrl);\n } catch {\n throw new ExternalUrlError(\"Invalid URL\", rawUrl);\n }\n const hostname = parsed.hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n const isLocalhostHostname = hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"::1\";\n const baseProtocols = options.allowedProtocols ?? [\"https:\"];\n const protocols = options.allowLocalhost && isLocalhostHostname ? [...baseProtocols, \"http:\"] : baseProtocols;\n if (!protocols.includes(parsed.protocol)) {\n throw new ExternalUrlError(\n `Protocol ${parsed.protocol} not allowed (allowed: ${protocols.join(\", \")})`,\n rawUrl\n );\n }\n if (CLOUD_METADATA_HOSTS.has(hostname)) {\n throw new ExternalUrlError(\n `Cloud-metadata hostname rejected: ${parsed.hostname}`,\n rawUrl\n );\n }\n if (IPV4_RE.test(hostname)) {\n if (!isPublicIpv4(\n hostname,\n options.allowLocalhost === true && hostname === \"127.0.0.1\"\n )) {\n throw new ExternalUrlError(\n `Resolved to non-public IP: ${hostname}`,\n rawUrl\n );\n }\n return { url: parsed, pinnedIp: hostname, family: 4 };\n }\n if (hostname.includes(\":\")) {\n if (!isPublicIpv6(\n hostname,\n options.allowLocalhost === true && hostname === \"::1\"\n )) {\n throw new ExternalUrlError(\n `Resolved to non-public IP: ${hostname}`,\n rawUrl\n );\n }\n return { url: parsed, pinnedIp: hostname, family: 6 };\n }\n const { lookup } = await import(\"dns/promises\");\n let addresses;\n try {\n addresses = await lookup(hostname, { all: true });\n } catch (err) {\n throw new ExternalUrlError(\n `DNS lookup failed: ${err.message}`,\n rawUrl\n );\n }\n if (addresses.length === 0) {\n throw new ExternalUrlError(\"No IPs returned for host\", rawUrl);\n }\n for (const { address, family } of addresses) {\n const allow = options.allowLocalhost === true && isLocalhostHostname && family === 4;\n const ok = family === 4 ? isPublicIpv4(address, allow) : isPublicIpv6(address, allow);\n if (!ok) {\n throw new ExternalUrlError(\n `Resolved to non-public IP: ${address}`,\n rawUrl\n );\n }\n }\n const first = addresses[0];\n return {\n url: parsed,\n pinnedIp: first.address,\n family: first.family === 6 ? 6 : 4\n };\n}\nvar DEFAULT_MAX_RESPONSE_BYTES = 10 * 1024 * 1024;\nvar DEFAULT_TIMEOUT_MS = 3e4;\nvar SafeFetchError = class extends NextlyError {\n constructor(message, url, reason, status) {\n super({\n code: \"EXTERNAL_REQUEST_FAILED\",\n publicMessage: message,\n logContext: { url, reason }\n });\n this.url = url;\n this.reason = reason;\n this.status = status;\n this.name = \"SafeFetchError\";\n }\n};\nfunction createPinnedLookup(ip, family) {\n return (_hostname, options, callback) => {\n if (options && options.all) {\n callback(null, [{ address: ip, family }]);\n } else {\n callback(null, ip, family);\n }\n };\n}\nasync function safeFetch(rawUrl, options = {}) {\n const {\n allowLocalhost,\n allowedProtocols,\n method,\n headers,\n body,\n signal,\n maxResponseBytes = DEFAULT_MAX_RESPONSE_BYTES,\n timeoutMs = DEFAULT_TIMEOUT_MS\n } = options;\n const controller = new AbortController();\n const forwardAbort = () => controller.abort(signal?.reason);\n if (signal) {\n if (signal.aborted) controller.abort(signal.reason);\n else signal.addEventListener(\"abort\", forwardAbort, { once: true });\n }\n const timer = setTimeout(\n () => controller.abort(\n new SafeFetchError(`Request exceeded ${timeoutMs}ms`, rawUrl, \"timeout\")\n ),\n timeoutMs\n );\n try {\n const validated = await abortable(\n validateExternalUrl(rawUrl, { allowLocalhost, allowedProtocols }),\n controller.signal\n );\n return await pinnedFetch(validated, {\n method,\n headers,\n body,\n signal: controller.signal,\n maxResponseBytes\n });\n } finally {\n clearTimeout(timer);\n if (signal) signal.removeEventListener(\"abort\", forwardAbort);\n }\n}\nfunction abortError(signal) {\n const reason = signal.reason;\n if (reason instanceof Error) return reason;\n return new DOMException(\"The operation was aborted\", \"AbortError\");\n}\nfunction abortable(promise, signal) {\n if (signal.aborted) return Promise.reject(abortError(signal));\n let onAbort;\n const aborted = new Promise((_resolve, reject) => {\n onAbort = () => reject(abortError(signal));\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n return Promise.race([promise, aborted]).finally(\n () => signal.removeEventListener(\"abort\", onAbort)\n );\n}\nasync function pinnedFetch(validated, init) {\n const { url, pinnedIp, family } = validated;\n const httpMod = url.protocol === \"https:\" ? await import(\"https\") : await import(\"http\");\n const zlib = await import(\"zlib\");\n const lookup = createPinnedLookup(pinnedIp, family);\n const outHeaders = toOutgoingHeaders(init.headers);\n if (init.body != null) {\n delete outHeaders[\"transfer-encoding\"];\n outHeaders[\"content-length\"] = String(\n typeof init.body === \"string\" ? Buffer.byteLength(init.body) : init.body.byteLength\n );\n }\n return new Promise((resolve, reject) => {\n let settled = false;\n const settle = (fn) => {\n if (settled) return;\n settled = true;\n fn();\n };\n const failure = (err) => init.signal.aborted ? abortError(init.signal) : err;\n const req = httpMod.request(\n url,\n {\n method: init.method ?? \"GET\",\n headers: outHeaders,\n lookup,\n // Fresh socket per request so a pooled connection can't reuse a\n // differently-resolved address, and so the pinned lookup always runs.\n agent: false,\n // The combined deadline/caller signal aborts the request in flight.\n signal: init.signal\n },\n (res) => {\n const chunks = [];\n let received = 0;\n res.on(\"data\", (chunk) => {\n received += chunk.length;\n if (received > init.maxResponseBytes) {\n res.destroy();\n req.destroy();\n settle(\n () => reject(\n new SafeFetchError(\n `Response body exceeded ${init.maxResponseBytes} bytes`,\n url.href,\n \"response-too-large\",\n res.statusCode\n )\n )\n );\n return;\n }\n chunks.push(chunk);\n });\n res.on(\"end\", () => {\n const decoded = decodeBody(\n Buffer.concat(chunks),\n res.headers[\"content-encoding\"],\n zlib,\n init.maxResponseBytes,\n url.href,\n res.statusCode\n );\n if (decoded instanceof SafeFetchError) {\n settle(() => reject(decoded));\n return;\n }\n settle(\n () => resolve(toWhatwgResponse(res, decoded.body, decoded.decoded))\n );\n });\n res.on(\"error\", (err) => settle(() => reject(failure(err))));\n }\n );\n req.on(\"error\", (err) => settle(() => reject(failure(err))));\n if (!req.destroyed) {\n if (init.body != null) req.write(init.body);\n req.end();\n }\n });\n}\nfunction toOutgoingHeaders(headers) {\n const out = {};\n if (!headers) return out;\n const add = (rawKey, value) => {\n const key = rawKey.toLowerCase();\n if (key === \"host\") return;\n const existing = out[key];\n out[key] = existing === void 0 ? value : [].concat(existing, value);\n };\n if (headers instanceof Headers) {\n headers.forEach((value, key) => add(key, value));\n } else if (Array.isArray(headers)) {\n for (const [key, value] of headers) add(key, value);\n } else {\n for (const [key, value] of Object.entries(headers)) add(key, value);\n }\n return out;\n}\nfunction toWhatwgResponse(res, body, stripContentHeaders) {\n const headers = new Headers();\n for (const [key, value] of Object.entries(res.headers)) {\n if (value == null) continue;\n const lower = key.toLowerCase();\n if (stripContentHeaders && (lower === \"content-encoding\" || lower === \"content-length\")) {\n continue;\n }\n const values = Array.isArray(value) ? value : [value];\n for (const v of values) {\n try {\n headers.append(key, v);\n } catch {\n }\n }\n }\n const raw = res.statusCode ?? 502;\n const status = raw >= 200 && raw <= 599 ? raw : 502;\n const nullBody = status === 204 || status === 205 || status === 304;\n const bytes = new Uint8Array(body.byteLength);\n bytes.set(body);\n return new Response(nullBody ? null : bytes, {\n status,\n statusText: res.statusMessage ?? \"\",\n headers\n });\n}\nfunction decodeBody(buf, encoding, zlib, cap, url, status) {\n if (!encoding) return { body: buf, decoded: false };\n if (buf.length === 0) return { body: buf, decoded: true };\n const layers = encoding.split(\",\").map((e) => e.trim().toLowerCase()).filter(Boolean);\n const opts = { maxOutputLength: cap };\n let current = buf;\n let decoded = false;\n try {\n for (let i = layers.length - 1; i >= 0; i--) {\n const enc = layers[i];\n if (enc === \"identity\") continue;\n if (enc === \"gzip\" || enc === \"x-gzip\") {\n current = zlib.gunzipSync(current, opts);\n } else if (enc === \"br\") {\n current = zlib.brotliDecompressSync(current, opts);\n } else if (enc === \"deflate\") {\n try {\n current = zlib.inflateSync(current, opts);\n } catch (inflateErr) {\n if (errorCode(inflateErr) === \"ERR_BUFFER_TOO_LARGE\")\n throw inflateErr;\n current = zlib.inflateRawSync(current, opts);\n }\n } else {\n if (decoded) {\n return new SafeFetchError(\n `Cannot fully decode content-encoding \"${encoding}\"`,\n url,\n \"decode-failed\",\n status\n );\n }\n return { body: buf, decoded: false };\n }\n decoded = true;\n }\n return { body: current, decoded };\n } catch (err) {\n const tooLarge = errorCode(err) === \"ERR_BUFFER_TOO_LARGE\";\n return new SafeFetchError(\n tooLarge ? `Decoded ${encoding} response body exceeded the size cap` : `Failed to decode ${encoding} response body`,\n url,\n tooLarge ? \"response-too-large\" : \"decode-failed\",\n status\n );\n }\n}\nfunction errorCode(err) {\n if (err != null && typeof err === \"object\" && \"code\" in err) {\n const code = err.code;\n return typeof code === \"string\" ? code : void 0;\n }\n return void 0;\n}\nfunction ipv4ToInt(ip) {\n const parts = ip.split(\".\");\n if (parts.length !== 4) return null;\n let acc = 0;\n for (const p of parts) {\n const n = Number(p);\n if (!Number.isInteger(n) || n < 0 || n > 255) return null;\n acc = acc << 8 | n;\n }\n return acc >>> 0;\n}\nfunction isIpv4InCidr(intIp, cidr) {\n const [addr, prefixRaw] = cidr.split(\"/\");\n const intCidr = ipv4ToInt(addr);\n if (intCidr === null) return false;\n const prefix = Number(prefixRaw);\n if (!Number.isInteger(prefix) || prefix < 0 || prefix > 32) return false;\n const mask = prefix === 0 ? 0 : -1 >>> 32 - prefix << 32 - prefix;\n return (intIp & mask) >>> 0 === (intCidr & mask) >>> 0;\n}\nfunction isPublicIpv4(addr, allowLoopback) {\n const intIp = ipv4ToInt(addr);\n if (intIp === null) return false;\n if (allowLoopback && addr === \"127.0.0.1\") return true;\n for (const cidr of PRIVATE_IPV4_CIDRS) {\n if (isIpv4InCidr(intIp, cidr)) return false;\n }\n return true;\n}\nfunction mappedIpv4(lower) {\n const dotted = lower.match(/^::ffff:(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})$/);\n if (dotted) return dotted[1];\n const hex = lower.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);\n if (hex) {\n const hi = parseInt(hex[1], 16);\n const lo = parseInt(hex[2], 16);\n return [hi >> 8, hi & 255, lo >> 8, lo & 255].join(\".\");\n }\n return null;\n}\nfunction isPublicIpv6(addr, allowLoopback) {\n const lower = addr.toLowerCase();\n if (allowLoopback && lower === \"::1\") return true;\n const mapped = mappedIpv4(lower);\n if (mapped) {\n return isPublicIpv4(mapped, allowLoopback);\n }\n if (lower === \"::\" || lower === \"::1\") return false;\n const firstHextet = lower.split(\":\")[0] || \"\";\n if (firstHextet.startsWith(\"fc\") || firstHextet.startsWith(\"fd\"))\n return false;\n if (firstHextet.startsWith(\"fe8\") || firstHextet.startsWith(\"fe9\"))\n return false;\n if (firstHextet.startsWith(\"fea\") || firstHextet.startsWith(\"feb\"))\n return false;\n if (firstHextet.startsWith(\"ff\")) return false;\n return true;\n}\n\n// src/storage/fetch-stored-bytes.ts\nasync function fetchStoredBytes(url, context, label, options, signal) {\n let response;\n try {\n response = await safeFetch(url, {\n ...options?.maxBytes === void 0 ? {} : { maxResponseBytes: options.maxBytes },\n /*\n * A caller's signal REPLACES the deadline rather than joining it.\n *\n * These adapters look the object's address up before fetching it, and\n * that lookup can stall too. Starting a fresh timer here would give the\n * fetch its own full budget on top of however long the lookup took, so a\n * read could outlive the deadline the caller was told applied — by\n * roughly double. One signal begun before the lookup governs both phases.\n */\n ...signal !== void 0 ? { signal } : options?.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs }\n });\n } catch (error) {\n const verdict = classifyFetchFailure(error);\n if (verdict === \"absent\") return null;\n if (verdict === \"oversized\") {\n throw new StorageReadTooLargeError(\n context,\n resolveReadBounds(options).maxBytes\n );\n }\n throw error;\n }\n if (response.status === 404) return null;\n if (!response.ok) {\n throw NextlyError.internal({\n logContext: {\n service: label,\n path: context,\n status: response.status,\n statusText: response.statusText\n }\n });\n }\n return Buffer.from(await response.arrayBuffer());\n}\nfunction classifyFetchFailure(error) {\n if (!(error instanceof SafeFetchError)) return \"unknown\";\n if (error.status === 404) return \"absent\";\n const successful = error.status !== void 0 && error.status >= 200 && error.status < 300;\n return error.reason === \"response-too-large\" && successful ? \"oversized\" : \"unknown\";\n}\nvar DEFAULT_READ_TIMEOUT_MS = DEFAULT_TIMEOUT_MS;\nvar DEFAULT_READ_MAX_BYTES = DEFAULT_MAX_RESPONSE_BYTES;\nfunction resolveReadBounds(options) {\n return {\n maxBytes: options?.maxBytes ?? DEFAULT_READ_MAX_BYTES,\n timeoutMs: options?.timeoutMs ?? DEFAULT_READ_TIMEOUT_MS\n };\n}\nfunction deadlineSignal(timeoutMs, context) {\n const controller = new AbortController();\n const timer = setTimeout(() => {\n controller.abort(new StorageReadTimeoutError(context, timeoutMs));\n }, timeoutMs);\n timer.unref?.();\n return {\n signal: controller.signal,\n /*\n * Called once the read has settled, whichever way it went. `unref` only\n * stops a pending timer holding the process open; it still sits on the\n * timer heap retaining the controller and the path, so a server doing a\n * thousand reads a second keeps thirty seconds of them alive and then runs\n * a thousand aborts that answer nobody.\n */\n cancel: () => {\n clearTimeout(timer);\n }\n };\n}\nasync function withDeadline(work, signal) {\n if (signal === void 0) return await work;\n return await Promise.race([\n work,\n new Promise((_, reject) => {\n if (signal.aborted) {\n reject(signal.reason);\n return;\n }\n signal.addEventListener(\"abort\", () => reject(signal.reason), {\n once: true\n });\n })\n ]);\n}\n\nexport {\n ExternalUrlError,\n validateExternalUrl,\n SafeFetchError,\n safeFetch,\n fetchStoredBytes,\n classifyFetchFailure,\n DEFAULT_READ_TIMEOUT_MS,\n DEFAULT_READ_MAX_BYTES,\n resolveReadBounds,\n deadlineSignal,\n withDeadline\n};\n","/**\n * Vercel Blob Storage Adapter\n *\n * Stores files on Vercel Blob Storage, a globally distributed object storage\n * service powered by Cloudflare R2. Optimized for Vercel deployments with\n * built-in CDN distribution.\n *\n * Features:\n * - Globally distributed CDN-backed storage\n * - Automatic file management with unique filenames\n * - Token-based authentication\n * - Client-side upload support (via handleUpload API)\n * - Serverless-friendly (no filesystem access required)\n *\n * @example Basic usage\n * ```typescript\n * const adapter = new VercelBlobStorageAdapter({\n * token: process.env.BLOB_READ_WRITE_TOKEN,\n * collections: { media: true }\n * });\n *\n * const result = await adapter.upload(buffer, {\n * filename: 'photo.jpg',\n * mimeType: 'image/jpeg'\n * });\n * // result.url: \"https://abc123.public.blob.vercel-storage.com/photo-xyz.jpg\"\n * ```\n */\n\nimport { put, del, head, list, BlobNotFoundError } from \"@vercel/blob\";\nimport { NextlyError } from \"nextly/errors\";\nimport type {\n IStorageAdapter,\n UploadOptions,\n UploadResult,\n StorageAdapterInfo,\n ClientUploadData,\n FileMetadata,\n BulkDeleteResult,\n StorageReadOptions,\n} from \"nextly/storage\";\nimport {\n fetchStoredBytes,\n DEFAULT_READ_TIMEOUT_MS,\n} from \"nextly/storage/fetch-stored-bytes\";\n\nimport type {\n VercelBlobStorageConfig,\n ResolvedVercelBlobConfig,\n} from \"./types\";\n\n// ============================================================\n// Vercel Blob Storage Adapter\n// ============================================================\n\n/**\n * Vercel Blob Storage Adapter\n *\n * Implements the IStorageAdapter interface for Vercel Blob Storage.\n * Provides file upload, deletion, existence checks, and metadata retrieval.\n */\nexport class VercelBlobStorageAdapter implements IStorageAdapter {\n private resolvedConfig: ResolvedVercelBlobConfig;\n\n /**\n * Create a new Vercel Blob storage adapter.\n *\n * @param config - Vercel Blob storage configuration\n * @throws Error if token is not provided\n */\n constructor(private config: VercelBlobStorageConfig) {\n // Resolve token from config or environment\n const token = config.token || process.env.BLOB_READ_WRITE_TOKEN || \"\";\n\n if (!token) {\n throw new Error(\n \"@nextly/storage-vercel-blob: token is required.\\n\\n\" +\n \"Either set the BLOB_READ_WRITE_TOKEN environment variable or pass token in config.\\n\" +\n \"Get your token from: Vercel Dashboard > Storage > Blob > Tokens\"\n );\n }\n\n // Resolve config with defaults\n this.resolvedConfig = {\n token,\n addRandomSuffix: config.addRandomSuffix ?? true,\n cacheControlMaxAge: config.cacheControlMaxAge ?? 31536000,\n access: config.access ?? \"public\",\n storeId: config.storeId,\n allowOverwrite: config.allowOverwrite ?? false,\n multipartThreshold: config.multipartThreshold ?? 5 * 1024 * 1024, // 5MB\n };\n }\n\n // ============================================================\n // Core IStorageAdapter Methods\n // ============================================================\n\n /**\n * Upload file to Vercel Blob.\n *\n * Files are stored with globally distributed CDN backing.\n * By default, a random suffix is added to prevent filename collisions.\n *\n * @param buffer - File content as Buffer\n * @param options - Upload options (filename, mimeType, folder, collection)\n * @returns Upload result with URL and storage path\n */\n async upload(buffer: Buffer, options: UploadOptions): Promise<UploadResult> {\n const mimeType = (options.contentType || options.mimeType || \"\")\n .toLowerCase()\n .trim();\n const filename = (options.filename || \"\").toLowerCase();\n const ext = filename.includes(\".\")\n ? filename.slice(filename.lastIndexOf(\".\") + 1)\n : \"\";\n const isHtml =\n mimeType === \"text/html\" ||\n mimeType === \"application/xhtml+xml\" ||\n ext === \"html\" ||\n ext === \"htm\" ||\n ext === \"xhtml\";\n // HTML stays unconditionally rejected. The `downloadUrl` trick that\n // makes SVG safe (see below) doesn't help HTML — a downloaded HTML\n // file is still a usable XSS vector when opened from disk, and\n // Vercel Blob has no equivalent of `Content-Security-Policy` to\n // defang it.\n if (isHtml) {\n throw NextlyError.validation({\n errors: [\n {\n path: \"file\",\n code: \"UNSUPPORTED_FOR_BACKEND\",\n message:\n \"HTML files cannot be hosted on Vercel Blob. Use the S3 or R2 adapter, or upload as another format.\",\n },\n ],\n logContext: {\n adapter: \"vercel-blob\",\n claimedMimeType: options.mimeType,\n reason: \"vercel-blob-rejects-html\",\n filename: options.filename,\n },\n });\n }\n\n const isSvg =\n mimeType === \"image/svg+xml\" || ext === \"svg\" || ext === \"svgz\";\n\n const pathname = this.buildPathname(options.filename, options.folder);\n\n const result = await put(pathname, buffer, {\n access: this.resolvedConfig.access,\n token: this.resolvedConfig.token,\n contentType: options.contentType || options.mimeType,\n addRandomSuffix: this.resolvedConfig.addRandomSuffix,\n cacheControlMaxAge: this.resolvedConfig.cacheControlMaxAge,\n });\n\n // SVGs are served via Vercel Blob's `downloadUrl` (the same URL with\n // `?download=1` appended) so direct top-level navigation forces an\n // attachment download instead of rendering. `<img src>` ignores the\n // `Content-Disposition` header, so legitimate inline rendering still\n // works. The `@vercel/blob` SDK has no `contentDisposition` input\n // option on `put()`, so this query-param-driven approach is the\n // supported mechanism. Caller is responsible for sanitizing SVG\n // contents upstream (handled by `upload-validation`).\n const url =\n isSvg && options.contentDisposition === \"attachment\"\n ? result.downloadUrl\n : result.url;\n\n return {\n url,\n path: result.url,\n };\n }\n\n /**\n * Delete file from Vercel Blob.\n *\n * @param filePath - Full blob URL to delete\n */\n async delete(filePath: string): Promise<void> {\n await del(filePath, {\n token: this.resolvedConfig.token,\n });\n }\n\n /**\n * Delete multiple files from Vercel Blob in chunked batches.\n *\n * Processes deletions in chunks of 10 concurrent calls using Promise.allSettled,\n * collecting successes and failures without short-circuiting.\n *\n * @param filePaths - Array of full blob URLs to delete\n * @returns BulkDeleteResult with successful and failed arrays\n */\n async bulkDelete(filePaths: string[]): Promise<BulkDeleteResult> {\n const successful: string[] = [];\n const failed: Array<{ filePath: string; error: string }> = [];\n const chunkSize = 10;\n\n for (let i = 0; i < filePaths.length; i += chunkSize) {\n const chunk = filePaths.slice(i, i + chunkSize);\n const results = await Promise.allSettled(\n chunk.map(fp => del(fp, { token: this.resolvedConfig.token }))\n );\n\n results.forEach((result, idx) => {\n const fp = chunk[idx];\n if (result.status === \"fulfilled\") {\n successful.push(fp);\n } else {\n failed.push({\n filePath: fp,\n error:\n result.reason instanceof Error\n ? result.reason.message\n : String(result.reason),\n });\n }\n });\n }\n\n return { successful, failed };\n }\n\n /**\n * Check if file exists in Vercel Blob.\n *\n * Uses the head() function which is efficient for existence checks.\n *\n * @param filePath - Full blob URL to check\n * @returns true if file exists, false otherwise\n */\n async exists(filePath: string): Promise<boolean> {\n try {\n await head(filePath, {\n token: this.resolvedConfig.token,\n });\n return true;\n } catch {\n // Vercel Blob throws an error if the blob doesn't exist\n return false;\n }\n }\n\n /**\n * Read a stored blob back as bytes, or `null` when it is not there.\n *\n * A NETWORK round trip, unlike the local adapter's disk read, because the\n * bytes live on Vercel's CDN and there is no other way to reach them. That\n * cost is the reason a caller serving these from its own origin has to cache:\n * the privacy rule that forces same-origin serving does not also make the\n * fetch free, and an uncached proxy pays it on every request.\n *\n * The URL is taken from `head` rather than assembled from `filePath`,\n * because a blob's address is issued by the service — it carries a random\n * suffix this adapter never chose — so deriving one here would be guessing at\n * a string another system owns.\n *\n * `null` for a missing blob rather than a throw, matching {@link exists}.\n *\n * @param filePath - Blob path/key\n * @returns The blob's bytes, or `null` when it does not exist\n */\n async read(\n filePath: string,\n options?: StorageReadOptions\n ): Promise<Buffer | null> {\n /*\n * ONE deadline for both phases, started before the lookup.\n *\n * `head` can stall exactly as the fetch can, and it runs first — so a\n * deadline that begins only at the fetch leaves the lookup unbounded and\n * the read can outlive what the caller was promised. Created here and\n * handed to both.\n *\n * ALWAYS, not only when the caller named a timeout. `safeFetch` applies a\n * default deadline of its own, so a caller stating none was still bounded\n * for the fetch and unbounded for the lookup — which is the commonest call,\n * the email path among them, since it supplies only a byte cap. The default\n * comes from the same constant `safeFetch` uses rather than being restated.\n */\n const deadline = AbortSignal.timeout(\n options?.timeoutMs ?? DEFAULT_READ_TIMEOUT_MS\n );\n\n let target: string;\n try {\n const meta = await head(filePath, {\n token: this.resolvedConfig.token,\n abortSignal: deadline,\n });\n target = meta.downloadUrl ?? meta.url;\n } catch (error: unknown) {\n /*\n * ONLY the not-found class becomes `null`. `head` also rejects for an\n * expired token, a suspended or missing store, an aborted request and a\n * plain network failure, and every one of those says nothing about\n * whether the blob exists. Catching them all reports an outage as a\n * deletion, which a caller may act on by writing a replacement over a\n * file that is still there.\n *\n * Identified by the CLASS the SDK exports rather than by matching the\n * message, because the message is prose this package does not own.\n */\n if (error instanceof BlobNotFoundError) return null;\n throw error;\n }\n\n /*\n * OUTSIDE the catch above, deliberately, and through the shared helper so\n * that separation is stated once rather than in each adapter. A failed\n * fetch of a blob whose metadata just resolved is a transport failure\n * rather than an absence, and folding it into `null` would report a\n * network outage as a deleted file.\n */\n return await fetchStoredBytes(\n target,\n filePath,\n \"Vercel Blob\",\n options,\n deadline\n );\n }\n\n /**\n * Get public URL for Vercel Blob file.\n *\n * Vercel Blob paths ARE the public URLs - they're already full HTTPS URLs\n * with CDN distribution.\n *\n * @param filePath - Full blob URL\n * @returns The same URL (Vercel Blob paths are already public URLs)\n */\n getPublicUrl(filePath: string): string {\n // Vercel Blob paths are already full URLs\n return filePath;\n }\n\n /**\n * Get storage type identifier.\n */\n getType(): \"vercel-blob\" {\n return \"vercel-blob\";\n }\n\n // ============================================================\n // Optional IStorageAdapter Methods\n // ============================================================\n\n /**\n * Get adapter info including capabilities.\n *\n * @returns Adapter info with type, name, and capability flags\n */\n getInfo(): StorageAdapterInfo {\n return {\n type: \"vercel-blob\",\n name: \"VercelBlobStorageAdapter\",\n supportsSignedUrls: false, // Vercel Blob URLs are public by default\n supportsClientUploads: true, // Via handleUpload API\n };\n }\n\n /**\n * Get file metadata from Vercel Blob.\n *\n * Retrieves file information including size, content type, and upload date.\n *\n * @param filePath - Full blob URL\n * @returns File metadata or null if file not found\n */\n async getMetadata(filePath: string): Promise<FileMetadata | null> {\n try {\n const result = await head(filePath, {\n token: this.resolvedConfig.token,\n });\n\n // Extract filename from pathname\n const filename = result.pathname.split(\"/\").pop() || result.pathname;\n\n return {\n id: filePath,\n filename,\n originalFilename: filename,\n mimeType: result.contentType,\n size: result.size,\n url: result.url,\n createdAt: result.uploadedAt.toISOString(),\n };\n } catch {\n // File not found\n return null;\n }\n }\n\n /**\n * Generate pre-signed URL for client-side uploads.\n *\n * Vercel Blob uses a different pattern for client uploads - they require\n * the handleUpload API which handles token generation server-side.\n *\n * This method is not implemented because Vercel Blob's client upload flow\n * requires server-side route handlers with handleUpload().\n *\n * @see https://vercel.com/docs/storage/vercel-blob/client-upload\n * @throws Error always - client uploads require handleUpload API\n */\n getPresignedUploadUrl(\n _key: string,\n _mimeType: string,\n _expiresIn?: number\n ): Promise<ClientUploadData> {\n return Promise.reject(\n new Error(\n \"@nextly/storage-vercel-blob: Client uploads require the handleUpload API.\\n\\n\" +\n \"Vercel Blob uses a different pattern for client-side uploads that involves:\\n\" +\n \"1. A server-side route handler with handleUpload()\\n\" +\n \"2. The @vercel/blob/client upload() function\\n\\n\" +\n \"See: https://vercel.com/docs/storage/vercel-blob/client-upload\\n\\n\" +\n \"For server-side uploads, use the standard upload() method instead.\"\n )\n );\n }\n\n // ============================================================\n // Additional Methods\n // ============================================================\n\n /**\n * List blobs with optional prefix filter.\n *\n * Useful for browsing or batch operations on stored files.\n *\n * @param prefix - Optional prefix to filter results\n * @param options - List options (limit, cursor)\n * @returns List of blob metadata\n */\n async listBlobs(\n prefix?: string,\n options?: { limit?: number; cursor?: string }\n ): Promise<{\n blobs: Array<{\n url: string;\n pathname: string;\n size: number;\n uploadedAt: Date;\n }>;\n hasMore: boolean;\n cursor?: string;\n }> {\n const result = await list({\n token: this.resolvedConfig.token,\n prefix,\n limit: options?.limit,\n cursor: options?.cursor,\n });\n\n return {\n blobs: result.blobs.map(blob => ({\n url: blob.url,\n pathname: blob.pathname,\n size: blob.size,\n uploadedAt: blob.uploadedAt,\n })),\n hasMore: result.hasMore,\n cursor: result.cursor,\n };\n }\n\n // ============================================================\n // Helper Methods\n // ============================================================\n\n /**\n * Build pathname for Vercel Blob upload.\n *\n * Creates pathname in format: {folder}/{filename}\n * If no folder is provided, uses the filename directly.\n *\n * @param filename - Original filename (will be sanitized)\n * @param folder - Optional folder/prefix for organizing uploads\n * @returns Generated pathname\n * @throws Error if folder fails sanitization\n */\n private buildPathname(filename: string, folder?: string): string {\n const sanitized = this.sanitizeFilename(filename);\n if (!folder) return sanitized;\n return `${this.sanitizeFolder(folder)}/${sanitized}`;\n }\n\n /**\n * Sanitize filename to prevent path traversal issues.\n *\n * @param filename - Original filename\n * @returns Sanitized filename\n */\n private sanitizeFilename(filename: string): string {\n const basename = filename.split(/[/\\\\]/).pop() || filename;\n return basename.replace(/[^a-zA-Z0-9._-]/g, \"-\");\n }\n\n /**\n * Reject folder values that would let a caller\n * escape the configured prefix via path traversal or weird\n * separators. Vercel Blob is flat-keyed so `/` is just part of the\n * pathname, but an attacker who controls `folder` could still:\n *\n * - Use `..` to chain a relative-traversal-style key.\n * - Use `\\` (Windows separator) to confuse downstream tooling.\n * - Use control chars / null bytes to truncate the key.\n * - Use a leading `/` to look like an absolute path.\n *\n * Internal `/` segments stay allowed because callers legitimately\n * use nested folders (`docs/2026/...`); a leading `/`, empty\n * segments (`docs//x`), or `..` segments are rejected.\n *\n * @throws Error with a stable message so the storage facade can\n * surface a 400 instead of a 500.\n */\n private sanitizeFolder(folder: string): string {\n const trimmed = folder.replace(/\\/+$/, \"\"); // tolerate one trailing `/`\n if (!trimmed) {\n throw new Error(\"Folder must be a non-empty string.\");\n }\n // eslint-disable-next-line no-control-regex -- the whole point is to reject control chars\n if (/[\\\\\\0\\x01-\\x1f\\x7f]/.test(trimmed)) {\n throw new Error(\n \"Folder contains forbidden characters (backslash, control chars, or null bytes).\"\n );\n }\n if (trimmed.startsWith(\"/\")) {\n throw new Error(\"Folder must not start with `/`.\");\n }\n const segments = trimmed.split(\"/\");\n for (const segment of segments) {\n if (segment === \"\") {\n throw new Error(\"Folder must not contain empty segments (`//`).\");\n }\n if (segment === \"..\") {\n throw new Error(\"Folder must not contain `..` segments.\");\n }\n }\n return trimmed;\n }\n\n // ============================================================\n // Public Accessors\n // ============================================================\n\n /**\n * Get the configured token (masked for logging).\n */\n getTokenMasked(): string {\n const token = this.resolvedConfig.token;\n if (token.length <= 8) return \"****\";\n return `${token.slice(0, 4)}...${token.slice(-4)}`;\n }\n\n /**\n * Check if random suffix is enabled.\n */\n hasRandomSuffix(): boolean {\n return this.resolvedConfig.addRandomSuffix;\n }\n\n /**\n * Get configured cache control max age.\n */\n getCacheControlMaxAge(): number {\n return this.resolvedConfig.cacheControlMaxAge;\n }\n}\n","/**\n * Vercel Blob Storage Plugin\n *\n * Factory function that creates a storage plugin for Vercel Blob Storage.\n * Returns a StoragePlugin that can be registered with MediaStorage.\n *\n * @example Basic usage\n * ```typescript\n * import { vercelBlobStorage } from '@nextly/storage-vercel-blob'\n * import { defineConfig } from 'nextly/config'\n *\n * export default defineConfig({\n * storage: [\n * vercelBlobStorage({\n * token: process.env.BLOB_READ_WRITE_TOKEN,\n * collections: {\n * media: true\n * }\n * })\n * ]\n * })\n * ```\n *\n * @example With client uploads (recommended for Vercel)\n * ```typescript\n * vercelBlobStorage({\n * collections: {\n * media: {\n * clientUploads: true // Bypass 4.5MB serverless limit\n * }\n * }\n * })\n * ```\n *\n * @example With collection-specific configuration\n * ```typescript\n * vercelBlobStorage({\n * addRandomSuffix: true,\n * cacheControlMaxAge: 86400, // 1 day\n * collections: {\n * // Simple enable with defaults\n * media: true,\n *\n * // Full configuration\n * documents: {\n * prefix: 'docs/',\n * addRandomSuffix: false,\n * allowOverwrite: true\n * }\n * }\n * })\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { StoragePlugin, ClientUploadData } from \"nextly/storage\";\n\nimport { VercelBlobStorageAdapter } from \"./adapter\";\nimport type { VercelBlobStorageConfig } from \"./types\";\n\n// ============================================================\n// Plugin Factory Function\n// ============================================================\n\n/**\n * Create a Vercel Blob storage plugin for Nextly.\n *\n * This factory function creates a StoragePlugin that can be added to\n * the `storage` array in `nextly.config.ts`. Vercel Blob is optimized\n * for Vercel deployments with:\n *\n * - Global CDN distribution\n * - Simple token-based authentication\n * - Client-side upload support (via handleUpload API)\n * - Automatic file management\n *\n * @param config - Vercel Blob storage configuration\n * @returns A StoragePlugin that MediaStorage can register\n *\n * @throws Error if token is not provided (via adapter)\n */\nexport function vercelBlobStorage(\n config: VercelBlobStorageConfig\n): StoragePlugin {\n // Handle disabled plugin\n // When disabled, return a plugin with no collections and null adapter\n // MediaStorage.registerPlugin() checks for null adapter and skips registration\n if (config.enabled === false) {\n return {\n name: \"vercel-blob-storage\",\n type: \"vercel-blob\",\n collections: {},\n adapter: null as unknown as StoragePlugin[\"adapter\"],\n };\n }\n\n // Create the Vercel Blob adapter\n // Adapter constructor validates required config (token)\n const adapter = new VercelBlobStorageAdapter(config);\n\n // Build and return the plugin\n const plugin: StoragePlugin = {\n name: \"vercel-blob-storage\",\n type: \"vercel-blob\",\n collections: config.collections,\n adapter,\n\n /**\n * Generate upload URL for client-side uploads.\n *\n * Note: Vercel Blob uses a different pattern for client uploads.\n * Instead of pre-signed URLs, it uses the handleUpload() API which\n * requires server-side route handlers.\n *\n * This method throws an error explaining the correct approach.\n *\n * @see https://vercel.com/docs/storage/vercel-blob/client-upload\n */\n getClientUploadUrl(\n _filename: string,\n _mimeType: string,\n _collection: string\n ): Promise<ClientUploadData> {\n // Vercel Blob doesn't use pre-signed URLs like S3\n // Instead, it requires using the handleUpload API with @vercel/blob/client\n return Promise.reject(\n new Error(\n \"@nextly/storage-vercel-blob: Client uploads require the handleUpload API.\\n\\n\" +\n \"Vercel Blob uses a different pattern than S3 for client-side uploads:\\n\\n\" +\n \"1. Create a server-side route handler with handleUpload()\\n\" +\n \"2. Use upload() from @vercel/blob/client on the frontend\\n\\n\" +\n \"See: https://vercel.com/docs/storage/vercel-blob/client-upload\"\n )\n );\n },\n\n /**\n * Get signed download URL for file access.\n *\n * Note: Vercel Blob URLs are public by default and do not support\n * signed/temporary URLs. All uploaded blobs are accessible via their\n * public URL.\n *\n * @param path - Storage path (full blob URL)\n * @returns The same URL (Vercel Blob URLs are public)\n */\n getSignedDownloadUrl(path: string): Promise<string> {\n // Vercel Blob URLs are public by default\n // No signed URL support - just return the public URL\n return Promise.resolve(path);\n },\n };\n\n return plugin;\n}\n","/**\n * @nextly/storage-vercel-blob\n *\n * Vercel Blob storage adapter for Nextly CMS.\n * Optimized for Vercel deployments with client-side upload support\n * to bypass serverless function size limits (4.5MB).\n *\n * @example Basic usage\n * ```typescript\n * import { vercelBlobStorage } from '@nextly/storage-vercel-blob'\n * import { defineConfig } from 'nextly/config'\n *\n * export default defineConfig({\n * storage: [\n * vercelBlobStorage({\n * token: process.env.BLOB_READ_WRITE_TOKEN,\n * collections: {\n * media: true\n * }\n * })\n * ]\n * })\n * ```\n *\n * @example With client uploads (recommended for Vercel)\n * ```typescript\n * vercelBlobStorage({\n * collections: {\n * media: {\n * clientUploads: true // Bypass 4.5MB serverless limit\n * }\n * }\n * })\n * ```\n *\n * @packageDocumentation\n */\n\n// ============================================================\n// Vercel Blob Storage Plugin Export (Primary API)\n// ============================================================\n\nexport { vercelBlobStorage } from \"./plugin\";\n\n// ============================================================\n// Vercel Blob Storage Adapter Export\n// ============================================================\n\nexport { VercelBlobStorageAdapter } from \"./adapter\";\n\n// ============================================================\n// Vercel Blob Types Export\n// ============================================================\n\nexport type {\n VercelBlobStorageConfig,\n VercelBlobCollectionConfig,\n VercelBlobCollectionStorageMap,\n ResolvedVercelBlobConfig,\n} from \"./types\";\n\n// ============================================================\n// Package Metadata\n// ============================================================\n\nexport const PACKAGE_NAME = \"@nextly/storage-vercel-blob\";\nexport const PACKAGE_VERSION = \"0.1.0\";\n"]}
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@ import { put, del, head, BlobNotFoundError, list } from '@vercel/blob';
2
2
 
3
3
  // src/adapter.ts
4
4
 
5
- // ../nextly/dist/chunk-HJ5IQPOY.mjs
5
+ // ../nextly/dist/chunk-IAZJNA2U.mjs
6
6
  function isDbError(err) {
7
7
  if (!err || typeof err !== "object") return false;
8
8
  const obj = err;
@@ -105,6 +105,13 @@ var NEXTLY_ERROR_STATUS = {
105
105
  // Plugin platform (P4) — contributes.routes collection (D25).
106
106
  NEXTLY_ROUTE_COLLISION: 409,
107
107
  NEXTLY_ROUTE_INVALID_PATH: 400,
108
+ // A root-mounted route declared where the request pipeline never reaches the
109
+ // root pass. 400 like an invalid path and not 409: nothing else claims the
110
+ // address, the declaration simply cannot be served from there.
111
+ NEXTLY_ROUTE_UNREACHABLE_ROOT: 400,
112
+ // A `mount` outside the declared union, which only an untyped caller can
113
+ // produce. 400 for the same reason: the declaration itself is unserveable.
114
+ NEXTLY_ROUTE_INVALID_MOUNT: 400,
108
115
  // An email transport whose library is an optional peer dependency the host
109
116
  // has not installed. 503 rather than 500: the request is not malformed and
110
117
  // nothing is broken, the install simply cannot carry it out yet, and the
@@ -442,7 +449,7 @@ var NextlyError = class _NextlyError extends Error {
442
449
  }
443
450
  };
444
451
 
445
- // ../nextly/dist/chunk-W77AQUUQ.mjs
452
+ // ../nextly/dist/chunk-T3OVIJZM.mjs
446
453
  var StorageReadTooLargeError = class extends NextlyError {
447
454
  constructor(path, maxBytes, size) {
448
455
  super({
@@ -460,7 +467,7 @@ var StorageReadTooLargeError = class extends NextlyError {
460
467
  }
461
468
  };
462
469
 
463
- // ../nextly/dist/chunk-C2VHLQKK.mjs
470
+ // ../nextly/dist/chunk-YGE6AGZG.mjs
464
471
  var IPV4_RE = /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/;
465
472
  var PRIVATE_IPV4_CIDRS = [
466
473
  "0.0.0.0/8",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../nextly/dist/chunk-HJ5IQPOY.mjs","../../nextly/dist/chunk-W77AQUUQ.mjs","../../nextly/dist/chunk-C2VHLQKK.mjs","../src/adapter.ts","../src/plugin.ts","../src/index.ts"],"names":[],"mappings":";;;;;AAiBA,SAAS,UAAU,GAAA,EAAK;AACtB,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,UAAU,OAAO,KAAA;AAC5C,EAAA,MAAM,GAAA,GAAM,GAAA;AACZ,EAAA,OAAO,GAAA,CAAI,IAAA,KAAS,SAAA,IAAa,OAAO,IAAI,IAAA,KAAS,QAAA;AACvD;AA+FA,IAAI,mBAAA,GAAsB;AAAA,EACxB,gBAAA,EAAkB,GAAA;AAAA,EAClB,aAAA,EAAe,GAAA;AAAA,EACf,aAAA,EAAe,GAAA;AAAA,EACf,wBAAA,EAA0B,GAAA;AAAA,EAC1B,aAAA,EAAe,GAAA;AAAA,EACf,SAAA,EAAW,GAAA;AAAA;AAAA;AAAA,EAGX,gBAAA,EAAkB,GAAA;AAAA,EAClB,SAAA,EAAW,GAAA;AAAA,EACX,QAAA,EAAU,GAAA;AAAA,EACV,SAAA,EAAW,GAAA;AAAA,EACX,YAAA,EAAc,GAAA;AAAA,EACd,iBAAA,EAAmB,GAAA;AAAA,EACnB,sBAAA,EAAwB,GAAA;AAAA;AAAA;AAAA;AAAA,EAIxB,uBAAA,EAAyB,GAAA;AAAA,EACzB,cAAA,EAAgB,GAAA;AAAA,EAChB,cAAA,EAAgB,GAAA;AAAA,EAChB,sBAAA,EAAwB,GAAA;AAAA,EACxB,mBAAA,EAAqB,GAAA;AAAA;AAAA;AAAA,EAGrB,oBAAA,EAAsB,GAAA;AAAA,EACtB,uBAAA,EAAyB,GAAA;AAAA,EACzB,gBAAA,EAAkB,GAAA;AAAA,EAClB,iBAAA,EAAmB,GAAA;AAAA,EACnB,YAAA,EAAc,GAAA;AAAA,EACd,gBAAA,EAAkB,GAAA;AAAA,EAClB,aAAA,EAAe,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKf,sBAAA,EAAwB,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKxB,oBAAA,EAAsB,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKtB,wBAAA,EAA0B,GAAA;AAAA,EAC1B,mBAAA,EAAqB,GAAA;AAAA,EACrB,uBAAA,EAAyB,GAAA;AAAA,EACzB,uBAAA,EAAyB,GAAA;AAAA;AAAA,EAEzB,kCAAA,EAAoC,GAAA;AAAA,EACpC,mCAAA,EAAqC,GAAA;AAAA,EACrC,0BAAA,EAA4B,GAAA;AAAA;AAAA,EAE5B,wBAAA,EAA0B,GAAA;AAAA,EAC1B,6BAAA,EAA+B,GAAA;AAAA,EAC/B,4BAAA,EAA8B,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAK9B,8BAAA,EAAgC,GAAA;AAAA;AAAA,EAEhC,8BAAA,EAAgC,GAAA;AAAA,EAChC,+BAAA,EAAiC,GAAA;AAAA,EACjC,sBAAA,EAAwB,GAAA;AAAA,EACxB,6BAAA,EAA+B,GAAA;AAAA;AAAA,EAE/B,6BAAA,EAA+B,GAAA;AAAA,EAC/B,iCAAA,EAAmC,GAAA;AAAA,EACnC,8BAAA,EAAgC,GAAA;AAAA,EAChC,qCAAA,EAAuC,GAAA;AAAA;AAAA,EAEvC,wBAAA,EAA0B,GAAA;AAAA,EAC1B,4BAAA,EAA8B,GAAA;AAAA,EAC9B,qCAAA,EAAuC,GAAA;AAAA;AAAA,EAEvC,mCAAA,EAAqC,GAAA;AAAA,EACrC,oCAAA,EAAsC,GAAA;AAAA,EACtC,mCAAA,EAAqC,GAAA;AAAA;AAAA,EAErC,mCAAA,EAAqC,GAAA;AAAA;AAAA;AAAA,EAGrC,mCAAA,EAAqC,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKrC,kCAAA,EAAoC,GAAA;AAAA;AAAA,EAEpC,uBAAA,EAAyB,GAAA;AAAA;AAAA,EAEzB,sBAAA,EAAwB,GAAA;AAAA,EACxB,yBAAA,EAA2B,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAK3B,kCAAA,EAAoC,GAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpC,iCAAA,EAAmC;AACrC,CAAA;AACA,IAAI,yBAAA,GAA4B;AAAA,EAC9B,kBAAA;AAAA,EACA,eAAA;AAAA,EACA,WAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,mBAAA;AAAA,EACA,wBAAA;AAAA,EACA,cAAA;AAAA,EACA,wBAAA;AAAA,EACA;AACF,CAAA;CAEqB;AAAA,EACnB,GAAG,MAAA,CAAO,WAAA;AAAA,IACR,yBAAA,CAA0B,IAAI,CAAC,IAAA,KAAS,CAAC,mBAAA,CAAoB,IAAI,CAAA,EAAG,IAAI,CAAC;AAAA,GAG7E;AAwBA,IAAI,gBAAA,GAAmB;AAAA,EACrB,kBAAA,EAAoB;AAAA,IAClB,IAAA,EAAM,WAAA;AAAA,IACN,UAAA,EAAY,GAAA;AAAA,IACZ,aAAA,EAAe;AAAA,GACjB;AAAA,EACA,cAAA,EAAgB;AAAA,IACd,IAAA,EAAM,kBAAA;AAAA,IACN,UAAA,EAAY,GAAA;AAAA,IACZ,aAAA,EAAe;AAAA,GACjB;AAAA,EACA,oBAAA,EAAsB;AAAA,IACpB,IAAA,EAAM,kBAAA;AAAA,IACN,UAAA,EAAY,GAAA;AAAA,IACZ,aAAA,EAAe;AAAA,GACjB;AAAA,EACA,UAAA,EAAY;AAAA,IACV,IAAA,EAAM,kBAAA;AAAA,IACN,UAAA,EAAY,GAAA;AAAA,IACZ,aAAA,EAAe;AAAA,GACjB;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,UAAA;AAAA,IACN,UAAA,EAAY,GAAA;AAAA,IACZ,aAAA,EAAe;AAAA,GACjB;AAAA,EACA,uBAAA,EAAyB;AAAA,IACvB,IAAA,EAAM,UAAA;AAAA,IACN,UAAA,EAAY,GAAA;AAAA,IACZ,aAAA,EAAe;AAAA,GACjB;AAAA,EACA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,gBAAA;AAAA,IACN,UAAA,EAAY,GAAA;AAAA,IACZ,aAAA,EAAe;AAAA,GACjB;AAAA,EACA,iBAAA,EAAmB;AAAA,IACjB,IAAA,EAAM,gBAAA;AAAA,IACN,UAAA,EAAY,GAAA;AAAA,IACZ,aAAA,EAAe;AAAA,GACjB;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,gBAAA;AAAA,IACN,UAAA,EAAY,GAAA;AAAA,IACZ,aAAA,EAAe;AAAA,GACjB;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,gBAAA;AAAA,IACN,UAAA,EAAY,GAAA;AAAA,IACZ,aAAA,EAAe;AAAA;AAEnB,CAAA;AACA,IAAI,kBAAA,GAAqB,MAAA,CAAO,GAAA,CAAI,oBAAoB,CAAA;AACxD,SAAS,SAAS,KAAA,EAAO;AACvB,EAAA,IAAI,UAAU,IAAA,IAAQ,OAAO,UAAU,QAAA,IAAY,OAAO,UAAU,UAAA,EAAY;AAC9E,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAA,CAAM,kBAAkB,CAAA,KAAM,IAAA;AACvC;AACA,IAAI,WAAA,GAAc,MAAM,YAAA,SAAqB,KAAA,CAAM;AAAA,EACjD,IAAA;AAAA,EACA,UAAA;AAAA,EACA,aAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAY,IAAA,EAAM;AAChB,IAAA,KAAA,CAAM,KAAK,aAAa,CAAA;AACxB,IAAA,IAAA,CAAK,IAAA,GAAO,aAAA;AACZ,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AACjB,IAAA,IAAA,CAAK,gBAAgB,IAAA,CAAK,aAAA;AAC1B,IAAA,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA;AACvB,IAAA,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA;AACvB,IAAA,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA;AACvB,IAAA,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA;AACvB,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAClB,IAAA,IAAA,CAAK,SAAA,uBAAgC,IAAA,EAAK;AAC1C,IAAA,IAAA,CAAK,UAAA,GAAa,YAAA,CAAa,iBAAA,CAAkB,IAAI,CAAA;AACrD,IAAA,KAAA,CAAM,iBAAA,GAAoB,MAAM,YAAY,CAAA;AAAA,EAC9C;AAAA,EACA;AACE,IAAA,YAAA,CAAa,SAAA,CAAU,kBAAkB,CAAA,GAAI,IAAA;AAAA;AAC/C,EACA,OAAO,kBAAkB,IAAA,EAAM;AAC7B,IAAA,IAAI,OAAO,IAAA,CAAK,UAAA,KAAe,QAAA,SAAiB,IAAA,CAAK,UAAA;AACrD,IAAA,IAAI,IAAA,CAAK,QAAQ,mBAAA,EAAqB;AACpC,MAAA,OAAO,mBAAA,CAAoB,KAAK,IAAI,CAAA;AAAA,IACtC;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA;AAAA,EAEA,eAAe,SAAA,EAAW;AACxB,IAAA,MAAM,IAAA,GAAO;AAAA,MACX,IAAA,EAAM,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA;AAAA,MACtB,SAAS,IAAA,CAAK,aAAA;AAAA,MACd;AAAA,KACF;AACA,IAAA,IAAI,IAAA,CAAK,UAAA,EAAY,IAAA,CAAK,UAAA,GAAa,IAAA,CAAK,UAAA;AAC5C,IAAA,IAAI,IAAA,CAAK,UAAA,KAAe,MAAA,EAAQ,IAAA,CAAK,OAAO,IAAA,CAAK,UAAA;AACjD,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAEA,UAAU,SAAA,EAAW;AACnB,IAAA,OAAO;AAAA,MACL,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,eAAe,IAAA,CAAK,aAAA;AAAA,MACpB,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,YAAY,IAAA,CAAK,UAAA;AAAA,MACjB,KAAA,EAAO,KAAK,KAAA,GAAQ;AAAA,QAClB,IAAA,EAAM,KAAK,KAAA,CAAM,IAAA;AAAA,QACjB,OAAA,EAAS,KAAK,KAAA,CAAM,OAAA;AAAA,QACpB,KAAA,EAAO,KAAK,KAAA,CAAM;AAAA,OACpB,GAAI,MAAA;AAAA,MACJ,SAAA,EAAW,IAAA,CAAK,SAAA,CAAU,WAAA,EAAY;AAAA,MACtC;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,mBAAmB,IAAA,EAAM;AAC9B,IAAA,OAAO,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM,0BAAA;AAAA,MACN,aAAA,EAAe,4BAAA;AAAA,MACf,UAAA,EAAY,cAAA;AAAA,MACZ,YAAY,IAAA,EAAM;AAAA,KACnB,CAAA;AAAA,EACH;AAAA,EACA,OAAO,aAAa,IAAA,EAAM;AACxB,IAAA,OAAO,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM,eAAA;AAAA,MACN,aAAA,EAAe,0BAAA;AAAA,MACf,YAAY,IAAA,EAAM;AAAA,KACnB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,aAAa,IAAA,EAAM;AACxB,IAAA,OAAO,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM,eAAA;AAAA,MACN,aAAA,EAAe,0BAAA;AAAA,MACf,YAAY,IAAA,EAAM;AAAA,KACnB,CAAA;AAAA,EACH;AAAA,EACA,OAAO,SAAS,IAAA,EAAM;AACpB,IAAA,OAAO,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM,WAAA;AAAA,MACN,aAAA,EAAe,MAAM,OAAA,IAAW,YAAA;AAAA,MAChC,OAAO,IAAA,EAAM,KAAA;AAAA,MACb,YAAY,IAAA,EAAM;AAAA,KACnB,CAAA;AAAA,EACH;AAAA,EACA,OAAO,UAAU,IAAA,EAAM;AACrB,IAAA,OAAO,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM,WAAA;AAAA,MACN,aAAA,EAAe,mDAAA;AAAA,MACf,OAAO,IAAA,EAAM,KAAA;AAAA,MACb,YAAY,IAAA,EAAM;AAAA,KACnB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,OAAO,aAAa,IAAA,EAAM;AACxB,IAAA,OAAO,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM,eAAA;AAAA,MACN,eAAe,IAAA,CAAK,OAAA;AAAA,MACpB,YAAY,IAAA,CAAK;AAAA,KAClB,CAAA;AAAA,EACH;AAAA,EACA,OAAO,WAAW,IAAA,EAAM;AACtB,IAAA,OAAO,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM,kBAAA;AAAA,MACN,aAAA,EAAe,oBAAA;AAAA,MACf,UAAA,EAAY,EAAE,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAO;AAAA,MAClC,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,YAAY,IAAA,CAAK;AAAA,KAClB,CAAA;AAAA,EACH;AAAA,EACA,OAAO,SAAS,IAAA,EAAM;AACpB,IAAA,OAAO,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM,UAAA;AAAA,MACN,aAAA,EAAe,MAAM,OAAA,IAAW,kFAAA;AAAA,MAChC,OAAO,IAAA,EAAM,KAAA;AAAA,MACb,YAAY,EAAE,MAAA,EAAQ,MAAM,MAAA,EAAQ,GAAG,MAAM,UAAA;AAAW,KACzD,CAAA;AAAA,EACH;AAAA,EACA,OAAO,UAAU,IAAA,EAAM;AACrB,IAAA,OAAO,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM,WAAA;AAAA,MACN,aAAA,EAAe,0BAAA;AAAA,MACf,YAAY,IAAA,EAAM;AAAA,KACnB,CAAA;AAAA,EACH;AAAA,EACA,OAAO,YAAY,IAAA,EAAM;AACvB,IAAA,OAAO,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM,cAAA;AAAA,MACN,aAAA,EAAe,4CAAA;AAAA,MACf,UAAA,EAAY,MAAM,iBAAA,KAAsB,MAAA,GAAS,EAAE,iBAAA,EAAmB,IAAA,CAAK,mBAAkB,GAAI,MAAA;AAAA,MACjG,YAAY,IAAA,EAAM;AAAA,KACnB,CAAA;AAAA,EACH;AAAA,EACA,OAAO,SAAS,IAAA,EAAM;AACpB,IAAA,OAAO,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM,gBAAA;AAAA,MACN,aAAA,EAAe,+BAAA;AAAA,MACf,OAAO,IAAA,EAAM,KAAA;AAAA,MACb,YAAY,IAAA,EAAM;AAAA,KACnB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAIA,OAAO,mBAAmB,IAAA,EAAM;AAC9B,IAAA,OAAO,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM,qBAAA;AAAA,MACN,aAAA,EAAe,MAAM,aAAA,IAAiB,8CAAA;AAAA,MACtC,YAAY,IAAA,EAAM,UAAA;AAAA,MAClB,OAAO,IAAA,EAAM,KAAA;AAAA,MACb,YAAY,IAAA,EAAM;AAAA,KACnB,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OAAO,kBAAkB,KAAA,EAAO;AAC9B,IAAA,IAAI,SAAA,CAAU,KAAK,CAAA,EAAG;AACpB,MAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,KAAA,CAAM,IAAI,CAAA;AAC3C,MAAA,MAAM,UAAA,GAAa;AAAA,QACjB,QAAQ,KAAA,CAAM,IAAA;AAAA,QACd,SAAS,KAAA,CAAM;AAAA,OACjB;AACA,MAAA,IAAI,KAAA,CAAM,IAAA,KAAS,MAAA,EAAQ,UAAA,CAAW,SAAS,KAAA,CAAM,IAAA;AACrD,MAAA,IAAI,KAAA,CAAM,IAAA,KAAS,MAAA,EAAQ,UAAA,CAAW,OAAO,KAAA,CAAM,IAAA;AACnD,MAAA,OAAO,IAAI,YAAA,CAAa;AAAA,QACtB,MAAM,OAAA,CAAQ,IAAA;AAAA,QACd,YAAY,OAAA,CAAQ,UAAA;AAAA,QACpB,eAAe,OAAA,CAAQ,aAAA;AAAA,QACvB,UAAA,EAAY,gBAAA;AAAA,QACZ,UAAA;AAAA,QACA,KAAA,EAAO;AAAA,OACR,CAAA;AAAA,IACH;AACA,IAAA,OAAO,IAAI,YAAA,CAAa;AAAA,MACtB,IAAA,EAAM,gBAAA;AAAA,MACN,UAAA,EAAY,GAAA;AAAA,MACZ,aAAA,EAAe,+BAAA;AAAA,MACf,UAAA,EAAY,yCAAA;AAAA,MACZ,KAAA,EAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,MAAA;AAAA,MACxC,UAAA,EAAY,iBAAiB,KAAA,GAAQ,MAAA,GAAS,EAAE,KAAA,EAAO,MAAA,CAAO,KAAK,CAAA;AAAE,KACtE,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,GAAG,GAAA,EAAK;AACb,IAAA,OAAO,SAAS,GAAG,CAAA;AAAA,EACrB;AAAA,EACA,OAAO,MAAA,CAAO,GAAA,EAAK,IAAA,EAAM;AACvB,IAAA,OAAO,QAAA,CAAS,GAAG,CAAA,IAAK,GAAA,CAAI,IAAA,KAAS,IAAA;AAAA,EACvC;AAAA,EACA,OAAO,WAAW,GAAA,EAAK;AACrB,IAAA,OAAO,YAAA,CAAa,MAAA,CAAO,GAAA,EAAK,WAAW,CAAA;AAAA,EAC7C;AAAA,EACA,OAAO,aAAa,GAAA,EAAK;AACvB,IAAA,OAAO,YAAA,CAAa,MAAA,CAAO,GAAA,EAAK,kBAAkB,CAAA;AAAA,EACpD;AAAA,EACA,OAAO,eAAe,GAAA,EAAK;AACzB,IAAA,OAAO,YAAA,CAAa,MAAA,CAAO,GAAA,EAAK,eAAe,CAAA;AAAA,EACjD;AAAA,EACA,OAAO,YAAY,GAAA,EAAK;AACtB,IAAA,OAAO,YAAA,CAAa,MAAA,CAAO,GAAA,EAAK,WAAW,CAAA;AAAA,EAC7C;AAAA,EACA,OAAO,WAAW,GAAA,EAAK;AACrB,IAAA,OAAO,YAAA,CAAa,MAAA,CAAO,GAAA,EAAK,UAAU,CAAA;AAAA,EAC5C;AAAA,EACA,OAAO,cAAc,GAAA,EAAK;AACxB,IAAA,OAAO,YAAA,CAAa,MAAA,CAAO,GAAA,EAAK,cAAc,CAAA;AAAA,EAChD;AACF,CAAA;;;ACzjBA,IAAI,wBAAA,GAA2B,cAAc,WAAA,CAAY;AAAA,EACvD,WAAA,CAAY,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM;AAChC,IAAA,KAAA,CAAM;AAAA,MACJ,IAAA,EAAM,wBAAA;AAAA,MACN,aAAA,EAAe,yDAAA;AAAA,MACf,UAAA,EAAY;AAAA,QACV,IAAA;AAAA,QACA,QAAA;AAAA,QACA,GAAG,IAAA,KAAS,MAAA,GAAS,EAAC,GAAI,EAAE,IAAA;AAAK;AACnC,KACD,CAAA;AACD,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AAAA,EACd;AACF,CAAA;;;ACXA,IAAI,OAAA,GAAU,mFAAA;AACd,IAAI,kBAAA,GAAqB;AAAA,EACvB,WAAA;AAAA;AAAA,EAEA,YAAA;AAAA;AAAA,EAEA,eAAA;AAAA;AAAA,EAEA,aAAA;AAAA;AAAA,EAEA,gBAAA;AAAA;AAAA,EAEA,eAAA;AAAA;AAAA,EAEA,cAAA;AAAA;AAAA,EAEA,cAAA;AAAA;AAAA,EAEA,gBAAA;AAAA;AAAA,EAEA,eAAA;AAAA;AAAA,EAEA,iBAAA;AAAA;AAAA,EAEA,gBAAA;AAAA;AAAA,EAEA,aAAA;AAAA;AAAA,EAEA;AAAA;AAEF,CAAA;AACA,IAAI,oBAAA,uBAA2C,GAAA,CAAI;AAAA,EACjD,0BAAA;AAAA,EACA,yBAAA;AAAA,EACA;AAAA;AAEF,CAAC,CAAA;AACD,IAAI,gBAAA,GAAmB,cAAc,WAAA,CAAY;AAAA,EAC/C,WAAA,CAAY,SAAS,GAAA,EAAK;AACxB,IAAA,KAAA,CAAM;AAAA,MACJ,IAAA,EAAM,sBAAA;AAAA,MACN,aAAA,EAAe,OAAA;AAAA,MACf,UAAA,EAAY,EAAE,GAAA;AAAI,KACnB,CAAA;AACD,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AAAA,EACd;AACF,CAAA;AACA,eAAe,mBAAA,CAAoB,MAAA,EAAQ,OAAA,GAAU,EAAC,EAAG;AACvD,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,IAAI,IAAI,MAAM,CAAA;AAAA,EACzB,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,gBAAA,CAAiB,aAAA,EAAe,MAAM,CAAA;AAAA,EAClD;AACA,EAAA,MAAM,WAAW,MAAA,CAAO,QAAA,CAAS,aAAY,CAAE,OAAA,CAAQ,YAAY,EAAE,CAAA;AACrE,EAAA,MAAM,mBAAA,GAAsB,QAAA,KAAa,WAAA,IAAe,QAAA,KAAa,eAAe,QAAA,KAAa,KAAA;AACjG,EAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,gBAAA,IAAoB,CAAC,QAAQ,CAAA;AAC3D,EAAA,MAAM,SAAA,GAAY,QAAQ,cAAA,IAAkB,mBAAA,GAAsB,CAAC,GAAG,aAAA,EAAe,OAAO,CAAA,GAAI,aAAA;AAChG,EAAA,IAAI,CAAC,SAAA,CAAU,QAAA,CAAS,MAAA,CAAO,QAAQ,CAAA,EAAG;AACxC,IAAA,MAAM,IAAI,gBAAA;AAAA,MACR,YAAY,MAAA,CAAO,QAAQ,0BAA0B,SAAA,CAAU,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA;AAAA,MACzE;AAAA,KACF;AAAA,EACF;AACA,EAAA,IAAI,oBAAA,CAAqB,GAAA,CAAI,QAAQ,CAAA,EAAG;AACtC,IAAA,MAAM,IAAI,gBAAA;AAAA,MACR,CAAA,kCAAA,EAAqC,OAAO,QAAQ,CAAA,CAAA;AAAA,MACpD;AAAA,KACF;AAAA,EACF;AACA,EAAA,IAAI,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA,EAAG;AAC1B,IAAA,IAAI,CAAC,YAAA;AAAA,MACH,QAAA;AAAA,MACA,OAAA,CAAQ,cAAA,KAAmB,IAAA,IAAQ,QAAA,KAAa;AAAA,KAClD,EAAG;AACD,MAAA,MAAM,IAAI,gBAAA;AAAA,QACR,8BAA8B,QAAQ,CAAA,CAAA;AAAA,QACtC;AAAA,OACF;AAAA,IACF;AACA,IAAA,OAAO,EAAE,GAAA,EAAK,MAAA,EAAQ,QAAA,EAAU,QAAA,EAAU,QAAQ,CAAA,EAAE;AAAA,EACtD;AACA,EAAA,IAAI,QAAA,CAAS,QAAA,CAAS,GAAG,CAAA,EAAG;AAC1B,IAAA,IAAI,CAAC,YAAA;AAAA,MACH,QAAA;AAAA,MACA,OAAA,CAAQ,cAAA,KAAmB,IAAA,IAAQ,QAAA,KAAa;AAAA,KAClD,EAAG;AACD,MAAA,MAAM,IAAI,gBAAA;AAAA,QACR,8BAA8B,QAAQ,CAAA,CAAA;AAAA,QACtC;AAAA,OACF;AAAA,IACF;AACA,IAAA,OAAO,EAAE,GAAA,EAAK,MAAA,EAAQ,QAAA,EAAU,QAAA,EAAU,QAAQ,CAAA,EAAE;AAAA,EACtD;AACA,EAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAM,OAAO,cAAc,CAAA;AAC9C,EAAA,IAAI,SAAA;AACJ,EAAA,IAAI;AACF,IAAA,SAAA,GAAY,MAAM,MAAA,CAAO,QAAA,EAAU,EAAE,GAAA,EAAK,MAAM,CAAA;AAAA,EAClD,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,IAAI,gBAAA;AAAA,MACR,CAAA,mBAAA,EAAsB,IAAI,OAAO,CAAA,CAAA;AAAA,MACjC;AAAA,KACF;AAAA,EACF;AACA,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAI,gBAAA,CAAiB,0BAAA,EAA4B,MAAM,CAAA;AAAA,EAC/D;AACA,EAAA,KAAA,MAAW,EAAE,OAAA,EAAS,MAAA,EAAO,IAAK,SAAA,EAAW;AAC3C,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,cAAA,KAAmB,IAAA,IAAQ,uBAAuB,MAAA,KAAW,CAAA;AACnF,IAAA,MAAM,EAAA,GAAK,WAAW,CAAA,GAAI,YAAA,CAAa,SAAS,KAAK,CAAA,GAAI,YAAA,CAAa,OAAA,EAAS,KAAK,CAAA;AACpF,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,MAAM,IAAI,gBAAA;AAAA,QACR,8BAA8B,OAAO,CAAA,CAAA;AAAA,QACrC;AAAA,OACF;AAAA,IACF;AAAA,EACF;AACA,EAAA,MAAM,KAAA,GAAQ,UAAU,CAAC,CAAA;AACzB,EAAA,OAAO;AAAA,IACL,GAAA,EAAK,MAAA;AAAA,IACL,UAAU,KAAA,CAAM,OAAA;AAAA,IAChB,MAAA,EAAQ,KAAA,CAAM,MAAA,KAAW,CAAA,GAAI,CAAA,GAAI;AAAA,GACnC;AACF;AACA,IAAI,0BAAA,GAA6B,KAAK,IAAA,GAAO,IAAA;AAC7C,IAAI,kBAAA,GAAqB,GAAA;AACzB,IAAI,cAAA,GAAiB,cAAc,WAAA,CAAY;AAAA,EAC7C,WAAA,CAAY,OAAA,EAAS,GAAA,EAAK,MAAA,EAAQ,MAAA,EAAQ;AACxC,IAAA,KAAA,CAAM;AAAA,MACJ,IAAA,EAAM,yBAAA;AAAA,MACN,aAAA,EAAe,OAAA;AAAA,MACf,UAAA,EAAY,EAAE,GAAA,EAAK,MAAA;AAAO,KAC3B,CAAA;AACD,IAAA,IAAA,CAAK,GAAA,GAAM,GAAA;AACX,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AAAA,EACd;AACF,CAAA;AACA,SAAS,kBAAA,CAAmB,IAAI,MAAA,EAAQ;AACtC,EAAA,OAAO,CAAC,SAAA,EAAW,OAAA,EAAS,QAAA,KAAa;AACvC,IAAA,IAAI,OAAA,IAAW,QAAQ,GAAA,EAAK;AAC1B,MAAA,QAAA,CAAS,MAAM,CAAC,EAAE,SAAS,EAAA,EAAI,MAAA,EAAQ,CAAC,CAAA;AAAA,IAC1C,CAAA,MAAO;AACL,MAAA,QAAA,CAAS,IAAA,EAAM,IAAI,MAAM,CAAA;AAAA,IAC3B;AAAA,EACF,CAAA;AACF;AACA,eAAe,SAAA,CAAU,MAAA,EAAQ,OAAA,GAAU,EAAC,EAAG;AAC7C,EAAA,MAAM;AAAA,IACJ,cAAA;AAAA,IACA,gBAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAA;AAAA,IACA,gBAAA,GAAmB,0BAAA;AAAA,IACnB,SAAA,GAAY;AAAA,GACd,GAAI,OAAA;AACJ,EAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,EAAA,MAAM,YAAA,GAAe,MAAM,UAAA,CAAW,KAAA,CAAM,QAAQ,MAAM,CAAA;AAC1D,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,IAAI,MAAA,CAAO,OAAA,EAAS,UAAA,CAAW,KAAA,CAAM,OAAO,MAAM,CAAA;AAAA,gBACtC,gBAAA,CAAiB,OAAA,EAAS,cAAc,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,EACpE;AACA,EAAA,MAAM,KAAA,GAAQ,UAAA;AAAA,IACZ,MAAM,UAAA,CAAW,KAAA;AAAA,MACf,IAAI,cAAA,CAAe,CAAA,iBAAA,EAAoB,SAAS,CAAA,EAAA,CAAA,EAAM,QAAQ,SAAS;AAAA,KACzE;AAAA,IACA;AAAA,GACF;AACA,EAAA,IAAI;AACF,IAAA,MAAM,YAAY,MAAM,SAAA;AAAA,MACtB,mBAAA,CAAoB,MAAA,EAAQ,EAAE,cAAA,EAAgB,kBAAkB,CAAA;AAAA,MAChE,UAAA,CAAW;AAAA,KACb;AACA,IAAA,OAAO,MAAM,YAAY,SAAA,EAAW;AAAA,MAClC,MAAA;AAAA,MACA,OAAA;AAAA,MACA,IAAA;AAAA,MACA,QAAQ,UAAA,CAAW,MAAA;AAAA,MACnB;AAAA,KACD,CAAA;AAAA,EACH,CAAA,SAAE;AACA,IAAA,YAAA,CAAa,KAAK,CAAA;AAClB,IAAA,IAAI,MAAA,EAAQ,MAAA,CAAO,mBAAA,CAAoB,OAAA,EAAS,YAAY,CAAA;AAAA,EAC9D;AACF;AACA,SAAS,WAAW,MAAA,EAAQ;AAC1B,EAAA,MAAM,SAAS,MAAA,CAAO,MAAA;AACtB,EAAA,IAAI,MAAA,YAAkB,OAAO,OAAO,MAAA;AACpC,EAAA,OAAO,IAAI,YAAA,CAAa,2BAAA,EAA6B,YAAY,CAAA;AACnE;AACA,SAAS,SAAA,CAAU,SAAS,MAAA,EAAQ;AAClC,EAAA,IAAI,OAAO,OAAA,EAAS,OAAO,QAAQ,MAAA,CAAO,UAAA,CAAW,MAAM,CAAC,CAAA;AAC5D,EAAA,IAAI,OAAA;AACJ,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAQ,CAAC,UAAU,MAAA,KAAW;AAChD,IAAA,OAAA,GAAU,MAAM,MAAA,CAAO,UAAA,CAAW,MAAM,CAAC,CAAA;AACzC,IAAA,MAAA,CAAO,iBAAiB,OAAA,EAAS,OAAA,EAAS,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,EAC1D,CAAC,CAAA;AACD,EAAA,OAAO,QAAQ,IAAA,CAAK,CAAC,OAAA,EAAS,OAAO,CAAC,CAAA,CAAE,OAAA;AAAA,IACtC,MAAM,MAAA,CAAO,mBAAA,CAAoB,OAAA,EAAS,OAAO;AAAA,GACnD;AACF;AACA,eAAe,WAAA,CAAY,WAAW,IAAA,EAAM;AAC1C,EAAA,MAAM,EAAE,GAAA,EAAK,QAAA,EAAU,MAAA,EAAO,GAAI,SAAA;AAClC,EAAA,MAAM,OAAA,GAAU,GAAA,CAAI,QAAA,KAAa,QAAA,GAAW,MAAM,OAAO,OAAO,CAAA,GAAI,MAAM,OAAO,MAAM,CAAA;AACvF,EAAA,MAAM,IAAA,GAAO,MAAM,OAAO,MAAM,CAAA;AAChC,EAAA,MAAM,MAAA,GAAS,kBAAA,CAAmB,QAAA,EAAU,MAAM,CAAA;AAClD,EAAA,MAAM,UAAA,GAAa,iBAAA,CAAkB,IAAA,CAAK,OAAO,CAAA;AACjD,EAAA,IAAI,IAAA,CAAK,QAAQ,IAAA,EAAM;AACrB,IAAA,OAAO,WAAW,mBAAmB,CAAA;AACrC,IAAA,UAAA,CAAW,gBAAgB,CAAA,GAAI,MAAA;AAAA,MAC7B,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,GAAW,MAAA,CAAO,WAAW,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA,CAAK,IAAA,CAAK;AAAA,KAC3E;AAAA,EACF;AACA,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,IAAI,OAAA,GAAU,KAAA;AACd,IAAA,MAAM,MAAA,GAAS,CAAC,EAAA,KAAO;AACrB,MAAA,IAAI,OAAA,EAAS;AACb,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,EAAA,EAAG;AAAA,IACL,CAAA;AACA,IAAA,MAAM,OAAA,GAAU,CAAC,GAAA,KAAQ,IAAA,CAAK,OAAO,OAAA,GAAU,UAAA,CAAW,IAAA,CAAK,MAAM,CAAA,GAAI,GAAA;AACzE,IAAA,MAAM,MAAM,OAAA,CAAQ,OAAA;AAAA,MAClB,GAAA;AAAA,MACA;AAAA,QACE,MAAA,EAAQ,KAAK,MAAA,IAAU,KAAA;AAAA,QACvB,OAAA,EAAS,UAAA;AAAA,QACT,MAAA;AAAA;AAAA;AAAA,QAGA,KAAA,EAAO,KAAA;AAAA;AAAA,QAEP,QAAQ,IAAA,CAAK;AAAA,OACf;AAAA,MACA,CAAC,GAAA,KAAQ;AACP,QAAA,MAAM,SAAS,EAAC;AAChB,QAAA,IAAI,QAAA,GAAW,CAAA;AACf,QAAA,GAAA,CAAI,EAAA,CAAG,MAAA,EAAQ,CAAC,KAAA,KAAU;AACxB,UAAA,QAAA,IAAY,KAAA,CAAM,MAAA;AAClB,UAAA,IAAI,QAAA,GAAW,KAAK,gBAAA,EAAkB;AACpC,YAAA,GAAA,CAAI,OAAA,EAAQ;AACZ,YAAA,GAAA,CAAI,OAAA,EAAQ;AACZ,YAAA,MAAA;AAAA,cACE,MAAM,MAAA;AAAA,gBACJ,IAAI,cAAA;AAAA,kBACF,CAAA,uBAAA,EAA0B,KAAK,gBAAgB,CAAA,MAAA,CAAA;AAAA,kBAC/C,GAAA,CAAI,IAAA;AAAA,kBACJ,oBAAA;AAAA,kBACA,GAAA,CAAI;AAAA;AACN;AACF,aACF;AACA,YAAA;AAAA,UACF;AACA,UAAA,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA,QACnB,CAAC,CAAA;AACD,QAAA,GAAA,CAAI,EAAA,CAAG,OAAO,MAAM;AAClB,UAAA,MAAM,OAAA,GAAU,UAAA;AAAA,YACd,MAAA,CAAO,OAAO,MAAM,CAAA;AAAA,YACpB,GAAA,CAAI,QAAQ,kBAAkB,CAAA;AAAA,YAC9B,IAAA;AAAA,YACA,IAAA,CAAK,gBAAA;AAAA,YACL,GAAA,CAAI,IAAA;AAAA,YACJ,GAAA,CAAI;AAAA,WACN;AACA,UAAA,IAAI,mBAAmB,cAAA,EAAgB;AACrC,YAAA,MAAA,CAAO,MAAM,MAAA,CAAO,OAAO,CAAC,CAAA;AAC5B,YAAA;AAAA,UACF;AACA,UAAA,MAAA;AAAA,YACE,MAAM,QAAQ,gBAAA,CAAiB,GAAA,EAAK,QAAQ,IAAA,EAAM,OAAA,CAAQ,OAAO,CAAC;AAAA,WACpE;AAAA,QACF,CAAC,CAAA;AACD,QAAA,GAAA,CAAI,EAAA,CAAG,OAAA,EAAS,CAAC,GAAA,KAAQ,MAAA,CAAO,MAAM,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAC,CAAC,CAAC,CAAA;AAAA,MAC7D;AAAA,KACF;AACA,IAAA,GAAA,CAAI,EAAA,CAAG,OAAA,EAAS,CAAC,GAAA,KAAQ,MAAA,CAAO,MAAM,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAC,CAAC,CAAC,CAAA;AAC3D,IAAA,IAAI,CAAC,IAAI,SAAA,EAAW;AAClB,MAAA,IAAI,KAAK,IAAA,IAAQ,IAAA,EAAM,GAAA,CAAI,KAAA,CAAM,KAAK,IAAI,CAAA;AAC1C,MAAA,GAAA,CAAI,GAAA,EAAI;AAAA,IACV;AAAA,EACF,CAAC,CAAA;AACH;AACA,SAAS,kBAAkB,OAAA,EAAS;AAClC,EAAA,MAAM,MAAM,EAAC;AACb,EAAA,IAAI,CAAC,SAAS,OAAO,GAAA;AACrB,EAAA,MAAM,GAAA,GAAM,CAAC,MAAA,EAAQ,KAAA,KAAU;AAC7B,IAAA,MAAM,GAAA,GAAM,OAAO,WAAA,EAAY;AAC/B,IAAA,IAAI,QAAQ,MAAA,EAAQ;AACpB,IAAA,MAAM,QAAA,GAAW,IAAI,GAAG,CAAA;AACxB,IAAA,GAAA,CAAI,GAAG,IAAI,QAAA,KAAa,MAAA,GAAS,QAAQ,EAAC,CAAE,MAAA,CAAO,QAAA,EAAU,KAAK,CAAA;AAAA,EACpE,CAAA;AACA,EAAA,IAAI,mBAAmB,OAAA,EAAS;AAC9B,IAAA,OAAA,CAAQ,QAAQ,CAAC,KAAA,EAAO,QAAQ,GAAA,CAAI,GAAA,EAAK,KAAK,CAAC,CAAA;AAAA,EACjD,CAAA,MAAA,IAAW,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,EAAG;AACjC,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,OAAA,EAAS,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,EACpD,CAAA,MAAO;AACL,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,MAAA,CAAO,QAAQ,OAAO,CAAA,EAAG,GAAA,CAAI,GAAA,EAAK,KAAK,CAAA;AAAA,EACpE;AACA,EAAA,OAAO,GAAA;AACT;AACA,SAAS,gBAAA,CAAiB,GAAA,EAAK,IAAA,EAAM,mBAAA,EAAqB;AACxD,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,EAAQ;AAC5B,EAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,EAAG;AACtD,IAAA,IAAI,SAAS,IAAA,EAAM;AACnB,IAAA,MAAM,KAAA,GAAQ,IAAI,WAAA,EAAY;AAC9B,IAAA,IAAI,mBAAA,KAAwB,KAAA,KAAU,kBAAA,IAAsB,KAAA,KAAU,gBAAA,CAAA,EAAmB;AACvF,MAAA;AAAA,IACF;AACA,IAAA,MAAM,SAAS,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,GAAI,KAAA,GAAQ,CAAC,KAAK,CAAA;AACpD,IAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,MAAA,IAAI;AACF,QAAA,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,MACvB,CAAA,CAAA,MAAQ;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,EAAA,MAAM,GAAA,GAAM,IAAI,UAAA,IAAc,GAAA;AAC9B,EAAA,MAAM,MAAA,GAAS,GAAA,IAAO,GAAA,IAAO,GAAA,IAAO,MAAM,GAAA,GAAM,GAAA;AAChD,EAAA,MAAM,QAAA,GAAW,MAAA,KAAW,GAAA,IAAO,MAAA,KAAW,OAAO,MAAA,KAAW,GAAA;AAChE,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,IAAA,CAAK,UAAU,CAAA;AAC5C,EAAA,KAAA,CAAM,IAAI,IAAI,CAAA;AACd,EAAA,OAAO,IAAI,QAAA,CAAS,QAAA,GAAW,IAAA,GAAO,KAAA,EAAO;AAAA,IAC3C,MAAA;AAAA,IACA,UAAA,EAAY,IAAI,aAAA,IAAiB,EAAA;AAAA,IACjC;AAAA,GACD,CAAA;AACH;AACA,SAAS,WAAW,GAAA,EAAK,QAAA,EAAU,IAAA,EAAM,GAAA,EAAK,KAAK,MAAA,EAAQ;AACzD,EAAA,IAAI,CAAC,QAAA,EAAU,OAAO,EAAE,IAAA,EAAM,GAAA,EAAK,SAAS,KAAA,EAAM;AAClD,EAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG,OAAO,EAAE,IAAA,EAAM,GAAA,EAAK,SAAS,IAAA,EAAK;AACxD,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,KAAA,CAAM,GAAG,EAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,MAAK,CAAE,WAAA,EAAa,CAAA,CAAE,OAAO,OAAO,CAAA;AACpF,EAAA,MAAM,IAAA,GAAO,EAAE,eAAA,EAAiB,GAAA,EAAI;AACpC,EAAA,IAAI,OAAA,GAAU,GAAA;AACd,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,IAAI;AACF,IAAA,KAAA,IAAS,IAAI,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC3C,MAAA,MAAM,GAAA,GAAM,OAAO,CAAC,CAAA;AACpB,MAAA,IAAI,QAAQ,UAAA,EAAY;AACxB,MAAA,IAAI,GAAA,KAAQ,MAAA,IAAU,GAAA,KAAQ,QAAA,EAAU;AACtC,QAAA,OAAA,GAAU,IAAA,CAAK,UAAA,CAAW,OAAA,EAAS,IAAI,CAAA;AAAA,MACzC,CAAA,MAAA,IAAW,QAAQ,IAAA,EAAM;AACvB,QAAA,OAAA,GAAU,IAAA,CAAK,oBAAA,CAAqB,OAAA,EAAS,IAAI,CAAA;AAAA,MACnD,CAAA,MAAA,IAAW,QAAQ,SAAA,EAAW;AAC5B,QAAA,IAAI;AACF,UAAA,OAAA,GAAU,IAAA,CAAK,WAAA,CAAY,OAAA,EAAS,IAAI,CAAA;AAAA,QAC1C,SAAS,UAAA,EAAY;AACnB,UAAA,IAAI,SAAA,CAAU,UAAU,CAAA,KAAM,sBAAA;AAC5B,YAAA,MAAM,UAAA;AACR,UAAA,OAAA,GAAU,IAAA,CAAK,cAAA,CAAe,OAAA,EAAS,IAAI,CAAA;AAAA,QAC7C;AAAA,MACF,CAAA,MAAO;AACL,QAAA,IAAI,OAAA,EAAS;AACX,UAAA,OAAO,IAAI,cAAA;AAAA,YACT,yCAAyC,QAAQ,CAAA,CAAA,CAAA;AAAA,YACjD,GAAA;AAAA,YACA,eAAA;AAAA,YACA;AAAA,WACF;AAAA,QACF;AACA,QAAA,OAAO,EAAE,IAAA,EAAM,GAAA,EAAK,OAAA,EAAS,KAAA,EAAM;AAAA,MACrC;AACA,MAAA,OAAA,GAAU,IAAA;AAAA,IACZ;AACA,IAAA,OAAO,EAAE,IAAA,EAAM,OAAA,EAAS,OAAA,EAAQ;AAAA,EAClC,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,QAAA,GAAW,SAAA,CAAU,GAAG,CAAA,KAAM,sBAAA;AACpC,IAAA,OAAO,IAAI,cAAA;AAAA,MACT,QAAA,GAAW,CAAA,QAAA,EAAW,QAAQ,CAAA,oCAAA,CAAA,GAAyC,oBAAoB,QAAQ,CAAA,cAAA,CAAA;AAAA,MACnG,GAAA;AAAA,MACA,WAAW,oBAAA,GAAuB,eAAA;AAAA,MAClC;AAAA,KACF;AAAA,EACF;AACF;AACA,SAAS,UAAU,GAAA,EAAK;AACtB,EAAA,IAAI,OAAO,IAAA,IAAQ,OAAO,GAAA,KAAQ,QAAA,IAAY,UAAU,GAAA,EAAK;AAC3D,IAAA,MAAM,OAAO,GAAA,CAAI,IAAA;AACjB,IAAA,OAAO,OAAO,IAAA,KAAS,QAAA,GAAW,IAAA,GAAO,MAAA;AAAA,EAC3C;AACA,EAAA,OAAO,MAAA;AACT;AACA,SAAS,UAAU,EAAA,EAAI;AACrB,EAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,KAAA,CAAM,GAAG,CAAA;AAC1B,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAC/B,EAAA,IAAI,GAAA,GAAM,CAAA;AACV,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,IAAA,MAAM,CAAA,GAAI,OAAO,CAAC,CAAA;AAClB,IAAA,IAAI,CAAC,OAAO,SAAA,CAAU,CAAC,KAAK,CAAA,GAAI,CAAA,IAAK,CAAA,GAAI,GAAA,EAAK,OAAO,IAAA;AACrD,IAAA,GAAA,GAAM,OAAO,CAAA,GAAI,CAAA;AAAA,EACnB;AACA,EAAA,OAAO,GAAA,KAAQ,CAAA;AACjB;AACA,SAAS,YAAA,CAAa,OAAO,IAAA,EAAM;AACjC,EAAA,MAAM,CAAC,IAAA,EAAM,SAAS,CAAA,GAAI,IAAA,CAAK,MAAM,GAAG,CAAA;AACxC,EAAA,MAAM,OAAA,GAAU,UAAU,IAAI,CAAA;AAC9B,EAAA,IAAI,OAAA,KAAY,MAAM,OAAO,KAAA;AAC7B,EAAA,MAAM,MAAA,GAAS,OAAO,SAAS,CAAA;AAC/B,EAAA,IAAI,CAAC,OAAO,SAAA,CAAU,MAAM,KAAK,MAAA,GAAS,CAAA,IAAK,MAAA,GAAS,EAAA,EAAI,OAAO,KAAA;AACnE,EAAA,MAAM,OAAO,MAAA,KAAW,CAAA,GAAI,IAAI,EAAA,KAAO,EAAA,GAAK,UAAU,EAAA,GAAK,MAAA;AAC3D,EAAA,OAAA,CAAQ,KAAA,GAAQ,IAAA,MAAU,CAAA,KAAA,CAAO,OAAA,GAAU,IAAA,MAAU,CAAA;AACvD;AACA,SAAS,YAAA,CAAa,MAAM,aAAA,EAAe;AACzC,EAAA,MAAM,KAAA,GAAQ,UAAU,IAAI,CAAA;AAC5B,EAAA,IAAI,KAAA,KAAU,MAAM,OAAO,KAAA;AAC3B,EAAA,IAAI,aAAA,IAAiB,IAAA,KAAS,WAAA,EAAa,OAAO,IAAA;AAClD,EAAA,KAAA,MAAW,QAAQ,kBAAA,EAAoB;AACrC,IAAA,IAAI,YAAA,CAAa,KAAA,EAAO,IAAI,CAAA,EAAG,OAAO,KAAA;AAAA,EACxC;AACA,EAAA,OAAO,IAAA;AACT;AACA,SAAS,WAAW,KAAA,EAAO;AACzB,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,KAAA,CAAM,+CAA+C,CAAA;AAC1E,EAAA,IAAI,MAAA,EAAQ,OAAO,MAAA,CAAO,CAAC,CAAA;AAC3B,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,KAAA,CAAM,0CAA0C,CAAA;AAClE,EAAA,IAAI,GAAA,EAAK;AACP,IAAA,MAAM,EAAA,GAAK,QAAA,CAAS,GAAA,CAAI,CAAC,GAAG,EAAE,CAAA;AAC9B,IAAA,MAAM,EAAA,GAAK,QAAA,CAAS,GAAA,CAAI,CAAC,GAAG,EAAE,CAAA;AAC9B,IAAA,OAAO,CAAC,EAAA,IAAM,CAAA,EAAG,EAAA,GAAK,GAAA,EAAK,EAAA,IAAM,CAAA,EAAG,EAAA,GAAK,GAAG,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAAA,EACxD;AACA,EAAA,OAAO,IAAA;AACT;AACA,SAAS,YAAA,CAAa,MAAM,aAAA,EAAe;AACzC,EAAA,MAAM,KAAA,GAAQ,KAAK,WAAA,EAAY;AAC/B,EAAA,IAAI,aAAA,IAAiB,KAAA,KAAU,KAAA,EAAO,OAAO,IAAA;AAC7C,EAAA,MAAM,MAAA,GAAS,WAAW,KAAK,CAAA;AAC/B,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,OAAO,YAAA,CAAa,QAAQ,aAAa,CAAA;AAAA,EAC3C;AACA,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,KAAA,EAAO,OAAO,KAAA;AAC9C,EAAA,MAAM,cAAc,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA;AAC3C,EAAA,IAAI,YAAY,UAAA,CAAW,IAAI,CAAA,IAAK,WAAA,CAAY,WAAW,IAAI,CAAA;AAC7D,IAAA,OAAO,KAAA;AACT,EAAA,IAAI,YAAY,UAAA,CAAW,KAAK,CAAA,IAAK,WAAA,CAAY,WAAW,KAAK,CAAA;AAC/D,IAAA,OAAO,KAAA;AACT,EAAA,IAAI,YAAY,UAAA,CAAW,KAAK,CAAA,IAAK,WAAA,CAAY,WAAW,KAAK,CAAA;AAC/D,IAAA,OAAO,KAAA;AACT,EAAA,IAAI,WAAA,CAAY,UAAA,CAAW,IAAI,CAAA,EAAG,OAAO,KAAA;AACzC,EAAA,OAAO,IAAA;AACT;AAGA,eAAe,gBAAA,CAAiB,GAAA,EAAK,OAAA,EAAS,KAAA,EAAO,SAAS,MAAA,EAAQ;AACpE,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI;AACF,IAAA,QAAA,GAAW,MAAM,UAAU,GAAA,EAAK;AAAA,MAC9B,GAAG,SAAS,QAAA,KAAa,KAAA,CAAA,GAAS,EAAC,GAAI,EAAE,gBAAA,EAAkB,OAAA,CAAQ,QAAA,EAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAU5E,GAAG,MAAA,KAAW,KAAA,CAAA,GAAS,EAAE,QAAO,GAAI,OAAA,EAAS,SAAA,KAAc,KAAA,CAAA,GAAS,EAAC,GAAI,EAAE,SAAA,EAAW,QAAQ,SAAA;AAAU,KACzG,CAAA;AAAA,EACH,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,OAAA,GAAU,qBAAqB,KAAK,CAAA;AAC1C,IAAA,IAAI,OAAA,KAAY,UAAU,OAAO,IAAA;AACjC,IAAA,IAAI,YAAY,WAAA,EAAa;AAC3B,MAAA,MAAM,IAAI,wBAAA;AAAA,QACR,OAAA;AAAA,QACA,iBAAA,CAAkB,OAAO,CAAA,CAAE;AAAA,OAC7B;AAAA,IACF;AACA,IAAA,MAAM,KAAA;AAAA,EACR;AACA,EAAA,IAAI,QAAA,CAAS,MAAA,KAAW,GAAA,EAAK,OAAO,IAAA;AACpC,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,YAAY,QAAA,CAAS;AAAA,MACzB,UAAA,EAAY;AAAA,QACV,OAAA,EAAS,KAAA;AAAA,QACT,IAAA,EAAM,OAAA;AAAA,QACN,QAAQ,QAAA,CAAS,MAAA;AAAA,QACjB,YAAY,QAAA,CAAS;AAAA;AACvB,KACD,CAAA;AAAA,EACH;AACA,EAAA,OAAO,MAAA,CAAO,IAAA,CAAK,MAAM,QAAA,CAAS,aAAa,CAAA;AACjD;AACA,SAAS,qBAAqB,KAAA,EAAO;AACnC,EAAA,IAAI,EAAE,KAAA,YAAiB,cAAA,CAAA,EAAiB,OAAO,SAAA;AAC/C,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,GAAA,EAAK,OAAO,QAAA;AACjC,EAAA,MAAM,UAAA,GAAa,MAAM,MAAA,KAAW,MAAA,IAAU,MAAM,MAAA,IAAU,GAAA,IAAO,MAAM,MAAA,GAAS,GAAA;AACpF,EAAA,OAAO,KAAA,CAAM,MAAA,KAAW,oBAAA,IAAwB,UAAA,GAAa,WAAA,GAAc,SAAA;AAC7E;AACA,IAAI,uBAAA,GAA0B,kBAAA;AAC9B,IAAI,sBAAA,GAAyB,0BAAA;AAC7B,SAAS,kBAAkB,OAAA,EAAS;AAClC,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,SAAS,QAAA,IAAY,sBAAA;AAAA,IAC/B,SAAA,EAAW,SAAS,SAAA,IAAa;AAAA,GACnC;AACF;;;AC9bO,IAAM,2BAAN,MAA0D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS/D,YAAoB,MAAA,EAAiC;AAAjC,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;AAElB,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,IAAS,OAAA,CAAQ,IAAI,qBAAA,IAAyB,EAAA;AAEnE,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OAGF;AAAA,IACF;AAGA,IAAA,IAAA,CAAK,cAAA,GAAiB;AAAA,MACpB,KAAA;AAAA,MACA,eAAA,EAAiB,OAAO,eAAA,IAAmB,IAAA;AAAA,MAC3C,kBAAA,EAAoB,OAAO,kBAAA,IAAsB,OAAA;AAAA,MACjD,MAAA,EAAQ,OAAO,MAAA,IAAU,QAAA;AAAA,MACzB,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,cAAA,EAAgB,OAAO,cAAA,IAAkB,KAAA;AAAA,MACzC,kBAAA,EAAoB,MAAA,CAAO,kBAAA,IAAsB,CAAA,GAAI,IAAA,GAAO;AAAA;AAAA,KAC9D;AAAA,EACF;AAAA,EA9BQ,cAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8CR,MAAM,MAAA,CAAO,MAAA,EAAgB,OAAA,EAA+C;AAC1E,IAAA,MAAM,QAAA,GAAA,CAAY,QAAQ,WAAA,IAAe,OAAA,CAAQ,YAAY,EAAA,EAC1D,WAAA,GACA,IAAA,EAAK;AACR,IAAA,MAAM,QAAA,GAAA,CAAY,OAAA,CAAQ,QAAA,IAAY,EAAA,EAAI,WAAA,EAAY;AACtD,IAAA,MAAM,GAAA,GAAM,QAAA,CAAS,QAAA,CAAS,GAAG,CAAA,GAC7B,QAAA,CAAS,KAAA,CAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA,GAAI,CAAC,CAAA,GAC5C,EAAA;AACJ,IAAA,MAAM,MAAA,GACJ,aAAa,WAAA,IACb,QAAA,KAAa,2BACb,GAAA,KAAQ,MAAA,IACR,GAAA,KAAQ,KAAA,IACR,GAAA,KAAQ,OAAA;AAMV,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,MAAM,YAAY,UAAA,CAAW;AAAA,QAC3B,MAAA,EAAQ;AAAA,UACN;AAAA,YACE,IAAA,EAAM,MAAA;AAAA,YACN,IAAA,EAAM,yBAAA;AAAA,YACN,OAAA,EACE;AAAA;AACJ,SACF;AAAA,QACA,UAAA,EAAY;AAAA,UACV,OAAA,EAAS,aAAA;AAAA,UACT,iBAAiB,OAAA,CAAQ,QAAA;AAAA,UACzB,MAAA,EAAQ,0BAAA;AAAA,UACR,UAAU,OAAA,CAAQ;AAAA;AACpB,OACD,CAAA;AAAA,IACH;AAEA,IAAA,MAAM,KAAA,GACJ,QAAA,KAAa,eAAA,IAAmB,GAAA,KAAQ,SAAS,GAAA,KAAQ,MAAA;AAE3D,IAAA,MAAM,WAAW,IAAA,CAAK,aAAA,CAAc,OAAA,CAAQ,QAAA,EAAU,QAAQ,MAAM,CAAA;AAEpE,IAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,QAAA,EAAU,MAAA,EAAQ;AAAA,MACzC,MAAA,EAAQ,KAAK,cAAA,CAAe,MAAA;AAAA,MAC5B,KAAA,EAAO,KAAK,cAAA,CAAe,KAAA;AAAA,MAC3B,WAAA,EAAa,OAAA,CAAQ,WAAA,IAAe,OAAA,CAAQ,QAAA;AAAA,MAC5C,eAAA,EAAiB,KAAK,cAAA,CAAe,eAAA;AAAA,MACrC,kBAAA,EAAoB,KAAK,cAAA,CAAe;AAAA,KACzC,CAAA;AAUD,IAAA,MAAM,MACJ,KAAA,IAAS,OAAA,CAAQ,uBAAuB,YAAA,GACpC,MAAA,CAAO,cACP,MAAA,CAAO,GAAA;AAEb,IAAA,OAAO;AAAA,MACL,GAAA;AAAA,MACA,MAAM,MAAA,CAAO;AAAA,KACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAO,QAAA,EAAiC;AAC5C,IAAA,MAAM,IAAI,QAAA,EAAU;AAAA,MAClB,KAAA,EAAO,KAAK,cAAA,CAAe;AAAA,KAC5B,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,WAAW,SAAA,EAAgD;AAC/D,IAAA,MAAM,aAAuB,EAAC;AAC9B,IAAA,MAAM,SAAqD,EAAC;AAC5D,IAAA,MAAM,SAAA,GAAY,EAAA;AAElB,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,SAAA,CAAU,MAAA,EAAQ,KAAK,SAAA,EAAW;AACpD,MAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,KAAA,CAAM,CAAA,EAAG,IAAI,SAAS,CAAA;AAC9C,MAAA,MAAM,OAAA,GAAU,MAAM,OAAA,CAAQ,UAAA;AAAA,QAC5B,KAAA,CAAM,GAAA,CAAI,CAAA,EAAA,KAAM,GAAA,CAAI,EAAA,EAAI,EAAE,KAAA,EAAO,IAAA,CAAK,cAAA,CAAe,KAAA,EAAO,CAAC;AAAA,OAC/D;AAEA,MAAA,OAAA,CAAQ,OAAA,CAAQ,CAAC,MAAA,EAAQ,GAAA,KAAQ;AAC/B,QAAA,MAAM,EAAA,GAAK,MAAM,GAAG,CAAA;AACpB,QAAA,IAAI,MAAA,CAAO,WAAW,WAAA,EAAa;AACjC,UAAA,UAAA,CAAW,KAAK,EAAE,CAAA;AAAA,QACpB,CAAA,MAAO;AACL,UAAA,MAAA,CAAO,IAAA,CAAK;AAAA,YACV,QAAA,EAAU,EAAA;AAAA,YACV,KAAA,EACE,OAAO,MAAA,YAAkB,KAAA,GACrB,OAAO,MAAA,CAAO,OAAA,GACd,MAAA,CAAO,MAAA,CAAO,MAAM;AAAA,WAC3B,CAAA;AAAA,QACH;AAAA,MACF,CAAC,CAAA;AAAA,IACH;AAEA,IAAA,OAAO,EAAE,YAAY,MAAA,EAAO;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OAAO,QAAA,EAAoC;AAC/C,IAAA,IAAI;AACF,MAAA,MAAM,KAAK,QAAA,EAAU;AAAA,QACnB,KAAA,EAAO,KAAK,cAAA,CAAe;AAAA,OAC5B,CAAA;AACD,MAAA,OAAO,IAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AAEN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAM,IAAA,CACJ,QAAA,EACA,OAAA,EACwB;AAexB,IAAA,MAAM,WAAW,WAAA,CAAY,OAAA;AAAA,MAC3B,SAAS,SAAA,IAAa;AAAA,KACxB;AAEA,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,QAAA,EAAU;AAAA,QAChC,KAAA,EAAO,KAAK,cAAA,CAAe,KAAA;AAAA,QAC3B,WAAA,EAAa;AAAA,OACd,CAAA;AACD,MAAA,MAAA,GAAS,IAAA,CAAK,eAAe,IAAA,CAAK,GAAA;AAAA,IACpC,SAAS,KAAA,EAAgB;AAYvB,MAAA,IAAI,KAAA,YAAiB,mBAAmB,OAAO,IAAA;AAC/C,MAAA,MAAM,KAAA;AAAA,IACR;AASA,IAAA,OAAO,MAAM,gBAAA;AAAA,MACX,MAAA;AAAA,MACA,QAAA;AAAA,MACA,aAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,aAAa,QAAA,EAA0B;AAErC,IAAA,OAAO,QAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,OAAA,GAAyB;AACvB,IAAA,OAAO,aAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OAAA,GAA8B;AAC5B,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,aAAA;AAAA,MACN,IAAA,EAAM,0BAAA;AAAA,MACN,kBAAA,EAAoB,KAAA;AAAA;AAAA,MACpB,qBAAA,EAAuB;AAAA;AAAA,KACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,YAAY,QAAA,EAAgD;AAChE,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,QAAA,EAAU;AAAA,QAClC,KAAA,EAAO,KAAK,cAAA,CAAe;AAAA,OAC5B,CAAA;AAGD,MAAA,MAAM,QAAA,GAAW,OAAO,QAAA,CAAS,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,MAAS,MAAA,CAAO,QAAA;AAE5D,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,QAAA;AAAA,QACJ,QAAA;AAAA,QACA,gBAAA,EAAkB,QAAA;AAAA,QAClB,UAAU,MAAA,CAAO,WAAA;AAAA,QACjB,MAAM,MAAA,CAAO,IAAA;AAAA,QACb,KAAK,MAAA,CAAO,GAAA;AAAA,QACZ,SAAA,EAAW,MAAA,CAAO,UAAA,CAAW,WAAA;AAAY,OAC3C;AAAA,IACF,CAAA,CAAA,MAAQ;AAEN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,qBAAA,CACE,IAAA,EACA,SAAA,EACA,UAAA,EAC2B;AAC3B,IAAA,OAAO,OAAA,CAAQ,MAAA;AAAA,MACb,IAAI,KAAA;AAAA,QACF;AAAA;AAMF,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,MAAM,SAAA,CACJ,MAAA,EACA,OAAA,EAUC;AACD,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK;AAAA,MACxB,KAAA,EAAO,KAAK,cAAA,CAAe,KAAA;AAAA,MAC3B,MAAA;AAAA,MACA,OAAO,OAAA,EAAS,KAAA;AAAA,MAChB,QAAQ,OAAA,EAAS;AAAA,KAClB,CAAA;AAED,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,MAAA,CAAO,KAAA,CAAM,GAAA,CAAI,CAAA,IAAA,MAAS;AAAA,QAC/B,KAAK,IAAA,CAAK,GAAA;AAAA,QACV,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,MAAM,IAAA,CAAK,IAAA;AAAA,QACX,YAAY,IAAA,CAAK;AAAA,OACnB,CAAE,CAAA;AAAA,MACF,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,QAAQ,MAAA,CAAO;AAAA,KACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBQ,aAAA,CAAc,UAAkB,MAAA,EAAyB;AAC/D,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,gBAAA,CAAiB,QAAQ,CAAA;AAChD,IAAA,IAAI,CAAC,QAAQ,OAAO,SAAA;AACpB,IAAA,OAAO,GAAG,IAAA,CAAK,cAAA,CAAe,MAAM,CAAC,IAAI,SAAS,CAAA,CAAA;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,iBAAiB,QAAA,EAA0B;AACjD,IAAA,MAAM,WAAW,QAAA,CAAS,KAAA,CAAM,OAAO,CAAA,CAAE,KAAI,IAAK,QAAA;AAClD,IAAA,OAAO,QAAA,CAAS,OAAA,CAAQ,kBAAA,EAAoB,GAAG,CAAA;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBQ,eAAe,MAAA,EAAwB;AAC7C,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AACzC,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,MAAM,IAAI,MAAM,oCAAoC,CAAA;AAAA,IACtD;AAEA,IAAA,IAAI,qBAAA,CAAsB,IAAA,CAAK,OAAO,CAAA,EAAG;AACvC,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AACA,IAAA,IAAI,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,EAAG;AAC3B,MAAA,MAAM,IAAI,MAAM,iCAAiC,CAAA;AAAA,IACnD;AACA,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,CAAM,GAAG,CAAA;AAClC,IAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,MAAA,IAAI,YAAY,EAAA,EAAI;AAClB,QAAA,MAAM,IAAI,MAAM,gDAAgD,CAAA;AAAA,MAClE;AACA,MAAA,IAAI,YAAY,IAAA,EAAM;AACpB,QAAA,MAAM,IAAI,MAAM,wCAAwC,CAAA;AAAA,MAC1D;AAAA,IACF;AACA,IAAA,OAAO,OAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,cAAA,GAAyB;AACvB,IAAA,MAAM,KAAA,GAAQ,KAAK,cAAA,CAAe,KAAA;AAClC,IAAA,IAAI,KAAA,CAAM,MAAA,IAAU,CAAA,EAAG,OAAO,MAAA;AAC9B,IAAA,OAAO,CAAA,EAAG,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,GAAA,EAAM,KAAA,CAAM,KAAA,CAAM,EAAE,CAAC,CAAA,CAAA;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,GAA2B;AACzB,IAAA,OAAO,KAAK,cAAA,CAAe,eAAA;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAA,GAAgC;AAC9B,IAAA,OAAO,KAAK,cAAA,CAAe,kBAAA;AAAA,EAC7B;AACF;;;AC7eO,SAAS,kBACd,MAAA,EACe;AAIf,EAAA,IAAI,MAAA,CAAO,YAAY,KAAA,EAAO;AAC5B,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,qBAAA;AAAA,MACN,IAAA,EAAM,aAAA;AAAA,MACN,aAAa,EAAC;AAAA,MACd,OAAA,EAAS;AAAA,KACX;AAAA,EACF;AAIA,EAAA,MAAM,OAAA,GAAU,IAAI,wBAAA,CAAyB,MAAM,CAAA;AAGnD,EAAA,MAAM,MAAA,GAAwB;AAAA,IAC5B,IAAA,EAAM,qBAAA;AAAA,IACN,IAAA,EAAM,aAAA;AAAA,IACN,aAAa,MAAA,CAAO,WAAA;AAAA,IACpB,OAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAaA,kBAAA,CACE,SAAA,EACA,SAAA,EACA,WAAA,EAC2B;AAG3B,MAAA,OAAO,OAAA,CAAQ,MAAA;AAAA,QACb,IAAI,KAAA;AAAA,UACF;AAAA;AAKF,OACF;AAAA,IACF,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAYA,qBAAqB,IAAA,EAA+B;AAGlD,MAAA,OAAO,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAAA,IAC7B;AAAA,GACF;AAEA,EAAA,OAAO,MAAA;AACT;;;AC1FO,IAAM,YAAA,GAAe;AACrB,IAAM,eAAA,GAAkB","file":"index.mjs","sourcesContent":["// src/database/errors.ts\nvar DbError = class extends Error {\n kind;\n dialect;\n code;\n meta;\n cause;\n constructor(args) {\n super(args.message);\n this.name = \"DbError\";\n this.kind = args.kind;\n this.dialect = args.dialect;\n this.code = args.code;\n this.meta = args.meta;\n this.cause = args.cause;\n }\n};\nfunction isDbError(err) {\n if (!err || typeof err !== \"object\") return false;\n const obj = err;\n return obj.name === \"DbError\" && typeof obj.kind === \"string\";\n}\nfunction toDbError(dialect, error, meta) {\n if (isDbError(error)) return error;\n const code = safeCode(error);\n const rawMsg = error != null && typeof error === \"object\" && \"message\" in error ? error.message : void 0;\n const message = typeof rawMsg === \"string\" ? rawMsg : \"Database error\";\n let kind = \"internal\";\n switch (dialect) {\n case \"postgresql\":\n kind = mapPostgresCodeToKind(code);\n break;\n case \"mysql\":\n kind = mapMySqlCodeToKind(code);\n break;\n case \"sqlite\":\n kind = mapSqliteCodeToKind(code);\n break;\n }\n if ((dialect === \"mysql\" || dialect === \"sqlite\") && (kind === \"constraint\" || kind === \"internal\") && isLikelyUniqueViolationMessage(dialect, message)) {\n kind = \"unique-violation\";\n }\n if (kind === \"internal\" && code) {\n const c = code.toUpperCase();\n if (c === \"ECONNRESET\" || c.includes(\"PROTOCOL_CONNECTION_LOST\"))\n kind = \"connection-lost\";\n else if (c === \"ETIMEDOUT\") kind = \"timeout\";\n }\n return new DbError({ message, kind, dialect, code, meta, cause: error });\n}\nfunction safeCode(error) {\n if (!error || typeof error !== \"object\") return void 0;\n const e = error;\n let c = e.code ?? e.sqlState ?? e.state ?? e.errno ?? void 0;\n if (!c && typeof e.originalError?.code === \"string\") c = e.originalError.code;\n if (!c && typeof e.cause?.code === \"string\") c = e.cause.code;\n if (!c && typeof e.severity === \"string\" && typeof e.code === \"string\")\n c = e.code;\n if (typeof c === \"number\") return String(c);\n if (typeof c === \"string\" && c.length > 0) return c;\n return void 0;\n}\nfunction mapPostgresCodeToKind(code) {\n if (!code) return \"internal\";\n const c = code.toUpperCase();\n if (c === \"40P01\") return \"deadlock\";\n if (c === \"40001\") return \"serialization-failure\";\n if (c === \"57014\") return \"timeout\";\n if (c === \"23505\") return \"unique-violation\";\n if (c === \"23503\") return \"fk-violation\";\n if (c === \"23502\") return \"not-null-violation\";\n if (c === \"42601\") return \"syntax\";\n if (c.startsWith(\"08\") || c === \"57P01\") return \"connection-lost\";\n if (c.startsWith(\"23\")) return \"constraint\";\n return \"internal\";\n}\nfunction mapMySqlCodeToKind(code) {\n if (!code) return \"internal\";\n const c = code.toUpperCase();\n if (c === \"1213\" || c === \"ER_LOCK_DEADLOCK\") return \"deadlock\";\n if (c === \"1205\" || c === \"ER_LOCK_WAIT_TIMEOUT\") return \"timeout\";\n if (c === \"1062\" || c === \"ER_DUP_ENTRY\") return \"unique-violation\";\n if (c === \"23000\") return \"constraint\";\n if (c === \"1064\" || c === \"ER_PARSE_ERROR\") return \"syntax\";\n if (c === \"1452\" || c === \"ER_NO_REFERENCED_ROW_2\") return \"fk-violation\";\n if (c === \"1451\" || c === \"ER_ROW_IS_REFERENCED_2\") return \"fk-violation\";\n if (c === \"ECONNRESET\" || c.includes(\"PROTOCOL_CONNECTION_LOST\"))\n return \"connection-lost\";\n if (c === \"ETIMEDOUT\") return \"timeout\";\n return \"internal\";\n}\nfunction mapSqliteCodeToKind(code) {\n if (!code) return \"internal\";\n const c = code.toUpperCase();\n if (c === \"SQLITE_BUSY\" || c === \"SQLITE_LOCKED\") return \"deadlock\";\n if (c === \"SQLITE_CONSTRAINT_UNIQUE\") return \"unique-violation\";\n if (c === \"SQLITE_CONSTRAINT_PRIMARYKEY\") return \"unique-violation\";\n if (c === \"SQLITE_CONSTRAINT_FOREIGNKEY\") return \"fk-violation\";\n if (c === \"SQLITE_CONSTRAINT_NOTNULL\") return \"not-null-violation\";\n if (c === \"SQLITE_INTERRUPT\") return \"timeout\";\n if (c === \"SQLITE_ERROR\") return \"syntax\";\n if (c.startsWith(\"SQLITE_CONSTRAINT\")) return \"constraint\";\n return \"internal\";\n}\nfunction isLikelyUniqueViolationMessage(dialect, message) {\n const m = message.toLowerCase();\n if (dialect === \"mysql\") {\n return m.includes(\"duplicate entry\") || m.includes(\"duplicate key\");\n }\n if (dialect === \"sqlite\") {\n return m.includes(\"unique constraint failed\");\n }\n return false;\n}\n\n// src/errors/error-codes.ts\nvar NEXTLY_ERROR_STATUS = {\n VALIDATION_ERROR: 400,\n INVALID_INPUT: 400,\n AUTH_REQUIRED: 401,\n AUTH_INVALID_CREDENTIALS: 401,\n TOKEN_EXPIRED: 401,\n FORBIDDEN: 403,\n // The schema builder is off in this environment (production by default).\n // Separate from FORBIDDEN: the caller's permissions are not the problem.\n BUILDER_DISABLED: 403,\n NOT_FOUND: 404,\n CONFLICT: 409,\n DUPLICATE: 409,\n RATE_LIMITED: 429,\n PAYLOAD_TOO_LARGE: 413,\n UNSUPPORTED_MEDIA_TYPE: 415,\n // 422: understood, well-formed, and refused on a rule the caller can act on.\n // Deliberately NOT added to CANONICAL_CODE_FOR_STATUS -- that list drives the\n // status -> code direction, where 422 stays mapped to INVALID_INPUT.\n BUSINESS_RULE_VIOLATION: 422,\n INTERNAL_ERROR: 500,\n DATABASE_ERROR: 500,\n EXTERNAL_SERVICE_ERROR: 502,\n SERVICE_UNAVAILABLE: 503,\n // Outbound-fetch safety (utils/validate-external-url): a URL refused for SSRF\n // safety, and a fetch that timed out / exceeded the size cap / failed to decode.\n EXTERNAL_URL_BLOCKED: 400,\n EXTERNAL_REQUEST_FAILED: 502,\n FILENAME_INVALID: 400,\n EXTENSION_BLOCKED: 400,\n MIME_BLOCKED: 415,\n MIME_NOT_ALLOWED: 415,\n SIZE_EXCEEDED: 413,\n // A stored object exceeded the cap a READ was given, which is a different\n // question from SIZE_EXCEEDED above: that one refuses an upload the caller\n // is sending, this one refuses to buffer an object already stored. Kept\n // apart so a caller discriminating on the code cannot match both.\n STORAGE_READ_TOO_LARGE: 413,\n // A stored object did not answer within the deadline the read was given. 504\n // rather than 500 because the failure is the BACKEND not answering, and a\n // caller can act on that difference: a gateway timeout is worth retrying, an\n // internal error is not.\n STORAGE_READ_TIMEOUT: 504,\n // The store answered, and answered badly. 502 rather than 500 because the\n // fault is UPSTREAM of this process: a caller can retry it, and an operator\n // reading the log needs to look at the bucket rather than at this service.\n // Distinct from the timeout above, which never got an answer at all.\n STORAGE_READ_UNREACHABLE: 502,\n MAGIC_BYTE_MISMATCH: 400,\n SVG_SANITIZATION_FAILED: 400,\n UNSUPPORTED_FOR_BACKEND: 415,\n // Plan B — schema bookkeeping consolidation.\n NEXTLY_LEGACY_BOOKKEEPING_DETECTED: 409,\n NEXTLY_UPGRADE_TABLE_NAME_COLLISION: 409,\n NEXTLY_UPGRADE_IN_PROGRESS: 409,\n // Plan C2 — nextly migrate phases.\n NEXTLY_MIGRATE_LOCK_BUSY: 409,\n NEXTLY_BASELINE_LOCK_NOT_HELD: 409,\n NEXTLY_RESOLVE_LOCK_NOT_HELD: 409,\n // Boot refused to serve: the migrate lock stayed held past the wait deadline,\n // so this process never established whether the schema matches the code. 503\n // rather than 409 — a load balancer should take the instance out of rotation\n // and retry it, which is exactly the recovery this refusal wants.\n NEXTLY_BOOT_MIGRATIONS_NOT_RUN: 503,\n // Still running rather than refused. 503 for the same reason: retry shortly.\n NEXTLY_BOOT_MIGRATIONS_PENDING: 503,\n NEXTLY_CORE_DESTRUCTIVE_REFUSED: 409,\n NEXTLY_MIGRATION_DRIFT: 409,\n NEXTLY_MIGRATION_APPLY_FAILED: 500,\n // Plan C3 — migrate:resolve recovery command.\n NEXTLY_MIGRATION_FILE_MISSING: 404,\n NEXTLY_MIGRATION_SNAPSHOT_MISSING: 404,\n NEXTLY_MIGRATION_RESOLVE_DRIFT: 409,\n NEXTLY_MIGRATION_RESOLVE_PRECONDITION: 409,\n // Plan D — UI schema support.\n NEXTLY_UI_SCHEMA_INVALID: 400,\n NEXTLY_SCHEMA_SLUG_COLLISION: 409,\n NEXTLY_SCHEMA_RELATION_TARGET_MISSING: 400,\n // Plugin platform (P2b) — schema extend (contributes.extend) + relations (D15).\n NEXTLY_SCHEMA_EXTEND_TARGET_UNKNOWN: 400,\n NEXTLY_SCHEMA_EXTEND_FIELD_DUPLICATE: 409,\n NEXTLY_SCHEMA_CROSS_PLUGIN_RELATION: 409,\n // Plugin platform (P2c) — framework remap (.rename()).\n NEXTLY_SCHEMA_RENAME_UNKNOWN_TARGET: 400,\n // Plugin platform — a declared admin.clientConfig that cannot be delivered\n // to the browser, refused at boot rather than serialized mangled.\n NEXTLY_PLUGIN_CLIENT_CONFIG_INVALID: 500,\n // Plugin platform — a contributed admin widget that cannot be delivered to\n // the browser. Refused at boot because it is serialized into the ONE\n // `/api/admin-meta/workspace` payload: a value `JSON.stringify` throws on\n // fails that request for every admin, not just the widget's own card.\n NEXTLY_PLUGIN_ADMIN_WIDGET_INVALID: 500,\n // Plugin platform (P0) — boot-time plugin dependency/version resolution.\n PLUGIN_RESOLUTION_ERROR: 500,\n // Plugin platform (P4) — contributes.routes collection (D25).\n NEXTLY_ROUTE_COLLISION: 409,\n NEXTLY_ROUTE_INVALID_PATH: 400,\n // An email transport whose library is an optional peer dependency the host\n // has not installed. 503 rather than 500: the request is not malformed and\n // nothing is broken, the install simply cannot carry it out yet, and the\n // remedy is one command on the server rather than a change by the caller.\n NEXTLY_EMAIL_TRANSPORT_UNAVAILABLE: 503,\n // The tooling that compiles `nextly.config.ts` is an optional peer the host\n // has not installed. 503 rather than 500 for the same reason as the mail\n // transport above: nothing is broken and the request is not malformed, the\n // install simply cannot carry it out until one command is run.\n NEXTLY_CONFIG_TOOLING_UNAVAILABLE: 503\n};\nvar CANONICAL_CODE_FOR_STATUS = [\n \"VALIDATION_ERROR\",\n \"AUTH_REQUIRED\",\n \"FORBIDDEN\",\n \"NOT_FOUND\",\n \"CONFLICT\",\n \"PAYLOAD_TOO_LARGE\",\n \"UNSUPPORTED_MEDIA_TYPE\",\n \"RATE_LIMITED\",\n \"EXTERNAL_SERVICE_ERROR\",\n \"SERVICE_UNAVAILABLE\"\n];\nvar LEGACY_UNPROCESSABLE_STATUS = 422;\nvar STATUS_TO_CODE = {\n ...Object.fromEntries(\n CANONICAL_CODE_FOR_STATUS.map((code) => [NEXTLY_ERROR_STATUS[code], code])\n ),\n [LEGACY_UNPROCESSABLE_STATUS]: \"INVALID_INPUT\"\n};\nfunction statusToErrorCode(statusCode) {\n return STATUS_TO_CODE[statusCode] ?? \"INTERNAL_ERROR\";\n}\nvar GENERIC_PUBLIC_MESSAGE = {\n VALIDATION_ERROR: \"Validation failed.\",\n INVALID_INPUT: \"The request could not be processed.\",\n AUTH_REQUIRED: \"Authentication required.\",\n FORBIDDEN: \"You don't have permission to perform this action.\",\n NOT_FOUND: \"Not found.\",\n CONFLICT: \"The resource has changed since you last loaded it. Please refresh and try again.\",\n DUPLICATE: \"Resource already exists.\",\n PAYLOAD_TOO_LARGE: \"The request is too large.\",\n UNSUPPORTED_MEDIA_TYPE: \"That file type is not supported.\",\n RATE_LIMITED: \"Too many requests. Please try again later.\",\n EXTERNAL_SERVICE_ERROR: \"An upstream service failed.\",\n SERVICE_UNAVAILABLE: \"The service is temporarily unavailable.\",\n INTERNAL_ERROR: \"An unexpected error occurred.\"\n};\nfunction genericPublicMessage(code) {\n return GENERIC_PUBLIC_MESSAGE[code] ?? GENERIC_PUBLIC_MESSAGE.INTERNAL_ERROR;\n}\n\n// src/errors/nextly-error.ts\nvar DB_ERROR_MAPPING = {\n \"unique-violation\": {\n code: \"DUPLICATE\",\n statusCode: 409,\n publicMessage: \"Resource already exists.\"\n },\n \"fk-violation\": {\n code: \"VALIDATION_ERROR\",\n statusCode: 400,\n publicMessage: \"Referenced record does not exist.\"\n },\n \"not-null-violation\": {\n code: \"VALIDATION_ERROR\",\n statusCode: 400,\n publicMessage: \"A required field is missing.\"\n },\n constraint: {\n code: \"VALIDATION_ERROR\",\n statusCode: 400,\n publicMessage: \"The provided data violates a constraint.\"\n },\n deadlock: {\n code: \"CONFLICT\",\n statusCode: 409,\n publicMessage: \"The operation could not be completed. Please retry.\"\n },\n \"serialization-failure\": {\n code: \"CONFLICT\",\n statusCode: 409,\n publicMessage: \"The operation could not be completed. Please retry.\"\n },\n timeout: {\n code: \"DATABASE_ERROR\",\n statusCode: 500,\n publicMessage: \"The operation timed out. Please try again.\"\n },\n \"connection-lost\": {\n code: \"DATABASE_ERROR\",\n statusCode: 500,\n publicMessage: \"A temporary database error occurred. Please try again.\"\n },\n syntax: {\n code: \"INTERNAL_ERROR\",\n statusCode: 500,\n publicMessage: \"An unexpected error occurred.\"\n },\n internal: {\n code: \"INTERNAL_ERROR\",\n statusCode: 500,\n publicMessage: \"An unexpected error occurred.\"\n }\n};\nvar NEXTLY_ERROR_BRAND = Symbol.for(\"nextly/NextlyError\");\nfunction hasBrand(value) {\n if (value === null || typeof value !== \"object\" && typeof value !== \"function\") {\n return false;\n }\n return value[NEXTLY_ERROR_BRAND] === true;\n}\nvar NextlyError = class _NextlyError extends Error {\n code;\n statusCode;\n publicMessage;\n publicData;\n messageKey;\n logMessage;\n logContext;\n cause;\n timestamp;\n constructor(opts) {\n super(opts.publicMessage);\n this.name = \"NextlyError\";\n this.code = opts.code;\n this.publicMessage = opts.publicMessage;\n this.publicData = opts.publicData;\n this.messageKey = opts.messageKey;\n this.logMessage = opts.logMessage;\n this.logContext = opts.logContext;\n this.cause = opts.cause;\n this.timestamp = /* @__PURE__ */ new Date();\n this.statusCode = _NextlyError.resolveStatusCode(opts);\n Error.captureStackTrace?.(this, _NextlyError);\n }\n static {\n _NextlyError.prototype[NEXTLY_ERROR_BRAND] = true;\n }\n static resolveStatusCode(opts) {\n if (typeof opts.statusCode === \"number\") return opts.statusCode;\n if (opts.code in NEXTLY_ERROR_STATUS) {\n return NEXTLY_ERROR_STATUS[opts.code];\n }\n return 500;\n }\n /** HTTP-safe JSON. Strips logMessage / logContext / cause / stack. */\n toResponseJSON(requestId) {\n const json = {\n code: String(this.code),\n message: this.publicMessage,\n requestId\n };\n if (this.messageKey) json.messageKey = this.messageKey;\n if (this.publicData !== void 0) json.data = this.publicData;\n return json;\n }\n /** Operator-facing JSON for log lines. Includes everything. */\n toLogJSON(requestId) {\n return {\n code: this.code,\n statusCode: this.statusCode,\n publicMessage: this.publicMessage,\n messageKey: this.messageKey,\n logMessage: this.logMessage,\n logContext: this.logContext,\n cause: this.cause ? {\n name: this.cause.name,\n message: this.cause.message,\n stack: this.cause.stack\n } : void 0,\n timestamp: this.timestamp.toISOString(),\n requestId\n };\n }\n // ────────────────────────────────────────────────────────────────────\n // Static factories — the recommended throw site for every common case.\n // Public messages here follow the §13.8 rubric: complete sentence,\n // generic, no identifiers, no value echoing, no policy hints.\n // ────────────────────────────────────────────────────────────────────\n static invalidCredentials(opts) {\n return new _NextlyError({\n code: \"AUTH_INVALID_CREDENTIALS\",\n publicMessage: \"Invalid email or password.\",\n logMessage: \"Login failed\",\n logContext: opts?.logContext\n });\n }\n static authRequired(opts) {\n return new _NextlyError({\n code: \"AUTH_REQUIRED\",\n publicMessage: \"Authentication required.\",\n logContext: opts?.logContext\n });\n }\n /**\n * Distinct from `authRequired`: the caller was authenticated but the\n * session token expired. Clients key on the TOKEN_EXPIRED *code* to\n * silently refresh and retry rather than redirecting to login; the public\n * message stays the generic spec §13.6 string (\"Authentication required.\")\n * so the wire never reveals the session state — same as `authRequired`.\n */\n static tokenExpired(opts) {\n return new _NextlyError({\n code: \"TOKEN_EXPIRED\",\n publicMessage: \"Authentication required.\",\n logContext: opts?.logContext\n });\n }\n static notFound(opts) {\n return new _NextlyError({\n code: \"NOT_FOUND\",\n publicMessage: opts?.message ?? \"Not found.\",\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n static forbidden(opts) {\n return new _NextlyError({\n code: \"FORBIDDEN\",\n publicMessage: \"You don't have permission to perform this action.\",\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n /**\n * A call the caller got wrong, where naming the mistake IS the value of the\n * error.\n *\n * The only factory that takes its public message from the caller. The\n * generic messages elsewhere exist so an HTTP response cannot leak internal\n * detail; this one is for arguments and configuration a developer controls\n * and must be told about — a missing option, an unusable combination — where\n * `internal()` would reduce the one useful sentence to \"An unexpected error\n * occurred.\" Do not pass user-supplied data through it.\n */\n static invalidInput(opts) {\n return new _NextlyError({\n code: \"INVALID_INPUT\",\n publicMessage: opts.message,\n logContext: opts.logContext\n });\n }\n static validation(opts) {\n return new _NextlyError({\n code: \"VALIDATION_ERROR\",\n publicMessage: \"Validation failed.\",\n publicData: { errors: opts.errors },\n cause: opts.cause,\n logContext: opts.logContext\n });\n }\n static conflict(opts) {\n return new _NextlyError({\n code: \"CONFLICT\",\n publicMessage: opts?.message ?? \"The resource has changed since you last loaded it. Please refresh and try again.\",\n cause: opts?.cause,\n logContext: { reason: opts?.reason, ...opts?.logContext }\n });\n }\n static duplicate(opts) {\n return new _NextlyError({\n code: \"DUPLICATE\",\n publicMessage: \"Resource already exists.\",\n logContext: opts?.logContext\n });\n }\n static rateLimited(opts) {\n return new _NextlyError({\n code: \"RATE_LIMITED\",\n publicMessage: \"Too many requests. Please try again later.\",\n publicData: opts?.retryAfterSeconds !== void 0 ? { retryAfterSeconds: opts.retryAfterSeconds } : void 0,\n logContext: opts?.logContext\n });\n }\n static internal(opts) {\n return new _NextlyError({\n code: \"INTERNAL_ERROR\",\n publicMessage: \"An unexpected error occurred.\",\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n // Accepts an optional `logMessage` override so callers (e.g. the health\n // route) can record a specific operator narrative (\"Health check failed\")\n // while the public message stays canonical per spec §13.8.5.\n static serviceUnavailable(opts) {\n return new _NextlyError({\n code: \"SERVICE_UNAVAILABLE\",\n publicMessage: opts?.publicMessage ?? \"Service unavailable. Please try again later.\",\n logMessage: opts?.logMessage,\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n /**\n * Convert a DbError (or arbitrary unknown thrown by the DB layer) to a\n * NextlyError with a generic public message and rich logContext. Used by\n * `withDbErrors` for auto-conversion (Pattern A) and by services that\n * catch DB errors at boundaries (Pattern B). Spec §8.2 mapping table.\n *\n * Never leaks DB driver text, constraint names, or table names into\n * `publicMessage`. All DB context goes into `logContext`. The original\n * DbError is preserved as `cause`.\n */\n static fromDatabaseError(error) {\n if (isDbError(error)) {\n const mapping = DB_ERROR_MAPPING[error.kind];\n const logContext = {\n dbKind: error.kind,\n dialect: error.dialect\n };\n if (error.code !== void 0) logContext.dbCode = error.code;\n if (error.meta !== void 0) logContext.meta = error.meta;\n return new _NextlyError({\n code: mapping.code,\n statusCode: mapping.statusCode,\n publicMessage: mapping.publicMessage,\n logMessage: \"Database error\",\n logContext,\n cause: error\n });\n }\n return new _NextlyError({\n code: \"INTERNAL_ERROR\",\n statusCode: 500,\n publicMessage: \"An unexpected error occurred.\",\n logMessage: \"Non-DbError passed to fromDatabaseError\",\n cause: error instanceof Error ? error : void 0,\n logContext: error instanceof Error ? void 0 : { value: String(error) }\n });\n }\n // ────────────────────────────────────────────────────────────────────\n // Type guards. Structural rather than `instanceof` so they survive\n // package-boundary mismatches (one consumer's NextlyError is a\n // different module instance from another's).\n // ────────────────────────────────────────────────────────────────────\n static is(err) {\n return hasBrand(err);\n }\n static isCode(err, code) {\n return hasBrand(err) && err.code === code;\n }\n static isNotFound(err) {\n return _NextlyError.isCode(err, \"NOT_FOUND\");\n }\n static isValidation(err) {\n return _NextlyError.isCode(err, \"VALIDATION_ERROR\");\n }\n static isAuthRequired(err) {\n return _NextlyError.isCode(err, \"AUTH_REQUIRED\");\n }\n static isForbidden(err) {\n return _NextlyError.isCode(err, \"FORBIDDEN\");\n }\n static isConflict(err) {\n return _NextlyError.isCode(err, \"CONFLICT\");\n }\n static isRateLimited(err) {\n return _NextlyError.isCode(err, \"RATE_LIMITED\");\n }\n};\n\nexport {\n DbError,\n isDbError,\n toDbError,\n safeCode,\n NEXTLY_ERROR_STATUS,\n statusToErrorCode,\n genericPublicMessage,\n NextlyError\n};\n","import {\n NextlyError\n} from \"./chunk-HJ5IQPOY.mjs\";\n\n// src/storage/read-errors.ts\nvar StorageReadTooLargeError = class extends NextlyError {\n constructor(path, maxBytes, size) {\n super({\n code: \"STORAGE_READ_TOO_LARGE\",\n publicMessage: \"The stored file is larger than the limit for this read.\",\n logContext: {\n path,\n maxBytes,\n ...size === void 0 ? {} : { size }\n }\n });\n this.path = path;\n this.maxBytes = maxBytes;\n this.size = size;\n }\n};\nfunction isStorageReadTooLarge(error) {\n return NextlyError.is(error) && error.code === \"STORAGE_READ_TOO_LARGE\";\n}\nvar StorageReadTimeoutError = class extends NextlyError {\n constructor(path, timeoutMs) {\n super({\n code: \"STORAGE_READ_TIMEOUT\",\n publicMessage: \"The stored file could not be read in time.\",\n logContext: { path, timeoutMs }\n });\n this.path = path;\n this.timeoutMs = timeoutMs;\n }\n};\nfunction isStorageReadTimeout(error) {\n return NextlyError.is(error) && error.code === \"STORAGE_READ_TIMEOUT\";\n}\n\nexport {\n StorageReadTooLargeError,\n isStorageReadTooLarge,\n StorageReadTimeoutError,\n isStorageReadTimeout\n};\n","import {\n StorageReadTimeoutError,\n StorageReadTooLargeError\n} from \"./chunk-W77AQUUQ.mjs\";\nimport {\n NextlyError\n} from \"./chunk-HJ5IQPOY.mjs\";\n\n// src/utils/validate-external-url.ts\nvar IPV4_RE = /^(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)$/;\nvar PRIVATE_IPV4_CIDRS = [\n \"0.0.0.0/8\",\n // RFC1122 \"this network\" / wildcard\n \"10.0.0.0/8\",\n // RFC1918\n \"100.64.0.0/10\",\n // RFC6598 CGNAT\n \"127.0.0.0/8\",\n // RFC1122 loopback\n \"169.254.0.0/16\",\n // RFC3927 link-local + AWS/GCP metadata\n \"172.16.0.0/12\",\n // RFC1918\n \"192.0.0.0/24\",\n // RFC6890 IETF protocol assignments\n \"192.0.2.0/24\",\n // RFC5737 documentation\n \"192.168.0.0/16\",\n // RFC1918\n \"198.18.0.0/15\",\n // RFC2544 benchmarking\n \"198.51.100.0/24\",\n // RFC5737 documentation\n \"203.0.113.0/24\",\n // RFC5737 documentation\n \"224.0.0.0/4\",\n // RFC5771 multicast\n \"240.0.0.0/4\"\n // RFC1112 reserved\n];\nvar CLOUD_METADATA_HOSTS = /* @__PURE__ */ new Set([\n \"metadata.google.internal\",\n \"metadata.googleapis.com\",\n \"metadata\"\n // GCP short form\n]);\nvar ExternalUrlError = class extends NextlyError {\n constructor(message, url) {\n super({\n code: \"EXTERNAL_URL_BLOCKED\",\n publicMessage: message,\n logContext: { url }\n });\n this.url = url;\n this.name = \"ExternalUrlError\";\n }\n};\nasync function validateExternalUrl(rawUrl, options = {}) {\n let parsed;\n try {\n parsed = new URL(rawUrl);\n } catch {\n throw new ExternalUrlError(\"Invalid URL\", rawUrl);\n }\n const hostname = parsed.hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n const isLocalhostHostname = hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"::1\";\n const baseProtocols = options.allowedProtocols ?? [\"https:\"];\n const protocols = options.allowLocalhost && isLocalhostHostname ? [...baseProtocols, \"http:\"] : baseProtocols;\n if (!protocols.includes(parsed.protocol)) {\n throw new ExternalUrlError(\n `Protocol ${parsed.protocol} not allowed (allowed: ${protocols.join(\", \")})`,\n rawUrl\n );\n }\n if (CLOUD_METADATA_HOSTS.has(hostname)) {\n throw new ExternalUrlError(\n `Cloud-metadata hostname rejected: ${parsed.hostname}`,\n rawUrl\n );\n }\n if (IPV4_RE.test(hostname)) {\n if (!isPublicIpv4(\n hostname,\n options.allowLocalhost === true && hostname === \"127.0.0.1\"\n )) {\n throw new ExternalUrlError(\n `Resolved to non-public IP: ${hostname}`,\n rawUrl\n );\n }\n return { url: parsed, pinnedIp: hostname, family: 4 };\n }\n if (hostname.includes(\":\")) {\n if (!isPublicIpv6(\n hostname,\n options.allowLocalhost === true && hostname === \"::1\"\n )) {\n throw new ExternalUrlError(\n `Resolved to non-public IP: ${hostname}`,\n rawUrl\n );\n }\n return { url: parsed, pinnedIp: hostname, family: 6 };\n }\n const { lookup } = await import(\"dns/promises\");\n let addresses;\n try {\n addresses = await lookup(hostname, { all: true });\n } catch (err) {\n throw new ExternalUrlError(\n `DNS lookup failed: ${err.message}`,\n rawUrl\n );\n }\n if (addresses.length === 0) {\n throw new ExternalUrlError(\"No IPs returned for host\", rawUrl);\n }\n for (const { address, family } of addresses) {\n const allow = options.allowLocalhost === true && isLocalhostHostname && family === 4;\n const ok = family === 4 ? isPublicIpv4(address, allow) : isPublicIpv6(address, allow);\n if (!ok) {\n throw new ExternalUrlError(\n `Resolved to non-public IP: ${address}`,\n rawUrl\n );\n }\n }\n const first = addresses[0];\n return {\n url: parsed,\n pinnedIp: first.address,\n family: first.family === 6 ? 6 : 4\n };\n}\nvar DEFAULT_MAX_RESPONSE_BYTES = 10 * 1024 * 1024;\nvar DEFAULT_TIMEOUT_MS = 3e4;\nvar SafeFetchError = class extends NextlyError {\n constructor(message, url, reason, status) {\n super({\n code: \"EXTERNAL_REQUEST_FAILED\",\n publicMessage: message,\n logContext: { url, reason }\n });\n this.url = url;\n this.reason = reason;\n this.status = status;\n this.name = \"SafeFetchError\";\n }\n};\nfunction createPinnedLookup(ip, family) {\n return (_hostname, options, callback) => {\n if (options && options.all) {\n callback(null, [{ address: ip, family }]);\n } else {\n callback(null, ip, family);\n }\n };\n}\nasync function safeFetch(rawUrl, options = {}) {\n const {\n allowLocalhost,\n allowedProtocols,\n method,\n headers,\n body,\n signal,\n maxResponseBytes = DEFAULT_MAX_RESPONSE_BYTES,\n timeoutMs = DEFAULT_TIMEOUT_MS\n } = options;\n const controller = new AbortController();\n const forwardAbort = () => controller.abort(signal?.reason);\n if (signal) {\n if (signal.aborted) controller.abort(signal.reason);\n else signal.addEventListener(\"abort\", forwardAbort, { once: true });\n }\n const timer = setTimeout(\n () => controller.abort(\n new SafeFetchError(`Request exceeded ${timeoutMs}ms`, rawUrl, \"timeout\")\n ),\n timeoutMs\n );\n try {\n const validated = await abortable(\n validateExternalUrl(rawUrl, { allowLocalhost, allowedProtocols }),\n controller.signal\n );\n return await pinnedFetch(validated, {\n method,\n headers,\n body,\n signal: controller.signal,\n maxResponseBytes\n });\n } finally {\n clearTimeout(timer);\n if (signal) signal.removeEventListener(\"abort\", forwardAbort);\n }\n}\nfunction abortError(signal) {\n const reason = signal.reason;\n if (reason instanceof Error) return reason;\n return new DOMException(\"The operation was aborted\", \"AbortError\");\n}\nfunction abortable(promise, signal) {\n if (signal.aborted) return Promise.reject(abortError(signal));\n let onAbort;\n const aborted = new Promise((_resolve, reject) => {\n onAbort = () => reject(abortError(signal));\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n return Promise.race([promise, aborted]).finally(\n () => signal.removeEventListener(\"abort\", onAbort)\n );\n}\nasync function pinnedFetch(validated, init) {\n const { url, pinnedIp, family } = validated;\n const httpMod = url.protocol === \"https:\" ? await import(\"https\") : await import(\"http\");\n const zlib = await import(\"zlib\");\n const lookup = createPinnedLookup(pinnedIp, family);\n const outHeaders = toOutgoingHeaders(init.headers);\n if (init.body != null) {\n delete outHeaders[\"transfer-encoding\"];\n outHeaders[\"content-length\"] = String(\n typeof init.body === \"string\" ? Buffer.byteLength(init.body) : init.body.byteLength\n );\n }\n return new Promise((resolve, reject) => {\n let settled = false;\n const settle = (fn) => {\n if (settled) return;\n settled = true;\n fn();\n };\n const failure = (err) => init.signal.aborted ? abortError(init.signal) : err;\n const req = httpMod.request(\n url,\n {\n method: init.method ?? \"GET\",\n headers: outHeaders,\n lookup,\n // Fresh socket per request so a pooled connection can't reuse a\n // differently-resolved address, and so the pinned lookup always runs.\n agent: false,\n // The combined deadline/caller signal aborts the request in flight.\n signal: init.signal\n },\n (res) => {\n const chunks = [];\n let received = 0;\n res.on(\"data\", (chunk) => {\n received += chunk.length;\n if (received > init.maxResponseBytes) {\n res.destroy();\n req.destroy();\n settle(\n () => reject(\n new SafeFetchError(\n `Response body exceeded ${init.maxResponseBytes} bytes`,\n url.href,\n \"response-too-large\",\n res.statusCode\n )\n )\n );\n return;\n }\n chunks.push(chunk);\n });\n res.on(\"end\", () => {\n const decoded = decodeBody(\n Buffer.concat(chunks),\n res.headers[\"content-encoding\"],\n zlib,\n init.maxResponseBytes,\n url.href,\n res.statusCode\n );\n if (decoded instanceof SafeFetchError) {\n settle(() => reject(decoded));\n return;\n }\n settle(\n () => resolve(toWhatwgResponse(res, decoded.body, decoded.decoded))\n );\n });\n res.on(\"error\", (err) => settle(() => reject(failure(err))));\n }\n );\n req.on(\"error\", (err) => settle(() => reject(failure(err))));\n if (!req.destroyed) {\n if (init.body != null) req.write(init.body);\n req.end();\n }\n });\n}\nfunction toOutgoingHeaders(headers) {\n const out = {};\n if (!headers) return out;\n const add = (rawKey, value) => {\n const key = rawKey.toLowerCase();\n if (key === \"host\") return;\n const existing = out[key];\n out[key] = existing === void 0 ? value : [].concat(existing, value);\n };\n if (headers instanceof Headers) {\n headers.forEach((value, key) => add(key, value));\n } else if (Array.isArray(headers)) {\n for (const [key, value] of headers) add(key, value);\n } else {\n for (const [key, value] of Object.entries(headers)) add(key, value);\n }\n return out;\n}\nfunction toWhatwgResponse(res, body, stripContentHeaders) {\n const headers = new Headers();\n for (const [key, value] of Object.entries(res.headers)) {\n if (value == null) continue;\n const lower = key.toLowerCase();\n if (stripContentHeaders && (lower === \"content-encoding\" || lower === \"content-length\")) {\n continue;\n }\n const values = Array.isArray(value) ? value : [value];\n for (const v of values) {\n try {\n headers.append(key, v);\n } catch {\n }\n }\n }\n const raw = res.statusCode ?? 502;\n const status = raw >= 200 && raw <= 599 ? raw : 502;\n const nullBody = status === 204 || status === 205 || status === 304;\n const bytes = new Uint8Array(body.byteLength);\n bytes.set(body);\n return new Response(nullBody ? null : bytes, {\n status,\n statusText: res.statusMessage ?? \"\",\n headers\n });\n}\nfunction decodeBody(buf, encoding, zlib, cap, url, status) {\n if (!encoding) return { body: buf, decoded: false };\n if (buf.length === 0) return { body: buf, decoded: true };\n const layers = encoding.split(\",\").map((e) => e.trim().toLowerCase()).filter(Boolean);\n const opts = { maxOutputLength: cap };\n let current = buf;\n let decoded = false;\n try {\n for (let i = layers.length - 1; i >= 0; i--) {\n const enc = layers[i];\n if (enc === \"identity\") continue;\n if (enc === \"gzip\" || enc === \"x-gzip\") {\n current = zlib.gunzipSync(current, opts);\n } else if (enc === \"br\") {\n current = zlib.brotliDecompressSync(current, opts);\n } else if (enc === \"deflate\") {\n try {\n current = zlib.inflateSync(current, opts);\n } catch (inflateErr) {\n if (errorCode(inflateErr) === \"ERR_BUFFER_TOO_LARGE\")\n throw inflateErr;\n current = zlib.inflateRawSync(current, opts);\n }\n } else {\n if (decoded) {\n return new SafeFetchError(\n `Cannot fully decode content-encoding \"${encoding}\"`,\n url,\n \"decode-failed\",\n status\n );\n }\n return { body: buf, decoded: false };\n }\n decoded = true;\n }\n return { body: current, decoded };\n } catch (err) {\n const tooLarge = errorCode(err) === \"ERR_BUFFER_TOO_LARGE\";\n return new SafeFetchError(\n tooLarge ? `Decoded ${encoding} response body exceeded the size cap` : `Failed to decode ${encoding} response body`,\n url,\n tooLarge ? \"response-too-large\" : \"decode-failed\",\n status\n );\n }\n}\nfunction errorCode(err) {\n if (err != null && typeof err === \"object\" && \"code\" in err) {\n const code = err.code;\n return typeof code === \"string\" ? code : void 0;\n }\n return void 0;\n}\nfunction ipv4ToInt(ip) {\n const parts = ip.split(\".\");\n if (parts.length !== 4) return null;\n let acc = 0;\n for (const p of parts) {\n const n = Number(p);\n if (!Number.isInteger(n) || n < 0 || n > 255) return null;\n acc = acc << 8 | n;\n }\n return acc >>> 0;\n}\nfunction isIpv4InCidr(intIp, cidr) {\n const [addr, prefixRaw] = cidr.split(\"/\");\n const intCidr = ipv4ToInt(addr);\n if (intCidr === null) return false;\n const prefix = Number(prefixRaw);\n if (!Number.isInteger(prefix) || prefix < 0 || prefix > 32) return false;\n const mask = prefix === 0 ? 0 : -1 >>> 32 - prefix << 32 - prefix;\n return (intIp & mask) >>> 0 === (intCidr & mask) >>> 0;\n}\nfunction isPublicIpv4(addr, allowLoopback) {\n const intIp = ipv4ToInt(addr);\n if (intIp === null) return false;\n if (allowLoopback && addr === \"127.0.0.1\") return true;\n for (const cidr of PRIVATE_IPV4_CIDRS) {\n if (isIpv4InCidr(intIp, cidr)) return false;\n }\n return true;\n}\nfunction mappedIpv4(lower) {\n const dotted = lower.match(/^::ffff:(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})$/);\n if (dotted) return dotted[1];\n const hex = lower.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);\n if (hex) {\n const hi = parseInt(hex[1], 16);\n const lo = parseInt(hex[2], 16);\n return [hi >> 8, hi & 255, lo >> 8, lo & 255].join(\".\");\n }\n return null;\n}\nfunction isPublicIpv6(addr, allowLoopback) {\n const lower = addr.toLowerCase();\n if (allowLoopback && lower === \"::1\") return true;\n const mapped = mappedIpv4(lower);\n if (mapped) {\n return isPublicIpv4(mapped, allowLoopback);\n }\n if (lower === \"::\" || lower === \"::1\") return false;\n const firstHextet = lower.split(\":\")[0] || \"\";\n if (firstHextet.startsWith(\"fc\") || firstHextet.startsWith(\"fd\"))\n return false;\n if (firstHextet.startsWith(\"fe8\") || firstHextet.startsWith(\"fe9\"))\n return false;\n if (firstHextet.startsWith(\"fea\") || firstHextet.startsWith(\"feb\"))\n return false;\n if (firstHextet.startsWith(\"ff\")) return false;\n return true;\n}\n\n// src/storage/fetch-stored-bytes.ts\nasync function fetchStoredBytes(url, context, label, options, signal) {\n let response;\n try {\n response = await safeFetch(url, {\n ...options?.maxBytes === void 0 ? {} : { maxResponseBytes: options.maxBytes },\n /*\n * A caller's signal REPLACES the deadline rather than joining it.\n *\n * These adapters look the object's address up before fetching it, and\n * that lookup can stall too. Starting a fresh timer here would give the\n * fetch its own full budget on top of however long the lookup took, so a\n * read could outlive the deadline the caller was told applied — by\n * roughly double. One signal begun before the lookup governs both phases.\n */\n ...signal !== void 0 ? { signal } : options?.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs }\n });\n } catch (error) {\n const verdict = classifyFetchFailure(error);\n if (verdict === \"absent\") return null;\n if (verdict === \"oversized\") {\n throw new StorageReadTooLargeError(\n context,\n resolveReadBounds(options).maxBytes\n );\n }\n throw error;\n }\n if (response.status === 404) return null;\n if (!response.ok) {\n throw NextlyError.internal({\n logContext: {\n service: label,\n path: context,\n status: response.status,\n statusText: response.statusText\n }\n });\n }\n return Buffer.from(await response.arrayBuffer());\n}\nfunction classifyFetchFailure(error) {\n if (!(error instanceof SafeFetchError)) return \"unknown\";\n if (error.status === 404) return \"absent\";\n const successful = error.status !== void 0 && error.status >= 200 && error.status < 300;\n return error.reason === \"response-too-large\" && successful ? \"oversized\" : \"unknown\";\n}\nvar DEFAULT_READ_TIMEOUT_MS = DEFAULT_TIMEOUT_MS;\nvar DEFAULT_READ_MAX_BYTES = DEFAULT_MAX_RESPONSE_BYTES;\nfunction resolveReadBounds(options) {\n return {\n maxBytes: options?.maxBytes ?? DEFAULT_READ_MAX_BYTES,\n timeoutMs: options?.timeoutMs ?? DEFAULT_READ_TIMEOUT_MS\n };\n}\nfunction deadlineSignal(timeoutMs, context) {\n const controller = new AbortController();\n const timer = setTimeout(() => {\n controller.abort(new StorageReadTimeoutError(context, timeoutMs));\n }, timeoutMs);\n timer.unref?.();\n return {\n signal: controller.signal,\n /*\n * Called once the read has settled, whichever way it went. `unref` only\n * stops a pending timer holding the process open; it still sits on the\n * timer heap retaining the controller and the path, so a server doing a\n * thousand reads a second keeps thirty seconds of them alive and then runs\n * a thousand aborts that answer nobody.\n */\n cancel: () => {\n clearTimeout(timer);\n }\n };\n}\nasync function withDeadline(work, signal) {\n if (signal === void 0) return await work;\n return await Promise.race([\n work,\n new Promise((_, reject) => {\n if (signal.aborted) {\n reject(signal.reason);\n return;\n }\n signal.addEventListener(\"abort\", () => reject(signal.reason), {\n once: true\n });\n })\n ]);\n}\n\nexport {\n ExternalUrlError,\n validateExternalUrl,\n SafeFetchError,\n safeFetch,\n fetchStoredBytes,\n classifyFetchFailure,\n DEFAULT_READ_TIMEOUT_MS,\n DEFAULT_READ_MAX_BYTES,\n resolveReadBounds,\n deadlineSignal,\n withDeadline\n};\n","/**\n * Vercel Blob Storage Adapter\n *\n * Stores files on Vercel Blob Storage, a globally distributed object storage\n * service powered by Cloudflare R2. Optimized for Vercel deployments with\n * built-in CDN distribution.\n *\n * Features:\n * - Globally distributed CDN-backed storage\n * - Automatic file management with unique filenames\n * - Token-based authentication\n * - Client-side upload support (via handleUpload API)\n * - Serverless-friendly (no filesystem access required)\n *\n * @example Basic usage\n * ```typescript\n * const adapter = new VercelBlobStorageAdapter({\n * token: process.env.BLOB_READ_WRITE_TOKEN,\n * collections: { media: true }\n * });\n *\n * const result = await adapter.upload(buffer, {\n * filename: 'photo.jpg',\n * mimeType: 'image/jpeg'\n * });\n * // result.url: \"https://abc123.public.blob.vercel-storage.com/photo-xyz.jpg\"\n * ```\n */\n\nimport { put, del, head, list, BlobNotFoundError } from \"@vercel/blob\";\nimport { NextlyError } from \"nextly/errors\";\nimport type {\n IStorageAdapter,\n UploadOptions,\n UploadResult,\n StorageAdapterInfo,\n ClientUploadData,\n FileMetadata,\n BulkDeleteResult,\n StorageReadOptions,\n} from \"nextly/storage\";\nimport {\n fetchStoredBytes,\n DEFAULT_READ_TIMEOUT_MS,\n} from \"nextly/storage/fetch-stored-bytes\";\n\nimport type {\n VercelBlobStorageConfig,\n ResolvedVercelBlobConfig,\n} from \"./types\";\n\n// ============================================================\n// Vercel Blob Storage Adapter\n// ============================================================\n\n/**\n * Vercel Blob Storage Adapter\n *\n * Implements the IStorageAdapter interface for Vercel Blob Storage.\n * Provides file upload, deletion, existence checks, and metadata retrieval.\n */\nexport class VercelBlobStorageAdapter implements IStorageAdapter {\n private resolvedConfig: ResolvedVercelBlobConfig;\n\n /**\n * Create a new Vercel Blob storage adapter.\n *\n * @param config - Vercel Blob storage configuration\n * @throws Error if token is not provided\n */\n constructor(private config: VercelBlobStorageConfig) {\n // Resolve token from config or environment\n const token = config.token || process.env.BLOB_READ_WRITE_TOKEN || \"\";\n\n if (!token) {\n throw new Error(\n \"@nextly/storage-vercel-blob: token is required.\\n\\n\" +\n \"Either set the BLOB_READ_WRITE_TOKEN environment variable or pass token in config.\\n\" +\n \"Get your token from: Vercel Dashboard > Storage > Blob > Tokens\"\n );\n }\n\n // Resolve config with defaults\n this.resolvedConfig = {\n token,\n addRandomSuffix: config.addRandomSuffix ?? true,\n cacheControlMaxAge: config.cacheControlMaxAge ?? 31536000,\n access: config.access ?? \"public\",\n storeId: config.storeId,\n allowOverwrite: config.allowOverwrite ?? false,\n multipartThreshold: config.multipartThreshold ?? 5 * 1024 * 1024, // 5MB\n };\n }\n\n // ============================================================\n // Core IStorageAdapter Methods\n // ============================================================\n\n /**\n * Upload file to Vercel Blob.\n *\n * Files are stored with globally distributed CDN backing.\n * By default, a random suffix is added to prevent filename collisions.\n *\n * @param buffer - File content as Buffer\n * @param options - Upload options (filename, mimeType, folder, collection)\n * @returns Upload result with URL and storage path\n */\n async upload(buffer: Buffer, options: UploadOptions): Promise<UploadResult> {\n const mimeType = (options.contentType || options.mimeType || \"\")\n .toLowerCase()\n .trim();\n const filename = (options.filename || \"\").toLowerCase();\n const ext = filename.includes(\".\")\n ? filename.slice(filename.lastIndexOf(\".\") + 1)\n : \"\";\n const isHtml =\n mimeType === \"text/html\" ||\n mimeType === \"application/xhtml+xml\" ||\n ext === \"html\" ||\n ext === \"htm\" ||\n ext === \"xhtml\";\n // HTML stays unconditionally rejected. The `downloadUrl` trick that\n // makes SVG safe (see below) doesn't help HTML — a downloaded HTML\n // file is still a usable XSS vector when opened from disk, and\n // Vercel Blob has no equivalent of `Content-Security-Policy` to\n // defang it.\n if (isHtml) {\n throw NextlyError.validation({\n errors: [\n {\n path: \"file\",\n code: \"UNSUPPORTED_FOR_BACKEND\",\n message:\n \"HTML files cannot be hosted on Vercel Blob. Use the S3 or R2 adapter, or upload as another format.\",\n },\n ],\n logContext: {\n adapter: \"vercel-blob\",\n claimedMimeType: options.mimeType,\n reason: \"vercel-blob-rejects-html\",\n filename: options.filename,\n },\n });\n }\n\n const isSvg =\n mimeType === \"image/svg+xml\" || ext === \"svg\" || ext === \"svgz\";\n\n const pathname = this.buildPathname(options.filename, options.folder);\n\n const result = await put(pathname, buffer, {\n access: this.resolvedConfig.access,\n token: this.resolvedConfig.token,\n contentType: options.contentType || options.mimeType,\n addRandomSuffix: this.resolvedConfig.addRandomSuffix,\n cacheControlMaxAge: this.resolvedConfig.cacheControlMaxAge,\n });\n\n // SVGs are served via Vercel Blob's `downloadUrl` (the same URL with\n // `?download=1` appended) so direct top-level navigation forces an\n // attachment download instead of rendering. `<img src>` ignores the\n // `Content-Disposition` header, so legitimate inline rendering still\n // works. The `@vercel/blob` SDK has no `contentDisposition` input\n // option on `put()`, so this query-param-driven approach is the\n // supported mechanism. Caller is responsible for sanitizing SVG\n // contents upstream (handled by `upload-validation`).\n const url =\n isSvg && options.contentDisposition === \"attachment\"\n ? result.downloadUrl\n : result.url;\n\n return {\n url,\n path: result.url,\n };\n }\n\n /**\n * Delete file from Vercel Blob.\n *\n * @param filePath - Full blob URL to delete\n */\n async delete(filePath: string): Promise<void> {\n await del(filePath, {\n token: this.resolvedConfig.token,\n });\n }\n\n /**\n * Delete multiple files from Vercel Blob in chunked batches.\n *\n * Processes deletions in chunks of 10 concurrent calls using Promise.allSettled,\n * collecting successes and failures without short-circuiting.\n *\n * @param filePaths - Array of full blob URLs to delete\n * @returns BulkDeleteResult with successful and failed arrays\n */\n async bulkDelete(filePaths: string[]): Promise<BulkDeleteResult> {\n const successful: string[] = [];\n const failed: Array<{ filePath: string; error: string }> = [];\n const chunkSize = 10;\n\n for (let i = 0; i < filePaths.length; i += chunkSize) {\n const chunk = filePaths.slice(i, i + chunkSize);\n const results = await Promise.allSettled(\n chunk.map(fp => del(fp, { token: this.resolvedConfig.token }))\n );\n\n results.forEach((result, idx) => {\n const fp = chunk[idx];\n if (result.status === \"fulfilled\") {\n successful.push(fp);\n } else {\n failed.push({\n filePath: fp,\n error:\n result.reason instanceof Error\n ? result.reason.message\n : String(result.reason),\n });\n }\n });\n }\n\n return { successful, failed };\n }\n\n /**\n * Check if file exists in Vercel Blob.\n *\n * Uses the head() function which is efficient for existence checks.\n *\n * @param filePath - Full blob URL to check\n * @returns true if file exists, false otherwise\n */\n async exists(filePath: string): Promise<boolean> {\n try {\n await head(filePath, {\n token: this.resolvedConfig.token,\n });\n return true;\n } catch {\n // Vercel Blob throws an error if the blob doesn't exist\n return false;\n }\n }\n\n /**\n * Read a stored blob back as bytes, or `null` when it is not there.\n *\n * A NETWORK round trip, unlike the local adapter's disk read, because the\n * bytes live on Vercel's CDN and there is no other way to reach them. That\n * cost is the reason a caller serving these from its own origin has to cache:\n * the privacy rule that forces same-origin serving does not also make the\n * fetch free, and an uncached proxy pays it on every request.\n *\n * The URL is taken from `head` rather than assembled from `filePath`,\n * because a blob's address is issued by the service — it carries a random\n * suffix this adapter never chose — so deriving one here would be guessing at\n * a string another system owns.\n *\n * `null` for a missing blob rather than a throw, matching {@link exists}.\n *\n * @param filePath - Blob path/key\n * @returns The blob's bytes, or `null` when it does not exist\n */\n async read(\n filePath: string,\n options?: StorageReadOptions\n ): Promise<Buffer | null> {\n /*\n * ONE deadline for both phases, started before the lookup.\n *\n * `head` can stall exactly as the fetch can, and it runs first — so a\n * deadline that begins only at the fetch leaves the lookup unbounded and\n * the read can outlive what the caller was promised. Created here and\n * handed to both.\n *\n * ALWAYS, not only when the caller named a timeout. `safeFetch` applies a\n * default deadline of its own, so a caller stating none was still bounded\n * for the fetch and unbounded for the lookup — which is the commonest call,\n * the email path among them, since it supplies only a byte cap. The default\n * comes from the same constant `safeFetch` uses rather than being restated.\n */\n const deadline = AbortSignal.timeout(\n options?.timeoutMs ?? DEFAULT_READ_TIMEOUT_MS\n );\n\n let target: string;\n try {\n const meta = await head(filePath, {\n token: this.resolvedConfig.token,\n abortSignal: deadline,\n });\n target = meta.downloadUrl ?? meta.url;\n } catch (error: unknown) {\n /*\n * ONLY the not-found class becomes `null`. `head` also rejects for an\n * expired token, a suspended or missing store, an aborted request and a\n * plain network failure, and every one of those says nothing about\n * whether the blob exists. Catching them all reports an outage as a\n * deletion, which a caller may act on by writing a replacement over a\n * file that is still there.\n *\n * Identified by the CLASS the SDK exports rather than by matching the\n * message, because the message is prose this package does not own.\n */\n if (error instanceof BlobNotFoundError) return null;\n throw error;\n }\n\n /*\n * OUTSIDE the catch above, deliberately, and through the shared helper so\n * that separation is stated once rather than in each adapter. A failed\n * fetch of a blob whose metadata just resolved is a transport failure\n * rather than an absence, and folding it into `null` would report a\n * network outage as a deleted file.\n */\n return await fetchStoredBytes(\n target,\n filePath,\n \"Vercel Blob\",\n options,\n deadline\n );\n }\n\n /**\n * Get public URL for Vercel Blob file.\n *\n * Vercel Blob paths ARE the public URLs - they're already full HTTPS URLs\n * with CDN distribution.\n *\n * @param filePath - Full blob URL\n * @returns The same URL (Vercel Blob paths are already public URLs)\n */\n getPublicUrl(filePath: string): string {\n // Vercel Blob paths are already full URLs\n return filePath;\n }\n\n /**\n * Get storage type identifier.\n */\n getType(): \"vercel-blob\" {\n return \"vercel-blob\";\n }\n\n // ============================================================\n // Optional IStorageAdapter Methods\n // ============================================================\n\n /**\n * Get adapter info including capabilities.\n *\n * @returns Adapter info with type, name, and capability flags\n */\n getInfo(): StorageAdapterInfo {\n return {\n type: \"vercel-blob\",\n name: \"VercelBlobStorageAdapter\",\n supportsSignedUrls: false, // Vercel Blob URLs are public by default\n supportsClientUploads: true, // Via handleUpload API\n };\n }\n\n /**\n * Get file metadata from Vercel Blob.\n *\n * Retrieves file information including size, content type, and upload date.\n *\n * @param filePath - Full blob URL\n * @returns File metadata or null if file not found\n */\n async getMetadata(filePath: string): Promise<FileMetadata | null> {\n try {\n const result = await head(filePath, {\n token: this.resolvedConfig.token,\n });\n\n // Extract filename from pathname\n const filename = result.pathname.split(\"/\").pop() || result.pathname;\n\n return {\n id: filePath,\n filename,\n originalFilename: filename,\n mimeType: result.contentType,\n size: result.size,\n url: result.url,\n createdAt: result.uploadedAt.toISOString(),\n };\n } catch {\n // File not found\n return null;\n }\n }\n\n /**\n * Generate pre-signed URL for client-side uploads.\n *\n * Vercel Blob uses a different pattern for client uploads - they require\n * the handleUpload API which handles token generation server-side.\n *\n * This method is not implemented because Vercel Blob's client upload flow\n * requires server-side route handlers with handleUpload().\n *\n * @see https://vercel.com/docs/storage/vercel-blob/client-upload\n * @throws Error always - client uploads require handleUpload API\n */\n getPresignedUploadUrl(\n _key: string,\n _mimeType: string,\n _expiresIn?: number\n ): Promise<ClientUploadData> {\n return Promise.reject(\n new Error(\n \"@nextly/storage-vercel-blob: Client uploads require the handleUpload API.\\n\\n\" +\n \"Vercel Blob uses a different pattern for client-side uploads that involves:\\n\" +\n \"1. A server-side route handler with handleUpload()\\n\" +\n \"2. The @vercel/blob/client upload() function\\n\\n\" +\n \"See: https://vercel.com/docs/storage/vercel-blob/client-upload\\n\\n\" +\n \"For server-side uploads, use the standard upload() method instead.\"\n )\n );\n }\n\n // ============================================================\n // Additional Methods\n // ============================================================\n\n /**\n * List blobs with optional prefix filter.\n *\n * Useful for browsing or batch operations on stored files.\n *\n * @param prefix - Optional prefix to filter results\n * @param options - List options (limit, cursor)\n * @returns List of blob metadata\n */\n async listBlobs(\n prefix?: string,\n options?: { limit?: number; cursor?: string }\n ): Promise<{\n blobs: Array<{\n url: string;\n pathname: string;\n size: number;\n uploadedAt: Date;\n }>;\n hasMore: boolean;\n cursor?: string;\n }> {\n const result = await list({\n token: this.resolvedConfig.token,\n prefix,\n limit: options?.limit,\n cursor: options?.cursor,\n });\n\n return {\n blobs: result.blobs.map(blob => ({\n url: blob.url,\n pathname: blob.pathname,\n size: blob.size,\n uploadedAt: blob.uploadedAt,\n })),\n hasMore: result.hasMore,\n cursor: result.cursor,\n };\n }\n\n // ============================================================\n // Helper Methods\n // ============================================================\n\n /**\n * Build pathname for Vercel Blob upload.\n *\n * Creates pathname in format: {folder}/{filename}\n * If no folder is provided, uses the filename directly.\n *\n * @param filename - Original filename (will be sanitized)\n * @param folder - Optional folder/prefix for organizing uploads\n * @returns Generated pathname\n * @throws Error if folder fails sanitization\n */\n private buildPathname(filename: string, folder?: string): string {\n const sanitized = this.sanitizeFilename(filename);\n if (!folder) return sanitized;\n return `${this.sanitizeFolder(folder)}/${sanitized}`;\n }\n\n /**\n * Sanitize filename to prevent path traversal issues.\n *\n * @param filename - Original filename\n * @returns Sanitized filename\n */\n private sanitizeFilename(filename: string): string {\n const basename = filename.split(/[/\\\\]/).pop() || filename;\n return basename.replace(/[^a-zA-Z0-9._-]/g, \"-\");\n }\n\n /**\n * Reject folder values that would let a caller\n * escape the configured prefix via path traversal or weird\n * separators. Vercel Blob is flat-keyed so `/` is just part of the\n * pathname, but an attacker who controls `folder` could still:\n *\n * - Use `..` to chain a relative-traversal-style key.\n * - Use `\\` (Windows separator) to confuse downstream tooling.\n * - Use control chars / null bytes to truncate the key.\n * - Use a leading `/` to look like an absolute path.\n *\n * Internal `/` segments stay allowed because callers legitimately\n * use nested folders (`docs/2026/...`); a leading `/`, empty\n * segments (`docs//x`), or `..` segments are rejected.\n *\n * @throws Error with a stable message so the storage facade can\n * surface a 400 instead of a 500.\n */\n private sanitizeFolder(folder: string): string {\n const trimmed = folder.replace(/\\/+$/, \"\"); // tolerate one trailing `/`\n if (!trimmed) {\n throw new Error(\"Folder must be a non-empty string.\");\n }\n // eslint-disable-next-line no-control-regex -- the whole point is to reject control chars\n if (/[\\\\\\0\\x01-\\x1f\\x7f]/.test(trimmed)) {\n throw new Error(\n \"Folder contains forbidden characters (backslash, control chars, or null bytes).\"\n );\n }\n if (trimmed.startsWith(\"/\")) {\n throw new Error(\"Folder must not start with `/`.\");\n }\n const segments = trimmed.split(\"/\");\n for (const segment of segments) {\n if (segment === \"\") {\n throw new Error(\"Folder must not contain empty segments (`//`).\");\n }\n if (segment === \"..\") {\n throw new Error(\"Folder must not contain `..` segments.\");\n }\n }\n return trimmed;\n }\n\n // ============================================================\n // Public Accessors\n // ============================================================\n\n /**\n * Get the configured token (masked for logging).\n */\n getTokenMasked(): string {\n const token = this.resolvedConfig.token;\n if (token.length <= 8) return \"****\";\n return `${token.slice(0, 4)}...${token.slice(-4)}`;\n }\n\n /**\n * Check if random suffix is enabled.\n */\n hasRandomSuffix(): boolean {\n return this.resolvedConfig.addRandomSuffix;\n }\n\n /**\n * Get configured cache control max age.\n */\n getCacheControlMaxAge(): number {\n return this.resolvedConfig.cacheControlMaxAge;\n }\n}\n","/**\n * Vercel Blob Storage Plugin\n *\n * Factory function that creates a storage plugin for Vercel Blob Storage.\n * Returns a StoragePlugin that can be registered with MediaStorage.\n *\n * @example Basic usage\n * ```typescript\n * import { vercelBlobStorage } from '@nextly/storage-vercel-blob'\n * import { defineConfig } from 'nextly/config'\n *\n * export default defineConfig({\n * storage: [\n * vercelBlobStorage({\n * token: process.env.BLOB_READ_WRITE_TOKEN,\n * collections: {\n * media: true\n * }\n * })\n * ]\n * })\n * ```\n *\n * @example With client uploads (recommended for Vercel)\n * ```typescript\n * vercelBlobStorage({\n * collections: {\n * media: {\n * clientUploads: true // Bypass 4.5MB serverless limit\n * }\n * }\n * })\n * ```\n *\n * @example With collection-specific configuration\n * ```typescript\n * vercelBlobStorage({\n * addRandomSuffix: true,\n * cacheControlMaxAge: 86400, // 1 day\n * collections: {\n * // Simple enable with defaults\n * media: true,\n *\n * // Full configuration\n * documents: {\n * prefix: 'docs/',\n * addRandomSuffix: false,\n * allowOverwrite: true\n * }\n * }\n * })\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { StoragePlugin, ClientUploadData } from \"nextly/storage\";\n\nimport { VercelBlobStorageAdapter } from \"./adapter\";\nimport type { VercelBlobStorageConfig } from \"./types\";\n\n// ============================================================\n// Plugin Factory Function\n// ============================================================\n\n/**\n * Create a Vercel Blob storage plugin for Nextly.\n *\n * This factory function creates a StoragePlugin that can be added to\n * the `storage` array in `nextly.config.ts`. Vercel Blob is optimized\n * for Vercel deployments with:\n *\n * - Global CDN distribution\n * - Simple token-based authentication\n * - Client-side upload support (via handleUpload API)\n * - Automatic file management\n *\n * @param config - Vercel Blob storage configuration\n * @returns A StoragePlugin that MediaStorage can register\n *\n * @throws Error if token is not provided (via adapter)\n */\nexport function vercelBlobStorage(\n config: VercelBlobStorageConfig\n): StoragePlugin {\n // Handle disabled plugin\n // When disabled, return a plugin with no collections and null adapter\n // MediaStorage.registerPlugin() checks for null adapter and skips registration\n if (config.enabled === false) {\n return {\n name: \"vercel-blob-storage\",\n type: \"vercel-blob\",\n collections: {},\n adapter: null as unknown as StoragePlugin[\"adapter\"],\n };\n }\n\n // Create the Vercel Blob adapter\n // Adapter constructor validates required config (token)\n const adapter = new VercelBlobStorageAdapter(config);\n\n // Build and return the plugin\n const plugin: StoragePlugin = {\n name: \"vercel-blob-storage\",\n type: \"vercel-blob\",\n collections: config.collections,\n adapter,\n\n /**\n * Generate upload URL for client-side uploads.\n *\n * Note: Vercel Blob uses a different pattern for client uploads.\n * Instead of pre-signed URLs, it uses the handleUpload() API which\n * requires server-side route handlers.\n *\n * This method throws an error explaining the correct approach.\n *\n * @see https://vercel.com/docs/storage/vercel-blob/client-upload\n */\n getClientUploadUrl(\n _filename: string,\n _mimeType: string,\n _collection: string\n ): Promise<ClientUploadData> {\n // Vercel Blob doesn't use pre-signed URLs like S3\n // Instead, it requires using the handleUpload API with @vercel/blob/client\n return Promise.reject(\n new Error(\n \"@nextly/storage-vercel-blob: Client uploads require the handleUpload API.\\n\\n\" +\n \"Vercel Blob uses a different pattern than S3 for client-side uploads:\\n\\n\" +\n \"1. Create a server-side route handler with handleUpload()\\n\" +\n \"2. Use upload() from @vercel/blob/client on the frontend\\n\\n\" +\n \"See: https://vercel.com/docs/storage/vercel-blob/client-upload\"\n )\n );\n },\n\n /**\n * Get signed download URL for file access.\n *\n * Note: Vercel Blob URLs are public by default and do not support\n * signed/temporary URLs. All uploaded blobs are accessible via their\n * public URL.\n *\n * @param path - Storage path (full blob URL)\n * @returns The same URL (Vercel Blob URLs are public)\n */\n getSignedDownloadUrl(path: string): Promise<string> {\n // Vercel Blob URLs are public by default\n // No signed URL support - just return the public URL\n return Promise.resolve(path);\n },\n };\n\n return plugin;\n}\n","/**\n * @nextly/storage-vercel-blob\n *\n * Vercel Blob storage adapter for Nextly CMS.\n * Optimized for Vercel deployments with client-side upload support\n * to bypass serverless function size limits (4.5MB).\n *\n * @example Basic usage\n * ```typescript\n * import { vercelBlobStorage } from '@nextly/storage-vercel-blob'\n * import { defineConfig } from 'nextly/config'\n *\n * export default defineConfig({\n * storage: [\n * vercelBlobStorage({\n * token: process.env.BLOB_READ_WRITE_TOKEN,\n * collections: {\n * media: true\n * }\n * })\n * ]\n * })\n * ```\n *\n * @example With client uploads (recommended for Vercel)\n * ```typescript\n * vercelBlobStorage({\n * collections: {\n * media: {\n * clientUploads: true // Bypass 4.5MB serverless limit\n * }\n * }\n * })\n * ```\n *\n * @packageDocumentation\n */\n\n// ============================================================\n// Vercel Blob Storage Plugin Export (Primary API)\n// ============================================================\n\nexport { vercelBlobStorage } from \"./plugin\";\n\n// ============================================================\n// Vercel Blob Storage Adapter Export\n// ============================================================\n\nexport { VercelBlobStorageAdapter } from \"./adapter\";\n\n// ============================================================\n// Vercel Blob Types Export\n// ============================================================\n\nexport type {\n VercelBlobStorageConfig,\n VercelBlobCollectionConfig,\n VercelBlobCollectionStorageMap,\n ResolvedVercelBlobConfig,\n} from \"./types\";\n\n// ============================================================\n// Package Metadata\n// ============================================================\n\nexport const PACKAGE_NAME = \"@nextly/storage-vercel-blob\";\nexport const PACKAGE_VERSION = \"0.1.0\";\n"]}
1
+ {"version":3,"sources":["../../nextly/dist/chunk-IAZJNA2U.mjs","../../nextly/dist/chunk-T3OVIJZM.mjs","../../nextly/dist/chunk-YGE6AGZG.mjs","../src/adapter.ts","../src/plugin.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["// src/database/errors.ts\nvar DbError = class extends Error {\n kind;\n dialect;\n code;\n meta;\n cause;\n constructor(args) {\n super(args.message);\n this.name = \"DbError\";\n this.kind = args.kind;\n this.dialect = args.dialect;\n this.code = args.code;\n this.meta = args.meta;\n this.cause = args.cause;\n }\n};\nfunction isDbError(err) {\n if (!err || typeof err !== \"object\") return false;\n const obj = err;\n return obj.name === \"DbError\" && typeof obj.kind === \"string\";\n}\nfunction toDbError(dialect, error, meta) {\n if (isDbError(error)) return error;\n const code = safeCode(error);\n const rawMsg = error != null && typeof error === \"object\" && \"message\" in error ? error.message : void 0;\n const message = typeof rawMsg === \"string\" ? rawMsg : \"Database error\";\n let kind = \"internal\";\n switch (dialect) {\n case \"postgresql\":\n kind = mapPostgresCodeToKind(code);\n break;\n case \"mysql\":\n kind = mapMySqlCodeToKind(code);\n break;\n case \"sqlite\":\n kind = mapSqliteCodeToKind(code);\n break;\n }\n if ((dialect === \"mysql\" || dialect === \"sqlite\") && (kind === \"constraint\" || kind === \"internal\") && isLikelyUniqueViolationMessage(dialect, message)) {\n kind = \"unique-violation\";\n }\n if (kind === \"internal\" && code) {\n const c = code.toUpperCase();\n if (c === \"ECONNRESET\" || c.includes(\"PROTOCOL_CONNECTION_LOST\"))\n kind = \"connection-lost\";\n else if (c === \"ETIMEDOUT\") kind = \"timeout\";\n }\n return new DbError({ message, kind, dialect, code, meta, cause: error });\n}\nfunction safeCode(error) {\n if (!error || typeof error !== \"object\") return void 0;\n const e = error;\n let c = e.code ?? e.sqlState ?? e.state ?? e.errno ?? void 0;\n if (!c && typeof e.originalError?.code === \"string\") c = e.originalError.code;\n if (!c && typeof e.cause?.code === \"string\") c = e.cause.code;\n if (!c && typeof e.severity === \"string\" && typeof e.code === \"string\")\n c = e.code;\n if (typeof c === \"number\") return String(c);\n if (typeof c === \"string\" && c.length > 0) return c;\n return void 0;\n}\nfunction mapPostgresCodeToKind(code) {\n if (!code) return \"internal\";\n const c = code.toUpperCase();\n if (c === \"40P01\") return \"deadlock\";\n if (c === \"40001\") return \"serialization-failure\";\n if (c === \"57014\") return \"timeout\";\n if (c === \"23505\") return \"unique-violation\";\n if (c === \"23503\") return \"fk-violation\";\n if (c === \"23502\") return \"not-null-violation\";\n if (c === \"42601\") return \"syntax\";\n if (c.startsWith(\"08\") || c === \"57P01\") return \"connection-lost\";\n if (c.startsWith(\"23\")) return \"constraint\";\n return \"internal\";\n}\nfunction mapMySqlCodeToKind(code) {\n if (!code) return \"internal\";\n const c = code.toUpperCase();\n if (c === \"1213\" || c === \"ER_LOCK_DEADLOCK\") return \"deadlock\";\n if (c === \"1205\" || c === \"ER_LOCK_WAIT_TIMEOUT\") return \"timeout\";\n if (c === \"1062\" || c === \"ER_DUP_ENTRY\") return \"unique-violation\";\n if (c === \"23000\") return \"constraint\";\n if (c === \"1064\" || c === \"ER_PARSE_ERROR\") return \"syntax\";\n if (c === \"1452\" || c === \"ER_NO_REFERENCED_ROW_2\") return \"fk-violation\";\n if (c === \"1451\" || c === \"ER_ROW_IS_REFERENCED_2\") return \"fk-violation\";\n if (c === \"ECONNRESET\" || c.includes(\"PROTOCOL_CONNECTION_LOST\"))\n return \"connection-lost\";\n if (c === \"ETIMEDOUT\") return \"timeout\";\n return \"internal\";\n}\nfunction mapSqliteCodeToKind(code) {\n if (!code) return \"internal\";\n const c = code.toUpperCase();\n if (c === \"SQLITE_BUSY\" || c === \"SQLITE_LOCKED\") return \"deadlock\";\n if (c === \"SQLITE_CONSTRAINT_UNIQUE\") return \"unique-violation\";\n if (c === \"SQLITE_CONSTRAINT_PRIMARYKEY\") return \"unique-violation\";\n if (c === \"SQLITE_CONSTRAINT_FOREIGNKEY\") return \"fk-violation\";\n if (c === \"SQLITE_CONSTRAINT_NOTNULL\") return \"not-null-violation\";\n if (c === \"SQLITE_INTERRUPT\") return \"timeout\";\n if (c === \"SQLITE_ERROR\") return \"syntax\";\n if (c.startsWith(\"SQLITE_CONSTRAINT\")) return \"constraint\";\n return \"internal\";\n}\nfunction isLikelyUniqueViolationMessage(dialect, message) {\n const m = message.toLowerCase();\n if (dialect === \"mysql\") {\n return m.includes(\"duplicate entry\") || m.includes(\"duplicate key\");\n }\n if (dialect === \"sqlite\") {\n return m.includes(\"unique constraint failed\");\n }\n return false;\n}\n\n// src/errors/error-codes.ts\nvar NEXTLY_ERROR_STATUS = {\n VALIDATION_ERROR: 400,\n INVALID_INPUT: 400,\n AUTH_REQUIRED: 401,\n AUTH_INVALID_CREDENTIALS: 401,\n TOKEN_EXPIRED: 401,\n FORBIDDEN: 403,\n // The schema builder is off in this environment (production by default).\n // Separate from FORBIDDEN: the caller's permissions are not the problem.\n BUILDER_DISABLED: 403,\n NOT_FOUND: 404,\n CONFLICT: 409,\n DUPLICATE: 409,\n RATE_LIMITED: 429,\n PAYLOAD_TOO_LARGE: 413,\n UNSUPPORTED_MEDIA_TYPE: 415,\n // 422: understood, well-formed, and refused on a rule the caller can act on.\n // Deliberately NOT added to CANONICAL_CODE_FOR_STATUS -- that list drives the\n // status -> code direction, where 422 stays mapped to INVALID_INPUT.\n BUSINESS_RULE_VIOLATION: 422,\n INTERNAL_ERROR: 500,\n DATABASE_ERROR: 500,\n EXTERNAL_SERVICE_ERROR: 502,\n SERVICE_UNAVAILABLE: 503,\n // Outbound-fetch safety (utils/validate-external-url): a URL refused for SSRF\n // safety, and a fetch that timed out / exceeded the size cap / failed to decode.\n EXTERNAL_URL_BLOCKED: 400,\n EXTERNAL_REQUEST_FAILED: 502,\n FILENAME_INVALID: 400,\n EXTENSION_BLOCKED: 400,\n MIME_BLOCKED: 415,\n MIME_NOT_ALLOWED: 415,\n SIZE_EXCEEDED: 413,\n // A stored object exceeded the cap a READ was given, which is a different\n // question from SIZE_EXCEEDED above: that one refuses an upload the caller\n // is sending, this one refuses to buffer an object already stored. Kept\n // apart so a caller discriminating on the code cannot match both.\n STORAGE_READ_TOO_LARGE: 413,\n // A stored object did not answer within the deadline the read was given. 504\n // rather than 500 because the failure is the BACKEND not answering, and a\n // caller can act on that difference: a gateway timeout is worth retrying, an\n // internal error is not.\n STORAGE_READ_TIMEOUT: 504,\n // The store answered, and answered badly. 502 rather than 500 because the\n // fault is UPSTREAM of this process: a caller can retry it, and an operator\n // reading the log needs to look at the bucket rather than at this service.\n // Distinct from the timeout above, which never got an answer at all.\n STORAGE_READ_UNREACHABLE: 502,\n MAGIC_BYTE_MISMATCH: 400,\n SVG_SANITIZATION_FAILED: 400,\n UNSUPPORTED_FOR_BACKEND: 415,\n // Plan B — schema bookkeeping consolidation.\n NEXTLY_LEGACY_BOOKKEEPING_DETECTED: 409,\n NEXTLY_UPGRADE_TABLE_NAME_COLLISION: 409,\n NEXTLY_UPGRADE_IN_PROGRESS: 409,\n // Plan C2 — nextly migrate phases.\n NEXTLY_MIGRATE_LOCK_BUSY: 409,\n NEXTLY_BASELINE_LOCK_NOT_HELD: 409,\n NEXTLY_RESOLVE_LOCK_NOT_HELD: 409,\n // Boot refused to serve: the migrate lock stayed held past the wait deadline,\n // so this process never established whether the schema matches the code. 503\n // rather than 409 — a load balancer should take the instance out of rotation\n // and retry it, which is exactly the recovery this refusal wants.\n NEXTLY_BOOT_MIGRATIONS_NOT_RUN: 503,\n // Still running rather than refused. 503 for the same reason: retry shortly.\n NEXTLY_BOOT_MIGRATIONS_PENDING: 503,\n NEXTLY_CORE_DESTRUCTIVE_REFUSED: 409,\n NEXTLY_MIGRATION_DRIFT: 409,\n NEXTLY_MIGRATION_APPLY_FAILED: 500,\n // Plan C3 — migrate:resolve recovery command.\n NEXTLY_MIGRATION_FILE_MISSING: 404,\n NEXTLY_MIGRATION_SNAPSHOT_MISSING: 404,\n NEXTLY_MIGRATION_RESOLVE_DRIFT: 409,\n NEXTLY_MIGRATION_RESOLVE_PRECONDITION: 409,\n // Plan D — UI schema support.\n NEXTLY_UI_SCHEMA_INVALID: 400,\n NEXTLY_SCHEMA_SLUG_COLLISION: 409,\n NEXTLY_SCHEMA_RELATION_TARGET_MISSING: 400,\n // Plugin platform (P2b) — schema extend (contributes.extend) + relations (D15).\n NEXTLY_SCHEMA_EXTEND_TARGET_UNKNOWN: 400,\n NEXTLY_SCHEMA_EXTEND_FIELD_DUPLICATE: 409,\n NEXTLY_SCHEMA_CROSS_PLUGIN_RELATION: 409,\n // Plugin platform (P2c) — framework remap (.rename()).\n NEXTLY_SCHEMA_RENAME_UNKNOWN_TARGET: 400,\n // Plugin platform — a declared admin.clientConfig that cannot be delivered\n // to the browser, refused at boot rather than serialized mangled.\n NEXTLY_PLUGIN_CLIENT_CONFIG_INVALID: 500,\n // Plugin platform — a contributed admin widget that cannot be delivered to\n // the browser. Refused at boot because it is serialized into the ONE\n // `/api/admin-meta/workspace` payload: a value `JSON.stringify` throws on\n // fails that request for every admin, not just the widget's own card.\n NEXTLY_PLUGIN_ADMIN_WIDGET_INVALID: 500,\n // Plugin platform (P0) — boot-time plugin dependency/version resolution.\n PLUGIN_RESOLUTION_ERROR: 500,\n // Plugin platform (P4) — contributes.routes collection (D25).\n NEXTLY_ROUTE_COLLISION: 409,\n NEXTLY_ROUTE_INVALID_PATH: 400,\n // A root-mounted route declared where the request pipeline never reaches the\n // root pass. 400 like an invalid path and not 409: nothing else claims the\n // address, the declaration simply cannot be served from there.\n NEXTLY_ROUTE_UNREACHABLE_ROOT: 400,\n // A `mount` outside the declared union, which only an untyped caller can\n // produce. 400 for the same reason: the declaration itself is unserveable.\n NEXTLY_ROUTE_INVALID_MOUNT: 400,\n // An email transport whose library is an optional peer dependency the host\n // has not installed. 503 rather than 500: the request is not malformed and\n // nothing is broken, the install simply cannot carry it out yet, and the\n // remedy is one command on the server rather than a change by the caller.\n NEXTLY_EMAIL_TRANSPORT_UNAVAILABLE: 503,\n // The tooling that compiles `nextly.config.ts` is an optional peer the host\n // has not installed. 503 rather than 500 for the same reason as the mail\n // transport above: nothing is broken and the request is not malformed, the\n // install simply cannot carry it out until one command is run.\n NEXTLY_CONFIG_TOOLING_UNAVAILABLE: 503\n};\nvar CANONICAL_CODE_FOR_STATUS = [\n \"VALIDATION_ERROR\",\n \"AUTH_REQUIRED\",\n \"FORBIDDEN\",\n \"NOT_FOUND\",\n \"CONFLICT\",\n \"PAYLOAD_TOO_LARGE\",\n \"UNSUPPORTED_MEDIA_TYPE\",\n \"RATE_LIMITED\",\n \"EXTERNAL_SERVICE_ERROR\",\n \"SERVICE_UNAVAILABLE\"\n];\nvar LEGACY_UNPROCESSABLE_STATUS = 422;\nvar STATUS_TO_CODE = {\n ...Object.fromEntries(\n CANONICAL_CODE_FOR_STATUS.map((code) => [NEXTLY_ERROR_STATUS[code], code])\n ),\n [LEGACY_UNPROCESSABLE_STATUS]: \"INVALID_INPUT\"\n};\nfunction statusToErrorCode(statusCode) {\n return STATUS_TO_CODE[statusCode] ?? \"INTERNAL_ERROR\";\n}\nvar GENERIC_PUBLIC_MESSAGE = {\n VALIDATION_ERROR: \"Validation failed.\",\n INVALID_INPUT: \"The request could not be processed.\",\n AUTH_REQUIRED: \"Authentication required.\",\n FORBIDDEN: \"You don't have permission to perform this action.\",\n NOT_FOUND: \"Not found.\",\n CONFLICT: \"The resource has changed since you last loaded it. Please refresh and try again.\",\n DUPLICATE: \"Resource already exists.\",\n PAYLOAD_TOO_LARGE: \"The request is too large.\",\n UNSUPPORTED_MEDIA_TYPE: \"That file type is not supported.\",\n RATE_LIMITED: \"Too many requests. Please try again later.\",\n EXTERNAL_SERVICE_ERROR: \"An upstream service failed.\",\n SERVICE_UNAVAILABLE: \"The service is temporarily unavailable.\",\n INTERNAL_ERROR: \"An unexpected error occurred.\"\n};\nfunction genericPublicMessage(code) {\n return GENERIC_PUBLIC_MESSAGE[code] ?? GENERIC_PUBLIC_MESSAGE.INTERNAL_ERROR;\n}\n\n// src/errors/nextly-error.ts\nvar DB_ERROR_MAPPING = {\n \"unique-violation\": {\n code: \"DUPLICATE\",\n statusCode: 409,\n publicMessage: \"Resource already exists.\"\n },\n \"fk-violation\": {\n code: \"VALIDATION_ERROR\",\n statusCode: 400,\n publicMessage: \"Referenced record does not exist.\"\n },\n \"not-null-violation\": {\n code: \"VALIDATION_ERROR\",\n statusCode: 400,\n publicMessage: \"A required field is missing.\"\n },\n constraint: {\n code: \"VALIDATION_ERROR\",\n statusCode: 400,\n publicMessage: \"The provided data violates a constraint.\"\n },\n deadlock: {\n code: \"CONFLICT\",\n statusCode: 409,\n publicMessage: \"The operation could not be completed. Please retry.\"\n },\n \"serialization-failure\": {\n code: \"CONFLICT\",\n statusCode: 409,\n publicMessage: \"The operation could not be completed. Please retry.\"\n },\n timeout: {\n code: \"DATABASE_ERROR\",\n statusCode: 500,\n publicMessage: \"The operation timed out. Please try again.\"\n },\n \"connection-lost\": {\n code: \"DATABASE_ERROR\",\n statusCode: 500,\n publicMessage: \"A temporary database error occurred. Please try again.\"\n },\n syntax: {\n code: \"INTERNAL_ERROR\",\n statusCode: 500,\n publicMessage: \"An unexpected error occurred.\"\n },\n internal: {\n code: \"INTERNAL_ERROR\",\n statusCode: 500,\n publicMessage: \"An unexpected error occurred.\"\n }\n};\nvar NEXTLY_ERROR_BRAND = Symbol.for(\"nextly/NextlyError\");\nfunction hasBrand(value) {\n if (value === null || typeof value !== \"object\" && typeof value !== \"function\") {\n return false;\n }\n return value[NEXTLY_ERROR_BRAND] === true;\n}\nvar NextlyError = class _NextlyError extends Error {\n code;\n statusCode;\n publicMessage;\n publicData;\n messageKey;\n logMessage;\n logContext;\n cause;\n timestamp;\n constructor(opts) {\n super(opts.publicMessage);\n this.name = \"NextlyError\";\n this.code = opts.code;\n this.publicMessage = opts.publicMessage;\n this.publicData = opts.publicData;\n this.messageKey = opts.messageKey;\n this.logMessage = opts.logMessage;\n this.logContext = opts.logContext;\n this.cause = opts.cause;\n this.timestamp = /* @__PURE__ */ new Date();\n this.statusCode = _NextlyError.resolveStatusCode(opts);\n Error.captureStackTrace?.(this, _NextlyError);\n }\n static {\n _NextlyError.prototype[NEXTLY_ERROR_BRAND] = true;\n }\n static resolveStatusCode(opts) {\n if (typeof opts.statusCode === \"number\") return opts.statusCode;\n if (opts.code in NEXTLY_ERROR_STATUS) {\n return NEXTLY_ERROR_STATUS[opts.code];\n }\n return 500;\n }\n /** HTTP-safe JSON. Strips logMessage / logContext / cause / stack. */\n toResponseJSON(requestId) {\n const json = {\n code: String(this.code),\n message: this.publicMessage,\n requestId\n };\n if (this.messageKey) json.messageKey = this.messageKey;\n if (this.publicData !== void 0) json.data = this.publicData;\n return json;\n }\n /** Operator-facing JSON for log lines. Includes everything. */\n toLogJSON(requestId) {\n return {\n code: this.code,\n statusCode: this.statusCode,\n publicMessage: this.publicMessage,\n messageKey: this.messageKey,\n logMessage: this.logMessage,\n logContext: this.logContext,\n cause: this.cause ? {\n name: this.cause.name,\n message: this.cause.message,\n stack: this.cause.stack\n } : void 0,\n timestamp: this.timestamp.toISOString(),\n requestId\n };\n }\n // ────────────────────────────────────────────────────────────────────\n // Static factories — the recommended throw site for every common case.\n // Public messages here follow the §13.8 rubric: complete sentence,\n // generic, no identifiers, no value echoing, no policy hints.\n // ────────────────────────────────────────────────────────────────────\n static invalidCredentials(opts) {\n return new _NextlyError({\n code: \"AUTH_INVALID_CREDENTIALS\",\n publicMessage: \"Invalid email or password.\",\n logMessage: \"Login failed\",\n logContext: opts?.logContext\n });\n }\n static authRequired(opts) {\n return new _NextlyError({\n code: \"AUTH_REQUIRED\",\n publicMessage: \"Authentication required.\",\n logContext: opts?.logContext\n });\n }\n /**\n * Distinct from `authRequired`: the caller was authenticated but the\n * session token expired. Clients key on the TOKEN_EXPIRED *code* to\n * silently refresh and retry rather than redirecting to login; the public\n * message stays the generic spec §13.6 string (\"Authentication required.\")\n * so the wire never reveals the session state — same as `authRequired`.\n */\n static tokenExpired(opts) {\n return new _NextlyError({\n code: \"TOKEN_EXPIRED\",\n publicMessage: \"Authentication required.\",\n logContext: opts?.logContext\n });\n }\n static notFound(opts) {\n return new _NextlyError({\n code: \"NOT_FOUND\",\n publicMessage: opts?.message ?? \"Not found.\",\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n static forbidden(opts) {\n return new _NextlyError({\n code: \"FORBIDDEN\",\n publicMessage: \"You don't have permission to perform this action.\",\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n /**\n * A call the caller got wrong, where naming the mistake IS the value of the\n * error.\n *\n * The only factory that takes its public message from the caller. The\n * generic messages elsewhere exist so an HTTP response cannot leak internal\n * detail; this one is for arguments and configuration a developer controls\n * and must be told about — a missing option, an unusable combination — where\n * `internal()` would reduce the one useful sentence to \"An unexpected error\n * occurred.\" Do not pass user-supplied data through it.\n */\n static invalidInput(opts) {\n return new _NextlyError({\n code: \"INVALID_INPUT\",\n publicMessage: opts.message,\n logContext: opts.logContext\n });\n }\n static validation(opts) {\n return new _NextlyError({\n code: \"VALIDATION_ERROR\",\n publicMessage: \"Validation failed.\",\n publicData: { errors: opts.errors },\n cause: opts.cause,\n logContext: opts.logContext\n });\n }\n static conflict(opts) {\n return new _NextlyError({\n code: \"CONFLICT\",\n publicMessage: opts?.message ?? \"The resource has changed since you last loaded it. Please refresh and try again.\",\n cause: opts?.cause,\n logContext: { reason: opts?.reason, ...opts?.logContext }\n });\n }\n static duplicate(opts) {\n return new _NextlyError({\n code: \"DUPLICATE\",\n publicMessage: \"Resource already exists.\",\n logContext: opts?.logContext\n });\n }\n static rateLimited(opts) {\n return new _NextlyError({\n code: \"RATE_LIMITED\",\n publicMessage: \"Too many requests. Please try again later.\",\n publicData: opts?.retryAfterSeconds !== void 0 ? { retryAfterSeconds: opts.retryAfterSeconds } : void 0,\n logContext: opts?.logContext\n });\n }\n static internal(opts) {\n return new _NextlyError({\n code: \"INTERNAL_ERROR\",\n publicMessage: \"An unexpected error occurred.\",\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n // Accepts an optional `logMessage` override so callers (e.g. the health\n // route) can record a specific operator narrative (\"Health check failed\")\n // while the public message stays canonical per spec §13.8.5.\n static serviceUnavailable(opts) {\n return new _NextlyError({\n code: \"SERVICE_UNAVAILABLE\",\n publicMessage: opts?.publicMessage ?? \"Service unavailable. Please try again later.\",\n logMessage: opts?.logMessage,\n cause: opts?.cause,\n logContext: opts?.logContext\n });\n }\n /**\n * Convert a DbError (or arbitrary unknown thrown by the DB layer) to a\n * NextlyError with a generic public message and rich logContext. Used by\n * `withDbErrors` for auto-conversion (Pattern A) and by services that\n * catch DB errors at boundaries (Pattern B). Spec §8.2 mapping table.\n *\n * Never leaks DB driver text, constraint names, or table names into\n * `publicMessage`. All DB context goes into `logContext`. The original\n * DbError is preserved as `cause`.\n */\n static fromDatabaseError(error) {\n if (isDbError(error)) {\n const mapping = DB_ERROR_MAPPING[error.kind];\n const logContext = {\n dbKind: error.kind,\n dialect: error.dialect\n };\n if (error.code !== void 0) logContext.dbCode = error.code;\n if (error.meta !== void 0) logContext.meta = error.meta;\n return new _NextlyError({\n code: mapping.code,\n statusCode: mapping.statusCode,\n publicMessage: mapping.publicMessage,\n logMessage: \"Database error\",\n logContext,\n cause: error\n });\n }\n return new _NextlyError({\n code: \"INTERNAL_ERROR\",\n statusCode: 500,\n publicMessage: \"An unexpected error occurred.\",\n logMessage: \"Non-DbError passed to fromDatabaseError\",\n cause: error instanceof Error ? error : void 0,\n logContext: error instanceof Error ? void 0 : { value: String(error) }\n });\n }\n // ────────────────────────────────────────────────────────────────────\n // Type guards. Structural rather than `instanceof` so they survive\n // package-boundary mismatches (one consumer's NextlyError is a\n // different module instance from another's).\n // ────────────────────────────────────────────────────────────────────\n static is(err) {\n return hasBrand(err);\n }\n static isCode(err, code) {\n return hasBrand(err) && err.code === code;\n }\n static isNotFound(err) {\n return _NextlyError.isCode(err, \"NOT_FOUND\");\n }\n static isValidation(err) {\n return _NextlyError.isCode(err, \"VALIDATION_ERROR\");\n }\n static isAuthRequired(err) {\n return _NextlyError.isCode(err, \"AUTH_REQUIRED\");\n }\n static isForbidden(err) {\n return _NextlyError.isCode(err, \"FORBIDDEN\");\n }\n static isConflict(err) {\n return _NextlyError.isCode(err, \"CONFLICT\");\n }\n static isRateLimited(err) {\n return _NextlyError.isCode(err, \"RATE_LIMITED\");\n }\n};\n\nexport {\n DbError,\n isDbError,\n toDbError,\n safeCode,\n NEXTLY_ERROR_STATUS,\n statusToErrorCode,\n genericPublicMessage,\n NextlyError\n};\n","import {\n NextlyError\n} from \"./chunk-IAZJNA2U.mjs\";\n\n// src/storage/read-errors.ts\nvar StorageReadTooLargeError = class extends NextlyError {\n constructor(path, maxBytes, size) {\n super({\n code: \"STORAGE_READ_TOO_LARGE\",\n publicMessage: \"The stored file is larger than the limit for this read.\",\n logContext: {\n path,\n maxBytes,\n ...size === void 0 ? {} : { size }\n }\n });\n this.path = path;\n this.maxBytes = maxBytes;\n this.size = size;\n }\n};\nfunction isStorageReadTooLarge(error) {\n return NextlyError.is(error) && error.code === \"STORAGE_READ_TOO_LARGE\";\n}\nvar StorageReadTimeoutError = class extends NextlyError {\n constructor(path, timeoutMs) {\n super({\n code: \"STORAGE_READ_TIMEOUT\",\n publicMessage: \"The stored file could not be read in time.\",\n logContext: { path, timeoutMs }\n });\n this.path = path;\n this.timeoutMs = timeoutMs;\n }\n};\nfunction isStorageReadTimeout(error) {\n return NextlyError.is(error) && error.code === \"STORAGE_READ_TIMEOUT\";\n}\n\nexport {\n StorageReadTooLargeError,\n isStorageReadTooLarge,\n StorageReadTimeoutError,\n isStorageReadTimeout\n};\n","import {\n StorageReadTimeoutError,\n StorageReadTooLargeError\n} from \"./chunk-T3OVIJZM.mjs\";\nimport {\n NextlyError\n} from \"./chunk-IAZJNA2U.mjs\";\n\n// src/utils/validate-external-url.ts\nvar IPV4_RE = /^(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)$/;\nvar PRIVATE_IPV4_CIDRS = [\n \"0.0.0.0/8\",\n // RFC1122 \"this network\" / wildcard\n \"10.0.0.0/8\",\n // RFC1918\n \"100.64.0.0/10\",\n // RFC6598 CGNAT\n \"127.0.0.0/8\",\n // RFC1122 loopback\n \"169.254.0.0/16\",\n // RFC3927 link-local + AWS/GCP metadata\n \"172.16.0.0/12\",\n // RFC1918\n \"192.0.0.0/24\",\n // RFC6890 IETF protocol assignments\n \"192.0.2.0/24\",\n // RFC5737 documentation\n \"192.168.0.0/16\",\n // RFC1918\n \"198.18.0.0/15\",\n // RFC2544 benchmarking\n \"198.51.100.0/24\",\n // RFC5737 documentation\n \"203.0.113.0/24\",\n // RFC5737 documentation\n \"224.0.0.0/4\",\n // RFC5771 multicast\n \"240.0.0.0/4\"\n // RFC1112 reserved\n];\nvar CLOUD_METADATA_HOSTS = /* @__PURE__ */ new Set([\n \"metadata.google.internal\",\n \"metadata.googleapis.com\",\n \"metadata\"\n // GCP short form\n]);\nvar ExternalUrlError = class extends NextlyError {\n constructor(message, url) {\n super({\n code: \"EXTERNAL_URL_BLOCKED\",\n publicMessage: message,\n logContext: { url }\n });\n this.url = url;\n this.name = \"ExternalUrlError\";\n }\n};\nasync function validateExternalUrl(rawUrl, options = {}) {\n let parsed;\n try {\n parsed = new URL(rawUrl);\n } catch {\n throw new ExternalUrlError(\"Invalid URL\", rawUrl);\n }\n const hostname = parsed.hostname.toLowerCase().replace(/^\\[|\\]$/g, \"\");\n const isLocalhostHostname = hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"::1\";\n const baseProtocols = options.allowedProtocols ?? [\"https:\"];\n const protocols = options.allowLocalhost && isLocalhostHostname ? [...baseProtocols, \"http:\"] : baseProtocols;\n if (!protocols.includes(parsed.protocol)) {\n throw new ExternalUrlError(\n `Protocol ${parsed.protocol} not allowed (allowed: ${protocols.join(\", \")})`,\n rawUrl\n );\n }\n if (CLOUD_METADATA_HOSTS.has(hostname)) {\n throw new ExternalUrlError(\n `Cloud-metadata hostname rejected: ${parsed.hostname}`,\n rawUrl\n );\n }\n if (IPV4_RE.test(hostname)) {\n if (!isPublicIpv4(\n hostname,\n options.allowLocalhost === true && hostname === \"127.0.0.1\"\n )) {\n throw new ExternalUrlError(\n `Resolved to non-public IP: ${hostname}`,\n rawUrl\n );\n }\n return { url: parsed, pinnedIp: hostname, family: 4 };\n }\n if (hostname.includes(\":\")) {\n if (!isPublicIpv6(\n hostname,\n options.allowLocalhost === true && hostname === \"::1\"\n )) {\n throw new ExternalUrlError(\n `Resolved to non-public IP: ${hostname}`,\n rawUrl\n );\n }\n return { url: parsed, pinnedIp: hostname, family: 6 };\n }\n const { lookup } = await import(\"dns/promises\");\n let addresses;\n try {\n addresses = await lookup(hostname, { all: true });\n } catch (err) {\n throw new ExternalUrlError(\n `DNS lookup failed: ${err.message}`,\n rawUrl\n );\n }\n if (addresses.length === 0) {\n throw new ExternalUrlError(\"No IPs returned for host\", rawUrl);\n }\n for (const { address, family } of addresses) {\n const allow = options.allowLocalhost === true && isLocalhostHostname && family === 4;\n const ok = family === 4 ? isPublicIpv4(address, allow) : isPublicIpv6(address, allow);\n if (!ok) {\n throw new ExternalUrlError(\n `Resolved to non-public IP: ${address}`,\n rawUrl\n );\n }\n }\n const first = addresses[0];\n return {\n url: parsed,\n pinnedIp: first.address,\n family: first.family === 6 ? 6 : 4\n };\n}\nvar DEFAULT_MAX_RESPONSE_BYTES = 10 * 1024 * 1024;\nvar DEFAULT_TIMEOUT_MS = 3e4;\nvar SafeFetchError = class extends NextlyError {\n constructor(message, url, reason, status) {\n super({\n code: \"EXTERNAL_REQUEST_FAILED\",\n publicMessage: message,\n logContext: { url, reason }\n });\n this.url = url;\n this.reason = reason;\n this.status = status;\n this.name = \"SafeFetchError\";\n }\n};\nfunction createPinnedLookup(ip, family) {\n return (_hostname, options, callback) => {\n if (options && options.all) {\n callback(null, [{ address: ip, family }]);\n } else {\n callback(null, ip, family);\n }\n };\n}\nasync function safeFetch(rawUrl, options = {}) {\n const {\n allowLocalhost,\n allowedProtocols,\n method,\n headers,\n body,\n signal,\n maxResponseBytes = DEFAULT_MAX_RESPONSE_BYTES,\n timeoutMs = DEFAULT_TIMEOUT_MS\n } = options;\n const controller = new AbortController();\n const forwardAbort = () => controller.abort(signal?.reason);\n if (signal) {\n if (signal.aborted) controller.abort(signal.reason);\n else signal.addEventListener(\"abort\", forwardAbort, { once: true });\n }\n const timer = setTimeout(\n () => controller.abort(\n new SafeFetchError(`Request exceeded ${timeoutMs}ms`, rawUrl, \"timeout\")\n ),\n timeoutMs\n );\n try {\n const validated = await abortable(\n validateExternalUrl(rawUrl, { allowLocalhost, allowedProtocols }),\n controller.signal\n );\n return await pinnedFetch(validated, {\n method,\n headers,\n body,\n signal: controller.signal,\n maxResponseBytes\n });\n } finally {\n clearTimeout(timer);\n if (signal) signal.removeEventListener(\"abort\", forwardAbort);\n }\n}\nfunction abortError(signal) {\n const reason = signal.reason;\n if (reason instanceof Error) return reason;\n return new DOMException(\"The operation was aborted\", \"AbortError\");\n}\nfunction abortable(promise, signal) {\n if (signal.aborted) return Promise.reject(abortError(signal));\n let onAbort;\n const aborted = new Promise((_resolve, reject) => {\n onAbort = () => reject(abortError(signal));\n signal.addEventListener(\"abort\", onAbort, { once: true });\n });\n return Promise.race([promise, aborted]).finally(\n () => signal.removeEventListener(\"abort\", onAbort)\n );\n}\nasync function pinnedFetch(validated, init) {\n const { url, pinnedIp, family } = validated;\n const httpMod = url.protocol === \"https:\" ? await import(\"https\") : await import(\"http\");\n const zlib = await import(\"zlib\");\n const lookup = createPinnedLookup(pinnedIp, family);\n const outHeaders = toOutgoingHeaders(init.headers);\n if (init.body != null) {\n delete outHeaders[\"transfer-encoding\"];\n outHeaders[\"content-length\"] = String(\n typeof init.body === \"string\" ? Buffer.byteLength(init.body) : init.body.byteLength\n );\n }\n return new Promise((resolve, reject) => {\n let settled = false;\n const settle = (fn) => {\n if (settled) return;\n settled = true;\n fn();\n };\n const failure = (err) => init.signal.aborted ? abortError(init.signal) : err;\n const req = httpMod.request(\n url,\n {\n method: init.method ?? \"GET\",\n headers: outHeaders,\n lookup,\n // Fresh socket per request so a pooled connection can't reuse a\n // differently-resolved address, and so the pinned lookup always runs.\n agent: false,\n // The combined deadline/caller signal aborts the request in flight.\n signal: init.signal\n },\n (res) => {\n const chunks = [];\n let received = 0;\n res.on(\"data\", (chunk) => {\n received += chunk.length;\n if (received > init.maxResponseBytes) {\n res.destroy();\n req.destroy();\n settle(\n () => reject(\n new SafeFetchError(\n `Response body exceeded ${init.maxResponseBytes} bytes`,\n url.href,\n \"response-too-large\",\n res.statusCode\n )\n )\n );\n return;\n }\n chunks.push(chunk);\n });\n res.on(\"end\", () => {\n const decoded = decodeBody(\n Buffer.concat(chunks),\n res.headers[\"content-encoding\"],\n zlib,\n init.maxResponseBytes,\n url.href,\n res.statusCode\n );\n if (decoded instanceof SafeFetchError) {\n settle(() => reject(decoded));\n return;\n }\n settle(\n () => resolve(toWhatwgResponse(res, decoded.body, decoded.decoded))\n );\n });\n res.on(\"error\", (err) => settle(() => reject(failure(err))));\n }\n );\n req.on(\"error\", (err) => settle(() => reject(failure(err))));\n if (!req.destroyed) {\n if (init.body != null) req.write(init.body);\n req.end();\n }\n });\n}\nfunction toOutgoingHeaders(headers) {\n const out = {};\n if (!headers) return out;\n const add = (rawKey, value) => {\n const key = rawKey.toLowerCase();\n if (key === \"host\") return;\n const existing = out[key];\n out[key] = existing === void 0 ? value : [].concat(existing, value);\n };\n if (headers instanceof Headers) {\n headers.forEach((value, key) => add(key, value));\n } else if (Array.isArray(headers)) {\n for (const [key, value] of headers) add(key, value);\n } else {\n for (const [key, value] of Object.entries(headers)) add(key, value);\n }\n return out;\n}\nfunction toWhatwgResponse(res, body, stripContentHeaders) {\n const headers = new Headers();\n for (const [key, value] of Object.entries(res.headers)) {\n if (value == null) continue;\n const lower = key.toLowerCase();\n if (stripContentHeaders && (lower === \"content-encoding\" || lower === \"content-length\")) {\n continue;\n }\n const values = Array.isArray(value) ? value : [value];\n for (const v of values) {\n try {\n headers.append(key, v);\n } catch {\n }\n }\n }\n const raw = res.statusCode ?? 502;\n const status = raw >= 200 && raw <= 599 ? raw : 502;\n const nullBody = status === 204 || status === 205 || status === 304;\n const bytes = new Uint8Array(body.byteLength);\n bytes.set(body);\n return new Response(nullBody ? null : bytes, {\n status,\n statusText: res.statusMessage ?? \"\",\n headers\n });\n}\nfunction decodeBody(buf, encoding, zlib, cap, url, status) {\n if (!encoding) return { body: buf, decoded: false };\n if (buf.length === 0) return { body: buf, decoded: true };\n const layers = encoding.split(\",\").map((e) => e.trim().toLowerCase()).filter(Boolean);\n const opts = { maxOutputLength: cap };\n let current = buf;\n let decoded = false;\n try {\n for (let i = layers.length - 1; i >= 0; i--) {\n const enc = layers[i];\n if (enc === \"identity\") continue;\n if (enc === \"gzip\" || enc === \"x-gzip\") {\n current = zlib.gunzipSync(current, opts);\n } else if (enc === \"br\") {\n current = zlib.brotliDecompressSync(current, opts);\n } else if (enc === \"deflate\") {\n try {\n current = zlib.inflateSync(current, opts);\n } catch (inflateErr) {\n if (errorCode(inflateErr) === \"ERR_BUFFER_TOO_LARGE\")\n throw inflateErr;\n current = zlib.inflateRawSync(current, opts);\n }\n } else {\n if (decoded) {\n return new SafeFetchError(\n `Cannot fully decode content-encoding \"${encoding}\"`,\n url,\n \"decode-failed\",\n status\n );\n }\n return { body: buf, decoded: false };\n }\n decoded = true;\n }\n return { body: current, decoded };\n } catch (err) {\n const tooLarge = errorCode(err) === \"ERR_BUFFER_TOO_LARGE\";\n return new SafeFetchError(\n tooLarge ? `Decoded ${encoding} response body exceeded the size cap` : `Failed to decode ${encoding} response body`,\n url,\n tooLarge ? \"response-too-large\" : \"decode-failed\",\n status\n );\n }\n}\nfunction errorCode(err) {\n if (err != null && typeof err === \"object\" && \"code\" in err) {\n const code = err.code;\n return typeof code === \"string\" ? code : void 0;\n }\n return void 0;\n}\nfunction ipv4ToInt(ip) {\n const parts = ip.split(\".\");\n if (parts.length !== 4) return null;\n let acc = 0;\n for (const p of parts) {\n const n = Number(p);\n if (!Number.isInteger(n) || n < 0 || n > 255) return null;\n acc = acc << 8 | n;\n }\n return acc >>> 0;\n}\nfunction isIpv4InCidr(intIp, cidr) {\n const [addr, prefixRaw] = cidr.split(\"/\");\n const intCidr = ipv4ToInt(addr);\n if (intCidr === null) return false;\n const prefix = Number(prefixRaw);\n if (!Number.isInteger(prefix) || prefix < 0 || prefix > 32) return false;\n const mask = prefix === 0 ? 0 : -1 >>> 32 - prefix << 32 - prefix;\n return (intIp & mask) >>> 0 === (intCidr & mask) >>> 0;\n}\nfunction isPublicIpv4(addr, allowLoopback) {\n const intIp = ipv4ToInt(addr);\n if (intIp === null) return false;\n if (allowLoopback && addr === \"127.0.0.1\") return true;\n for (const cidr of PRIVATE_IPV4_CIDRS) {\n if (isIpv4InCidr(intIp, cidr)) return false;\n }\n return true;\n}\nfunction mappedIpv4(lower) {\n const dotted = lower.match(/^::ffff:(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})$/);\n if (dotted) return dotted[1];\n const hex = lower.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/);\n if (hex) {\n const hi = parseInt(hex[1], 16);\n const lo = parseInt(hex[2], 16);\n return [hi >> 8, hi & 255, lo >> 8, lo & 255].join(\".\");\n }\n return null;\n}\nfunction isPublicIpv6(addr, allowLoopback) {\n const lower = addr.toLowerCase();\n if (allowLoopback && lower === \"::1\") return true;\n const mapped = mappedIpv4(lower);\n if (mapped) {\n return isPublicIpv4(mapped, allowLoopback);\n }\n if (lower === \"::\" || lower === \"::1\") return false;\n const firstHextet = lower.split(\":\")[0] || \"\";\n if (firstHextet.startsWith(\"fc\") || firstHextet.startsWith(\"fd\"))\n return false;\n if (firstHextet.startsWith(\"fe8\") || firstHextet.startsWith(\"fe9\"))\n return false;\n if (firstHextet.startsWith(\"fea\") || firstHextet.startsWith(\"feb\"))\n return false;\n if (firstHextet.startsWith(\"ff\")) return false;\n return true;\n}\n\n// src/storage/fetch-stored-bytes.ts\nasync function fetchStoredBytes(url, context, label, options, signal) {\n let response;\n try {\n response = await safeFetch(url, {\n ...options?.maxBytes === void 0 ? {} : { maxResponseBytes: options.maxBytes },\n /*\n * A caller's signal REPLACES the deadline rather than joining it.\n *\n * These adapters look the object's address up before fetching it, and\n * that lookup can stall too. Starting a fresh timer here would give the\n * fetch its own full budget on top of however long the lookup took, so a\n * read could outlive the deadline the caller was told applied — by\n * roughly double. One signal begun before the lookup governs both phases.\n */\n ...signal !== void 0 ? { signal } : options?.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs }\n });\n } catch (error) {\n const verdict = classifyFetchFailure(error);\n if (verdict === \"absent\") return null;\n if (verdict === \"oversized\") {\n throw new StorageReadTooLargeError(\n context,\n resolveReadBounds(options).maxBytes\n );\n }\n throw error;\n }\n if (response.status === 404) return null;\n if (!response.ok) {\n throw NextlyError.internal({\n logContext: {\n service: label,\n path: context,\n status: response.status,\n statusText: response.statusText\n }\n });\n }\n return Buffer.from(await response.arrayBuffer());\n}\nfunction classifyFetchFailure(error) {\n if (!(error instanceof SafeFetchError)) return \"unknown\";\n if (error.status === 404) return \"absent\";\n const successful = error.status !== void 0 && error.status >= 200 && error.status < 300;\n return error.reason === \"response-too-large\" && successful ? \"oversized\" : \"unknown\";\n}\nvar DEFAULT_READ_TIMEOUT_MS = DEFAULT_TIMEOUT_MS;\nvar DEFAULT_READ_MAX_BYTES = DEFAULT_MAX_RESPONSE_BYTES;\nfunction resolveReadBounds(options) {\n return {\n maxBytes: options?.maxBytes ?? DEFAULT_READ_MAX_BYTES,\n timeoutMs: options?.timeoutMs ?? DEFAULT_READ_TIMEOUT_MS\n };\n}\nfunction deadlineSignal(timeoutMs, context) {\n const controller = new AbortController();\n const timer = setTimeout(() => {\n controller.abort(new StorageReadTimeoutError(context, timeoutMs));\n }, timeoutMs);\n timer.unref?.();\n return {\n signal: controller.signal,\n /*\n * Called once the read has settled, whichever way it went. `unref` only\n * stops a pending timer holding the process open; it still sits on the\n * timer heap retaining the controller and the path, so a server doing a\n * thousand reads a second keeps thirty seconds of them alive and then runs\n * a thousand aborts that answer nobody.\n */\n cancel: () => {\n clearTimeout(timer);\n }\n };\n}\nasync function withDeadline(work, signal) {\n if (signal === void 0) return await work;\n return await Promise.race([\n work,\n new Promise((_, reject) => {\n if (signal.aborted) {\n reject(signal.reason);\n return;\n }\n signal.addEventListener(\"abort\", () => reject(signal.reason), {\n once: true\n });\n })\n ]);\n}\n\nexport {\n ExternalUrlError,\n validateExternalUrl,\n SafeFetchError,\n safeFetch,\n fetchStoredBytes,\n classifyFetchFailure,\n DEFAULT_READ_TIMEOUT_MS,\n DEFAULT_READ_MAX_BYTES,\n resolveReadBounds,\n deadlineSignal,\n withDeadline\n};\n","/**\n * Vercel Blob Storage Adapter\n *\n * Stores files on Vercel Blob Storage, a globally distributed object storage\n * service powered by Cloudflare R2. Optimized for Vercel deployments with\n * built-in CDN distribution.\n *\n * Features:\n * - Globally distributed CDN-backed storage\n * - Automatic file management with unique filenames\n * - Token-based authentication\n * - Client-side upload support (via handleUpload API)\n * - Serverless-friendly (no filesystem access required)\n *\n * @example Basic usage\n * ```typescript\n * const adapter = new VercelBlobStorageAdapter({\n * token: process.env.BLOB_READ_WRITE_TOKEN,\n * collections: { media: true }\n * });\n *\n * const result = await adapter.upload(buffer, {\n * filename: 'photo.jpg',\n * mimeType: 'image/jpeg'\n * });\n * // result.url: \"https://abc123.public.blob.vercel-storage.com/photo-xyz.jpg\"\n * ```\n */\n\nimport { put, del, head, list, BlobNotFoundError } from \"@vercel/blob\";\nimport { NextlyError } from \"nextly/errors\";\nimport type {\n IStorageAdapter,\n UploadOptions,\n UploadResult,\n StorageAdapterInfo,\n ClientUploadData,\n FileMetadata,\n BulkDeleteResult,\n StorageReadOptions,\n} from \"nextly/storage\";\nimport {\n fetchStoredBytes,\n DEFAULT_READ_TIMEOUT_MS,\n} from \"nextly/storage/fetch-stored-bytes\";\n\nimport type {\n VercelBlobStorageConfig,\n ResolvedVercelBlobConfig,\n} from \"./types\";\n\n// ============================================================\n// Vercel Blob Storage Adapter\n// ============================================================\n\n/**\n * Vercel Blob Storage Adapter\n *\n * Implements the IStorageAdapter interface for Vercel Blob Storage.\n * Provides file upload, deletion, existence checks, and metadata retrieval.\n */\nexport class VercelBlobStorageAdapter implements IStorageAdapter {\n private resolvedConfig: ResolvedVercelBlobConfig;\n\n /**\n * Create a new Vercel Blob storage adapter.\n *\n * @param config - Vercel Blob storage configuration\n * @throws Error if token is not provided\n */\n constructor(private config: VercelBlobStorageConfig) {\n // Resolve token from config or environment\n const token = config.token || process.env.BLOB_READ_WRITE_TOKEN || \"\";\n\n if (!token) {\n throw new Error(\n \"@nextly/storage-vercel-blob: token is required.\\n\\n\" +\n \"Either set the BLOB_READ_WRITE_TOKEN environment variable or pass token in config.\\n\" +\n \"Get your token from: Vercel Dashboard > Storage > Blob > Tokens\"\n );\n }\n\n // Resolve config with defaults\n this.resolvedConfig = {\n token,\n addRandomSuffix: config.addRandomSuffix ?? true,\n cacheControlMaxAge: config.cacheControlMaxAge ?? 31536000,\n access: config.access ?? \"public\",\n storeId: config.storeId,\n allowOverwrite: config.allowOverwrite ?? false,\n multipartThreshold: config.multipartThreshold ?? 5 * 1024 * 1024, // 5MB\n };\n }\n\n // ============================================================\n // Core IStorageAdapter Methods\n // ============================================================\n\n /**\n * Upload file to Vercel Blob.\n *\n * Files are stored with globally distributed CDN backing.\n * By default, a random suffix is added to prevent filename collisions.\n *\n * @param buffer - File content as Buffer\n * @param options - Upload options (filename, mimeType, folder, collection)\n * @returns Upload result with URL and storage path\n */\n async upload(buffer: Buffer, options: UploadOptions): Promise<UploadResult> {\n const mimeType = (options.contentType || options.mimeType || \"\")\n .toLowerCase()\n .trim();\n const filename = (options.filename || \"\").toLowerCase();\n const ext = filename.includes(\".\")\n ? filename.slice(filename.lastIndexOf(\".\") + 1)\n : \"\";\n const isHtml =\n mimeType === \"text/html\" ||\n mimeType === \"application/xhtml+xml\" ||\n ext === \"html\" ||\n ext === \"htm\" ||\n ext === \"xhtml\";\n // HTML stays unconditionally rejected. The `downloadUrl` trick that\n // makes SVG safe (see below) doesn't help HTML — a downloaded HTML\n // file is still a usable XSS vector when opened from disk, and\n // Vercel Blob has no equivalent of `Content-Security-Policy` to\n // defang it.\n if (isHtml) {\n throw NextlyError.validation({\n errors: [\n {\n path: \"file\",\n code: \"UNSUPPORTED_FOR_BACKEND\",\n message:\n \"HTML files cannot be hosted on Vercel Blob. Use the S3 or R2 adapter, or upload as another format.\",\n },\n ],\n logContext: {\n adapter: \"vercel-blob\",\n claimedMimeType: options.mimeType,\n reason: \"vercel-blob-rejects-html\",\n filename: options.filename,\n },\n });\n }\n\n const isSvg =\n mimeType === \"image/svg+xml\" || ext === \"svg\" || ext === \"svgz\";\n\n const pathname = this.buildPathname(options.filename, options.folder);\n\n const result = await put(pathname, buffer, {\n access: this.resolvedConfig.access,\n token: this.resolvedConfig.token,\n contentType: options.contentType || options.mimeType,\n addRandomSuffix: this.resolvedConfig.addRandomSuffix,\n cacheControlMaxAge: this.resolvedConfig.cacheControlMaxAge,\n });\n\n // SVGs are served via Vercel Blob's `downloadUrl` (the same URL with\n // `?download=1` appended) so direct top-level navigation forces an\n // attachment download instead of rendering. `<img src>` ignores the\n // `Content-Disposition` header, so legitimate inline rendering still\n // works. The `@vercel/blob` SDK has no `contentDisposition` input\n // option on `put()`, so this query-param-driven approach is the\n // supported mechanism. Caller is responsible for sanitizing SVG\n // contents upstream (handled by `upload-validation`).\n const url =\n isSvg && options.contentDisposition === \"attachment\"\n ? result.downloadUrl\n : result.url;\n\n return {\n url,\n path: result.url,\n };\n }\n\n /**\n * Delete file from Vercel Blob.\n *\n * @param filePath - Full blob URL to delete\n */\n async delete(filePath: string): Promise<void> {\n await del(filePath, {\n token: this.resolvedConfig.token,\n });\n }\n\n /**\n * Delete multiple files from Vercel Blob in chunked batches.\n *\n * Processes deletions in chunks of 10 concurrent calls using Promise.allSettled,\n * collecting successes and failures without short-circuiting.\n *\n * @param filePaths - Array of full blob URLs to delete\n * @returns BulkDeleteResult with successful and failed arrays\n */\n async bulkDelete(filePaths: string[]): Promise<BulkDeleteResult> {\n const successful: string[] = [];\n const failed: Array<{ filePath: string; error: string }> = [];\n const chunkSize = 10;\n\n for (let i = 0; i < filePaths.length; i += chunkSize) {\n const chunk = filePaths.slice(i, i + chunkSize);\n const results = await Promise.allSettled(\n chunk.map(fp => del(fp, { token: this.resolvedConfig.token }))\n );\n\n results.forEach((result, idx) => {\n const fp = chunk[idx];\n if (result.status === \"fulfilled\") {\n successful.push(fp);\n } else {\n failed.push({\n filePath: fp,\n error:\n result.reason instanceof Error\n ? result.reason.message\n : String(result.reason),\n });\n }\n });\n }\n\n return { successful, failed };\n }\n\n /**\n * Check if file exists in Vercel Blob.\n *\n * Uses the head() function which is efficient for existence checks.\n *\n * @param filePath - Full blob URL to check\n * @returns true if file exists, false otherwise\n */\n async exists(filePath: string): Promise<boolean> {\n try {\n await head(filePath, {\n token: this.resolvedConfig.token,\n });\n return true;\n } catch {\n // Vercel Blob throws an error if the blob doesn't exist\n return false;\n }\n }\n\n /**\n * Read a stored blob back as bytes, or `null` when it is not there.\n *\n * A NETWORK round trip, unlike the local adapter's disk read, because the\n * bytes live on Vercel's CDN and there is no other way to reach them. That\n * cost is the reason a caller serving these from its own origin has to cache:\n * the privacy rule that forces same-origin serving does not also make the\n * fetch free, and an uncached proxy pays it on every request.\n *\n * The URL is taken from `head` rather than assembled from `filePath`,\n * because a blob's address is issued by the service — it carries a random\n * suffix this adapter never chose — so deriving one here would be guessing at\n * a string another system owns.\n *\n * `null` for a missing blob rather than a throw, matching {@link exists}.\n *\n * @param filePath - Blob path/key\n * @returns The blob's bytes, or `null` when it does not exist\n */\n async read(\n filePath: string,\n options?: StorageReadOptions\n ): Promise<Buffer | null> {\n /*\n * ONE deadline for both phases, started before the lookup.\n *\n * `head` can stall exactly as the fetch can, and it runs first — so a\n * deadline that begins only at the fetch leaves the lookup unbounded and\n * the read can outlive what the caller was promised. Created here and\n * handed to both.\n *\n * ALWAYS, not only when the caller named a timeout. `safeFetch` applies a\n * default deadline of its own, so a caller stating none was still bounded\n * for the fetch and unbounded for the lookup — which is the commonest call,\n * the email path among them, since it supplies only a byte cap. The default\n * comes from the same constant `safeFetch` uses rather than being restated.\n */\n const deadline = AbortSignal.timeout(\n options?.timeoutMs ?? DEFAULT_READ_TIMEOUT_MS\n );\n\n let target: string;\n try {\n const meta = await head(filePath, {\n token: this.resolvedConfig.token,\n abortSignal: deadline,\n });\n target = meta.downloadUrl ?? meta.url;\n } catch (error: unknown) {\n /*\n * ONLY the not-found class becomes `null`. `head` also rejects for an\n * expired token, a suspended or missing store, an aborted request and a\n * plain network failure, and every one of those says nothing about\n * whether the blob exists. Catching them all reports an outage as a\n * deletion, which a caller may act on by writing a replacement over a\n * file that is still there.\n *\n * Identified by the CLASS the SDK exports rather than by matching the\n * message, because the message is prose this package does not own.\n */\n if (error instanceof BlobNotFoundError) return null;\n throw error;\n }\n\n /*\n * OUTSIDE the catch above, deliberately, and through the shared helper so\n * that separation is stated once rather than in each adapter. A failed\n * fetch of a blob whose metadata just resolved is a transport failure\n * rather than an absence, and folding it into `null` would report a\n * network outage as a deleted file.\n */\n return await fetchStoredBytes(\n target,\n filePath,\n \"Vercel Blob\",\n options,\n deadline\n );\n }\n\n /**\n * Get public URL for Vercel Blob file.\n *\n * Vercel Blob paths ARE the public URLs - they're already full HTTPS URLs\n * with CDN distribution.\n *\n * @param filePath - Full blob URL\n * @returns The same URL (Vercel Blob paths are already public URLs)\n */\n getPublicUrl(filePath: string): string {\n // Vercel Blob paths are already full URLs\n return filePath;\n }\n\n /**\n * Get storage type identifier.\n */\n getType(): \"vercel-blob\" {\n return \"vercel-blob\";\n }\n\n // ============================================================\n // Optional IStorageAdapter Methods\n // ============================================================\n\n /**\n * Get adapter info including capabilities.\n *\n * @returns Adapter info with type, name, and capability flags\n */\n getInfo(): StorageAdapterInfo {\n return {\n type: \"vercel-blob\",\n name: \"VercelBlobStorageAdapter\",\n supportsSignedUrls: false, // Vercel Blob URLs are public by default\n supportsClientUploads: true, // Via handleUpload API\n };\n }\n\n /**\n * Get file metadata from Vercel Blob.\n *\n * Retrieves file information including size, content type, and upload date.\n *\n * @param filePath - Full blob URL\n * @returns File metadata or null if file not found\n */\n async getMetadata(filePath: string): Promise<FileMetadata | null> {\n try {\n const result = await head(filePath, {\n token: this.resolvedConfig.token,\n });\n\n // Extract filename from pathname\n const filename = result.pathname.split(\"/\").pop() || result.pathname;\n\n return {\n id: filePath,\n filename,\n originalFilename: filename,\n mimeType: result.contentType,\n size: result.size,\n url: result.url,\n createdAt: result.uploadedAt.toISOString(),\n };\n } catch {\n // File not found\n return null;\n }\n }\n\n /**\n * Generate pre-signed URL for client-side uploads.\n *\n * Vercel Blob uses a different pattern for client uploads - they require\n * the handleUpload API which handles token generation server-side.\n *\n * This method is not implemented because Vercel Blob's client upload flow\n * requires server-side route handlers with handleUpload().\n *\n * @see https://vercel.com/docs/storage/vercel-blob/client-upload\n * @throws Error always - client uploads require handleUpload API\n */\n getPresignedUploadUrl(\n _key: string,\n _mimeType: string,\n _expiresIn?: number\n ): Promise<ClientUploadData> {\n return Promise.reject(\n new Error(\n \"@nextly/storage-vercel-blob: Client uploads require the handleUpload API.\\n\\n\" +\n \"Vercel Blob uses a different pattern for client-side uploads that involves:\\n\" +\n \"1. A server-side route handler with handleUpload()\\n\" +\n \"2. The @vercel/blob/client upload() function\\n\\n\" +\n \"See: https://vercel.com/docs/storage/vercel-blob/client-upload\\n\\n\" +\n \"For server-side uploads, use the standard upload() method instead.\"\n )\n );\n }\n\n // ============================================================\n // Additional Methods\n // ============================================================\n\n /**\n * List blobs with optional prefix filter.\n *\n * Useful for browsing or batch operations on stored files.\n *\n * @param prefix - Optional prefix to filter results\n * @param options - List options (limit, cursor)\n * @returns List of blob metadata\n */\n async listBlobs(\n prefix?: string,\n options?: { limit?: number; cursor?: string }\n ): Promise<{\n blobs: Array<{\n url: string;\n pathname: string;\n size: number;\n uploadedAt: Date;\n }>;\n hasMore: boolean;\n cursor?: string;\n }> {\n const result = await list({\n token: this.resolvedConfig.token,\n prefix,\n limit: options?.limit,\n cursor: options?.cursor,\n });\n\n return {\n blobs: result.blobs.map(blob => ({\n url: blob.url,\n pathname: blob.pathname,\n size: blob.size,\n uploadedAt: blob.uploadedAt,\n })),\n hasMore: result.hasMore,\n cursor: result.cursor,\n };\n }\n\n // ============================================================\n // Helper Methods\n // ============================================================\n\n /**\n * Build pathname for Vercel Blob upload.\n *\n * Creates pathname in format: {folder}/{filename}\n * If no folder is provided, uses the filename directly.\n *\n * @param filename - Original filename (will be sanitized)\n * @param folder - Optional folder/prefix for organizing uploads\n * @returns Generated pathname\n * @throws Error if folder fails sanitization\n */\n private buildPathname(filename: string, folder?: string): string {\n const sanitized = this.sanitizeFilename(filename);\n if (!folder) return sanitized;\n return `${this.sanitizeFolder(folder)}/${sanitized}`;\n }\n\n /**\n * Sanitize filename to prevent path traversal issues.\n *\n * @param filename - Original filename\n * @returns Sanitized filename\n */\n private sanitizeFilename(filename: string): string {\n const basename = filename.split(/[/\\\\]/).pop() || filename;\n return basename.replace(/[^a-zA-Z0-9._-]/g, \"-\");\n }\n\n /**\n * Reject folder values that would let a caller\n * escape the configured prefix via path traversal or weird\n * separators. Vercel Blob is flat-keyed so `/` is just part of the\n * pathname, but an attacker who controls `folder` could still:\n *\n * - Use `..` to chain a relative-traversal-style key.\n * - Use `\\` (Windows separator) to confuse downstream tooling.\n * - Use control chars / null bytes to truncate the key.\n * - Use a leading `/` to look like an absolute path.\n *\n * Internal `/` segments stay allowed because callers legitimately\n * use nested folders (`docs/2026/...`); a leading `/`, empty\n * segments (`docs//x`), or `..` segments are rejected.\n *\n * @throws Error with a stable message so the storage facade can\n * surface a 400 instead of a 500.\n */\n private sanitizeFolder(folder: string): string {\n const trimmed = folder.replace(/\\/+$/, \"\"); // tolerate one trailing `/`\n if (!trimmed) {\n throw new Error(\"Folder must be a non-empty string.\");\n }\n // eslint-disable-next-line no-control-regex -- the whole point is to reject control chars\n if (/[\\\\\\0\\x01-\\x1f\\x7f]/.test(trimmed)) {\n throw new Error(\n \"Folder contains forbidden characters (backslash, control chars, or null bytes).\"\n );\n }\n if (trimmed.startsWith(\"/\")) {\n throw new Error(\"Folder must not start with `/`.\");\n }\n const segments = trimmed.split(\"/\");\n for (const segment of segments) {\n if (segment === \"\") {\n throw new Error(\"Folder must not contain empty segments (`//`).\");\n }\n if (segment === \"..\") {\n throw new Error(\"Folder must not contain `..` segments.\");\n }\n }\n return trimmed;\n }\n\n // ============================================================\n // Public Accessors\n // ============================================================\n\n /**\n * Get the configured token (masked for logging).\n */\n getTokenMasked(): string {\n const token = this.resolvedConfig.token;\n if (token.length <= 8) return \"****\";\n return `${token.slice(0, 4)}...${token.slice(-4)}`;\n }\n\n /**\n * Check if random suffix is enabled.\n */\n hasRandomSuffix(): boolean {\n return this.resolvedConfig.addRandomSuffix;\n }\n\n /**\n * Get configured cache control max age.\n */\n getCacheControlMaxAge(): number {\n return this.resolvedConfig.cacheControlMaxAge;\n }\n}\n","/**\n * Vercel Blob Storage Plugin\n *\n * Factory function that creates a storage plugin for Vercel Blob Storage.\n * Returns a StoragePlugin that can be registered with MediaStorage.\n *\n * @example Basic usage\n * ```typescript\n * import { vercelBlobStorage } from '@nextly/storage-vercel-blob'\n * import { defineConfig } from 'nextly/config'\n *\n * export default defineConfig({\n * storage: [\n * vercelBlobStorage({\n * token: process.env.BLOB_READ_WRITE_TOKEN,\n * collections: {\n * media: true\n * }\n * })\n * ]\n * })\n * ```\n *\n * @example With client uploads (recommended for Vercel)\n * ```typescript\n * vercelBlobStorage({\n * collections: {\n * media: {\n * clientUploads: true // Bypass 4.5MB serverless limit\n * }\n * }\n * })\n * ```\n *\n * @example With collection-specific configuration\n * ```typescript\n * vercelBlobStorage({\n * addRandomSuffix: true,\n * cacheControlMaxAge: 86400, // 1 day\n * collections: {\n * // Simple enable with defaults\n * media: true,\n *\n * // Full configuration\n * documents: {\n * prefix: 'docs/',\n * addRandomSuffix: false,\n * allowOverwrite: true\n * }\n * }\n * })\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { StoragePlugin, ClientUploadData } from \"nextly/storage\";\n\nimport { VercelBlobStorageAdapter } from \"./adapter\";\nimport type { VercelBlobStorageConfig } from \"./types\";\n\n// ============================================================\n// Plugin Factory Function\n// ============================================================\n\n/**\n * Create a Vercel Blob storage plugin for Nextly.\n *\n * This factory function creates a StoragePlugin that can be added to\n * the `storage` array in `nextly.config.ts`. Vercel Blob is optimized\n * for Vercel deployments with:\n *\n * - Global CDN distribution\n * - Simple token-based authentication\n * - Client-side upload support (via handleUpload API)\n * - Automatic file management\n *\n * @param config - Vercel Blob storage configuration\n * @returns A StoragePlugin that MediaStorage can register\n *\n * @throws Error if token is not provided (via adapter)\n */\nexport function vercelBlobStorage(\n config: VercelBlobStorageConfig\n): StoragePlugin {\n // Handle disabled plugin\n // When disabled, return a plugin with no collections and null adapter\n // MediaStorage.registerPlugin() checks for null adapter and skips registration\n if (config.enabled === false) {\n return {\n name: \"vercel-blob-storage\",\n type: \"vercel-blob\",\n collections: {},\n adapter: null as unknown as StoragePlugin[\"adapter\"],\n };\n }\n\n // Create the Vercel Blob adapter\n // Adapter constructor validates required config (token)\n const adapter = new VercelBlobStorageAdapter(config);\n\n // Build and return the plugin\n const plugin: StoragePlugin = {\n name: \"vercel-blob-storage\",\n type: \"vercel-blob\",\n collections: config.collections,\n adapter,\n\n /**\n * Generate upload URL for client-side uploads.\n *\n * Note: Vercel Blob uses a different pattern for client uploads.\n * Instead of pre-signed URLs, it uses the handleUpload() API which\n * requires server-side route handlers.\n *\n * This method throws an error explaining the correct approach.\n *\n * @see https://vercel.com/docs/storage/vercel-blob/client-upload\n */\n getClientUploadUrl(\n _filename: string,\n _mimeType: string,\n _collection: string\n ): Promise<ClientUploadData> {\n // Vercel Blob doesn't use pre-signed URLs like S3\n // Instead, it requires using the handleUpload API with @vercel/blob/client\n return Promise.reject(\n new Error(\n \"@nextly/storage-vercel-blob: Client uploads require the handleUpload API.\\n\\n\" +\n \"Vercel Blob uses a different pattern than S3 for client-side uploads:\\n\\n\" +\n \"1. Create a server-side route handler with handleUpload()\\n\" +\n \"2. Use upload() from @vercel/blob/client on the frontend\\n\\n\" +\n \"See: https://vercel.com/docs/storage/vercel-blob/client-upload\"\n )\n );\n },\n\n /**\n * Get signed download URL for file access.\n *\n * Note: Vercel Blob URLs are public by default and do not support\n * signed/temporary URLs. All uploaded blobs are accessible via their\n * public URL.\n *\n * @param path - Storage path (full blob URL)\n * @returns The same URL (Vercel Blob URLs are public)\n */\n getSignedDownloadUrl(path: string): Promise<string> {\n // Vercel Blob URLs are public by default\n // No signed URL support - just return the public URL\n return Promise.resolve(path);\n },\n };\n\n return plugin;\n}\n","/**\n * @nextly/storage-vercel-blob\n *\n * Vercel Blob storage adapter for Nextly CMS.\n * Optimized for Vercel deployments with client-side upload support\n * to bypass serverless function size limits (4.5MB).\n *\n * @example Basic usage\n * ```typescript\n * import { vercelBlobStorage } from '@nextly/storage-vercel-blob'\n * import { defineConfig } from 'nextly/config'\n *\n * export default defineConfig({\n * storage: [\n * vercelBlobStorage({\n * token: process.env.BLOB_READ_WRITE_TOKEN,\n * collections: {\n * media: true\n * }\n * })\n * ]\n * })\n * ```\n *\n * @example With client uploads (recommended for Vercel)\n * ```typescript\n * vercelBlobStorage({\n * collections: {\n * media: {\n * clientUploads: true // Bypass 4.5MB serverless limit\n * }\n * }\n * })\n * ```\n *\n * @packageDocumentation\n */\n\n// ============================================================\n// Vercel Blob Storage Plugin Export (Primary API)\n// ============================================================\n\nexport { vercelBlobStorage } from \"./plugin\";\n\n// ============================================================\n// Vercel Blob Storage Adapter Export\n// ============================================================\n\nexport { VercelBlobStorageAdapter } from \"./adapter\";\n\n// ============================================================\n// Vercel Blob Types Export\n// ============================================================\n\nexport type {\n VercelBlobStorageConfig,\n VercelBlobCollectionConfig,\n VercelBlobCollectionStorageMap,\n ResolvedVercelBlobConfig,\n} from \"./types\";\n\n// ============================================================\n// Package Metadata\n// ============================================================\n\nexport const PACKAGE_NAME = \"@nextly/storage-vercel-blob\";\nexport const PACKAGE_VERSION = \"0.1.0\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextlyhq/storage-vercel-blob",
3
- "version": "0.0.2-alpha.64",
3
+ "version": "0.0.2-alpha.66",
4
4
  "description": "Vercel Blob storage adapter for Nextly",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -32,9 +32,9 @@
32
32
  "typescript": "^5.9.3",
33
33
  "vite-tsconfig-paths": "^5.1.4",
34
34
  "vitest": "^4.1.0",
35
- "@nextlyhq/eslint-config": "0.0.2-alpha.64",
36
- "@nextlyhq/tsconfig": "0.0.2-alpha.64",
37
- "nextly": "0.0.2-alpha.64"
35
+ "@nextlyhq/eslint-config": "0.0.2-alpha.66",
36
+ "@nextlyhq/tsconfig": "0.0.2-alpha.66",
37
+ "nextly": "0.0.2-alpha.66"
38
38
  },
39
39
  "keywords": [
40
40
  "nextly",