@stacksjs/server 0.70.23 → 0.70.26
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/server +0 -0
- package/dist/start.js.map +13 -0
- package/package.json +17 -12
- package/dist/config.d.ts +0 -3
- package/dist/imports.d.ts +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -418
package/dist/server
ADDED
|
Binary file
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../orm/routes.ts", "src/start.ts", "src/config-production.ts", "../../defaults/app/Routes.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * ORM-generated routes\n *\n * Auto-generates CRUD REST API routes based on model `useApi` trait definitions.\n * User-defined routes in ./routes/ are loaded first and always take priority.\n */\n\nimport type { EnhancedRequest } from '@stacksjs/bun-router'\nimport { route } from '@stacksjs/router'\nimport { projectPath } from '@stacksjs/path'\nimport { setConfig, createQueryBuilder } from '@stacksjs/query-builder'\nimport { HttpError } from '@stacksjs/error-handling'\n\n// Initialize query builder config from project's config/qb.ts\nconst qbConfigPath = projectPath('config/qb.ts')\nconst qbConfig = (await import(qbConfigPath)).default\nsetConfig(qbConfig)\n\n// Load all models from app/Models/ (individually, so one broken model doesn't block the rest)\nconst modelsDir = projectPath('app/Models')\nconst models: Record<string, any> = {}\n\ntry {\n const { readdirSync, statSync } = await import('node:fs')\n const { extname, basename } = await import('node:path')\n\n const entries = readdirSync(modelsDir)\n for (const entry of entries) {\n const full = `${modelsDir}/${entry}`\n const st = statSync(full)\n if (st.isDirectory()) continue\n const ext = extname(full)\n if (!['.ts', '.js'].includes(ext)) continue\n\n try {\n const mod = await import(`${full}?t=${Date.now()}`)\n const def = mod.default ?? mod\n const name = def.name ?? basename(entry, ext)\n models[name] = { ...def, name }\n }\n catch {\n // Skip models that fail to import (e.g., missing dependencies)\n }\n }\n}\ncatch {\n // Models directory may not exist yet\n}\n\n// Create a query builder instance (uses the config set above)\nconst db = createQueryBuilder()\n\n// Helper: check if a route is already registered (user-defined routes take priority)\nfunction routeExists(method: string, path: string): boolean {\n return route.routes.some(\n (r: any) => r.method === method && r.path === path,\n )\n}\n\n// Helper: get fillable attribute names from a model\nfunction getFillableFields(model: any): string[] {\n if (!model.attributes) return []\n return Object.entries(model.attributes)\n .filter(([_, attr]: [string, any]) => attr.fillable === true)\n .map(([name]: [string, any]) => name)\n}\n\n// Helper: get hidden attribute names from a model\nfunction getHiddenFields(model: any): string[] {\n if (!model.attributes) return []\n return Object.entries(model.attributes)\n .filter(([_, attr]: [string, any]) => attr.hidden === true)\n .map(([name]: [string, any]) => name)\n}\n\n// Helper: strip hidden fields from a record\nfunction stripHidden(record: any, hiddenFields: string[]): any {\n if (!record || hiddenFields.length === 0) return record\n const result = { ...record }\n for (const field of hiddenFields) {\n delete result[field]\n }\n return result\n}\n\n// Helper: filter request body to only fillable fields\nfunction filterFillable(body: any, fillableFields: string[]): Record<string, any> {\n if (!body || fillableFields.length === 0) return {}\n const result: Record<string, any> = {}\n for (const field of fillableFields) {\n if (field in body) {\n result[field] = body[field]\n }\n }\n return result\n}\n\n// Built-in cast resolvers — kept in sync with @stacksjs/orm/define-model.\n// A duplicate here is the simplest way to keep auto-CRUD parity with the\n// model-driven path without introducing a circular import.\nconst AUTO_CRUD_CASTERS: Record<string, { get: (v: unknown) => unknown, set: (v: unknown) => unknown }> = {\n string: { get: v => v != null ? String(v) : null, set: v => v != null ? String(v) : null },\n number: { get: v => v != null ? Number(v) : null, set: v => v != null ? Number(v) : null },\n integer: { get: v => v != null ? Math.trunc(Number(v)) : null, set: v => v != null ? Math.trunc(Number(v)) : null },\n float: { get: v => v != null ? Number.parseFloat(String(v)) : null, set: v => v != null ? Number.parseFloat(String(v)) : null },\n boolean: { get: v => v === 1 || v === '1' || v === true || v === 'true', set: v => (v === true || v === 1 || v === '1' || v === 'true') ? 1 : 0 },\n json: { get: v => v == null ? null : (typeof v === 'string' ? safeJSON(v) : v), set: v => v == null ? null : typeof v === 'string' ? v : JSON.stringify(v) },\n datetime: { get: v => v ? new Date(v as string) : null, set: v => v instanceof Date ? v.toISOString() : v },\n date: { get: v => v ? new Date(v as string) : null, set: v => v instanceof Date ? (v.toISOString().split('T')[0] as string) : v },\n array: { get: v => v == null ? [] : Array.isArray(v) ? v : (typeof v === 'string' ? safeJSONOrEmpty(v) : []), set: v => v == null ? null : Array.isArray(v) ? JSON.stringify(v) : v },\n}\n\nfunction safeJSON(s: string): unknown { try { return JSON.parse(s) } catch { return s } }\nfunction safeJSONOrEmpty(_s: string): unknown { try { return JSON.parse(_s) } catch { return [] } }\n\n// Run each declared `validation.rule` against an incoming write payload.\n// Returns { valid: true } or { valid: false, errors }. Per-attribute custom\n// messages from `validation.message` override the rule's default text.\n//\n// Skips fields the caller never sent on PATCH requests so a partial update\n// doesn't trip a \"required\" rule on a sibling field that wasn't touched.\nfunction validateWriteBody(\n _data: Record<string, any>,\n _model: any,\n _hook: 'creating' | 'updating',\n): { valid: true } | { valid: false, errors: Record<string, string[]> } {\n const data = _data\n const model = _model\n const hook = _hook\n const attrs = model?.attributes ?? {}\n const errors: Record<string, string[]> = {}\n for (const [field, def] of Object.entries(attrs as Record<string, any>)) {\n const rule: any = def?.validation?.rule\n if (!rule || typeof rule.validate !== 'function') continue\n const present = Object.prototype.hasOwnProperty.call(data, field)\n if (!present && hook === 'updating') continue\n const value = present ? data[field] : undefined\n const result = rule.validate(value)\n if (!result?.valid && Array.isArray(result?.errors) && result.errors.length > 0) {\n errors[field] = result.errors.map((e: any) =>\n def?.validation?.message?.[e?.code] ?? e?.message ?? 'invalid',\n )\n }\n }\n return Object.keys(errors).length === 0 ? { valid: true } : { valid: false, errors }\n}\n\n// Convert PascalCase model name to snake_case for default relation key\n// + FK convention (HostProfile → host_profile, host_profile_id).\nfunction toSnakeCase(s: string): string {\n return s.replace(/([a-z\\d])([A-Z])/g, '$1_$2').replace(/([A-Z])([A-Z][a-z])/g, '$1_$2').toLowerCase()\n}\n\n// Naive English pluralization for hasMany relation names. Matches\n// bun-query-builder's table-name convention (User → users, CarPhoto →\n// car_photos). Edge cases (mouse → mice, child → children) are not\n// covered — models that need them should override `useApi.uri`.\nfunction pluralize(s: string): string {\n if (s.endsWith('y') && !/[aeiou]y$/i.test(s)) return `${s.slice(0, -1)}ies`\n if (/(?:s|x|z|ch|sh)$/i.test(s)) return `${s}es`\n return `${s}s`\n}\n\n/**\n * Eager-load `belongsTo` + `hasMany` relations declared on a model and\n * attach them under snake_case keys on each row. Hidden fields are\n * recursively stripped from every loaded relation so a `?include=user`\n * on a Booking can never leak the user's password hash even if a future\n * model marks it fillable.\n *\n * Limited to one level of depth — `?include=user.host_profile` would\n * need a recursive walker that's beyond the scope of the v1 implementation.\n */\nasync function applyIncludes(\n rows: any[],\n model: any,\n includeParam: string,\n modelsRegistry: Record<string, any>,\n): Promise<any[]> {\n if (!rows.length) return rows\n const requested = includeParam.split(',').map(s => s.trim()).filter(Boolean)\n if (!requested.length) return rows\n\n const belongsTo: string[] = Array.isArray(model.belongsTo) ? model.belongsTo : []\n const hasMany: string[] = Array.isArray(model.hasMany) ? model.hasMany : []\n const hasOne: string[] = Array.isArray(model.hasOne) ? model.hasOne : []\n\n // Build a lookup: snake_case include key → { kind, modelName }\n const allowed = new Map<string, { kind: 'belongsTo' | 'hasOne' | 'hasMany', modelName: string }>()\n for (const m of belongsTo) allowed.set(toSnakeCase(m), { kind: 'belongsTo', modelName: m })\n for (const m of hasOne) allowed.set(toSnakeCase(m), { kind: 'hasOne', modelName: m })\n for (const m of hasMany) allowed.set(pluralize(toSnakeCase(m)), { kind: 'hasMany', modelName: m })\n\n for (const include of requested) {\n const meta = allowed.get(include)\n if (!meta) continue // silently drop unknown includes — same shape as filter handling\n const related = modelsRegistry[meta.modelName]\n if (!related) continue\n const relatedTable = related.table || pluralize(toSnakeCase(meta.modelName))\n const relatedHidden = getHiddenFields(related)\n const relatedAttrs = (id: any) => stripHidden(applyReadCasts(id, related), relatedHidden)\n\n if (meta.kind === 'belongsTo' || meta.kind === 'hasOne') {\n const fkOnParent = `${toSnakeCase(meta.modelName)}_id`\n const ids = [...new Set(rows.map(r => r[fkOnParent]).filter(v => v != null))]\n if (!ids.length) {\n for (const r of rows) r[include] = null\n continue\n }\n const childRows = await (db as any).selectFrom(relatedTable).whereIn('id', ids).get()\n const byId = new Map<string, any>()\n for (const cr of childRows ?? []) byId.set(String(cr.id), relatedAttrs(cr))\n for (const r of rows) r[include] = byId.get(String(r[fkOnParent])) ?? null\n }\n else {\n // hasMany: child rows have parent_id pointing back at us.\n const parentName = String(model.name ?? '')\n const fkOnChild = `${toSnakeCase(parentName)}_id`\n const parentIds = [...new Set(rows.map(r => r.id).filter(v => v != null))]\n if (!parentIds.length) {\n for (const r of rows) r[include] = []\n continue\n }\n const childRows = await (db as any).selectFrom(relatedTable).whereIn(fkOnChild, parentIds).get()\n const grouped = new Map<string, any[]>()\n for (const cr of childRows ?? []) {\n const key = String(cr[fkOnChild])\n const arr = grouped.get(key) ?? []\n arr.push(relatedAttrs(cr))\n grouped.set(key, arr)\n }\n for (const r of rows) r[include] = grouped.get(String(r.id)) ?? []\n }\n }\n return rows\n}\n\n// Drop attribute keys flagged `hidden: true` from an incoming write body.\n// `hidden` already protects the response shape; this protects the request\n// shape so a curious client can't sneak `payment_intent_id` into a PATCH\n// even when the field is fillable for internal callers.\nfunction dropHiddenInputs(data: Record<string, any>, hiddenFields: string[]): Record<string, any> {\n if (!hiddenFields.length) return data\n const out: Record<string, any> = { ...data }\n for (const f of hiddenFields) delete out[f]\n return out\n}\n\n// Apply user-defined `set:` hooks (e.g. User.set.password = bcrypt) before\n// raw DB writes so the auto-CRUD store/update endpoints don't end up storing\n// plaintext where the model declared a transformation. Mirrors the helper\n// in @stacksjs/orm/define-model — duplicated here to avoid a circular\n// import. Errors from individual setters are swallowed (logged in\n// define-model's version) so a single broken setter can't kill the whole\n// payload.\nasync function applyDefinedSetters(data: Record<string, any>, model: any): Promise<Record<string, any>> {\n const setters: Record<string, (attrs: Record<string, unknown>) => unknown> | undefined = model?.set\n if (!setters || typeof setters !== 'object') return data\n const out: Record<string, any> = { ...data }\n for (const [key, fn] of Object.entries(setters)) {\n if (typeof fn !== 'function' || !(key in out)) continue\n try {\n out[key] = await fn(out)\n }\n catch { /* surfaced via define-model's logger */ }\n }\n return out\n}\n\n// Apply set-side casts (input → DB shape) so PATCH /api/cars/{id} with\n// `{ instant_book: true }` writes `1`, matching what model.create() does.\nfunction applySetCasts(data: Record<string, any>, model: any): Record<string, any> {\n const casts: Record<string, string | { get: any, set: any }> = model?.casts ?? {}\n if (!casts || Object.keys(casts).length === 0 || !data) return data\n const out: Record<string, any> = { ...data }\n for (const [attr, castDef] of Object.entries(casts)) {\n if (Object.prototype.hasOwnProperty.call(out, attr)) {\n const caster = typeof castDef === 'string' ? AUTO_CRUD_CASTERS[castDef] : castDef\n if (caster) out[attr] = caster.set(out[attr])\n }\n }\n return out\n}\n\n// Apply read-side casts (DB shape → JS-typed values) so the auto-CRUD\n// returns `instant_book: true` instead of the raw SQLite text `\"1\"`.\nfunction applyReadCasts(row: any, model: any): any {\n const casts: Record<string, string | { get: any, set: any }> = model?.casts ?? {}\n if (!row || typeof row !== 'object' || !casts || Object.keys(casts).length === 0) return row\n const out: Record<string, any> = { ...row }\n for (const [attr, castDef] of Object.entries(casts)) {\n if (Object.prototype.hasOwnProperty.call(out, attr)) {\n const caster = typeof castDef === 'string' ? AUTO_CRUD_CASTERS[castDef] : castDef\n if (caster) out[attr] = caster.get(out[attr])\n }\n }\n return out\n}\n\n// Helper: create JSON response\nfunction jsonResponse(data: any, status = 200): Response {\n return new Response(JSON.stringify(data), {\n status,\n headers: { 'Content-Type': 'application/json' },\n })\n}\n\n// Same as jsonResponse but stamps `request_id` into the body for error\n// envelopes. Pairs with the X-Request-ID response header so SPAs + RUM\n// tooling can correlate a user-facing error to a specific log line\n// without relying on header capture.\nfunction errorResponse(req: any, body: Record<string, any>, status = 400): Response {\n const reqId = req?._requestId\n const enriched = reqId ? { ...body, request_id: reqId } : body\n return new Response(JSON.stringify(enriched), {\n status,\n headers: { 'Content-Type': 'application/json' },\n })\n}\n\n// Helper: get request body (uses pre-parsed body from stacks-router middleware, falls back to clone).\n// Throws an HttpError on malformed JSON so the route handler can return 400 rather than silently\n// treating a corrupted payload as `{}` (which previously surfaced as \"No fillable fields\" 422s\n// and made debugging client bugs impossible).\n// Cap any single request body at this many bytes. 1 MB is generous for\n// JSON CRUD payloads (a 6-photo car listing is ~5 KB) but tight enough\n// that a hostile client can't park a 50 MB body and tie up the parser.\n// File uploads have their own multipart pipeline upstream and don't\n// route through this helper.\nconst MAX_BODY_BYTES = 1_048_576\n\nasync function getRequestBody(req: EnhancedRequest): Promise<Record<string, any>> {\n // Body-size check runs FIRST so even pre-parsed bodies (jsonBody attached\n // by upstream middleware) can't slip past the cap. We trust the\n // advertised content-length header here — clients that lie about it\n // get caught when the actual text is read below.\n const contentLength = Number(req.headers?.get?.('content-length') ?? 0)\n if (contentLength > MAX_BODY_BYTES)\n throw new HttpError(413, `Request body exceeds ${MAX_BODY_BYTES}-byte limit`)\n\n if ((req as any).jsonBody && typeof (req as any).jsonBody === 'object') {\n return (req as any).jsonBody\n }\n if ((req as any).formBody && typeof (req as any).formBody === 'object') {\n return (req as any).formBody\n }\n\n try {\n const text = await req.clone().text()\n if (text.length > MAX_BODY_BYTES)\n throw new HttpError(413, `Request body exceeds ${MAX_BODY_BYTES}-byte limit`)\n if (!text) return {}\n const parsed = JSON.parse(text)\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {}\n }\n catch (err) {\n if (err instanceof HttpError) throw err\n throw new HttpError(400, `Invalid JSON body: ${(err as Error).message}`)\n }\n}\n\n// Helper: coerce a primary-key-shaped value submitted by a client (bulk-delete IDs,\n// path params, etc.) into a number when the column looks numeric, or pass through\n// when it's a non-empty string (UUID, slug). Anything else becomes null and the\n// caller should reject with 422.\nfunction coerceId(raw: unknown): number | string | null {\n if (raw == null) return null\n if (typeof raw === 'number') return Number.isFinite(raw) && raw > 0 ? raw : null\n if (typeof raw === 'string') {\n const trimmed = raw.trim()\n if (!trimmed) return null\n if (/^\\d+$/.test(trimmed)) {\n const n = Number(trimmed)\n return Number.isFinite(n) && n > 0 ? n : null\n }\n return trimmed\n }\n return null\n}\n\n// Apply sort parameter to a query builder chain. Comma-separated tokens\n// each optionally `-` prefixed for descending. bun-query-builder's\n// `orderBy` is now compose-aware — chaining multiple calls produces a\n// single `ORDER BY a ASC, b DESC` clause.\n//\n// Examples:\n// ?sort=name → ORDER BY name ASC\n// ?sort=-rating → ORDER BY rating DESC\n// ?sort=-rating,name → ORDER BY rating DESC, name ASC\nfunction applySorting(query: any, sortParam: string | null, _table: string): any {\n if (!sortParam) return query\n const tokens = String(sortParam).split(',').map(t => t.trim()).filter(Boolean)\n let q = query\n for (const tok of tokens) {\n const desc = tok.startsWith('-')\n const column = desc ? tok.slice(1) : tok\n if (!/^\\w+$/.test(column)) continue\n q = q.orderBy(column, desc ? 'desc' : 'asc')\n }\n return q\n}\n\n// Helper: extract bearer token from a request, falling back to the raw header\n// when the enhanced request hasn't attached a `bearerToken()` method.\nfunction bearerOf(req: EnhancedRequest): string | null {\n const fn = (req as any).bearerToken\n if (typeof fn === 'function') {\n const t = fn.call(req)\n if (t) return t\n }\n const auth = req.headers?.get?.('authorization') || req.headers?.get?.('Authorization') || ''\n if (typeof auth === 'string' && auth.startsWith('Bearer '))\n return auth.substring(7)\n return null\n}\n\n// Helper: resolve the authed user via the @stacksjs/auth façade — used by the\n// `authedFill` model option to derive ownership-stamping fields like\n// `host_profile_id` from the requesting user. Returns null when unauthed.\nasync function authedUserFromRequest(req: EnhancedRequest): Promise<any | null> {\n const stored = (req as any)._authenticatedUser\n if (stored) return stored\n const token = bearerOf(req)\n if (!token) return null\n try {\n const { Auth } = await import('@stacksjs/auth')\n const user = await (Auth as any).getUserFromToken(token)\n if (user) (req as any)._authenticatedUser = user\n return user || null\n }\n catch {\n return null\n }\n}\n\n// Helper: resolve the authed user's \"owner identity\" for a given model so\n// the auto-CRUD update/destroy/bulk-destroy paths can compare it against\n// the row's `field`.\n//\n// `ownership` model config shape:\n// ownership: {\n// field: 'host_profile_id', // column on this row\n// resolve: async (user) => number?, // what value of `field` does\n// // the authed user own?\n// bypass?: (user) => boolean, // optional admin escape hatch\n// }\n//\n// Returns the resolved owner value, or `null` if the model has no\n// ownership config (caller should treat as \"no per-row check\").\n// Helper: do row's ownership field value belong to the resolved owner?\n// Supports both scalar (single owner id) and array (set of allowed ids,\n// useful for two-hop ownership where a Photo's car_id must be ∈ the\n// authed host's owned car ids).\nfunction ownsRow(rowField: unknown, ownerValue: unknown): boolean {\n if (rowField == null || ownerValue == null) return false\n if (Array.isArray(ownerValue))\n return ownerValue.some(v => String(v) === String(rowField))\n return String(rowField) === String(ownerValue)\n}\n\nasync function resolveOwnership(\n model: any,\n user: any,\n req: EnhancedRequest,\n): Promise<{ enforced: boolean, value: unknown, field: string, bypass: boolean }> {\n const cfg = model?.ownership\n if (!cfg || !cfg.field || typeof cfg.resolve !== 'function')\n return { enforced: false, value: null, field: '', bypass: false }\n const bypass = typeof cfg.bypass === 'function' ? !!cfg.bypass(user, req) : false\n let value: unknown = null\n try {\n value = await cfg.resolve(user, req)\n }\n catch { value = null }\n return { enforced: true, value, field: String(cfg.field), bypass }\n}\n\n// Helper: apply a model's `authedFill` config for the given lifecycle hook.\n// Returns a partial object to merge into the insert/update payload.\nasync function resolveAuthedFill(\n model: any,\n hook: 'creating' | 'updating',\n user: any,\n req: EnhancedRequest,\n): Promise<Record<string, any>> {\n const cfg = model?.authedFill?.[hook]\n if (!cfg) return {}\n if (typeof cfg === 'function') {\n try {\n const result = await cfg(user, req)\n return result && typeof result === 'object' ? result : {}\n }\n catch {\n return {}\n }\n }\n if (typeof cfg === 'object') {\n const out: Record<string, any> = {}\n for (const [field, getter] of Object.entries(cfg)) {\n try {\n out[field] = typeof getter === 'function' ? await (getter as any)(user, req) : getter\n }\n catch { /* ignore individual getter errors */ }\n }\n return out\n }\n return {}\n}\n\n// Register CRUD routes for each model with useApi trait\nfor (const [modelName, model] of Object.entries(models)) {\n const useApi = model.traits?.useApi\n if (!useApi) continue\n\n // useApi can be `true` (auto-derive uri from table) or an object with { uri, routes }\n const apiConfig = typeof useApi === 'object' ? useApi : {}\n const uri = apiConfig.uri || model.table || modelName.toLowerCase() + 's'\n\n const enabledRoutes: string[] = apiConfig.routes || ['index', 'show', 'store', 'update', 'destroy']\n const table = model.table || uri\n const fillableFields = getFillableFields(model)\n const hiddenFields = getHiddenFields(model)\n const basePath = `/api/${uri}`\n\n // Per-model middleware list, applied to every CRUD route this model\n // generates. Honors the `useApi.middleware` field declared on the\n // model trait (e.g. `middleware: ['auth']` for resources that should\n // never be browsed anonymously). Without this, auto-generated REST\n // routes are unauthenticated by default — fine for public catalog\n // tables (products, posts), wrong for anything PII-shaped\n // (subscribers, customers, orders).\n const apiMiddleware: string[] = Array.isArray((apiConfig as any).middleware)\n ? ((apiConfig as any).middleware as string[]).filter(m => typeof m === 'string' && m.length > 0)\n : (typeof (apiConfig as any).middleware === 'string' && (apiConfig as any).middleware\n ? [(apiConfig as any).middleware]\n : [])\n\n // Local helper: chain `.middleware()` for every entry in `apiMiddleware`.\n // The chainable return value from `route.get/post/...` accepts one\n // name per call, so we fold the list into successive calls.\n const applyMiddleware = (chain: any): any => {\n let r = chain\n for (const name of apiMiddleware) {\n if (r && typeof r.middleware === 'function') r = r.middleware(name)\n }\n return r\n }\n\n // GET /api/{uri} — list all records (paginated, sortable)\n if (enabledRoutes.includes('index') && !routeExists('GET', basePath)) {\n applyMiddleware(route.get(basePath, async (req: EnhancedRequest) => {\n try {\n const url = new URL(req.url)\n const page = Number.parseInt(url.searchParams.get('page') || '1', 10)\n const perPage = Math.min(Number.parseInt(url.searchParams.get('per_page') || '25', 10), 100)\n const offset = (page - 1) * perPage\n const sort = url.searchParams.get('sort')\n\n let query = (db as any).selectFrom(table)\n query = applySorting(query, sort, table)\n\n // Apply query string filters: ?status=active&name=foo filters by column values.\n // Reserved query params (pagination, sort, etc.) are skipped. Filter keys are\n // validated against the model's declared attribute keys + system columns —\n // an unknown key is ignored rather than emitted as raw SQL (e.g. `WHERE limit = ?`\n // would blow up because `limit` is a SQL keyword).\n const RESERVED = new Set(['page', 'per_page', 'sort', 'fields', 'search', 'include', 'limit', 'offset', 'with_count', 'withTrashed', 'onlyTrashed'])\n const SYSTEM_COLUMNS = new Set(['id', 'uuid', 'created_at', 'updated_at', 'deleted_at'])\n const validColumns = new Set([\n ...Object.keys(model.attributes ?? {}),\n ...SYSTEM_COLUMNS,\n ])\n for (const [key, value] of url.searchParams.entries()) {\n if (RESERVED.has(key) || !value) continue\n if (validColumns.has(key) && /^[a-z_][a-z0-9_]*$/i.test(key)) {\n query = query.where(key, '=', value)\n }\n }\n\n // Apply search across fillable text fields: ?search=keyword\n const searchTerm = url.searchParams.get('search')\n if (searchTerm && fillableFields.length > 0) {\n const textFields = fillableFields.slice(0, 5) // Limit to first 5 fields for performance\n query = query.where((qb: any) => {\n for (const field of textFields) {\n qb = qb.orWhere(field, 'like', `%${searchTerm}%`)\n }\n return qb\n })\n }\n\n // Apply field selection: ?fields=id,name,email\n const fieldsParam = url.searchParams.get('fields')\n if (fieldsParam) {\n const selectedFields = fieldsParam.split(',').filter(f => /^[a-z_][a-z0-9_]*$/i.test(f.trim()))\n if (selectedFields.length > 0) {\n query = query.select(selectedFields.map((f: string) => f.trim()))\n }\n }\n\n // Soft-delete filtering. By default the index hides deleted_at IS NOT NULL\n // rows; ?withTrashed=true includes them, ?onlyTrashed=true returns only\n // them (admin/audit views). Skip silently if the trait isn't enabled.\n const usesSoftDeletes = !!model.traits?.useSoftDeletes\n const withTrashed = url.searchParams.get('withTrashed') === 'true'\n const onlyTrashed = url.searchParams.get('onlyTrashed') === 'true'\n if (usesSoftDeletes && !withTrashed) {\n query = onlyTrashed ? query.whereNotNull('deleted_at') : query.whereNull('deleted_at')\n }\n\n const results = await query.limit(perPage).offset(offset).get()\n let records = (results || []).map((r: any) => stripHidden(applyReadCasts(r, model), hiddenFields))\n\n const includeParam = url.searchParams.get('include')\n if (includeParam)\n records = await applyIncludes(records, model, includeParam, models)\n\n // Total count is opt-in via ?with_count=true. Skipping it by default\n // turns the index from \"two queries every request\" into \"one\", which\n // is a meaningful win on big tables — the SPA usually paginates by\n // \"load more\" anyway and doesn't need a precise total.\n const wantCount = url.searchParams.get('with_count') === 'true'\n let total: number | undefined\n if (wantCount) {\n try {\n // bun-query-builder's count() resolves to a number directly —\n // not to a builder you call executeTakeFirst() on. The previous\n // shape silently swallowed a TypeError in this try/catch and\n // total stayed `undefined`, defeating the whole opt-in.\n const raw = await (db as any).selectFrom(table).count()\n const n = typeof raw === 'number' ? raw : Number(raw?.count ?? raw)\n if (Number.isFinite(n)) total = n\n } catch {\n // count() may not be supported by all query builder versions\n }\n }\n\n const respHeaders: Record<string, string> = { 'Content-Type': 'application/json' }\n if (total !== undefined && !Number.isNaN(total)) respHeaders['X-Total-Count'] = String(total)\n // Modest caching for unauthenticated browse — list views change\n // less frequently than detail views and SPAs naturally re-hit them\n // on navigation. Authed lists (which include user-specific filter\n // results) carry a `Vary: Authorization` so caches don't merge\n // them with the public response.\n respHeaders['Cache-Control'] = 'public, max-age=15, must-revalidate'\n respHeaders.Vary = 'Authorization'\n\n return new Response(JSON.stringify({\n data: records,\n meta: {\n page,\n per_page: perPage,\n ...(total !== undefined && !Number.isNaN(total) ? { total, last_page: Math.ceil(total / perPage) } : {}),\n },\n }), { status: 200, headers: respHeaders })\n }\n catch (err) {\n if (err instanceof HttpError) {\n const body: Record<string, unknown> = { error: err.message }\n if (err.details !== undefined) body.details = err.details\n return jsonResponse(body, err.status || 400)\n }\n return jsonResponse({ error: `Failed to fetch ${uri}`, detail: String(err) }, 500)\n }\n }))\n }\n\n // GET /api/{uri}/{id} — show single record\n if (enabledRoutes.includes('show') && !routeExists('GET', `${basePath}/{id}`)) {\n applyMiddleware(route.get(`${basePath}/{id}`, async (req: EnhancedRequest) => {\n try {\n const id = coerceId((req as any).params?.id)\n\n // Validate ID parameter — coerceId returns null for negatives,\n // empty strings, NaN, etc., so this single check catches them all.\n if (id == null) {\n return jsonResponse({ error: 'Invalid ID parameter' }, 400)\n }\n\n const result = await (db as any).selectFrom(table).where({ id }).executeTakeFirst()\n\n if (!result) {\n return jsonResponse({ error: `${modelName} not found` }, 404)\n }\n\n // Mirror the soft-delete filter from the index handler — without\n // this, GET /api/cars/123 would happily return a row that was\n // soft-deleted, even though it doesn't appear in the listing.\n const url = new URL(req.url)\n if (model.traits?.useSoftDeletes && (result as any).deleted_at && url.searchParams.get('withTrashed') !== 'true') {\n return jsonResponse({ error: `${modelName} not found` }, 404)\n }\n\n let payload: any = stripHidden(applyReadCasts(result, model), hiddenFields)\n\n // ?include=user,host_profile,car_photos hydrates declared relations.\n // Hidden fields are recursively stripped from each loaded relation.\n const includeParam = url.searchParams.get('include')\n if (includeParam) {\n const [withRel] = await applyIncludes([payload], model, includeParam, models)\n payload = withRel\n }\n\n // ETag derived from updated_at (or created_at) lets SPAs send\n // If-None-Match and short-circuit re-renders. The 304 response is\n // empty per spec — the client keeps its cached copy. Skip when the\n // request is authed because per-user variants would poison shared\n // caches.\n const lastWrite = (payload as any)?.updated_at || (payload as any)?.created_at\n const etag = lastWrite ? `W/\"${(payload as any).id}-${String(lastWrite)}\"` : undefined\n const ifNoneMatch = req.headers?.get?.('if-none-match')\n if (etag && ifNoneMatch && ifNoneMatch === etag) {\n return new Response(null, { status: 304, headers: { ETag: etag } })\n }\n\n const headers: Record<string, string> = { 'Content-Type': 'application/json' }\n if (etag) headers.ETag = etag\n // Public caches default to a short TTL — long enough for SPA list/detail\n // hops to share, short enough that a stale row clears within a minute.\n headers['Cache-Control'] = 'public, max-age=30, must-revalidate'\n return new Response(JSON.stringify({ data: payload }), { status: 200, headers })\n }\n catch (err) {\n if (err instanceof HttpError) {\n const body: Record<string, unknown> = { error: err.message }\n if (err.details !== undefined) body.details = err.details\n return jsonResponse(body, err.status || 400)\n }\n return jsonResponse({ error: `Failed to fetch ${modelName}`, detail: String(err) }, 500)\n }\n }))\n }\n\n // POST /api/{uri} — create record\n if (enabledRoutes.includes('store') && !routeExists('POST', basePath)) {\n applyMiddleware(route.post(basePath, async (req: EnhancedRequest) => {\n try {\n const body = await getRequestBody(req)\n // Belt-and-suspenders: drop hidden inputs FIRST so a curious client\n // can't sneak `payment_intent_id` etc. into a POST even if a future\n // change accidentally flips them to fillable.\n const safeBody = dropHiddenInputs(body, hiddenFields)\n const data = filterFillable(safeBody, fillableFields)\n\n // Stamp ownership / context-aware fields from the authed user before\n // the body fillable check, so models can declare e.g.\n // authedFill: { creating: { host_profile_id: async (u) => ... } }\n // and never have to ship a custom Store action just to attach FKs.\n const authedUser = await authedUserFromRequest(req)\n if (authedUser) {\n const stamped = await resolveAuthedFill(model, 'creating', authedUser, req)\n for (const [k, v] of Object.entries(stamped)) {\n if (v !== undefined && v !== null && data[k] === undefined)\n data[k] = v\n }\n }\n\n if (Object.keys(data).length === 0) {\n return jsonResponse({ error: 'No fillable fields provided' }, 422)\n }\n\n // Run declared validation rules. Models declare `validation: { rule:\n // schema.string().required().email() }` per attribute — without this\n // call, those declarations were dead documentation.\n const v = validateWriteBody(data, model, 'creating')\n if (!v.valid) return jsonResponse({ error: 'Validation failed', errors: v.errors }, 422)\n\n // Add timestamps if model uses them\n if (model.traits?.useTimestamps !== false) {\n const now = new Date().toISOString()\n data.created_at = now\n data.updated_at = now\n }\n\n // 1) User-defined `set:` hooks first (e.g. User.set.password = bcrypt)\n // so plaintext inputs never reach the DB on POST /api/users.\n // 2) Then the cast pass so booleans/JSON/dates are coerced to the\n // column shape (mirror of model.create() write path).\n const hookedData = await applyDefinedSetters(data, model)\n const writeData = applySetCasts(hookedData, model)\n\n const result = await (db as any).insertInto(table).values(writeData).execute()\n\n // Try to return the full record with database-assigned ID\n let created = writeData\n try {\n const lastId = result?.lastInsertRowid ?? result?.insertId ?? result\n if (lastId) {\n const fetched = await (db as any).selectFrom(table).where({ id: lastId }).executeTakeFirst()\n if (fetched) created = fetched\n }\n } catch {\n // Fall back to returning the input data\n }\n\n return jsonResponse({ data: stripHidden(applyReadCasts(created, model), hiddenFields) }, 201)\n }\n catch (err) {\n if (err instanceof HttpError) {\n const body: Record<string, unknown> = { error: err.message }\n if (err.details !== undefined) body.details = err.details\n return jsonResponse(body, err.status || 400)\n }\n return jsonResponse({ error: `Failed to create ${modelName}`, detail: String(err) }, 500)\n }\n }))\n }\n\n // PUT/PATCH /api/{uri}/{id} — update record\n if (enabledRoutes.includes('update')) {\n const updateHandler = async (req: EnhancedRequest) => {\n try {\n const id = coerceId((req as any).params?.id)\n if (id == null) {\n return jsonResponse({ error: 'Invalid ID parameter' }, 400)\n }\n const body = await getRequestBody(req)\n const safeBody = dropHiddenInputs(body, hiddenFields)\n const data = filterFillable(safeBody, fillableFields)\n\n // Apply authedFill.updating stamps (mirror of the Store path).\n const authedUser = await authedUserFromRequest(req)\n if (authedUser) {\n const stamped = await resolveAuthedFill(model, 'updating', authedUser, req)\n for (const [k, v] of Object.entries(stamped)) {\n if (v !== undefined && v !== null && data[k] === undefined)\n data[k] = v\n }\n }\n\n if (Object.keys(data).length === 0) {\n return jsonResponse({ error: 'No fillable fields provided' }, 422)\n }\n\n // Run declared validation rules. Partial updates only validate fields\n // the caller actually sent — see validateWriteBody for the rule.\n const v = validateWriteBody(data, model, 'updating')\n if (!v.valid) return jsonResponse({ error: 'Validation failed', errors: v.errors }, 422)\n\n // 404 fast if the row doesn't exist — previously the UPDATE silently\n // matched zero rows and we returned the request body as if it had\n // succeeded, which masked legit \"deleted between read and write\" bugs.\n const existing = await (db as any).selectFrom(table).where({ id }).executeTakeFirst()\n if (!existing) {\n return jsonResponse({ error: `${modelName} not found` }, 404)\n }\n\n // Ownership check: when the model declares `ownership`, only the row's\n // owner (or an admin via `bypass`) can update it. Without this, any\n // authed user could PATCH /api/cars/{id} and re-parent another host's\n // car to themselves. `authedFill.updating` ALSO can't defend on its\n // own because it only fills missing fields, not replaces submitted ones.\n const own = await resolveOwnership(model, authedUser, req)\n if (own.enforced && !own.bypass) {\n if (!authedUser) return jsonResponse({ error: 'Auth required' }, 401)\n const rowOwner = (existing as Record<string, unknown>)[own.field]\n if (!ownsRow(rowOwner, own.value)) {\n return jsonResponse({ error: `Not your ${modelName}` }, 403)\n }\n // Also defend against the request trying to re-parent ownership.\n if (own.field in data && !ownsRow(data[own.field], own.value)) {\n return jsonResponse({ error: `Cannot reassign ${modelName} ownership` }, 403)\n }\n }\n\n // Add updated_at timestamp\n if (model.traits?.useTimestamps !== false) {\n data.updated_at = new Date().toISOString()\n }\n\n // Same hook+cast pass as the create path — and crucially the set-hooks\n // must run too, otherwise `PATCH /api/users/{id}` with a password\n // field would store plaintext.\n const hookedData = await applyDefinedSetters(data, model)\n const writeData = applySetCasts(hookedData, model)\n\n await (db as any).updateTable(table).set(writeData).where({ id }).execute()\n\n // Return the full updated record\n let updated: any = { ...existing, ...writeData }\n try {\n const fetched = await (db as any).selectFrom(table).where({ id }).executeTakeFirst()\n if (fetched) updated = fetched\n } catch {\n // Fall back to merging known existing + diff\n }\n\n return jsonResponse({ data: stripHidden(applyReadCasts(updated, model), hiddenFields) })\n }\n catch (err) {\n if (err instanceof HttpError) {\n const body: Record<string, unknown> = { error: err.message }\n if (err.details !== undefined) body.details = err.details\n return jsonResponse(body, err.status || 400)\n }\n return jsonResponse({ error: `Failed to update ${modelName}`, detail: String(err) }, 500)\n }\n }\n\n if (!routeExists('PUT', `${basePath}/{id}`)) {\n applyMiddleware(route.put(`${basePath}/{id}`, updateHandler))\n }\n if (!routeExists('PATCH', `${basePath}/{id}`)) {\n applyMiddleware(route.patch(`${basePath}/{id}`, updateHandler))\n }\n }\n\n // DELETE /api/{uri}/{id} — delete record (or soft-delete if model has useSoftDeletes).\n const usesSoftDeletes = !!model.traits?.useSoftDeletes\n if (enabledRoutes.includes('destroy') && !routeExists('DELETE', `${basePath}/{id}`)) {\n applyMiddleware(route.delete(`${basePath}/{id}`, async (req: EnhancedRequest) => {\n try {\n const id = coerceId((req as any).params?.id)\n if (id == null) {\n return jsonResponse({ error: 'Invalid ID parameter' }, 400)\n }\n\n // Need the row both for the 404 fast-path and the ownership check.\n const existing = await (db as any).selectFrom(table).where({ id }).executeTakeFirst()\n if (!existing) {\n return jsonResponse({ error: `${modelName} not found` }, 404)\n }\n\n const authedUser = await authedUserFromRequest(req)\n const own = await resolveOwnership(model, authedUser, req)\n if (own.enforced && !own.bypass) {\n if (!authedUser) return jsonResponse({ error: 'Auth required' }, 401)\n const rowOwner = (existing as Record<string, unknown>)[own.field]\n if (!ownsRow(rowOwner, own.value)) {\n return jsonResponse({ error: `Not your ${modelName}` }, 403)\n }\n }\n\n if (usesSoftDeletes) {\n // Soft delete: stamp deleted_at + updated_at instead of dropping the row.\n // Reads in the index handler filter `WHERE deleted_at IS NULL` unless\n // the caller passes ?withTrashed=true.\n const now = new Date().toISOString()\n await (db as any).updateTable(table)\n .set({ deleted_at: now, updated_at: now })\n .where({ id })\n .execute()\n }\n else {\n await (db as any).deleteFrom(table).where({ id }).execute()\n }\n\n return new Response(null, { status: 204 })\n }\n catch (err) {\n if (err instanceof HttpError) {\n const body: Record<string, unknown> = { error: err.message }\n if (err.details !== undefined) body.details = err.details\n return jsonResponse(body, err.status || 400)\n }\n return jsonResponse({ error: `Failed to delete ${modelName}`, detail: String(err) }, 500)\n }\n }))\n }\n\n // POST /api/{uri}/bulk-delete — delete multiple records (also soft-aware,\n // also ownership-checked per row).\n if (enabledRoutes.includes('destroy') && !routeExists('POST', `${basePath}/bulk-delete`)) {\n applyMiddleware(route.post(`${basePath}/bulk-delete`, async (req: EnhancedRequest) => {\n try {\n const body = await getRequestBody(req)\n const ids = body?.ids\n\n if (!Array.isArray(ids) || ids.length === 0) {\n return jsonResponse({ error: 'An array of IDs is required' }, 422)\n }\n\n // Limit bulk operations to 100 records\n if (ids.length > 100) {\n return jsonResponse({ error: 'Cannot delete more than 100 records at once' }, 422)\n }\n\n // Coerce + validate each ID before opening any transactions.\n // A single bad ID inside a 100-element batch previously fell through\n // to a SQL syntax error after partial deletes had already committed.\n const validIds: Array<number | string> = []\n const invalidIds: unknown[] = []\n for (const raw of ids) {\n const coerced = coerceId(raw)\n if (coerced != null) validIds.push(coerced)\n else invalidIds.push(raw)\n }\n if (invalidIds.length > 0) {\n return jsonResponse({ error: 'Invalid IDs in batch', invalid: invalidIds }, 422)\n }\n\n const authedUser = await authedUserFromRequest(req)\n const own = await resolveOwnership(model, authedUser, req)\n\n // For ownership-enforced models, refuse the whole batch if any row\n // isn't owned by the caller. Partial deletes are worse than nothing.\n if (own.enforced && !own.bypass) {\n if (!authedUser) return jsonResponse({ error: 'Auth required' }, 401)\n if (own.value == null) return jsonResponse({ error: 'Caller has no ownership identity' }, 403)\n const rows = await (db as any).selectFrom(table).select(['id', own.field]).execute()\n const ownedIds = new Set(\n (rows as Array<Record<string, unknown>>)\n .filter(r => ownsRow(r[own.field], own.value))\n .map(r => String(r.id)),\n )\n const notOwned = validIds.filter(id => !ownedIds.has(String(id)))\n if (notOwned.length > 0)\n return jsonResponse({ error: `Cannot delete ${modelName} you don't own`, ids: notOwned }, 403)\n }\n\n const now = new Date().toISOString()\n for (const id of validIds) {\n if (usesSoftDeletes) {\n await (db as any).updateTable(table)\n .set({ deleted_at: now, updated_at: now })\n .where({ id })\n .execute()\n }\n else {\n await (db as any).deleteFrom(table).where({ id }).execute()\n }\n }\n\n return jsonResponse({ message: `Successfully deleted ${validIds.length} ${uri}` })\n }\n catch (err) {\n if (err instanceof HttpError) {\n const body: Record<string, unknown> = { error: err.message }\n if (err.details !== undefined) body.details = err.details\n return jsonResponse(body, err.status || 400)\n }\n return jsonResponse({ error: `Failed to bulk delete ${uri}`, detail: String(err) }, 500)\n }\n }))\n }\n}\n\nexport default route\n",
|
|
6
|
+
"// Mark as binary mode to prevent auto-registration in routes/api.ts\n;(globalThis as any).__STACKS_BINARY_MODE__ = true\n\n// IMPORTANT: Import router package first to ensure it's initialized before routes\nimport { loadRoutes, serve } from '@stacksjs/router'\nimport config from './config-production'\nimport routeRegistry from '../../../../../app/Routes'\n\nconsole.log('[START] Application starting...')\nconsole.log('[START] Node version:', process.version)\nconsole.log('[START] Working directory:', process.cwd())\nconsole.log('[START] Environment:', process.env.APP_ENV || 'not set')\n\n// Disable runtime config loading for compiled binary\nprocess.env.SKIP_CONFIG_LOADING = 'true'\n\nconsole.log('[START] Config loaded:', {\n port: config.server.port,\n host: config.server.host,\n appName: config.app.name,\n appUrl: config.app.url,\n})\n\n// Load routes from the registry, then ORM auto-routes, then start the server\nconsole.log('[START] Loading routes from registry...')\nloadRoutes(routeRegistry)\n .then(async () => {\n console.log('[START] Routes loaded successfully')\n\n // Load ORM auto-generated routes (model CRUD endpoints)\n // These run after manual routes so routeExists() correctly detects conflicts\n try {\n await import('../../orm/routes')\n console.log('[START] ORM routes loaded successfully')\n } catch (ormError) {\n console.warn('[START] ORM routes skipped:', ormError instanceof Error ? ormError.message : String(ormError))\n }\n\n console.log('[START] Calling serve()...')\n try {\n serve({\n port: config.server.port,\n host: config.server.host,\n } as any)\n console.log('[START] serve() called successfully')\n } catch (error) {\n console.error('[START] ERROR calling serve():', error)\n process.exit(1)\n }\n })\n .catch((error) => {\n console.error('[START] ERROR loading routes:', error)\n process.exit(1)\n })\n",
|
|
7
|
+
"/**\n * Production server config - minimal, no runtime file loading\n * This config is inlined at build time for compiled binaries\n */\n\nexport const config = {\n app: {\n name: process.env.APP_NAME || 'Stacks',\n env: process.env.APP_ENV || 'production',\n debug: process.env.APP_DEBUG === 'true' || false,\n url: process.env.APP_URL || 'https://stacksjs.com',\n },\n server: {\n port: Number(process.env.PORT) || 3000,\n host: '0.0.0.0',\n },\n logging: {\n level: process.env.LOG_LEVEL || 'info',\n },\n}\n\nexport default config\n",
|
|
8
|
+
"export interface RouteDefinition {\n /** Route file path (relative to routes/) */\n path: string\n /** Optional URL prefix (overrides the key-based prefix) */\n prefix?: string\n /** Optional middleware for all routes in file */\n middleware?: string | string[]\n}\n\nexport type RouteRegistry = Record<string, string | RouteDefinition>\n\n/**\n * Application route registry.\n *\n * Define your route files here. The key becomes the URL prefix automatically.\n * Special keys 'api' and 'web' have no prefix (loaded at root /).\n *\n * @example\n * // No prefix - routes/api.ts loaded at /*\n * 'api': 'api',\n *\n * // Auto prefix from key - routes/api/v1.ts loaded at /v1/*\n * 'v1': 'api/v1',\n *\n * // Explicit prefix - routes/api/v1.ts loaded at /api/v1/*\n * 'legacy': { path: 'api/v1', prefix: '/api/v1' },\n *\n * // No prefix override - routes/internal.ts loaded at /* (no prefix)\n * 'internal': { path: 'internal', prefix: '' },\n *\n * // With middleware - routes/admin.ts loaded at /admin/* with auth\n * 'admin': { path: 'admin', middleware: ['auth'] },\n */\nexport default {\n // Default API routes (no prefix)\n 'api': 'api',\n\n // Add versioned or prefixed routes here:\n 'v1': { path: 'v1', prefix: 'v1' }\n // 'v2': 'api/v2',\n // 'admin': { path: 'admin', middleware: ['auth'] },\n} satisfies RouteRegistry\n"
|
|
9
|
+
],
|
|
10
|
+
"mappings": ";qRAQA,gBAAS,yBACT,sBAAS,wBACT,oBAAS,yBAAW,iCACpB,oBAAS,iCA0CT,SAAS,CAAW,CAAC,EAAgB,EAAuB,CAC1D,OAAO,EAAM,OAAO,KAClB,CAAC,IAAW,EAAE,SAAW,GAAU,EAAE,OAAS,CAChD,EAIF,SAAS,EAAiB,CAAC,EAAsB,CAC/C,GAAI,CAAC,EAAM,WAAY,MAAO,CAAC,EAC/B,OAAO,OAAO,QAAQ,EAAM,UAAU,EACnC,OAAO,EAAE,EAAG,KAAyB,EAAK,WAAa,EAAI,EAC3D,IAAI,EAAE,KAAyB,CAAI,EAIxC,SAAS,EAAe,CAAC,EAAsB,CAC7C,GAAI,CAAC,EAAM,WAAY,MAAO,CAAC,EAC/B,OAAO,OAAO,QAAQ,EAAM,UAAU,EACnC,OAAO,EAAE,EAAG,KAAyB,EAAK,SAAW,EAAI,EACzD,IAAI,EAAE,KAAyB,CAAI,EAIxC,SAAS,CAAW,CAAC,EAAa,EAA6B,CAC7D,GAAI,CAAC,GAAU,EAAa,SAAW,EAAG,OAAO,EACjD,IAAM,EAAS,IAAK,CAAO,EAC3B,QAAW,KAAS,EAClB,OAAO,EAAO,GAEhB,OAAO,EAIT,SAAS,EAAc,CAAC,EAAW,EAA+C,CAChF,GAAI,CAAC,GAAQ,EAAe,SAAW,EAAG,MAAO,CAAC,EAClD,IAAM,EAA8B,CAAC,EACrC,QAAW,KAAS,EAClB,GAAI,KAAS,EACX,EAAO,GAAS,EAAK,GAGzB,OAAO,EAkBT,SAAS,EAAQ,CAAC,EAAoB,CAAE,GAAI,CAAE,OAAO,KAAK,MAAM,CAAC,EAAI,KAAM,CAAE,OAAO,GACpF,SAAS,EAAe,CAAC,EAAqB,CAAE,GAAI,CAAE,OAAO,KAAK,MAAM,CAAE,EAAI,KAAM,CAAE,MAAO,CAAC,GAQ9F,SAAS,EAAiB,CACxB,EACA,EACA,EACsE,CACtE,IAAM,EAAO,EACP,EAAQ,EACR,EAAO,EACP,EAAQ,GAAO,YAAc,CAAC,EAC9B,EAAmC,CAAC,EAC1C,QAAY,EAAO,KAAQ,OAAO,QAAQ,CAA4B,EAAG,CACvE,IAAM,EAAY,GAAK,YAAY,KACnC,GAAI,CAAC,GAAQ,OAAO,EAAK,WAAa,WAAY,SAClD,IAAM,EAAU,OAAO,UAAU,eAAe,KAAK,EAAM,CAAK,EAChE,GAAI,CAAC,GAAW,IAAS,WAAY,SACrC,IAAM,EAAQ,EAAU,EAAK,GAAS,OAChC,EAAS,EAAK,SAAS,CAAK,EAClC,GAAI,CAAC,GAAQ,OAAS,MAAM,QAAQ,GAAQ,MAAM,GAAK,EAAO,OAAO,OAAS,EAC5E,EAAO,GAAS,EAAO,OAAO,IAAI,CAAC,IACjC,GAAK,YAAY,UAAU,GAAG,OAAS,GAAG,SAAW,SACvD,EAGJ,OAAO,OAAO,KAAK,CAAM,EAAE,SAAW,EAAI,CAAE,MAAO,EAAK,EAAI,CAAE,MAAO,GAAO,QAAO,EAKrF,SAAS,CAAW,CAAC,EAAmB,CACtC,OAAO,EAAE,QAAQ,oBAAqB,OAAO,EAAE,QAAQ,uBAAwB,OAAO,EAAE,YAAY,EAOtG,SAAS,EAAS,CAAC,EAAmB,CACpC,GAAI,EAAE,SAAS,GAAG,GAAK,CAAC,aAAa,KAAK,CAAC,EAAG,MAAO,GAAG,EAAE,MAAM,EAAG,EAAE,OACrE,GAAI,oBAAoB,KAAK,CAAC,EAAG,MAAO,GAAG,MAC3C,MAAO,GAAG,KAaZ,eAAe,EAAa,CAC1B,EACA,EACA,EACA,EACgB,CAChB,GAAI,CAAC,EAAK,OAAQ,OAAO,EACzB,IAAM,EAAY,EAAa,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO,EAC3E,GAAI,CAAC,EAAU,OAAQ,OAAO,EAE9B,IAAM,EAAsB,MAAM,QAAQ,EAAM,SAAS,EAAI,EAAM,UAAY,CAAC,EAC1E,EAAoB,MAAM,QAAQ,EAAM,OAAO,EAAI,EAAM,QAAU,CAAC,EACpE,EAAmB,MAAM,QAAQ,EAAM,MAAM,EAAI,EAAM,OAAS,CAAC,EAGjE,EAAU,IAAI,IACpB,QAAW,KAAK,EAAW,EAAQ,IAAI,EAAY,CAAC,EAAG,CAAE,KAAM,YAAa,UAAW,CAAE,CAAC,EAC1F,QAAW,KAAK,EAAQ,EAAQ,IAAI,EAAY,CAAC,EAAG,CAAE,KAAM,SAAU,UAAW,CAAE,CAAC,EACpF,QAAW,KAAK,EAAS,EAAQ,IAAI,GAAU,EAAY,CAAC,CAAC,EAAG,CAAE,KAAM,UAAW,UAAW,CAAE,CAAC,EAEjG,QAAW,KAAW,EAAW,CAC/B,IAAM,EAAO,EAAQ,IAAI,CAAO,EAChC,GAAI,CAAC,EAAM,SACX,IAAM,EAAU,EAAe,EAAK,WACpC,GAAI,CAAC,EAAS,SACd,IAAM,EAAe,EAAQ,OAAS,GAAU,EAAY,EAAK,SAAS,CAAC,EACrE,EAAgB,GAAgB,CAAO,EACvC,EAAe,CAAC,IAAY,EAAY,EAAe,EAAI,CAAO,EAAG,CAAa,EAExF,GAAI,EAAK,OAAS,aAAe,EAAK,OAAS,SAAU,CACvD,IAAM,EAAa,GAAG,EAAY,EAAK,SAAS,OAC1C,EAAM,CAAC,GAAG,IAAI,IAAI,EAAK,IAAI,KAAK,EAAE,EAAW,EAAE,OAAO,KAAK,GAAK,IAAI,CAAC,CAAC,EAC5E,GAAI,CAAC,EAAI,OAAQ,CACf,QAAW,KAAK,EAAM,EAAE,GAAW,KACnC,SAEF,IAAM,EAAY,MAAO,EAAW,WAAW,CAAY,EAAE,QAAQ,KAAM,CAAG,EAAE,IAAI,EAC9E,EAAO,IAAI,IACjB,QAAW,KAAM,GAAa,CAAC,EAAG,EAAK,IAAI,OAAO,EAAG,EAAE,EAAG,EAAa,CAAE,CAAC,EAC1E,QAAW,KAAK,EAAM,EAAE,GAAW,EAAK,IAAI,OAAO,EAAE,EAAW,CAAC,GAAK,KAEnE,KAEH,IAAM,EAAa,OAAO,EAAM,MAAQ,EAAE,EACpC,EAAY,GAAG,EAAY,CAAU,OACrC,EAAY,CAAC,GAAG,IAAI,IAAI,EAAK,IAAI,KAAK,EAAE,EAAE,EAAE,OAAO,KAAK,GAAK,IAAI,CAAC,CAAC,EACzE,GAAI,CAAC,EAAU,OAAQ,CACrB,QAAW,KAAK,EAAM,EAAE,GAAW,CAAC,EACpC,SAEF,IAAM,EAAY,MAAO,EAAW,WAAW,CAAY,EAAE,QAAQ,EAAW,CAAS,EAAE,IAAI,EACzF,EAAU,IAAI,IACpB,QAAW,KAAM,GAAa,CAAC,EAAG,CAChC,IAAM,EAAM,OAAO,EAAG,EAAU,EAC1B,EAAM,EAAQ,IAAI,CAAG,GAAK,CAAC,EACjC,EAAI,KAAK,EAAa,CAAE,CAAC,EACzB,EAAQ,IAAI,EAAK,CAAG,EAEtB,QAAW,KAAK,EAAM,EAAE,GAAW,EAAQ,IAAI,OAAO,EAAE,EAAE,CAAC,GAAK,CAAC,GAGrE,OAAO,EAOT,SAAS,EAAgB,CAAC,EAA2B,EAA6C,CAChG,GAAI,CAAC,EAAa,OAAQ,OAAO,EACjC,IAAM,EAA2B,IAAK,CAAK,EAC3C,QAAW,KAAK,EAAc,OAAO,EAAI,GACzC,OAAO,EAUT,eAAe,EAAmB,CAAC,EAA2B,EAA0C,CACtG,IAAM,EAAmF,GAAO,IAChG,GAAI,CAAC,GAAW,OAAO,IAAY,SAAU,OAAO,EACpD,IAAM,EAA2B,IAAK,CAAK,EAC3C,QAAY,EAAK,KAAO,OAAO,QAAQ,CAAO,EAAG,CAC/C,GAAI,OAAO,IAAO,YAAc,EAAE,KAAO,GAAM,SAC/C,GAAI,CACF,EAAI,GAAO,MAAM,EAAG,CAAG,EAEzB,KAAM,GAER,OAAO,EAKT,SAAS,EAAa,CAAC,EAA2B,EAAiC,CACjF,IAAM,EAAyD,GAAO,OAAS,CAAC,EAChF,GAAI,CAAC,GAAS,OAAO,KAAK,CAAK,EAAE,SAAW,GAAK,CAAC,EAAM,OAAO,EAC/D,IAAM,EAA2B,IAAK,CAAK,EAC3C,QAAY,EAAM,KAAY,OAAO,QAAQ,CAAK,EAChD,GAAI,OAAO,UAAU,eAAe,KAAK,EAAK,CAAI,EAAG,CACnD,IAAM,EAAS,OAAO,IAAY,SAAW,GAAkB,GAAW,EAC1E,GAAI,EAAQ,EAAI,GAAQ,EAAO,IAAI,EAAI,EAAK,EAGhD,OAAO,EAKT,SAAS,CAAc,CAAC,EAAU,EAAiB,CACjD,IAAM,EAAyD,GAAO,OAAS,CAAC,EAChF,GAAI,CAAC,GAAO,OAAO,IAAQ,UAAY,CAAC,GAAS,OAAO,KAAK,CAAK,EAAE,SAAW,EAAG,OAAO,EACzF,IAAM,EAA2B,IAAK,CAAI,EAC1C,QAAY,EAAM,KAAY,OAAO,QAAQ,CAAK,EAChD,GAAI,OAAO,UAAU,eAAe,KAAK,EAAK,CAAI,EAAG,CACnD,IAAM,EAAS,OAAO,IAAY,SAAW,GAAkB,GAAW,EAC1E,GAAI,EAAQ,EAAI,GAAQ,EAAO,IAAI,EAAI,EAAK,EAGhD,OAAO,EAIT,SAAS,CAAY,CAAC,EAAW,EAAS,IAAe,CACvD,OAAO,IAAI,SAAS,KAAK,UAAU,CAAI,EAAG,CACxC,SACA,QAAS,CAAE,eAAgB,kBAAmB,CAChD,CAAC,EA2BH,eAAe,CAAc,CAAC,EAAoD,CAMhF,GADsB,OAAO,EAAI,SAAS,MAAM,gBAAgB,GAAK,CAAC,EAClD,EAClB,MAAM,IAAI,EAAU,IAAK,wBAAwB,cAA2B,EAE9E,GAAK,EAAY,UAAY,OAAQ,EAAY,WAAa,SAC5D,OAAQ,EAAY,SAEtB,GAAK,EAAY,UAAY,OAAQ,EAAY,WAAa,SAC5D,OAAQ,EAAY,SAGtB,GAAI,CACF,IAAM,EAAO,MAAM,EAAI,MAAM,EAAE,KAAK,EACpC,GAAI,EAAK,OAAS,EAChB,MAAM,IAAI,EAAU,IAAK,wBAAwB,cAA2B,EAC9E,GAAI,CAAC,EAAM,MAAO,CAAC,EACnB,IAAM,EAAS,KAAK,MAAM,CAAI,EAC9B,OAAO,GAAU,OAAO,IAAW,UAAY,CAAC,MAAM,QAAQ,CAAM,EAAI,EAAS,CAAC,EAEpF,MAAO,EAAK,CACV,GAAI,aAAe,EAAW,MAAM,EACpC,MAAM,IAAI,EAAU,IAAK,sBAAuB,EAAc,SAAS,GAQ3E,SAAS,CAAQ,CAAC,EAAsC,CACtD,GAAI,GAAO,KAAM,OAAO,KACxB,GAAI,OAAO,IAAQ,SAAU,OAAO,OAAO,SAAS,CAAG,GAAK,EAAM,EAAI,EAAM,KAC5E,GAAI,OAAO,IAAQ,SAAU,CAC3B,IAAM,EAAU,EAAI,KAAK,EACzB,GAAI,CAAC,EAAS,OAAO,KACrB,GAAI,QAAQ,KAAK,CAAO,EAAG,CACzB,IAAM,EAAI,OAAO,CAAO,EACxB,OAAO,OAAO,SAAS,CAAC,GAAK,EAAI,EAAI,EAAI,KAE3C,OAAO,EAET,OAAO,KAYT,SAAS,EAAY,CAAC,EAAY,EAA0B,EAAqB,CAC/E,GAAI,CAAC,EAAW,OAAO,EACvB,IAAM,EAAS,OAAO,CAAS,EAAE,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO,EACzE,EAAI,EACR,QAAW,KAAO,EAAQ,CACxB,IAAM,EAAO,EAAI,WAAW,GAAG,EACzB,EAAS,EAAO,EAAI,MAAM,CAAC,EAAI,EACrC,GAAI,CAAC,QAAQ,KAAK,CAAM,EAAG,SAC3B,EAAI,EAAE,QAAQ,EAAQ,EAAO,OAAS,KAAK,EAE7C,OAAO,EAKT,SAAS,EAAQ,CAAC,EAAqC,CACrD,IAAM,EAAM,EAAY,YACxB,GAAI,OAAO,IAAO,WAAY,CAC5B,IAAM,EAAI,EAAG,KAAK,CAAG,EACrB,GAAI,EAAG,OAAO,EAEhB,IAAM,EAAO,EAAI,SAAS,MAAM,eAAe,GAAK,EAAI,SAAS,MAAM,eAAe,GAAK,GAC3F,GAAI,OAAO,IAAS,UAAY,EAAK,WAAW,SAAS,EACvD,OAAO,EAAK,UAAU,CAAC,EACzB,OAAO,KAMT,eAAe,CAAqB,CAAC,EAA2C,CAC9E,IAAM,EAAU,EAAY,mBAC5B,GAAI,EAAQ,OAAO,EACnB,IAAM,EAAQ,GAAS,CAAG,EAC1B,GAAI,CAAC,EAAO,OAAO,KACnB,GAAI,CACF,IAAQ,QAAS,KAAa,0BACxB,EAAO,MAAO,EAAa,iBAAiB,CAAK,EACvD,GAAI,EAAO,EAAY,mBAAqB,EAC5C,OAAO,GAAQ,KAEjB,KAAM,CACJ,OAAO,MAsBX,SAAS,CAAO,CAAC,EAAmB,EAA8B,CAChE,GAAI,GAAY,MAAQ,GAAc,KAAM,MAAO,GACnD,GAAI,MAAM,QAAQ,CAAU,EAC1B,OAAO,EAAW,KAAK,KAAK,OAAO,CAAC,IAAM,OAAO,CAAQ,CAAC,EAC5D,OAAO,OAAO,CAAQ,IAAM,OAAO,CAAU,EAG/C,eAAe,CAAgB,CAC7B,EACA,EACA,EACgF,CAChF,IAAM,EAAM,GAAO,UACnB,GAAI,CAAC,GAAO,CAAC,EAAI,OAAS,OAAO,EAAI,UAAY,WAC/C,MAAO,CAAE,SAAU,GAAO,MAAO,KAAM,MAAO,GAAI,OAAQ,EAAM,EAClE,IAAM,EAAS,OAAO,EAAI,SAAW,WAAa,CAAC,CAAC,EAAI,OAAO,EAAM,CAAG,EAAI,GACxE,EAAiB,KACrB,GAAI,CACF,EAAQ,MAAM,EAAI,QAAQ,EAAM,CAAG,EAErC,KAAM,CAAE,EAAQ,KAChB,MAAO,CAAE,SAAU,GAAM,QAAO,MAAO,OAAO,EAAI,KAAK,EAAG,QAAO,EAKnE,eAAe,EAAiB,CAC9B,EACA,EACA,EACA,EAC8B,CAC9B,IAAM,EAAM,GAAO,aAAa,GAChC,GAAI,CAAC,EAAK,MAAO,CAAC,EAClB,GAAI,OAAO,IAAQ,WACjB,GAAI,CACF,IAAM,EAAS,MAAM,EAAI,EAAM,CAAG,EAClC,OAAO,GAAU,OAAO,IAAW,SAAW,EAAS,CAAC,EAE1D,KAAM,CACJ,MAAO,CAAC,EAGZ,GAAI,OAAO,IAAQ,SAAU,CAC3B,IAAM,EAA2B,CAAC,EAClC,QAAY,EAAO,KAAW,OAAO,QAAQ,CAAG,EAC9C,GAAI,CACF,EAAI,GAAS,OAAO,IAAW,WAAa,MAAO,EAAe,EAAM,CAAG,EAAI,EAEjF,KAAM,EAER,OAAO,EAET,MAAO,CAAC,MA5eJ,GACA,GAIA,EACA,EA8BA,EAkDA,GAqOA,EAAiB,QAosBR,uBA//BT,GAAe,GAAY,cAAc,EACzC,IAAY,MAAa,YAAe,QAC9C,GAAU,EAAQ,EAGZ,EAAY,GAAY,YAAY,EACpC,EAA8B,CAAC,EAErC,GAAI,CACF,IAAQ,cAAa,YAAa,KAAa,eACvC,UAAS,YAAa,KAAa,gBAErC,EAAU,EAAY,CAAS,EACrC,QAAW,KAAS,EAAS,CAC3B,IAAM,EAAO,GAAG,KAAa,IAE7B,GADW,EAAS,CAAI,EACjB,YAAY,EAAG,SACtB,IAAM,EAAM,EAAQ,CAAI,EACxB,GAAI,CAAC,CAAC,MAAO,KAAK,EAAE,SAAS,CAAG,EAAG,SAEnC,GAAI,CACF,IAAM,EAAM,MAAa,UAAG,OAAU,KAAK,IAAI,KACzC,EAAM,EAAI,SAAW,EACrB,EAAO,EAAI,MAAQ,EAAS,EAAO,CAAG,EAC5C,EAAO,GAAQ,IAAK,EAAK,MAAK,EAEhC,KAAM,IAKV,KAAM,EAKA,EAAK,GAAmB,EAkDxB,GAAoG,CACxG,OAAU,CAAE,IAAK,KAAK,GAAK,KAAO,OAAO,CAAC,EAAI,KAAqC,IAAK,KAAK,GAAK,KAAO,OAAO,CAAC,EAAI,IAAK,EAC1H,OAAU,CAAE,IAAK,KAAK,GAAK,KAAO,OAAO,CAAC,EAAI,KAAqC,IAAK,KAAK,GAAK,KAAO,OAAO,CAAC,EAAI,IAAK,EAC1H,QAAU,CAAE,IAAK,KAAK,GAAK,KAAO,KAAK,MAAM,OAAO,CAAC,CAAC,EAAI,KAAyB,IAAK,KAAK,GAAK,KAAO,KAAK,MAAM,OAAO,CAAC,CAAC,EAAI,IAAK,EACtI,MAAU,CAAE,IAAK,KAAK,GAAK,KAAO,OAAO,WAAW,OAAO,CAAC,CAAC,EAAI,KAAkB,IAAK,KAAK,GAAK,KAAO,OAAO,WAAW,OAAO,CAAC,CAAC,EAAI,IAAK,EAC7I,QAAU,CAAE,IAAK,KAAK,IAAM,GAAK,IAAM,KAAO,IAAM,IAAQ,IAAM,OAAgB,IAAK,KAAM,IAAM,IAAQ,IAAM,GAAK,IAAM,KAAO,IAAM,OAAU,EAAI,CAAE,EACzJ,KAAU,CAAE,IAAK,KAAK,GAAK,KAAO,KAAQ,OAAO,IAAM,SAAW,GAAS,CAAC,EAAI,EAAI,IAAK,KAAK,GAAK,KAAO,KAAO,OAAO,IAAM,SAAW,EAAI,KAAK,UAAU,CAAC,CAAE,EAC/J,SAAU,CAAE,IAAK,KAAK,EAAI,IAAI,KAAK,CAAW,EAAI,KAAiC,IAAK,KAAK,aAAa,KAAO,EAAE,YAAY,EAAI,CAAE,EACrI,KAAU,CAAE,IAAK,KAAK,EAAI,IAAI,KAAK,CAAW,EAAI,KAAiC,IAAK,KAAK,aAAa,KAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE,GAAgB,CAAE,EAC/J,MAAU,CAAE,IAAK,KAAK,GAAK,KAAO,CAAC,EAAI,MAAM,QAAQ,CAAC,EAAI,EAAK,OAAO,IAAM,SAAW,GAAgB,CAAC,EAAI,CAAC,EAAI,IAAK,KAAK,GAAK,KAAO,KAAO,MAAM,QAAQ,CAAC,EAAI,KAAK,UAAU,CAAC,EAAI,CAAE,CACzL,EAgZA,QAAY,EAAW,KAAU,OAAO,QAAQ,CAAM,EAAG,CACvD,IAAM,EAAS,EAAM,QAAQ,OAC7B,GAAI,CAAC,EAAQ,SAGb,IAAM,EAAY,OAAO,IAAW,SAAW,EAAS,CAAC,EACnD,EAAM,EAAU,KAAO,EAAM,OAAS,EAAU,YAAY,EAAI,IAEhE,EAA0B,EAAU,QAAU,CAAC,QAAS,OAAQ,QAAS,SAAU,SAAS,EAC5F,EAAQ,EAAM,OAAS,EACvB,EAAiB,GAAkB,CAAK,EACxC,EAAe,GAAgB,CAAK,EACpC,EAAW,QAAQ,IASnB,EAA0B,MAAM,QAAS,EAAkB,UAAU,EACrE,EAAkB,WAAwB,OAAO,KAAK,OAAO,IAAM,UAAY,EAAE,OAAS,CAAC,EAC5F,OAAQ,EAAkB,aAAe,UAAa,EAAkB,WACrE,CAAE,EAAkB,UAAU,EAC9B,CAAC,EAKH,EAAkB,CAAC,IAAoB,CAC3C,IAAI,EAAI,EACR,QAAW,KAAQ,EACjB,GAAI,GAAK,OAAO,EAAE,aAAe,WAAY,EAAI,EAAE,WAAW,CAAI,EAEpE,OAAO,GAIT,GAAI,EAAc,SAAS,OAAO,GAAK,CAAC,EAAY,MAAO,CAAQ,EACjE,EAAgB,EAAM,IAAI,EAAU,MAAO,IAAyB,CAClE,GAAI,CACF,IAAM,EAAM,IAAI,IAAI,EAAI,GAAG,EACrB,EAAO,OAAO,SAAS,EAAI,aAAa,IAAI,MAAM,GAAK,IAAK,EAAE,EAC9D,EAAU,KAAK,IAAI,OAAO,SAAS,EAAI,aAAa,IAAI,UAAU,GAAK,KAAM,EAAE,EAAG,GAAG,EACrF,GAAU,EAAO,GAAK,EACtB,EAAO,EAAI,aAAa,IAAI,MAAM,EAEpC,EAAS,EAAW,WAAW,CAAK,EACxC,EAAQ,GAAa,EAAO,EAAM,CAAK,EAOvC,IAAM,EAAW,IAAI,IAAI,CAAC,OAAQ,WAAY,OAAQ,SAAU,SAAU,UAAW,QAAS,SAAU,aAAc,cAAe,aAAa,CAAC,EAC7I,EAAiB,IAAI,IAAI,CAAC,KAAM,OAAQ,aAAc,aAAc,YAAY,CAAC,EACjF,EAAe,IAAI,IAAI,CAC3B,GAAG,OAAO,KAAK,EAAM,YAAc,CAAC,CAAC,EACrC,GAAG,CACL,CAAC,EACD,QAAY,EAAK,KAAU,EAAI,aAAa,QAAQ,EAAG,CACrD,GAAI,EAAS,IAAI,CAAG,GAAK,CAAC,EAAO,SACjC,GAAI,EAAa,IAAI,CAAG,GAAK,sBAAsB,KAAK,CAAG,EACzD,EAAQ,EAAM,MAAM,EAAK,IAAK,CAAK,EAKvC,IAAM,EAAa,EAAI,aAAa,IAAI,QAAQ,EAChD,GAAI,GAAc,EAAe,OAAS,EAAG,CAC3C,IAAM,EAAa,EAAe,MAAM,EAAG,CAAC,EAC5C,EAAQ,EAAM,MAAM,CAAC,IAAY,CAC/B,QAAW,MAAS,EAClB,EAAK,EAAG,QAAQ,GAAO,OAAQ,IAAI,IAAa,EAElD,OAAO,EACR,EAIH,IAAM,EAAc,EAAI,aAAa,IAAI,QAAQ,EACjD,GAAI,EAAa,CACf,IAAM,EAAiB,EAAY,MAAM,GAAG,EAAE,OAAO,KAAK,sBAAsB,KAAK,EAAE,KAAK,CAAC,CAAC,EAC9F,GAAI,EAAe,OAAS,EAC1B,EAAQ,EAAM,OAAO,EAAe,IAAI,CAAC,IAAc,EAAE,KAAK,CAAC,CAAC,EAOpE,IAAM,EAAkB,CAAC,CAAC,EAAM,QAAQ,eAClC,EAAc,EAAI,aAAa,IAAI,aAAa,IAAM,OACtD,EAAc,EAAI,aAAa,IAAI,aAAa,IAAM,OAC5D,GAAI,GAAmB,CAAC,EACtB,EAAQ,EAAc,EAAM,aAAa,YAAY,EAAI,EAAM,UAAU,YAAY,EAIvF,IAAI,GADY,MAAM,EAAM,MAAM,CAAO,EAAE,OAAO,CAAM,EAAE,IAAI,GACpC,CAAC,GAAG,IAAI,CAAC,IAAW,EAAY,EAAe,EAAG,CAAK,EAAG,CAAY,CAAC,EAE3F,EAAe,EAAI,aAAa,IAAI,SAAS,EACnD,GAAI,EACF,EAAU,MAAM,GAAc,EAAS,EAAO,EAAc,CAAM,EAMpE,IAAM,GAAY,EAAI,aAAa,IAAI,YAAY,IAAM,OACrD,EACJ,GAAI,GACF,GAAI,CAKF,IAAM,EAAM,MAAO,EAAW,WAAW,CAAK,EAAE,MAAM,EAChD,EAAI,OAAO,IAAQ,SAAW,EAAM,OAAO,GAAK,OAAS,CAAG,EAClE,GAAI,OAAO,SAAS,CAAC,EAAG,EAAQ,EAChC,KAAM,EAKV,IAAM,EAAsC,CAAE,eAAgB,kBAAmB,EACjF,GAAI,IAAU,QAAa,CAAC,OAAO,MAAM,CAAK,EAAG,EAAY,iBAAmB,OAAO,CAAK,EAS5F,OAHA,EAAY,iBAAmB,sCAC/B,EAAY,KAAO,gBAEZ,IAAI,SAAS,KAAK,UAAU,CACjC,KAAM,EACN,KAAM,CACJ,OACA,SAAU,KACN,IAAU,QAAa,CAAC,OAAO,MAAM,CAAK,EAAI,CAAE,QAAO,UAAW,KAAK,KAAK,EAAQ,CAAO,CAAE,EAAI,CAAC,CACxG,CACF,CAAC,EAAG,CAAE,OAAQ,IAAK,QAAS,CAAY,CAAC,EAE3C,MAAO,EAAK,CACV,GAAI,aAAe,EAAW,CAC5B,IAAM,EAAgC,CAAE,MAAO,EAAI,OAAQ,EAC3D,GAAI,EAAI,UAAY,OAAW,EAAK,QAAU,EAAI,QAClD,OAAO,EAAa,EAAM,EAAI,QAAU,GAAG,EAE7C,OAAO,EAAa,CAAE,MAAO,mBAAmB,IAAO,OAAQ,OAAO,CAAG,CAAE,EAAG,GAAG,GAEpF,CAAC,EAIJ,GAAI,EAAc,SAAS,MAAM,GAAK,CAAC,EAAY,MAAO,GAAG,QAAe,EAC1E,EAAgB,EAAM,IAAI,GAAG,SAAiB,MAAO,IAAyB,CAC5E,GAAI,CACF,IAAM,EAAK,EAAU,EAAY,QAAQ,EAAE,EAI3C,GAAI,GAAM,KACR,OAAO,EAAa,CAAE,MAAO,sBAAuB,EAAG,GAAG,EAG5D,IAAM,EAAS,MAAO,EAAW,WAAW,CAAK,EAAE,MAAM,CAAE,IAAG,CAAC,EAAE,iBAAiB,EAElF,GAAI,CAAC,EACH,OAAO,EAAa,CAAE,MAAO,GAAG,aAAsB,EAAG,GAAG,EAM9D,IAAM,EAAM,IAAI,IAAI,EAAI,GAAG,EAC3B,GAAI,EAAM,QAAQ,gBAAmB,EAAe,YAAc,EAAI,aAAa,IAAI,aAAa,IAAM,OACxG,OAAO,EAAa,CAAE,MAAO,GAAG,aAAsB,EAAG,GAAG,EAG9D,IAAI,EAAe,EAAY,EAAe,EAAQ,CAAK,EAAG,CAAY,EAIpE,EAAe,EAAI,aAAa,IAAI,SAAS,EACnD,GAAI,EAAc,CAChB,IAAO,GAAW,MAAM,GAAc,CAAC,CAAO,EAAG,EAAO,EAAc,CAAM,EAC5E,EAAU,EAQZ,IAAM,EAAa,GAAiB,YAAe,GAAiB,WAC9D,EAAO,EAAY,MAAO,EAAgB,MAAM,OAAO,CAAS,KAAO,OACvE,EAAc,EAAI,SAAS,MAAM,eAAe,EACtD,GAAI,GAAQ,GAAe,IAAgB,EACzC,OAAO,IAAI,SAAS,KAAM,CAAE,OAAQ,IAAK,QAAS,CAAE,KAAM,CAAK,CAAE,CAAC,EAGpE,IAAM,EAAkC,CAAE,eAAgB,kBAAmB,EAC7E,GAAI,EAAM,EAAQ,KAAO,EAIzB,OADA,EAAQ,iBAAmB,sCACpB,IAAI,SAAS,KAAK,UAAU,CAAE,KAAM,CAAQ,CAAC,EAAG,CAAE,OAAQ,IAAK,SAAQ,CAAC,EAEjF,MAAO,EAAK,CACV,GAAI,aAAe,EAAW,CAC5B,IAAM,EAAgC,CAAE,MAAO,EAAI,OAAQ,EAC3D,GAAI,EAAI,UAAY,OAAW,EAAK,QAAU,EAAI,QAClD,OAAO,EAAa,EAAM,EAAI,QAAU,GAAG,EAE7C,OAAO,EAAa,CAAE,MAAO,mBAAmB,IAAa,OAAQ,OAAO,CAAG,CAAE,EAAG,GAAG,GAE1F,CAAC,EAIJ,GAAI,EAAc,SAAS,OAAO,GAAK,CAAC,EAAY,OAAQ,CAAQ,EAClE,EAAgB,EAAM,KAAK,EAAU,MAAO,IAAyB,CACnE,GAAI,CACF,IAAM,EAAO,MAAM,EAAe,CAAG,EAI/B,EAAW,GAAiB,EAAM,CAAY,EAC9C,EAAO,GAAe,EAAU,CAAc,EAM9C,EAAa,MAAM,EAAsB,CAAG,EAClD,GAAI,EAAY,CACd,IAAM,EAAU,MAAM,GAAkB,EAAO,WAAY,EAAY,CAAG,EAC1E,QAAY,EAAG,KAAM,OAAO,QAAQ,CAAO,EACzC,GAAI,IAAM,QAAa,IAAM,MAAQ,EAAK,KAAO,OAC/C,EAAK,GAAK,EAIhB,GAAI,OAAO,KAAK,CAAI,EAAE,SAAW,EAC/B,OAAO,EAAa,CAAE,MAAO,6BAA8B,EAAG,GAAG,EAMnE,IAAM,EAAI,GAAkB,EAAM,EAAO,UAAU,EACnD,GAAI,CAAC,EAAE,MAAO,OAAO,EAAa,CAAE,MAAO,oBAAqB,OAAQ,EAAE,MAAO,EAAG,GAAG,EAGvF,GAAI,EAAM,QAAQ,gBAAkB,GAAO,CACzC,IAAM,EAAM,IAAI,KAAK,EAAE,YAAY,EACnC,EAAK,WAAa,EAClB,EAAK,WAAa,EAOpB,IAAM,EAAa,MAAM,GAAoB,EAAM,CAAK,EAClD,EAAY,GAAc,EAAY,CAAK,EAE3C,EAAS,MAAO,EAAW,WAAW,CAAK,EAAE,OAAO,CAAS,EAAE,QAAQ,EAGzE,EAAU,EACd,GAAI,CACF,IAAM,EAAS,GAAQ,iBAAmB,GAAQ,UAAY,EAC9D,GAAI,EAAQ,CACV,IAAM,EAAU,MAAO,EAAW,WAAW,CAAK,EAAE,MAAM,CAAE,GAAI,CAAO,CAAC,EAAE,iBAAiB,EAC3F,GAAI,EAAS,EAAU,GAEzB,KAAM,EAIR,OAAO,EAAa,CAAE,KAAM,EAAY,EAAe,EAAS,CAAK,EAAG,CAAY,CAAE,EAAG,GAAG,EAE9F,MAAO,EAAK,CACV,GAAI,aAAe,EAAW,CAC5B,IAAM,EAAgC,CAAE,MAAO,EAAI,OAAQ,EAC3D,GAAI,EAAI,UAAY,OAAW,EAAK,QAAU,EAAI,QAClD,OAAO,EAAa,EAAM,EAAI,QAAU,GAAG,EAE7C,OAAO,EAAa,CAAE,MAAO,oBAAoB,IAAa,OAAQ,OAAO,CAAG,CAAE,EAAG,GAAG,GAE3F,CAAC,EAIJ,GAAI,EAAc,SAAS,QAAQ,EAAG,CACpC,IAAM,EAAgB,MAAO,IAAyB,CACpD,GAAI,CACF,IAAM,EAAK,EAAU,EAAY,QAAQ,EAAE,EAC3C,GAAI,GAAM,KACR,OAAO,EAAa,CAAE,MAAO,sBAAuB,EAAG,GAAG,EAE5D,IAAM,EAAO,MAAM,EAAe,CAAG,EAC/B,EAAW,GAAiB,EAAM,CAAY,EAC9C,EAAO,GAAe,EAAU,CAAc,EAG9C,EAAa,MAAM,EAAsB,CAAG,EAClD,GAAI,EAAY,CACd,IAAM,EAAU,MAAM,GAAkB,EAAO,WAAY,EAAY,CAAG,EAC1E,QAAY,EAAG,KAAM,OAAO,QAAQ,CAAO,EACzC,GAAI,IAAM,QAAa,IAAM,MAAQ,EAAK,KAAO,OAC/C,EAAK,GAAK,EAIhB,GAAI,OAAO,KAAK,CAAI,EAAE,SAAW,EAC/B,OAAO,EAAa,CAAE,MAAO,6BAA8B,EAAG,GAAG,EAKnE,IAAM,EAAI,GAAkB,EAAM,EAAO,UAAU,EACnD,GAAI,CAAC,EAAE,MAAO,OAAO,EAAa,CAAE,MAAO,oBAAqB,OAAQ,EAAE,MAAO,EAAG,GAAG,EAKvF,IAAM,EAAW,MAAO,EAAW,WAAW,CAAK,EAAE,MAAM,CAAE,IAAG,CAAC,EAAE,iBAAiB,EACpF,GAAI,CAAC,EACH,OAAO,EAAa,CAAE,MAAO,GAAG,aAAsB,EAAG,GAAG,EAQ9D,IAAM,EAAM,MAAM,EAAiB,EAAO,EAAY,CAAG,EACzD,GAAI,EAAI,UAAY,CAAC,EAAI,OAAQ,CAC/B,GAAI,CAAC,EAAY,OAAO,EAAa,CAAE,MAAO,eAAgB,EAAG,GAAG,EACpE,IAAM,EAAY,EAAqC,EAAI,OAC3D,GAAI,CAAC,EAAQ,EAAU,EAAI,KAAK,EAC9B,OAAO,EAAa,CAAE,MAAO,YAAY,GAAY,EAAG,GAAG,EAG7D,GAAI,EAAI,SAAS,GAAQ,CAAC,EAAQ,EAAK,EAAI,OAAQ,EAAI,KAAK,EAC1D,OAAO,EAAa,CAAE,MAAO,mBAAmB,aAAsB,EAAG,GAAG,EAKhF,GAAI,EAAM,QAAQ,gBAAkB,GAClC,EAAK,WAAa,IAAI,KAAK,EAAE,YAAY,EAM3C,IAAM,EAAa,MAAM,GAAoB,EAAM,CAAK,EAClD,EAAY,GAAc,EAAY,CAAK,EAEjD,MAAO,EAAW,YAAY,CAAK,EAAE,IAAI,CAAS,EAAE,MAAM,CAAE,IAAG,CAAC,EAAE,QAAQ,EAG1E,IAAI,EAAe,IAAK,KAAa,CAAU,EAC/C,GAAI,CACF,IAAM,EAAU,MAAO,EAAW,WAAW,CAAK,EAAE,MAAM,CAAE,IAAG,CAAC,EAAE,iBAAiB,EACnF,GAAI,EAAS,EAAU,EACvB,KAAM,EAIR,OAAO,EAAa,CAAE,KAAM,EAAY,EAAe,EAAS,CAAK,EAAG,CAAY,CAAE,CAAC,EAEzF,MAAO,EAAK,CACV,GAAI,aAAe,EAAW,CAC5B,IAAM,EAAgC,CAAE,MAAO,EAAI,OAAQ,EAC3D,GAAI,EAAI,UAAY,OAAW,EAAK,QAAU,EAAI,QAClD,OAAO,EAAa,EAAM,EAAI,QAAU,GAAG,EAE7C,OAAO,EAAa,CAAE,MAAO,oBAAoB,IAAa,OAAQ,OAAO,CAAG,CAAE,EAAG,GAAG,IAI5F,GAAI,CAAC,EAAY,MAAO,GAAG,QAAe,EACxC,EAAgB,EAAM,IAAI,GAAG,SAAiB,CAAa,CAAC,EAE9D,GAAI,CAAC,EAAY,QAAS,GAAG,QAAe,EAC1C,EAAgB,EAAM,MAAM,GAAG,SAAiB,CAAa,CAAC,EAKlE,IAAM,EAAkB,CAAC,CAAC,EAAM,QAAQ,eACxC,GAAI,EAAc,SAAS,SAAS,GAAK,CAAC,EAAY,SAAU,GAAG,QAAe,EAChF,EAAgB,EAAM,OAAO,GAAG,SAAiB,MAAO,IAAyB,CAC/E,GAAI,CACF,IAAM,EAAK,EAAU,EAAY,QAAQ,EAAE,EAC3C,GAAI,GAAM,KACR,OAAO,EAAa,CAAE,MAAO,sBAAuB,EAAG,GAAG,EAI5D,IAAM,EAAW,MAAO,EAAW,WAAW,CAAK,EAAE,MAAM,CAAE,IAAG,CAAC,EAAE,iBAAiB,EACpF,GAAI,CAAC,EACH,OAAO,EAAa,CAAE,MAAO,GAAG,aAAsB,EAAG,GAAG,EAG9D,IAAM,EAAa,MAAM,EAAsB,CAAG,EAC5C,EAAM,MAAM,EAAiB,EAAO,EAAY,CAAG,EACzD,GAAI,EAAI,UAAY,CAAC,EAAI,OAAQ,CAC/B,GAAI,CAAC,EAAY,OAAO,EAAa,CAAE,MAAO,eAAgB,EAAG,GAAG,EACpE,IAAM,EAAY,EAAqC,EAAI,OAC3D,GAAI,CAAC,EAAQ,EAAU,EAAI,KAAK,EAC9B,OAAO,EAAa,CAAE,MAAO,YAAY,GAAY,EAAG,GAAG,EAI/D,GAAI,EAAiB,CAInB,IAAM,EAAM,IAAI,KAAK,EAAE,YAAY,EACnC,MAAO,EAAW,YAAY,CAAK,EAChC,IAAI,CAAE,WAAY,EAAK,WAAY,CAAI,CAAC,EACxC,MAAM,CAAE,IAAG,CAAC,EACZ,QAAQ,EAGX,WAAO,EAAW,WAAW,CAAK,EAAE,MAAM,CAAE,IAAG,CAAC,EAAE,QAAQ,EAG5D,OAAO,IAAI,SAAS,KAAM,CAAE,OAAQ,GAAI,CAAC,EAE3C,MAAO,EAAK,CACV,GAAI,aAAe,EAAW,CAC5B,IAAM,EAAgC,CAAE,MAAO,EAAI,OAAQ,EAC3D,GAAI,EAAI,UAAY,OAAW,EAAK,QAAU,EAAI,QAClD,OAAO,EAAa,EAAM,EAAI,QAAU,GAAG,EAE7C,OAAO,EAAa,CAAE,MAAO,oBAAoB,IAAa,OAAQ,OAAO,CAAG,CAAE,EAAG,GAAG,GAE3F,CAAC,EAKJ,GAAI,EAAc,SAAS,SAAS,GAAK,CAAC,EAAY,OAAQ,GAAG,eAAsB,EACrF,EAAgB,EAAM,KAAK,GAAG,gBAAwB,MAAO,IAAyB,CACpF,GAAI,CAEF,IAAM,GADO,MAAM,EAAe,CAAG,IACnB,IAElB,GAAI,CAAC,MAAM,QAAQ,CAAG,GAAK,EAAI,SAAW,EACxC,OAAO,EAAa,CAAE,MAAO,6BAA8B,EAAG,GAAG,EAInE,GAAI,EAAI,OAAS,IACf,OAAO,EAAa,CAAE,MAAO,6CAA8C,EAAG,GAAG,EAMnF,IAAM,EAAmC,CAAC,EACpC,EAAwB,CAAC,EAC/B,QAAW,KAAO,EAAK,CACrB,IAAM,EAAU,EAAS,CAAG,EAC5B,GAAI,GAAW,KAAM,EAAS,KAAK,CAAO,EACrC,OAAW,KAAK,CAAG,EAE1B,GAAI,EAAW,OAAS,EACtB,OAAO,EAAa,CAAE,MAAO,uBAAwB,QAAS,CAAW,EAAG,GAAG,EAGjF,IAAM,EAAa,MAAM,EAAsB,CAAG,EAC5C,EAAM,MAAM,EAAiB,EAAO,EAAY,CAAG,EAIzD,GAAI,EAAI,UAAY,CAAC,EAAI,OAAQ,CAC/B,GAAI,CAAC,EAAY,OAAO,EAAa,CAAE,MAAO,eAAgB,EAAG,GAAG,EACpE,GAAI,EAAI,OAAS,KAAM,OAAO,EAAa,CAAE,MAAO,kCAAmC,EAAG,GAAG,EAC7F,IAAM,EAAO,MAAO,EAAW,WAAW,CAAK,EAAE,OAAO,CAAC,KAAM,EAAI,KAAK,CAAC,EAAE,QAAQ,EAC7E,EAAW,IAAI,IAClB,EACE,OAAO,KAAK,EAAQ,EAAE,EAAI,OAAQ,EAAI,KAAK,CAAC,EAC5C,IAAI,KAAK,OAAO,EAAE,EAAE,CAAC,CAC1B,EACM,EAAW,EAAS,OAAO,KAAM,CAAC,EAAS,IAAI,OAAO,CAAE,CAAC,CAAC,EAChE,GAAI,EAAS,OAAS,EACpB,OAAO,EAAa,CAAE,MAAO,iBAAiB,kBAA2B,IAAK,CAAS,EAAG,GAAG,EAGjG,IAAM,EAAM,IAAI,KAAK,EAAE,YAAY,EACnC,QAAW,KAAM,EACf,GAAI,EACF,MAAO,EAAW,YAAY,CAAK,EAChC,IAAI,CAAE,WAAY,EAAK,WAAY,CAAI,CAAC,EACxC,MAAM,CAAE,IAAG,CAAC,EACZ,QAAQ,EAGX,WAAO,EAAW,WAAW,CAAK,EAAE,MAAM,CAAE,IAAG,CAAC,EAAE,QAAQ,EAI9D,OAAO,EAAa,CAAE,QAAS,wBAAwB,EAAS,UAAU,GAAM,CAAC,EAEnF,MAAO,EAAK,CACV,GAAI,aAAe,EAAW,CAC5B,IAAM,EAAgC,CAAE,MAAO,EAAI,OAAQ,EAC3D,GAAI,EAAI,UAAY,OAAW,EAAK,QAAU,EAAI,QAClD,OAAO,EAAa,EAAM,EAAI,QAAU,GAAG,EAE7C,OAAO,EAAa,CAAE,MAAO,yBAAyB,IAAO,OAAQ,OAAO,CAAG,CAAE,EAAG,GAAG,GAE1F,CAAC,EAIS,OCzgCf,qBAAS,YAAY,0BCCd,IAAM,GAAS,CACpB,IAAK,CACH,KAAM,QAAQ,IAAI,UAAY,SAC9B,IAAK,QAAQ,IAAI,SAAW,aAC5B,MAAO,QAAQ,IAAI,YAAc,QAAU,GAC3C,IAAK,QAAQ,IAAI,SAAW,sBAC9B,EACA,OAAQ,CACN,KAAM,OAAO,QAAQ,IAAI,IAAI,GAAK,KAClC,KAAM,SACR,EACA,QAAS,CACP,MAAO,QAAQ,IAAI,WAAa,MAClC,CACF,EAEe,KCYf,IAAe,GAEb,IAAO,MAGP,GAAM,CAAE,KAAM,KAAM,OAAQ,IAAK,CAGnC,EFxCE,WAAmB,uBAAyB,GAO9C,QAAQ,IAAI,iCAAiC,EAC7C,QAAQ,IAAI,wBAAyB,QAAQ,OAAO,EACpD,QAAQ,IAAI,6BAA8B,QAAQ,IAAI,CAAC,EACvD,QAAQ,IAAI,uBAAwB,QAAQ,IAAI,SAAW,SAAS,EAGpE,QAAQ,IAAI,oBAAsB,OAElC,QAAQ,IAAI,yBAA0B,CACpC,KAAM,EAAO,OAAO,KACpB,KAAM,EAAO,OAAO,KACpB,QAAS,EAAO,IAAI,KACpB,OAAQ,EAAO,IAAI,GACrB,CAAC,EAGD,QAAQ,IAAI,yCAAyC,EACrD,GAAW,CAAa,EACrB,KAAK,SAAY,CAChB,QAAQ,IAAI,oCAAoC,EAIhD,GAAI,CACF,0BACA,QAAQ,IAAI,wCAAwC,EACpD,MAAO,EAAU,CACjB,QAAQ,KAAK,8BAA+B,aAAoB,MAAQ,EAAS,QAAU,OAAO,CAAQ,CAAC,EAG7G,QAAQ,IAAI,4BAA4B,EACxC,GAAI,CACF,GAAM,CACJ,KAAM,EAAO,OAAO,KACpB,KAAM,EAAO,OAAO,IACtB,CAAQ,EACR,QAAQ,IAAI,qCAAqC,EACjD,MAAO,EAAO,CACd,QAAQ,MAAM,iCAAkC,CAAK,EACrD,QAAQ,KAAK,CAAC,GAEjB,EACA,MAAM,CAAC,IAAU,CAChB,QAAQ,MAAM,gCAAiC,CAAK,EACpD,QAAQ,KAAK,CAAC,EACf",
|
|
11
|
+
"debugId": "3825AC7405F4C37064756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/server",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.70.
|
|
4
|
+
"version": "0.70.26",
|
|
5
5
|
"description": "Local development and production-ready.",
|
|
6
6
|
"author": "Chris Breuer",
|
|
7
|
-
"contributors": [
|
|
7
|
+
"contributors": [
|
|
8
|
+
"Chris Breuer <chris@stacksjs.com>"
|
|
9
|
+
],
|
|
8
10
|
"license": "MIT",
|
|
9
11
|
"funding": "https://github.com/sponsors/chrisbbreuer",
|
|
10
12
|
"homepage": "https://github.com/stacksjs/stacks/tree/main/storage/framework/core/server#readme",
|
|
@@ -18,8 +20,6 @@
|
|
|
18
20
|
},
|
|
19
21
|
"keywords": [
|
|
20
22
|
"server",
|
|
21
|
-
"vite",
|
|
22
|
-
"nitro",
|
|
23
23
|
"automation",
|
|
24
24
|
"aws",
|
|
25
25
|
"google cloud",
|
|
@@ -27,27 +27,32 @@
|
|
|
27
27
|
],
|
|
28
28
|
"exports": {
|
|
29
29
|
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"bun": "./src/index.ts",
|
|
30
32
|
"import": "./dist/index.js"
|
|
31
33
|
},
|
|
32
34
|
"./*": {
|
|
35
|
+
"bun": "./src/*",
|
|
33
36
|
"import": "./dist/*"
|
|
34
37
|
}
|
|
35
38
|
},
|
|
36
39
|
"module": "dist/index.js",
|
|
37
40
|
"types": "dist/index.d.ts",
|
|
38
|
-
"files": [
|
|
41
|
+
"files": [
|
|
42
|
+
"README.md",
|
|
43
|
+
"dist"
|
|
44
|
+
],
|
|
39
45
|
"scripts": {
|
|
40
46
|
"build": "bun build.ts",
|
|
41
47
|
"typecheck": "bun tsc --noEmit",
|
|
42
48
|
"prepublishOnly": "bun run build"
|
|
43
49
|
},
|
|
44
50
|
"devDependencies": {
|
|
45
|
-
"@stacksjs/config": "0.70.
|
|
46
|
-
"
|
|
47
|
-
"@stacksjs/path": "0.70.
|
|
48
|
-
"@stacksjs/router": "0.70.
|
|
49
|
-
"@stacksjs/validation": "0.70.
|
|
50
|
-
"bun-plugin-auto-imports": "^0.
|
|
51
|
-
"vite": "^6.2.4"
|
|
51
|
+
"@stacksjs/config": "0.70.23",
|
|
52
|
+
"better-dx": "^0.2.12",
|
|
53
|
+
"@stacksjs/path": "0.70.23",
|
|
54
|
+
"@stacksjs/router": "0.70.23",
|
|
55
|
+
"@stacksjs/validation": "0.70.23",
|
|
56
|
+
"bun-plugin-auto-imports": "^0.4.0"
|
|
52
57
|
}
|
|
53
58
|
}
|
package/dist/config.d.ts
DELETED
package/dist/imports.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function initiateImports(): void;
|
package/dist/index.d.ts
DELETED