omni-rest 0.5.1 → 0.5.2
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/adapters/nestjs.js +11 -4
- package/dist/adapters/nestjs.js.map +1 -1
- package/dist/adapters/nestjs.mjs +11 -4
- package/dist/adapters/nestjs.mjs.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/adapters/nestjs.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var module$1 = require('module');
|
|
4
|
+
|
|
3
5
|
var __defProp = Object.defineProperty;
|
|
4
6
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5
7
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
@@ -1079,8 +1081,6 @@ function handlePrismaError(e) {
|
|
|
1079
1081
|
};
|
|
1080
1082
|
}
|
|
1081
1083
|
__name(handlePrismaError, "handlePrismaError");
|
|
1082
|
-
|
|
1083
|
-
// src/adapters/nestjs.ts
|
|
1084
1084
|
function _ts_decorate(decorators, target, key, desc) {
|
|
1085
1085
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1086
1086
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1100,8 +1100,15 @@ function _ts_param(paramIndex, decorator) {
|
|
|
1100
1100
|
__name(_ts_param, "_ts_param");
|
|
1101
1101
|
function nestjsController(prisma, options = {}, prefix = "api") {
|
|
1102
1102
|
var _a;
|
|
1103
|
-
|
|
1104
|
-
|
|
1103
|
+
let nestRequire = __require;
|
|
1104
|
+
try {
|
|
1105
|
+
const callerRequire = module$1.createRequire(process.cwd() + "/package.json");
|
|
1106
|
+
callerRequire.resolve("@nestjs/common");
|
|
1107
|
+
nestRequire = callerRequire;
|
|
1108
|
+
} catch {
|
|
1109
|
+
}
|
|
1110
|
+
const { Controller, Get, Post, Put, Patch, Delete, Param, Body, Query, Req, Res, HttpStatus, Sse, MessageEvent } = nestRequire("@nestjs/common");
|
|
1111
|
+
const { Observable } = nestRequire("rxjs");
|
|
1105
1112
|
const { handle, modelMap, subscriptionBus } = createRouter(prisma, options);
|
|
1106
1113
|
const heartbeatMs = options.subscription?.heartbeatInterval ?? 3e4;
|
|
1107
1114
|
const guards = options.guards ?? {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/introspect.ts","../../src/query-builder.ts","../../src/middleware-helpers.ts","../../src/complexity.ts","../../src/subscriptions.ts","../../src/router.ts","../../src/adapters/nestjs.ts"],"names":["getModels","prisma","raw","_runtimeDataModel","models","modelsObj","Object","entries","map","name","model","fields","f","relationName","kind","undefined","prismaModule","require","dmmfModels","Prisma","dmmf","datamodel","Array","isArray","length","Error","JSON","stringify","slice","type","isId","isRequired","isList","isRelation","hasDefaultValue","default","isUpdatedAt","idField","find","routeName","toRouteName","modelName","toLowerCase","buildModelMap","allowList","filtered","filter","m","includes","fromEntries","detectSoftDeleteField","explicitField","value","Date","field","deletedAt","isActive","getDelegate","meta","key","charAt","delegate","FILTER_OPERATORS","_gte","_lte","_gt","_lt","_contains","_icontains","_startsWith","_endsWith","_in","_notIn","_not","RESERVED_KEYS","Set","buildQuery","searchParams","defaultLimit","maxLimit","modelFields","defaultPaginationMode","where","orderBy","include","select","parsedCursor","paginationMode","get","page","Math","max","parseInt","rawLimit","String","take","min","cursorParam","parse","Buffer","from","toString","skip","sortParam","part","split","dir","trim","direction","startsWith","relation","_count","keys","includeParam","rel","selectParam","searchValue","stringFields","orClauses","contains","mode","has","dotIndex","indexOf","fieldPart","relationMeta","sortedOps","sort","a","b","fieldName","fieldFilter","opMatched","suffix","endsWith","prismaOp","parsedValue","v","isNaN","Number","extra","nested","some","matched","cursor","runGuard","guards","method","ctx","modelGuards","fn","runHook","hook","e","console","error","scoreQuery","parsedQuery","rules","score","perInclude","perFilter","filterCount","k","perSort","perLimit100","ceil","formatSseEvent","event","formatSseHeartbeat","SubscriptionBus","options","buses","Map","checkGuard","modelRouteName","initBus","fg","pollMs","pollInterval","hasCreatedAt","hasUpdatedAt","initialIds","rows","findMany","r","bus","interval","listeners","watermark","knownIds","setInterval","size","tick","created","updated","Promise","all","createdAt","gt","updatedAt","lte","record","add","stripFieldGuard","forEach","l","currentRows","currentIds","id","delete","row","findUnique","catch","subscribe","listener","set","clearInterval","activeSubscriberCount","total","values","activeModels","blocked","hidden","writeOnly","out","createRouter","allow","beforeOperation","afterOperation","softDelete","softDeleteField","envelope","fieldGuards","rateLimit","subscription","features","aggregation","complexity","modelMap","subscriptionBus","handle","body","operation","status","data","available","rateLimitError","guardError","result","executeOperation","handlePrismaError","maxScore","includeArg","selectArg","projection","safeBody","sanitizeBody","parseAgg","val","_all","res","aggregate","_sum","_avg","_min","_max","byRaw","groupBy","by","createMany","count","bulkWhere","bulkData","updateMany","deleteMany","item","results","itemId","updateData","update","coerceId","records","ids","in","deleted","softDeleteInfo","listWhere","nextCursor","hasMore","lastRecord","err","code","dataResult","totalResult","$transaction","safeData","stripResponse","headers","metaBlock","floor","limit","totalPages","create","readOnly","n","target","message","nestjsController","prefix","Controller","Get","Post","Put","Patch","Delete","Param","Body","Query","Req","Res","HttpStatus","Sse","MessageEvent","Observable","heartbeatMs","heartbeatInterval","getSearchParams","query","URLSearchParams","join","OmniRestDynamicController","bulkUpdate","NO_CONTENT","send","json","INTERNAL_SERVER_ERROR","bulkDelete","req","subscriber","heartbeatTimer","unsubscribeFn","then","next","unsub","list","_processRequest","read","replace","remove"],"mappings":"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","file":"nestjs.js","sourcesContent":["import type { ModelMeta, FieldMeta } from \"./types\";\r\n\r\n/**\r\n * Reads Prisma's DMMF (Data Model Meta Format) at runtime\r\n * and returns structured metadata for every model in your schema.\r\n *\r\n * No file reading. No code generation. Pure runtime introspection.\r\n */\r\nexport function getModels(prisma?: any): ModelMeta[] {\r\n let raw: any[] | undefined;\r\n\r\n // Try to get from PrismaClient instance first (new v5 format)\r\n if (prisma?._runtimeDataModel?.models) {\r\n const modelsObj = prisma._runtimeDataModel.models;\r\n // Convert object to array, adding name from key\r\n raw = Object.entries(modelsObj).map(([name, model]: [string, any]) => ({\r\n name,\r\n ...model,\r\n fields: (model.fields || []).map((f: any) => ({\r\n ...f,\r\n relationName: f.kind === \"object\" ? f.name : undefined,\r\n })),\r\n }));\r\n }\r\n\r\n // NOTE: Prisma v7 removed the `Prisma.dmmf` export from `@prisma/client`.\r\n // The `_runtimeDataModel` path above is the only supported runtime path\r\n // for Prisma v5+. The DMMF fallback below is kept only for Prisma v4 and\r\n // older projects that still export it — it is intentionally guarded so it\r\n // never throws on v7.\r\n if (!raw) {\r\n try {\r\n // eslint-disable-next-line @typescript-eslint/no-var-requires\r\n const prismaModule = require(\"@prisma/client\");\r\n // Prisma v7 no longer exports Prisma.dmmf — guard every access\r\n const dmmfModels = prismaModule?.Prisma?.dmmf?.datamodel?.models;\r\n if (Array.isArray(dmmfModels) && dmmfModels.length > 0) {\r\n raw = dmmfModels;\r\n }\r\n } catch {\r\n // @prisma/client not available, not generated, or Prisma v7 — handled below\r\n }\r\n }\r\n\r\n if (!raw) {\r\n throw new Error(\r\n \"[omni-rest] Could not find Prisma DMMF. Ensure Prisma client is generated and you're passing a PrismaClient instance to omni-rest.\"\r\n );\r\n }\r\n\r\n if (!Array.isArray(raw)) {\r\n throw new Error(\r\n `[omni-rest] Expected models to be an array, got ${typeof raw}. Debug: prisma._runtimeDataModel.models=${!!prisma?._runtimeDataModel?.models}, raw value=${JSON.stringify(raw).slice(0, 100)}`\r\n );\r\n }\r\n\r\n return raw.map((model: any) => {\r\n const fields: FieldMeta[] = model.fields.map((f: any) => ({\r\n name: f.name,\r\n type: f.type,\r\n isId: f.isId,\r\n isRequired: f.isRequired,\r\n isList: f.isList,\r\n isRelation: !!f.relationName,\r\n hasDefaultValue: !!f.hasDefaultValue || !!f.default,\r\n isUpdatedAt: !!f.isUpdatedAt,\r\n }));\r\n\r\n const idField =\r\n model.fields.find((f: any) => f.isId)?.name ?? \"id\";\r\n\r\n return {\r\n name: model.name,\r\n routeName: toRouteName(model.name),\r\n fields,\r\n idField,\r\n };\r\n });\r\n}\r\n\r\n/**\r\n * Converts a Prisma model name to a URL-safe route segment.\r\n * \"UserProfile\" → \"userprofile\"\r\n * \"OrderItem\" → \"orderitem\"\r\n */\r\nexport function toRouteName(modelName: string): string {\r\n return modelName.toLowerCase();\r\n}\r\n\r\n/**\r\n * Returns a map of routeName → ModelMeta for O(1) lookups.\r\n */\r\nexport function buildModelMap(\r\n models: ModelMeta[],\r\n allowList?: string[]\r\n): Record<string, ModelMeta> {\r\n const filtered = allowList\r\n ? models.filter((m) => allowList.includes(m.routeName))\r\n : models;\r\n\r\n return Object.fromEntries(filtered.map((m) => [m.routeName, m]));\r\n}\r\n\r\n/**\r\n * Auto-detects the soft-delete field for a model.\r\n * Returns the field name and the value to set, or null if not found.\r\n *\r\n * Priority:\r\n * 1. Explicit `softDeleteField` option\r\n * 2. A field named \"deletedAt\" with type DateTime\r\n * 3. A field named \"isActive\" with type Boolean\r\n */\r\nexport function detectSoftDeleteField(\r\n fields: FieldMeta[],\r\n explicitField?: string\r\n): { field: string; value: Date | boolean } | null {\r\n if (explicitField) {\r\n const f = fields.find((f) => f.name === explicitField);\r\n if (!f) return null;\r\n // Infer value from type\r\n const value = f.type === \"Boolean\" ? false : new Date();\r\n return { field: explicitField, value };\r\n }\r\n\r\n const deletedAt = fields.find((f) => f.name === \"deletedAt\" && f.type === \"DateTime\");\r\n if (deletedAt) return { field: \"deletedAt\", value: new Date() };\r\n\r\n const isActive = fields.find((f) => f.name === \"isActive\" && f.type === \"Boolean\");\r\n if (isActive) return { field: \"isActive\", value: false };\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Gets the Prisma client delegate for a model.\r\n * prisma[\"userProfile\"] or prisma[\"user\"] — handles camelCase.\r\n */\r\nexport function getDelegate(prisma: any, meta: ModelMeta): any {\r\n // Prisma client properties are camelCase of model name\r\n // \"UserProfile\" → \"userProfile\"\r\n const key =\r\n meta.name.charAt(0).toLowerCase() + meta.name.slice(1);\r\n const delegate = prisma[key];\r\n\r\n if (!delegate) {\r\n throw new Error(\r\n `Could not find Prisma delegate for model \"${meta.name}\". ` +\r\n `Expected prisma.${key} to exist.`\r\n );\r\n }\r\n\r\n return delegate;\r\n}","import type { ParsedQuery, FieldMeta } from \"./types\";\r\n\r\n/**\r\n * Supported filter suffixes and their Prisma equivalents.\r\n *\r\n * Usage in URL:\r\n * ?name_contains=john\r\n * ?age_gte=18\r\n * ?status_in=active,inactive\r\n * ?email_not=test@test.com\r\n */\r\nconst FILTER_OPERATORS: Record<string, string> = {\r\n _gte: \"gte\",\r\n _lte: \"lte\",\r\n _gt: \"gt\",\r\n _lt: \"lt\",\r\n _contains: \"contains\",\r\n _icontains: \"contains\", // case-insensitive version (mode: insensitive)\r\n _startsWith: \"startsWith\",\r\n _endsWith: \"endsWith\",\r\n _in: \"in\",\r\n _notIn: \"notIn\",\r\n _not: \"not\",\r\n};\r\n\r\n/**\r\n * Reserved query keys — these are NOT treated as filters.\r\n */\r\nconst RESERVED_KEYS = new Set([\r\n \"page\",\r\n \"limit\",\r\n \"sort\",\r\n \"include\",\r\n \"select\",\r\n \"fields\",\r\n \"search\",\r\n]);\r\n\r\n/**\r\n * Parses URLSearchParams into a full Prisma query object.\r\n *\r\n * Supports:\r\n * Filtering → ?name=John ?age_gte=18 ?status_in=a,b\r\n * Relation filter → ?employees.isActive=true ?author.name_contains=john\r\n * Sorting → ?sort=createdAt:desc or ?sort=name:asc\r\n * Pagination → ?page=2&limit=10\r\n * Relations → ?include=posts,profile\r\n * Fields → ?select=id,name,email or ?fields=id,name,email\r\n * Search → ?search=eng (queries all String fields with OR)\r\n *\r\n * Dot-notation relation filtering:\r\n * ?relation.field=value → isList → { relation: { some: { field: value } } }\r\n * → singular → { relation: { field: value } }\r\n * Operator suffixes work inside dot notation:\r\n * ?author.name_contains=john → { author: { name: { contains: \"john\" } } }\r\n *\r\n * NOTE: Only one level of nesting is supported (relation.field).\r\n * Deeply nested filters (relation.nested.field) are not supported and will\r\n * be treated as a regular (non-relation) filter key.\r\n */\r\nexport function buildQuery(\r\n searchParams: URLSearchParams,\r\n defaultLimit = 20,\r\n maxLimit = 100,\r\n modelFields?: FieldMeta[],\r\n defaultPaginationMode: \"offset\" | \"cursor\" = \"offset\"\r\n): ParsedQuery {\r\n const where: Record<string, any> = {};\r\n const orderBy: Record<string, any> = {};\r\n let include: Record<string, boolean> = {};\r\n let select: Record<string, boolean> | null = null;\r\n let parsedCursor: Record<string, any> | undefined;\r\n\r\n // ─── Pagination ────────────────────────────────────────────────────────────\r\n const paginationMode =\r\n (searchParams.get(\"paginationMode\") as \"offset\" | \"cursor\") ||\r\n defaultPaginationMode;\r\n\r\n const page = Math.max(1, parseInt(searchParams.get(\"page\") ?? \"1\"));\r\n const rawLimit = parseInt(searchParams.get(\"limit\") ?? String(defaultLimit));\r\n const take = Math.min(rawLimit, maxLimit);\r\n\r\n if (paginationMode === \"cursor\") {\r\n const cursorParam = searchParams.get(\"cursor\");\r\n if (cursorParam) {\r\n try {\r\n parsedCursor = JSON.parse(Buffer.from(cursorParam, \"base64\").toString(\"utf-8\"));\r\n } catch {\r\n // Invalid cursor format, ignore and treat as first page\r\n }\r\n }\r\n }\r\n\r\n // If in cursor mode with a valid cursor, we skip 1 (the cursor record itself).\r\n // Otherwise, use offset logic (skip = (page - 1) * take).\r\n const skip = paginationMode === \"cursor\" && parsedCursor ? 1 : (page - 1) * take;\r\n\r\n // ─── Sort ──────────────────────────────────────────────────────────────────\r\n const sortParam = searchParams.get(\"sort\");\r\n if (sortParam) {\r\n // Supports multiple sorts: ?sort=name:asc,createdAt:desc,_count.posts:desc\r\n for (const part of sortParam.split(\",\")) {\r\n const [field, dir] = part.trim().split(\":\");\r\n if (!field) continue;\r\n const direction = dir === \"desc\" ? \"desc\" : \"asc\";\r\n\r\n // _count.relation:dir → { relation: { _count: dir } }\r\n if (field.startsWith(\"_count.\")) {\r\n const relation = field.slice(\"_count.\".length);\r\n if (relation) {\r\n orderBy[relation] = { _count: direction };\r\n }\r\n } else {\r\n orderBy[field] = direction;\r\n }\r\n }\r\n }\r\n\r\n // Ensure consistent sorting for cursor pagination if no sort is provided\r\n if (paginationMode === \"cursor\" && Object.keys(orderBy).length === 0 && modelFields) {\r\n const idField = modelFields.find((f) => f.isId)?.name ?? \"id\";\r\n orderBy[idField] = \"asc\";\r\n }\r\n\r\n // ─── Include (relations) ───────────────────────────────────────────────────\r\n const includeParam = searchParams.get(\"include\");\r\n if (includeParam) {\r\n for (const rel of includeParam.split(\",\")) {\r\n if (rel.trim()) include[rel.trim()] = true;\r\n }\r\n }\r\n\r\n // ─── Select (fields) — ?select= or ?fields= alias ────────────────────────\r\n const selectParam = searchParams.get(\"select\") ?? searchParams.get(\"fields\");\r\n if (selectParam) {\r\n select = {};\r\n for (const field of selectParam.split(\",\")) {\r\n if (field.trim()) select[field.trim()] = true;\r\n }\r\n }\r\n\r\n // ─── Global search (?search=) ─────────────────────────────────────────────\r\n const searchValue = searchParams.get(\"search\");\r\n if (searchValue && modelFields) {\r\n const stringFields = modelFields.filter(\r\n (f) => f.type === \"String\" && !f.isRelation\r\n );\r\n if (stringFields.length > 0) {\r\n const orClauses = stringFields.map((f) => ({\r\n [f.name]: { contains: searchValue, mode: \"insensitive\" },\r\n }));\r\n // Merge with any existing where via AND so other filters still apply\r\n where[\"OR\"] = orClauses;\r\n }\r\n }\r\n\r\n // ─── Filters ───────────────────────────────────────────────────────────────\r\n for (const [key, value] of searchParams.entries()) {\r\n if (RESERVED_KEYS.has(key)) continue;\r\n\r\n // ── Dot-notation relation filter (?relation.field[_op]=value) ──────────\r\n // Only handle a single dot (one level deep). Deeper nesting falls through.\r\n const dotIndex = key.indexOf(\".\");\r\n if (dotIndex > 0 && key.indexOf(\".\", dotIndex + 1) === -1 && modelFields) {\r\n const relationName = key.slice(0, dotIndex);\r\n const fieldPart = key.slice(dotIndex + 1); // e.g. \"isActive\" or \"name_contains\"\r\n\r\n const relationMeta = modelFields.find(\r\n (f) => f.name === relationName && f.isRelation\r\n );\r\n\r\n if (relationMeta) {\r\n // Parse the field part for operator suffix\r\n const sortedOps = Object.keys(FILTER_OPERATORS).sort(\r\n (a, b) => b.length - a.length\r\n );\r\n let fieldName = fieldPart;\r\n let fieldFilter: any;\r\n\r\n let opMatched = false;\r\n for (const suffix of sortedOps) {\r\n if (fieldPart.endsWith(suffix)) {\r\n fieldName = fieldPart.slice(0, -suffix.length);\r\n const prismaOp = FILTER_OPERATORS[suffix];\r\n let parsedValue: any = value;\r\n\r\n if (prismaOp === \"in\" || prismaOp === \"notIn\") {\r\n parsedValue = value.split(\",\").map((v) => v.trim());\r\n } else if (!isNaN(Number(parsedValue)) && typeof parsedValue === \"string\") {\r\n parsedValue = Number(parsedValue);\r\n }\r\n\r\n const extra = suffix === \"_icontains\" ? { mode: \"insensitive\" } : {};\r\n fieldFilter = { [prismaOp]: parsedValue, ...extra };\r\n opMatched = true;\r\n break;\r\n }\r\n }\r\n\r\n if (!opMatched) {\r\n // Exact match — coerce value\r\n let parsedValue: any = value;\r\n if (value === \"true\") parsedValue = true;\r\n else if (value === \"false\") parsedValue = false;\r\n else if (!isNaN(Number(value)) && value !== \"\") parsedValue = Number(value);\r\n fieldFilter = parsedValue;\r\n }\r\n\r\n // isList relation → some: { field: filter }\r\n // singular relation → direct: { field: filter }\r\n const nested = { [fieldName]: fieldFilter };\r\n where[relationName] = relationMeta.isList\r\n ? { some: nested }\r\n : nested;\r\n\r\n continue; // skip regular filter processing for this key\r\n }\r\n }\r\n\r\n // ── Regular filters ────────────────────────────────────────────────────\r\n // Check operator suffixes (longest match first)\r\n let matched = false;\r\n const sortedOps = Object.keys(FILTER_OPERATORS).sort(\r\n (a, b) => b.length - a.length\r\n );\r\n\r\n for (const suffix of sortedOps) {\r\n if (key.endsWith(suffix)) {\r\n const field = key.slice(0, -suffix.length);\r\n const prismaOp = FILTER_OPERATORS[suffix];\r\n\r\n let parsedValue: any = value;\r\n\r\n // Parse arrays\r\n if (prismaOp === \"in\" || prismaOp === \"notIn\") {\r\n parsedValue = value.split(\",\").map((v) => v.trim());\r\n }\r\n\r\n // Attempt numeric coercion\r\n if (!isNaN(Number(parsedValue)) && typeof parsedValue === \"string\") {\r\n parsedValue = Number(parsedValue);\r\n }\r\n\r\n // Case-insensitive flag\r\n const extra = suffix === \"_icontains\" ? { mode: \"insensitive\" } : {};\r\n\r\n where[field] = { [prismaOp]: parsedValue, ...extra };\r\n matched = true;\r\n break;\r\n }\r\n }\r\n\r\n // No operator — exact match\r\n if (!matched) {\r\n let parsedValue: any = value;\r\n\r\n // Coerce booleans\r\n if (value === \"true\") parsedValue = true;\r\n else if (value === \"false\") parsedValue = false;\r\n // Coerce numbers\r\n else if (!isNaN(Number(value)) && value !== \"\") {\r\n parsedValue = Number(value);\r\n }\r\n\r\n where[key] = parsedValue;\r\n }\r\n }\r\n\r\n return {\r\n where,\r\n orderBy,\r\n skip,\r\n take,\r\n cursor: parsedCursor,\r\n paginationMode,\r\n include,\r\n select\r\n };\r\n}","import type { GuardMap, HookFn, HookContext } from \"./types\";\r\n\r\n/**\r\n * Runs the guard for the given model+method combo.\r\n * Returns an error string if blocked, null if allowed.\r\n */\r\nexport async function runGuard(\r\n guards: GuardMap,\r\n model: string,\r\n method: string,\r\n ctx: { id?: string | null; body?: any }\r\n): Promise<string | null> {\r\n const modelGuards = guards[model];\r\n if (!modelGuards) return null;\r\n\r\n const fn = modelGuards[method as keyof typeof modelGuards];\r\n if (!fn) return null;\r\n\r\n return fn({ ...ctx, method });\r\n}\r\n\r\n/**\r\n * Runs a lifecycle hook (beforeOperation / afterOperation).\r\n * Silently swallows errors so hooks never crash the main flow.\r\n */\r\nexport async function runHook(\r\n hook: HookFn | undefined,\r\n ctx: HookContext\r\n): Promise<void> {\r\n if (!hook) return;\r\n try {\r\n await hook(ctx);\r\n } catch (e) {\r\n // Hooks should not crash the request\r\n console.error(\"[omni-rest] Hook error:\", e);\r\n }\r\n}","import type { ParsedQuery, ComplexityRules } from \"./types\";\n\n/**\n * Scores a parsed query based on the provided complexity rules.\n */\nexport function scoreQuery(\n parsedQuery: ParsedQuery,\n rules: ComplexityRules\n): number {\n let score = 0;\n\n if (rules.perInclude && parsedQuery.include) {\n score += Object.keys(parsedQuery.include).length * rules.perInclude;\n }\n\n if (rules.perFilter && parsedQuery.where) {\n // Approximate count of top-level filter keys (excludes OR, AND, etc. for simplicity, \n // but counts them as 1 top-level key which is fine for basic scoring)\n const filterCount = Object.keys(parsedQuery.where).filter(\n (k) => k !== \"OR\" && k !== \"AND\" && k !== \"NOT\"\n ).length;\n score += filterCount * rules.perFilter;\n }\n\n if (rules.perSort && parsedQuery.orderBy) {\n score += Object.keys(parsedQuery.orderBy).length * rules.perSort;\n }\n\n if (rules.perLimit100 && parsedQuery.take) {\n score += Math.ceil(parsedQuery.take / 100) * rules.perLimit100;\n }\n\n return score;\n}\n","import type { PrismaClient } from \"@prisma/client\";\nimport type { ModelMeta, SseEvent, SubscriptionOptions, FieldGuardConfig, GuardMap } from \"./types\";\nimport { getDelegate } from \"./introspect\";\nimport { runGuard } from \"./middleware-helpers\";\n\n// ─── Public helpers (adapters write these bytes to the response) ──────────────\n\n/** Formats a single SSE event line. */\nexport function formatSseEvent(event: SseEvent): string {\n return `data: ${JSON.stringify(event)}\\n\\n`;\n}\n\n/** Formats a heartbeat comment that keeps the TCP connection alive through proxies. */\nexport function formatSseHeartbeat(): string {\n return \": heartbeat\\n\\n\";\n}\n\n// ─── Subscription Bus ─────────────────────────────────────────────────────────\n\ntype Listener = (event: SseEvent) => void;\n\ninterface ModelBus {\n interval: ReturnType<typeof setInterval>;\n listeners: Set<Listener>;\n /** Timestamp of the last poll tick — used for watermark-based create/update detection. */\n watermark: Date;\n /** ID snapshot — used to detect hard-deletes by diffing current IDs against known ones. */\n knownIds: Set<unknown>;\n /** Whether the model has createdAt / updatedAt fields (determined once at bus init). */\n hasCreatedAt: boolean;\n hasUpdatedAt: boolean;\n}\n\n/**\n * SubscriptionBus manages one shared Prisma poll interval per model.\n *\n * Key performance properties:\n * - Zero DB activity for any model that has no active subscribers.\n * - When the first client subscribes to model X, one interval is started.\n * - Additional clients for the same model share that single interval (fan-out).\n * - When the last client disconnects, the interval is immediately cleared.\n *\n * This ensures CRUD routes for un-subscribed tables incur no extra overhead.\n */\nexport class SubscriptionBus {\n private buses = new Map<string, ModelBus>();\n\n constructor(\n private prisma: PrismaClient,\n private options: SubscriptionOptions = {}\n ) {}\n\n // ── Per-connection guard check ──────────────────────────────────────────────\n\n /**\n * Applies the GET guard for the model.\n * Returns an error string if the subscriber should be rejected, null if allowed.\n */\n async checkGuard(\n guards: GuardMap,\n modelRouteName: string,\n ctx: { id?: string | null; body?: any }\n ): Promise<string | null> {\n return runGuard(guards, modelRouteName, \"GET\", ctx);\n }\n\n // ── Bus lifecycle ───────────────────────────────────────────────────────────\n\n private async initBus(meta: ModelMeta, fg?: FieldGuardConfig): Promise<ModelBus> {\n const delegate = getDelegate(this.prisma, meta);\n const pollMs = this.options.pollInterval ?? 1_000;\n\n const hasCreatedAt = meta.fields.some((f) => f.name === \"createdAt\");\n const hasUpdatedAt = meta.fields.some((f) => f.name === \"updatedAt\");\n\n // Snapshot initial IDs so we can detect deletes on the first tick\n let initialIds: unknown[] = [];\n try {\n const rows = await (delegate as any).findMany({\n select: { [meta.idField]: true },\n });\n initialIds = rows.map((r: any) => r[meta.idField]);\n } catch {\n // Empty table or transient error — start with an empty set\n }\n\n const bus: ModelBus = {\n interval: null as any, // assigned below\n listeners: new Set(),\n watermark: new Date(),\n knownIds: new Set(initialIds),\n hasCreatedAt,\n hasUpdatedAt,\n };\n\n bus.interval = setInterval(async () => {\n // Skip work entirely when no clients are listening\n if (bus.listeners.size === 0) return;\n\n const tick = new Date();\n\n try {\n // ── 1. Watermark-based create / update detection ──────────────────────\n if (bus.hasCreatedAt && bus.hasUpdatedAt) {\n const [created, updated] = await Promise.all([\n // New records: createdAt after the last watermark\n (delegate as any).findMany({\n where: { createdAt: { gt: bus.watermark } },\n }),\n // Changed records: updatedAt after watermark but created before it\n (delegate as any).findMany({\n where: {\n updatedAt: { gt: bus.watermark },\n createdAt: { lte: bus.watermark },\n },\n }),\n ]);\n\n for (const record of created) {\n bus.knownIds.add(record[meta.idField]);\n const event: SseEvent = {\n event: \"create\",\n model: meta.name,\n record: stripFieldGuard(record, fg),\n };\n bus.listeners.forEach((l) => l(event));\n }\n\n for (const record of updated) {\n const event: SseEvent = {\n event: \"update\",\n model: meta.name,\n record: stripFieldGuard(record, fg),\n };\n bus.listeners.forEach((l) => l(event));\n }\n } else if (bus.hasUpdatedAt) {\n // No createdAt — only detect updates\n const updated = await (delegate as any).findMany({\n where: { updatedAt: { gt: bus.watermark } },\n });\n for (const record of updated) {\n const event: SseEvent = {\n event: \"update\",\n model: meta.name,\n record: stripFieldGuard(record, fg),\n };\n bus.listeners.forEach((l) => l(event));\n }\n }\n\n // ── 2. ID-set diff for delete detection ───────────────────────────────\n // This works regardless of whether the model has timestamp fields.\n // One extra SELECT(id) per tick — much cheaper than a full row fetch.\n const currentRows = await (delegate as any).findMany({\n select: { [meta.idField]: true },\n });\n const currentIds = new Set<unknown>(currentRows.map((r: any) => r[meta.idField]));\n\n // IDs we knew about but are gone → deleted\n for (const id of bus.knownIds) {\n if (!currentIds.has(id)) {\n bus.knownIds.delete(id);\n const event: SseEvent = { event: \"delete\", model: meta.name, id };\n bus.listeners.forEach((l) => l(event));\n }\n }\n\n // Absorb newly created IDs into the known set\n // (if timestamp-based path above already fired \"create\", this is a no-op for those IDs)\n for (const id of currentIds) {\n if (!bus.knownIds.has(id)) {\n bus.knownIds.add(id);\n // If we have no createdAt field we wouldn't have caught this above — emit now\n if (!bus.hasCreatedAt) {\n const row = await (delegate as any).findUnique({\n where: { [meta.idField]: id },\n }).catch(() => null);\n if (row) {\n const event: SseEvent = {\n event: \"create\",\n model: meta.name,\n record: stripFieldGuard(row, fg),\n };\n bus.listeners.forEach((l) => l(event));\n }\n }\n }\n }\n\n bus.watermark = tick;\n } catch {\n // Swallow individual poll errors — don't crash the bus\n }\n }, pollMs);\n\n return bus;\n }\n\n // ── Public API ──────────────────────────────────────────────────────────────\n\n /**\n * Subscribes a listener to events for the given model.\n *\n * If no bus exists for this model yet, one is created (starting the DB poll).\n * If a bus already exists, the listener is simply added to its fan-out set.\n *\n * Returns an unsubscribe function. Call it when the client disconnects — if\n * this was the last listener the poll interval is immediately cleared.\n */\n async subscribe(\n meta: ModelMeta,\n listener: Listener,\n fg?: FieldGuardConfig\n ): Promise<() => void> {\n let bus = this.buses.get(meta.routeName);\n\n if (!bus) {\n bus = await this.initBus(meta, fg);\n this.buses.set(meta.routeName, bus);\n }\n\n bus.listeners.add(listener);\n\n return () => {\n if (!bus) return;\n bus.listeners.delete(listener);\n\n // Tear down the poll when nobody is watching this model\n if (bus.listeners.size === 0) {\n clearInterval(bus.interval);\n this.buses.delete(meta.routeName);\n }\n };\n }\n\n /**\n * Returns the number of active listeners across all model buses.\n * Useful for diagnostics / metrics.\n */\n get activeSubscriberCount(): number {\n let total = 0;\n for (const bus of this.buses.values()) {\n total += bus.listeners.size;\n }\n return total;\n }\n\n /**\n * Returns a list of model route names that currently have active subscribers.\n */\n get activeModels(): string[] {\n return [...this.buses.keys()];\n }\n}\n\n// ─── Internal helpers ─────────────────────────────────────────────────────────\n\n/**\n * Strips hidden + writeOnly fields before sending a record over SSE.\n * Mirrors the same logic used in router.ts stripResponse.\n */\nfunction stripFieldGuard(record: any, fg?: FieldGuardConfig): any {\n if (!fg || !record || typeof record !== \"object\") return record;\n const blocked = new Set([...(fg.hidden ?? []), ...(fg.writeOnly ?? [])]);\n if (blocked.size === 0) return record;\n const out: Record<string, any> = {};\n for (const [k, v] of Object.entries(record)) {\n if (!blocked.has(k)) out[k] = v;\n }\n return out;\n}\n","import { PrismaClient } from \"@prisma/client\";\r\nimport { getModels, buildModelMap, getDelegate, detectSoftDeleteField } from \"./introspect\";\r\nimport { buildQuery } from \"./query-builder\";\r\nimport { runGuard, runHook } from \"./middleware-helpers\";\r\nimport { scoreQuery } from \"./complexity\";\r\nimport { SubscriptionBus } from \"./subscriptions\";\r\nimport type {\r\n PrismaRestOptions,\r\n HandlerResult,\r\n RouterInstance,\r\n ModelMeta,\r\n FieldGuardConfig,\r\n RateLimitFn,\r\n} from \"./types\";\r\n\r\n/**\r\n * Creates a framework-agnostic CRUD router powered by Prisma DMMF.\r\n *\r\n * All adapters (Express, Next.js, Fastify) use this under the hood.\r\n */\r\nexport function createRouter(\r\n prisma: PrismaClient,\r\n options: PrismaRestOptions = {}\r\n): RouterInstance {\r\n const {\r\n allow,\r\n guards = {},\r\n beforeOperation,\r\n afterOperation,\r\n defaultLimit = 20,\r\n maxLimit = 100,\r\n softDelete = false,\r\n softDeleteField,\r\n envelope = true,\r\n fieldGuards = {},\r\n rateLimit,\r\n subscription = {},\r\n paginationMode = \"offset\",\r\n features = { aggregation: true },\r\n complexity,\r\n } = options;\r\n\r\n // Introspect schema once at startup\r\n const models = getModels(prisma);\r\n const modelMap = buildModelMap(models, allow);\r\n\r\n // One shared subscription bus — zero overhead until a client actually connects\r\n const subscriptionBus = new SubscriptionBus(prisma, subscription);\r\n\r\n async function handle(\r\n method: string,\r\n modelName: string,\r\n id: string | null,\r\n body: any,\r\n searchParams: URLSearchParams,\r\n operation?: string\r\n ): Promise<HandlerResult> {\r\n // ── 1. Resolve model ───────────────────────────────────────────────────\r\n const meta = modelMap[modelName.toLowerCase()];\r\n if (!meta) {\r\n return {\r\n status: 404,\r\n data: {\r\n error: `Model \"${modelName}\" not found or not exposed.`,\r\n available: Object.keys(modelMap),\r\n },\r\n };\r\n }\r\n\r\n // ── 2. Rate limit check ────────────────────────────────────────────────\r\n if (rateLimit) {\r\n const rateLimitError = await rateLimit({ model: meta.name, method, id });\r\n if (rateLimitError) {\r\n return { status: 429, data: { error: rateLimitError } };\r\n }\r\n }\r\n\r\n // ── 3. Guard check ─────────────────────────────────────────────────────\r\n const guardError = await runGuard(guards, meta.routeName, method, {\r\n id,\r\n body,\r\n });\r\n if (guardError) {\r\n return { status: 403, data: { error: guardError } };\r\n }\r\n\r\n // ── 4. Before hook ─────────────────────────────────────────────────────\r\n await runHook(beforeOperation, { model: meta.name, method, id, body });\r\n\r\n // ── 5. Execute operation ───────────────────────────────────────────────\r\n let result: HandlerResult;\r\n\r\n try {\r\n result = await executeOperation(\r\n prisma,\r\n meta,\r\n method,\r\n id,\r\n body,\r\n searchParams,\r\n defaultLimit,\r\n maxLimit,\r\n operation,\r\n softDelete,\r\n softDeleteField,\r\n envelope,\r\n fieldGuards[meta.routeName],\r\n paginationMode,\r\n features,\r\n complexity\r\n );\r\n } catch (e: any) {\r\n return handlePrismaError(e);\r\n }\r\n\r\n // ── 6. After hook ──────────────────────────────────────────────────────\r\n await runHook(afterOperation, {\r\n model: meta.name,\r\n method,\r\n id,\r\n body,\r\n result: result.data,\r\n });\r\n\r\n return result;\r\n }\r\n\r\n return { handle, modelMap, models, subscriptionBus };\r\n}\r\n\r\n// ─── Operation executor ────────────────────────────────────────────────────────\r\n\r\nasync function executeOperation(\r\n prisma: PrismaClient,\r\n meta: ModelMeta,\r\n method: string,\r\n id: string | null,\r\n body: any,\r\n searchParams: URLSearchParams,\r\n defaultLimit: number,\r\n maxLimit: number,\r\n operation?: string,\r\n softDelete = false,\r\n softDeleteField?: string,\r\n envelope = true,\r\n fg?: FieldGuardConfig,\r\n defaultPaginationMode: \"offset\" | \"cursor\" = \"offset\",\r\n features?: { aggregation?: boolean },\r\n complexity?: import(\"./types\").ComplexityOptions\r\n): Promise<HandlerResult> {\r\n const delegate = getDelegate(prisma, meta);\r\n const { where, orderBy, skip, take, cursor, paginationMode, include, select } = buildQuery(\r\n searchParams,\r\n defaultLimit,\r\n maxLimit,\r\n meta.fields,\r\n defaultPaginationMode\r\n );\r\n\r\n // ── Complexity Check ───────────────────────────────────────────────────────\r\n if (complexity) {\r\n const score = scoreQuery({ where, orderBy, skip, take, cursor, paginationMode, include, select }, complexity.rules);\r\n if (score > complexity.maxScore) {\r\n return { status: 429, data: { error: \"Query too complex\", score, maxScore: complexity.maxScore } };\r\n }\r\n }\r\n\r\n // Build include/select args (mutually exclusive in Prisma)\r\n const includeArg = Object.keys(include).length > 0 ? include : undefined;\r\n const selectArg = select && Object.keys(select).length > 0 ? select : undefined;\r\n const projection = selectArg ? { select: selectArg } : includeArg ? { include: includeArg } : {};\r\n\r\n // Sanitize write body — strip readOnly fields before passing to Prisma\r\n const safeBody = sanitizeBody(body, fg);\r\n\r\n const parseAgg = (val: string | null) => {\r\n if (!val) return undefined;\r\n if (val === \"*\") return { _all: true };\r\n const res: Record<string, true> = {};\r\n val.split(\",\").forEach(f => res[f.trim()] = true);\r\n return res;\r\n };\r\n\r\n // ── GET /model/aggregate ───────────────────────────────────────────────────\r\n if (method === \"GET\" && id === \"aggregate\") {\r\n if (features?.aggregation === false) {\r\n return { status: 403, data: { error: \"Aggregation endpoints are disabled.\" } };\r\n }\r\n const result = await delegate.aggregate({\r\n where,\r\n _count: parseAgg(searchParams.get(\"_count\")),\r\n _sum: parseAgg(searchParams.get(\"_sum\")),\r\n _avg: parseAgg(searchParams.get(\"_avg\")),\r\n _min: parseAgg(searchParams.get(\"_min\")),\r\n _max: parseAgg(searchParams.get(\"_max\"))\r\n });\r\n return { status: 200, data: result };\r\n }\r\n\r\n // ── GET /model/groupBy ─────────────────────────────────────────────────────\r\n if (method === \"GET\" && id === \"groupBy\") {\r\n if (features?.aggregation === false) {\r\n return { status: 403, data: { error: \"Aggregation endpoints are disabled.\" } };\r\n }\r\n const byRaw = searchParams.get(\"by\");\r\n if (!byRaw) {\r\n return { status: 400, data: { error: \"groupBy requires a 'by' query parameter.\" } };\r\n }\r\n const result = await delegate.groupBy({\r\n by: byRaw.split(\",\").map(f => f.trim()),\r\n where,\r\n orderBy: Object.keys(orderBy).length > 0 ? orderBy : undefined,\r\n take: take !== defaultLimit ? take : undefined, // only apply if limit was set explicitly\r\n skip: skip > 0 ? skip : undefined,\r\n _count: parseAgg(searchParams.get(\"_count\")),\r\n _sum: parseAgg(searchParams.get(\"_sum\")),\r\n _avg: parseAgg(searchParams.get(\"_avg\")),\r\n _min: parseAgg(searchParams.get(\"_min\")),\r\n _max: parseAgg(searchParams.get(\"_max\"))\r\n });\r\n return { status: 200, data: result };\r\n }\r\n\r\n // ── POST /model/bulk — createMany ──────────────────────────────────────────\r\n if (method === \"POST\" && id === \"bulk\") {\r\n if (!Array.isArray(body) || body.length === 0) {\r\n return { status: 400, data: { error: \"Request body must be a non-empty array\" } };\r\n }\r\n const result = await delegate.createMany({ data: body });\r\n return { status: 201, data: { count: result.count } };\r\n }\r\n\r\n // ── PUT /model/bulk — updateMany ───────────────────────────────────────────\r\n if (method === \"PUT\" && id === \"bulk\") {\r\n const { where: bulkWhere, data: bulkData } = body || {};\r\n if (!bulkWhere || !bulkData) {\r\n return { status: 400, data: { error: \"Body must contain { where, data }\" } };\r\n }\r\n const result = await delegate.updateMany({ where: bulkWhere, data: bulkData });\r\n return { status: 200, data: { count: result.count } };\r\n }\r\n\r\n // ── DELETE /model/bulk — deleteMany ───────────────────────────────────────\r\n if (method === \"DELETE\" && id === \"bulk\") {\r\n const { where: bulkWhere } = body || {};\r\n if (!bulkWhere) {\r\n return { status: 400, data: { error: \"Body must contain { where }\" } };\r\n }\r\n const result = await delegate.deleteMany({ where: bulkWhere });\r\n return { status: 200, data: { count: result.count } };\r\n }\r\n\r\n // ── PATCH /model/bulk/update (legacy per-ID array) ─────────────────────────\r\n if (method === \"PATCH\" && operation === \"bulk-update\") {\r\n if (!Array.isArray(body) || body.length === 0) {\r\n return { status: 400, data: { error: \"Request body must be a non-empty array of update records\" } };\r\n }\r\n for (const item of body) {\r\n if (!item[meta.idField]) {\r\n return { status: 400, data: { error: `Each record must have an ${meta.idField} field` } };\r\n }\r\n }\r\n const results = await Promise.all(\r\n body.map((item) => {\r\n const itemId = item[meta.idField];\r\n const updateData = { ...item };\r\n delete updateData[meta.idField];\r\n return delegate.update({\r\n where: { [meta.idField]: coerceId(itemId) },\r\n data: updateData,\r\n ...projection,\r\n });\r\n })\r\n );\r\n return { status: 200, data: { updated: results.length, records: results } };\r\n }\r\n\r\n // ── DELETE /model/bulk/delete (legacy ID array) ────────────────────────────\r\n if (method === \"DELETE\" && operation === \"bulk-delete\") {\r\n if (!Array.isArray(body) || body.length === 0) {\r\n return { status: 400, data: { error: \"Request body must be a non-empty array of IDs\" } };\r\n }\r\n const ids = body.map((item: any) =>\r\n typeof item === \"object\" ? item[meta.idField] : item\r\n );\r\n const result = await delegate.deleteMany({\r\n where: { [meta.idField]: { in: ids.map(coerceId) } },\r\n });\r\n return { status: 200, data: { deleted: result.count } };\r\n }\r\n\r\n // ── GET /model ─────────────────────────────────────────────────────────────\r\n if (method === \"GET\" && !id) {\r\n const softDeleteInfo = softDelete\r\n ? detectSoftDeleteField(meta.fields, softDeleteField)\r\n : null;\r\n const listWhere = softDeleteInfo\r\n ? { ...where, [softDeleteInfo.field]: softDeleteInfo.field === \"isActive\" ? true : null }\r\n : where;\r\n\r\n let data: any[];\r\n let total: number | undefined;\r\n let nextCursor: string | null = null;\r\n let hasMore = false;\r\n\r\n if (paginationMode === \"cursor\") {\r\n try {\r\n data = await delegate.findMany({\r\n where: listWhere,\r\n orderBy,\r\n skip,\r\n take,\r\n cursor: cursor ? cursor : undefined,\r\n ...projection\r\n });\r\n hasMore = data.length === take;\r\n if (hasMore && data.length > 0) {\r\n const lastRecord = data[data.length - 1];\r\n nextCursor = Buffer.from(\r\n JSON.stringify({ [meta.idField]: lastRecord[meta.idField] })\r\n ).toString(\"base64\");\r\n }\r\n } catch (err: any) {\r\n // If cursor record is not found, Prisma throws P2025. Fallback gracefully.\r\n if (err?.code === \"P2025\") {\r\n data = [];\r\n hasMore = false;\r\n } else {\r\n throw err;\r\n }\r\n }\r\n } else {\r\n const [dataResult, totalResult] = await (prisma as any).$transaction([\r\n delegate.findMany({ where: listWhere, orderBy, skip, take, ...projection }),\r\n delegate.count({ where: listWhere }),\r\n ]);\r\n data = dataResult;\r\n total = totalResult;\r\n }\r\n\r\n const safeData = data.map((r: any) => stripResponse(r, fg));\r\n\r\n if (!envelope) {\r\n const headers: Record<string, string> = {};\r\n if (paginationMode === \"offset\" && total !== undefined) {\r\n headers[\"X-Total-Count\"] = String(total);\r\n } else if (paginationMode === \"cursor\") {\r\n headers[\"X-Has-More\"] = String(hasMore);\r\n if (nextCursor) headers[\"X-Next-Cursor\"] = nextCursor;\r\n }\r\n return { status: 200, data: safeData, headers };\r\n }\r\n\r\n const metaBlock = paginationMode === \"cursor\"\r\n ? { nextCursor, hasMore }\r\n : {\r\n total,\r\n page: Math.floor(skip / take) + 1,\r\n limit: take,\r\n totalPages: Math.ceil((total ?? 0) / take),\r\n };\r\n\r\n return {\r\n status: 200,\r\n data: {\r\n data: safeData,\r\n meta: metaBlock,\r\n },\r\n };\r\n }\r\n\r\n // ── GET /model/:id ─────────────────────────────────────────────────────────\r\n if (method === \"GET\" && id) {\r\n const record = await delegate.findUnique({\r\n where: { [meta.idField]: coerceId(id) },\r\n ...projection,\r\n });\r\n if (!record) {\r\n return { status: 404, data: { error: `${meta.name} with id \"${id}\" not found.` } };\r\n }\r\n return { status: 200, data: stripResponse(record, fg) };\r\n }\r\n\r\n // ── POST /model ────────────────────────────────────────────────────────────\r\n if (method === \"POST\" && !id) {\r\n const record = await delegate.create({ data: safeBody });\r\n return { status: 201, data: stripResponse(record, fg) };\r\n }\r\n\r\n // ── PUT /model/:id ─────────────────────────────────────────────────────────\r\n if ((method === \"PUT\" || method === \"PATCH\") && id) {\r\n const record = await delegate.update({\r\n where: { [meta.idField]: coerceId(id) },\r\n data: safeBody,\r\n });\r\n return { status: 200, data: stripResponse(record, fg) };\r\n }\r\n\r\n // ── DELETE /model/:id ──────────────────────────────────────────────────────\r\n if (method === \"DELETE\" && id) {\r\n const softDeleteInfo = softDelete\r\n ? detectSoftDeleteField(meta.fields, softDeleteField)\r\n : null;\r\n\r\n if (softDeleteInfo) {\r\n const record = await delegate.update({\r\n where: { [meta.idField]: coerceId(id) },\r\n data: { [softDeleteInfo.field]: softDeleteInfo.value },\r\n });\r\n return { status: 200, data: record };\r\n }\r\n\r\n await delegate.delete({ where: { [meta.idField]: coerceId(id) } });\r\n return { status: 204, data: null };\r\n }\r\n\r\n return { status: 405, data: { error: `Method ${method} not allowed.` } };\r\n}\r\n\r\n// ─── Helpers ──────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Strips hidden and writeOnly fields from a response record.\r\n */\r\nfunction stripResponse(record: any, fg?: FieldGuardConfig): any {\r\n if (!fg || !record || typeof record !== \"object\") return record;\r\n const blocked = new Set([...(fg.hidden ?? []), ...(fg.writeOnly ?? [])]);\r\n if (blocked.size === 0) return record;\r\n const out: Record<string, any> = {};\r\n for (const [k, v] of Object.entries(record)) {\r\n if (!blocked.has(k)) out[k] = v;\r\n }\r\n return out;\r\n}\r\n\r\n/**\r\n * Strips readOnly fields from a write body before passing to Prisma.\r\n */\r\nfunction sanitizeBody(body: any, fg?: FieldGuardConfig): any {\r\n if (!fg || !body || typeof body !== \"object\" || Array.isArray(body)) return body;\r\n const readOnly = new Set(fg.readOnly ?? []);\r\n if (readOnly.size === 0) return body;\r\n const out: Record<string, any> = {};\r\n for (const [k, v] of Object.entries(body)) {\r\n if (!readOnly.has(k)) out[k] = v;\r\n }\r\n return out;\r\n}\r\n\r\n/**\r\n * Coerces an ID string to number when possible (common with Int PKs).\r\n */\r\nfunction coerceId(id: string): string | number {\r\n const n = Number(id);\r\n return isNaN(n) ? id : n;\r\n}\r\n\r\n/**\r\n * Maps Prisma error codes to meaningful HTTP responses.\r\n */\r\nfunction handlePrismaError(e: any): HandlerResult {\r\n const code = e?.code;\r\n\r\n if (code === \"P2025\") {\r\n return { status: 404, data: { error: \"Record not found.\" } };\r\n }\r\n if (code === \"P2002\") {\r\n const fields = e?.meta?.target ?? \"unknown fields\";\r\n return { status: 409, data: { error: `Unique constraint failed on: ${fields}` } };\r\n }\r\n if (code === \"P2003\") {\r\n return { status: 400, data: { error: \"Foreign key constraint failed.\" } };\r\n }\r\n if (code === \"P2014\") {\r\n return { status: 400, data: { error: \"Relation violation.\" } };\r\n }\r\n\r\n return { status: 500, data: { error: e?.message ?? \"Internal server error.\" } };\r\n}\r\n","// @ts-nocheck\r\nimport { PrismaClient } from \"@prisma/client\";\r\nimport { createRouter } from \"../router\";\r\nimport { formatSseEvent, formatSseHeartbeat } from \"../subscriptions\";\r\nimport type { PrismaRestOptions } from \"../types\";\r\n\r\n/**\r\n * NestJS adapter for omni-rest.\r\n * Generates a dynamic controller block that maps wildcard routes directly into omni-rest handlers.\r\n *\r\n * @example\r\n * ```ts\r\n * import { Controller, Module, NestModule, MiddlewareConsumer } from '@nestjs/common';\r\n * import { PrismaClient } from '@prisma/client';\r\n * import { nestjsController } from 'omni-rest/nestjs';\r\n *\r\n * const prisma = new PrismaClient();\r\n *\r\n * // Create generating Controller natively via factory\r\n * export const OmniRestController = nestjsController(prisma, {\r\n * allow: [\"product\", \"category\"],\r\n * });\r\n *\r\n * @Module({\r\n * controllers: [OmniRestController],\r\n * })\r\n * export class AppModule {}\r\n * ```\r\n */\r\nexport function nestjsController(\r\n prisma: PrismaClient,\r\n options: PrismaRestOptions = {},\r\n prefix: string = \"api\"\r\n): any {\r\n // We lazily require NestJS specific decorators so they don't break applications that don't have `@nestjs/common`\r\n // eslint-disable-next-line @typescript-eslint/no-var-requires\r\n const { Controller, Get, Post, Put, Patch, Delete, Param, Body, Query, Req, Res, HttpStatus, Sse, MessageEvent } = require(\"@nestjs/common\");\r\n const { Observable } = require(\"rxjs\");\r\n const { handle, modelMap, subscriptionBus } = createRouter(prisma, options);\r\n const heartbeatMs = options.subscription?.heartbeatInterval ?? 30_000;\r\n const guards = (options.guards ?? {}) as Record<string, any>;\r\n const fieldGuards = (options.fieldGuards ?? {}) as Record<string, any>;\r\n\r\n const getSearchParams = (query: Record<string, string>): URLSearchParams => {\r\n return new URLSearchParams(\r\n Object.entries(query || {})\r\n .map(([k, v]) => `${k}=${v}`)\r\n .join(\"&\")\r\n );\r\n };\r\n\r\n @Controller(prefix)\r\n class OmniRestDynamicController {\r\n \r\n @Patch(\":model/bulk/update\")\r\n async bulkUpdate(\r\n @Param(\"model\") model: string,\r\n @Body() body: any[],\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n try {\r\n const { status, data } = await handle(\"PATCH\", model, null, body ?? [], getSearchParams(query), \"bulk-update\");\r\n if (status === 204) return res.status(HttpStatus.NO_CONTENT).send();\r\n return res.status(status).json(data);\r\n } catch (e: any) {\r\n return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: e.message });\r\n }\r\n }\r\n\r\n @Delete(\":model/bulk/delete\")\r\n async bulkDelete(\r\n @Param(\"model\") model: string,\r\n @Body() body: any[],\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n try {\r\n const { status, data } = await handle(\"DELETE\", model, null, body ?? [], getSearchParams(query), \"bulk-delete\");\r\n if (status === 204) return res.status(HttpStatus.NO_CONTENT).send();\r\n return res.status(status).json(data);\r\n } catch (e: any) {\r\n return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: e.message });\r\n }\r\n }\r\n\r\n // ── SSE: GET :model/subscribe ───────────────────────────────────────\r\n // Decorated with @Sse so NestJS handles Content-Type and streaming lifecycle.\r\n // Must appear before @Get(\":model\") to avoid route shadowing.\r\n @Sse(\":model/subscribe\")\r\n subscribe(\r\n @Param(\"model\") model: string,\r\n @Query() query: any,\r\n @Req() req: any\r\n ) {\r\n const meta = modelMap[model.toLowerCase()];\r\n return new Observable((subscriber: any) => {\r\n if (!meta) {\r\n subscriber.error(new Error(`Model \"${model}\" not found or not exposed.`));\r\n return;\r\n }\r\n\r\n const fg = fieldGuards[meta.routeName];\r\n let heartbeatTimer: ReturnType<typeof setInterval>;\r\n let unsubscribeFn: (() => void) | undefined;\r\n\r\n // Async setup inside the synchronous Observable factory\r\n subscriptionBus.checkGuard(guards, meta.routeName, { body: {} }).then((guardError: string | null) => {\r\n if (guardError) {\r\n subscriber.error(new Error(guardError));\r\n return;\r\n }\r\n\r\n subscriptionBus.subscribe(\r\n meta,\r\n (event: any) => {\r\n subscriber.next({ data: formatSseEvent(event) } as typeof MessageEvent);\r\n },\r\n fg\r\n ).then((unsub: () => void) => {\r\n unsubscribeFn = unsub;\r\n\r\n heartbeatTimer = setInterval(() => {\r\n subscriber.next({ data: formatSseHeartbeat() } as typeof MessageEvent);\r\n }, heartbeatMs);\r\n });\r\n });\r\n\r\n // Teardown: called when the client disconnects or Observable is unsubscribed\r\n return () => {\r\n if (heartbeatTimer) clearInterval(heartbeatTimer);\r\n if (unsubscribeFn) unsubscribeFn();\r\n };\r\n });\r\n }\r\n\r\n @Get(\":model\")\r\n async list(\r\n @Param(\"model\") model: string,\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n return await this._processRequest(\"GET\", model, null, {}, query, res);\r\n }\r\n\r\n @Post(\":model\")\r\n async create(\r\n @Param(\"model\") model: string,\r\n @Body() body: any,\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n return await this._processRequest(\"POST\", model, null, body, query, res);\r\n }\r\n\r\n @Get(\":model/:id\")\r\n async read(\r\n @Param(\"model\") model: string,\r\n @Param(\"id\") id: string,\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n return await this._processRequest(\"GET\", model, id, {}, query, res);\r\n }\r\n\r\n @Put(\":model/:id\")\r\n async replace(\r\n @Param(\"model\") model: string,\r\n @Param(\"id\") id: string,\r\n @Body() body: any,\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n return await this._processRequest(\"PUT\", model, id, body, query, res);\r\n }\r\n\r\n @Patch(\":model/:id\")\r\n async update(\r\n @Param(\"model\") model: string,\r\n @Param(\"id\") id: string,\r\n @Body() body: any,\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n return await this._processRequest(\"PATCH\", model, id, body, query, res);\r\n }\r\n\r\n @Delete(\":model/:id\")\r\n async remove(\r\n @Param(\"model\") model: string,\r\n @Param(\"id\") id: string,\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n return await this._processRequest(\"DELETE\", model, id, {}, query, res);\r\n }\r\n\r\n private async _processRequest(\r\n method: string, \r\n model: string, \r\n id: string | null, \r\n body: any, \r\n query: any, \r\n res: any\r\n ) {\r\n try {\r\n const { status, data } = await handle(method, model, id, body ?? {}, getSearchParams(query));\r\n if (status === 204) {\r\n return res.status(HttpStatus.NO_CONTENT).send();\r\n }\r\n return res.status(status).json(data);\r\n } catch (e: any) {\r\n return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: e.message });\r\n }\r\n }\r\n }\r\n\r\n return OmniRestDynamicController;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/introspect.ts","../../src/query-builder.ts","../../src/middleware-helpers.ts","../../src/complexity.ts","../../src/subscriptions.ts","../../src/router.ts","../../src/adapters/nestjs.ts"],"names":["getModels","prisma","raw","_runtimeDataModel","models","modelsObj","Object","entries","map","name","model","fields","f","relationName","kind","undefined","prismaModule","require","dmmfModels","Prisma","dmmf","datamodel","Array","isArray","length","Error","JSON","stringify","slice","type","isId","isRequired","isList","isRelation","hasDefaultValue","default","isUpdatedAt","idField","find","routeName","toRouteName","modelName","toLowerCase","buildModelMap","allowList","filtered","filter","m","includes","fromEntries","detectSoftDeleteField","explicitField","value","Date","field","deletedAt","isActive","getDelegate","meta","key","charAt","delegate","FILTER_OPERATORS","_gte","_lte","_gt","_lt","_contains","_icontains","_startsWith","_endsWith","_in","_notIn","_not","RESERVED_KEYS","Set","buildQuery","searchParams","defaultLimit","maxLimit","modelFields","defaultPaginationMode","where","orderBy","include","select","parsedCursor","paginationMode","get","page","Math","max","parseInt","rawLimit","String","take","min","cursorParam","parse","Buffer","from","toString","skip","sortParam","part","split","dir","trim","direction","startsWith","relation","_count","keys","includeParam","rel","selectParam","searchValue","stringFields","orClauses","contains","mode","has","dotIndex","indexOf","fieldPart","relationMeta","sortedOps","sort","a","b","fieldName","fieldFilter","opMatched","suffix","endsWith","prismaOp","parsedValue","v","isNaN","Number","extra","nested","some","matched","cursor","runGuard","guards","method","ctx","modelGuards","fn","runHook","hook","e","console","error","scoreQuery","parsedQuery","rules","score","perInclude","perFilter","filterCount","k","perSort","perLimit100","ceil","formatSseEvent","event","formatSseHeartbeat","SubscriptionBus","options","buses","Map","checkGuard","modelRouteName","initBus","fg","pollMs","pollInterval","hasCreatedAt","hasUpdatedAt","initialIds","rows","findMany","r","bus","interval","listeners","watermark","knownIds","setInterval","size","tick","created","updated","Promise","all","createdAt","gt","updatedAt","lte","record","add","stripFieldGuard","forEach","l","currentRows","currentIds","id","delete","row","findUnique","catch","subscribe","listener","set","clearInterval","activeSubscriberCount","total","values","activeModels","blocked","hidden","writeOnly","out","createRouter","allow","beforeOperation","afterOperation","softDelete","softDeleteField","envelope","fieldGuards","rateLimit","subscription","features","aggregation","complexity","modelMap","subscriptionBus","handle","body","operation","status","data","available","rateLimitError","guardError","result","executeOperation","handlePrismaError","maxScore","includeArg","selectArg","projection","safeBody","sanitizeBody","parseAgg","val","_all","res","aggregate","_sum","_avg","_min","_max","byRaw","groupBy","by","createMany","count","bulkWhere","bulkData","updateMany","deleteMany","item","results","itemId","updateData","update","coerceId","records","ids","in","deleted","softDeleteInfo","listWhere","nextCursor","hasMore","lastRecord","err","code","dataResult","totalResult","$transaction","safeData","stripResponse","headers","metaBlock","floor","limit","totalPages","create","readOnly","n","target","message","nestjsController","prefix","nestRequire","callerRequire","createRequire","process","cwd","resolve","Controller","Get","Post","Put","Patch","Delete","Param","Body","Query","Req","Res","HttpStatus","Sse","MessageEvent","Observable","heartbeatMs","heartbeatInterval","getSearchParams","query","URLSearchParams","join","OmniRestDynamicController","bulkUpdate","NO_CONTENT","send","json","INTERNAL_SERVER_ERROR","bulkDelete","req","subscriber","heartbeatTimer","unsubscribeFn","then","next","unsub","list","_processRequest","read","replace","remove"],"mappings":"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","file":"nestjs.js","sourcesContent":["import type { ModelMeta, FieldMeta } from \"./types\";\r\n\r\n/**\r\n * Reads Prisma's DMMF (Data Model Meta Format) at runtime\r\n * and returns structured metadata for every model in your schema.\r\n *\r\n * No file reading. No code generation. Pure runtime introspection.\r\n */\r\nexport function getModels(prisma?: any): ModelMeta[] {\r\n let raw: any[] | undefined;\r\n\r\n // Try to get from PrismaClient instance first (new v5 format)\r\n if (prisma?._runtimeDataModel?.models) {\r\n const modelsObj = prisma._runtimeDataModel.models;\r\n // Convert object to array, adding name from key\r\n raw = Object.entries(modelsObj).map(([name, model]: [string, any]) => ({\r\n name,\r\n ...model,\r\n fields: (model.fields || []).map((f: any) => ({\r\n ...f,\r\n relationName: f.kind === \"object\" ? f.name : undefined,\r\n })),\r\n }));\r\n }\r\n\r\n // NOTE: Prisma v7 removed the `Prisma.dmmf` export from `@prisma/client`.\r\n // The `_runtimeDataModel` path above is the only supported runtime path\r\n // for Prisma v5+. The DMMF fallback below is kept only for Prisma v4 and\r\n // older projects that still export it — it is intentionally guarded so it\r\n // never throws on v7.\r\n if (!raw) {\r\n try {\r\n // eslint-disable-next-line @typescript-eslint/no-var-requires\r\n const prismaModule = require(\"@prisma/client\");\r\n // Prisma v7 no longer exports Prisma.dmmf — guard every access\r\n const dmmfModels = prismaModule?.Prisma?.dmmf?.datamodel?.models;\r\n if (Array.isArray(dmmfModels) && dmmfModels.length > 0) {\r\n raw = dmmfModels;\r\n }\r\n } catch {\r\n // @prisma/client not available, not generated, or Prisma v7 — handled below\r\n }\r\n }\r\n\r\n if (!raw) {\r\n throw new Error(\r\n \"[omni-rest] Could not find Prisma DMMF. Ensure Prisma client is generated and you're passing a PrismaClient instance to omni-rest.\"\r\n );\r\n }\r\n\r\n if (!Array.isArray(raw)) {\r\n throw new Error(\r\n `[omni-rest] Expected models to be an array, got ${typeof raw}. Debug: prisma._runtimeDataModel.models=${!!prisma?._runtimeDataModel?.models}, raw value=${JSON.stringify(raw).slice(0, 100)}`\r\n );\r\n }\r\n\r\n return raw.map((model: any) => {\r\n const fields: FieldMeta[] = model.fields.map((f: any) => ({\r\n name: f.name,\r\n type: f.type,\r\n isId: f.isId,\r\n isRequired: f.isRequired,\r\n isList: f.isList,\r\n isRelation: !!f.relationName,\r\n hasDefaultValue: !!f.hasDefaultValue || !!f.default,\r\n isUpdatedAt: !!f.isUpdatedAt,\r\n }));\r\n\r\n const idField =\r\n model.fields.find((f: any) => f.isId)?.name ?? \"id\";\r\n\r\n return {\r\n name: model.name,\r\n routeName: toRouteName(model.name),\r\n fields,\r\n idField,\r\n };\r\n });\r\n}\r\n\r\n/**\r\n * Converts a Prisma model name to a URL-safe route segment.\r\n * \"UserProfile\" → \"userprofile\"\r\n * \"OrderItem\" → \"orderitem\"\r\n */\r\nexport function toRouteName(modelName: string): string {\r\n return modelName.toLowerCase();\r\n}\r\n\r\n/**\r\n * Returns a map of routeName → ModelMeta for O(1) lookups.\r\n */\r\nexport function buildModelMap(\r\n models: ModelMeta[],\r\n allowList?: string[]\r\n): Record<string, ModelMeta> {\r\n const filtered = allowList\r\n ? models.filter((m) => allowList.includes(m.routeName))\r\n : models;\r\n\r\n return Object.fromEntries(filtered.map((m) => [m.routeName, m]));\r\n}\r\n\r\n/**\r\n * Auto-detects the soft-delete field for a model.\r\n * Returns the field name and the value to set, or null if not found.\r\n *\r\n * Priority:\r\n * 1. Explicit `softDeleteField` option\r\n * 2. A field named \"deletedAt\" with type DateTime\r\n * 3. A field named \"isActive\" with type Boolean\r\n */\r\nexport function detectSoftDeleteField(\r\n fields: FieldMeta[],\r\n explicitField?: string\r\n): { field: string; value: Date | boolean } | null {\r\n if (explicitField) {\r\n const f = fields.find((f) => f.name === explicitField);\r\n if (!f) return null;\r\n // Infer value from type\r\n const value = f.type === \"Boolean\" ? false : new Date();\r\n return { field: explicitField, value };\r\n }\r\n\r\n const deletedAt = fields.find((f) => f.name === \"deletedAt\" && f.type === \"DateTime\");\r\n if (deletedAt) return { field: \"deletedAt\", value: new Date() };\r\n\r\n const isActive = fields.find((f) => f.name === \"isActive\" && f.type === \"Boolean\");\r\n if (isActive) return { field: \"isActive\", value: false };\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Gets the Prisma client delegate for a model.\r\n * prisma[\"userProfile\"] or prisma[\"user\"] — handles camelCase.\r\n */\r\nexport function getDelegate(prisma: any, meta: ModelMeta): any {\r\n // Prisma client properties are camelCase of model name\r\n // \"UserProfile\" → \"userProfile\"\r\n const key =\r\n meta.name.charAt(0).toLowerCase() + meta.name.slice(1);\r\n const delegate = prisma[key];\r\n\r\n if (!delegate) {\r\n throw new Error(\r\n `Could not find Prisma delegate for model \"${meta.name}\". ` +\r\n `Expected prisma.${key} to exist.`\r\n );\r\n }\r\n\r\n return delegate;\r\n}","import type { ParsedQuery, FieldMeta } from \"./types\";\r\n\r\n/**\r\n * Supported filter suffixes and their Prisma equivalents.\r\n *\r\n * Usage in URL:\r\n * ?name_contains=john\r\n * ?age_gte=18\r\n * ?status_in=active,inactive\r\n * ?email_not=test@test.com\r\n */\r\nconst FILTER_OPERATORS: Record<string, string> = {\r\n _gte: \"gte\",\r\n _lte: \"lte\",\r\n _gt: \"gt\",\r\n _lt: \"lt\",\r\n _contains: \"contains\",\r\n _icontains: \"contains\", // case-insensitive version (mode: insensitive)\r\n _startsWith: \"startsWith\",\r\n _endsWith: \"endsWith\",\r\n _in: \"in\",\r\n _notIn: \"notIn\",\r\n _not: \"not\",\r\n};\r\n\r\n/**\r\n * Reserved query keys — these are NOT treated as filters.\r\n */\r\nconst RESERVED_KEYS = new Set([\r\n \"page\",\r\n \"limit\",\r\n \"sort\",\r\n \"include\",\r\n \"select\",\r\n \"fields\",\r\n \"search\",\r\n]);\r\n\r\n/**\r\n * Parses URLSearchParams into a full Prisma query object.\r\n *\r\n * Supports:\r\n * Filtering → ?name=John ?age_gte=18 ?status_in=a,b\r\n * Relation filter → ?employees.isActive=true ?author.name_contains=john\r\n * Sorting → ?sort=createdAt:desc or ?sort=name:asc\r\n * Pagination → ?page=2&limit=10\r\n * Relations → ?include=posts,profile\r\n * Fields → ?select=id,name,email or ?fields=id,name,email\r\n * Search → ?search=eng (queries all String fields with OR)\r\n *\r\n * Dot-notation relation filtering:\r\n * ?relation.field=value → isList → { relation: { some: { field: value } } }\r\n * → singular → { relation: { field: value } }\r\n * Operator suffixes work inside dot notation:\r\n * ?author.name_contains=john → { author: { name: { contains: \"john\" } } }\r\n *\r\n * NOTE: Only one level of nesting is supported (relation.field).\r\n * Deeply nested filters (relation.nested.field) are not supported and will\r\n * be treated as a regular (non-relation) filter key.\r\n */\r\nexport function buildQuery(\r\n searchParams: URLSearchParams,\r\n defaultLimit = 20,\r\n maxLimit = 100,\r\n modelFields?: FieldMeta[],\r\n defaultPaginationMode: \"offset\" | \"cursor\" = \"offset\"\r\n): ParsedQuery {\r\n const where: Record<string, any> = {};\r\n const orderBy: Record<string, any> = {};\r\n let include: Record<string, boolean> = {};\r\n let select: Record<string, boolean> | null = null;\r\n let parsedCursor: Record<string, any> | undefined;\r\n\r\n // ─── Pagination ────────────────────────────────────────────────────────────\r\n const paginationMode =\r\n (searchParams.get(\"paginationMode\") as \"offset\" | \"cursor\") ||\r\n defaultPaginationMode;\r\n\r\n const page = Math.max(1, parseInt(searchParams.get(\"page\") ?? \"1\"));\r\n const rawLimit = parseInt(searchParams.get(\"limit\") ?? String(defaultLimit));\r\n const take = Math.min(rawLimit, maxLimit);\r\n\r\n if (paginationMode === \"cursor\") {\r\n const cursorParam = searchParams.get(\"cursor\");\r\n if (cursorParam) {\r\n try {\r\n parsedCursor = JSON.parse(Buffer.from(cursorParam, \"base64\").toString(\"utf-8\"));\r\n } catch {\r\n // Invalid cursor format, ignore and treat as first page\r\n }\r\n }\r\n }\r\n\r\n // If in cursor mode with a valid cursor, we skip 1 (the cursor record itself).\r\n // Otherwise, use offset logic (skip = (page - 1) * take).\r\n const skip = paginationMode === \"cursor\" && parsedCursor ? 1 : (page - 1) * take;\r\n\r\n // ─── Sort ──────────────────────────────────────────────────────────────────\r\n const sortParam = searchParams.get(\"sort\");\r\n if (sortParam) {\r\n // Supports multiple sorts: ?sort=name:asc,createdAt:desc,_count.posts:desc\r\n for (const part of sortParam.split(\",\")) {\r\n const [field, dir] = part.trim().split(\":\");\r\n if (!field) continue;\r\n const direction = dir === \"desc\" ? \"desc\" : \"asc\";\r\n\r\n // _count.relation:dir → { relation: { _count: dir } }\r\n if (field.startsWith(\"_count.\")) {\r\n const relation = field.slice(\"_count.\".length);\r\n if (relation) {\r\n orderBy[relation] = { _count: direction };\r\n }\r\n } else {\r\n orderBy[field] = direction;\r\n }\r\n }\r\n }\r\n\r\n // Ensure consistent sorting for cursor pagination if no sort is provided\r\n if (paginationMode === \"cursor\" && Object.keys(orderBy).length === 0 && modelFields) {\r\n const idField = modelFields.find((f) => f.isId)?.name ?? \"id\";\r\n orderBy[idField] = \"asc\";\r\n }\r\n\r\n // ─── Include (relations) ───────────────────────────────────────────────────\r\n const includeParam = searchParams.get(\"include\");\r\n if (includeParam) {\r\n for (const rel of includeParam.split(\",\")) {\r\n if (rel.trim()) include[rel.trim()] = true;\r\n }\r\n }\r\n\r\n // ─── Select (fields) — ?select= or ?fields= alias ────────────────────────\r\n const selectParam = searchParams.get(\"select\") ?? searchParams.get(\"fields\");\r\n if (selectParam) {\r\n select = {};\r\n for (const field of selectParam.split(\",\")) {\r\n if (field.trim()) select[field.trim()] = true;\r\n }\r\n }\r\n\r\n // ─── Global search (?search=) ─────────────────────────────────────────────\r\n const searchValue = searchParams.get(\"search\");\r\n if (searchValue && modelFields) {\r\n const stringFields = modelFields.filter(\r\n (f) => f.type === \"String\" && !f.isRelation\r\n );\r\n if (stringFields.length > 0) {\r\n const orClauses = stringFields.map((f) => ({\r\n [f.name]: { contains: searchValue, mode: \"insensitive\" },\r\n }));\r\n // Merge with any existing where via AND so other filters still apply\r\n where[\"OR\"] = orClauses;\r\n }\r\n }\r\n\r\n // ─── Filters ───────────────────────────────────────────────────────────────\r\n for (const [key, value] of searchParams.entries()) {\r\n if (RESERVED_KEYS.has(key)) continue;\r\n\r\n // ── Dot-notation relation filter (?relation.field[_op]=value) ──────────\r\n // Only handle a single dot (one level deep). Deeper nesting falls through.\r\n const dotIndex = key.indexOf(\".\");\r\n if (dotIndex > 0 && key.indexOf(\".\", dotIndex + 1) === -1 && modelFields) {\r\n const relationName = key.slice(0, dotIndex);\r\n const fieldPart = key.slice(dotIndex + 1); // e.g. \"isActive\" or \"name_contains\"\r\n\r\n const relationMeta = modelFields.find(\r\n (f) => f.name === relationName && f.isRelation\r\n );\r\n\r\n if (relationMeta) {\r\n // Parse the field part for operator suffix\r\n const sortedOps = Object.keys(FILTER_OPERATORS).sort(\r\n (a, b) => b.length - a.length\r\n );\r\n let fieldName = fieldPart;\r\n let fieldFilter: any;\r\n\r\n let opMatched = false;\r\n for (const suffix of sortedOps) {\r\n if (fieldPart.endsWith(suffix)) {\r\n fieldName = fieldPart.slice(0, -suffix.length);\r\n const prismaOp = FILTER_OPERATORS[suffix];\r\n let parsedValue: any = value;\r\n\r\n if (prismaOp === \"in\" || prismaOp === \"notIn\") {\r\n parsedValue = value.split(\",\").map((v) => v.trim());\r\n } else if (!isNaN(Number(parsedValue)) && typeof parsedValue === \"string\") {\r\n parsedValue = Number(parsedValue);\r\n }\r\n\r\n const extra = suffix === \"_icontains\" ? { mode: \"insensitive\" } : {};\r\n fieldFilter = { [prismaOp]: parsedValue, ...extra };\r\n opMatched = true;\r\n break;\r\n }\r\n }\r\n\r\n if (!opMatched) {\r\n // Exact match — coerce value\r\n let parsedValue: any = value;\r\n if (value === \"true\") parsedValue = true;\r\n else if (value === \"false\") parsedValue = false;\r\n else if (!isNaN(Number(value)) && value !== \"\") parsedValue = Number(value);\r\n fieldFilter = parsedValue;\r\n }\r\n\r\n // isList relation → some: { field: filter }\r\n // singular relation → direct: { field: filter }\r\n const nested = { [fieldName]: fieldFilter };\r\n where[relationName] = relationMeta.isList\r\n ? { some: nested }\r\n : nested;\r\n\r\n continue; // skip regular filter processing for this key\r\n }\r\n }\r\n\r\n // ── Regular filters ────────────────────────────────────────────────────\r\n // Check operator suffixes (longest match first)\r\n let matched = false;\r\n const sortedOps = Object.keys(FILTER_OPERATORS).sort(\r\n (a, b) => b.length - a.length\r\n );\r\n\r\n for (const suffix of sortedOps) {\r\n if (key.endsWith(suffix)) {\r\n const field = key.slice(0, -suffix.length);\r\n const prismaOp = FILTER_OPERATORS[suffix];\r\n\r\n let parsedValue: any = value;\r\n\r\n // Parse arrays\r\n if (prismaOp === \"in\" || prismaOp === \"notIn\") {\r\n parsedValue = value.split(\",\").map((v) => v.trim());\r\n }\r\n\r\n // Attempt numeric coercion\r\n if (!isNaN(Number(parsedValue)) && typeof parsedValue === \"string\") {\r\n parsedValue = Number(parsedValue);\r\n }\r\n\r\n // Case-insensitive flag\r\n const extra = suffix === \"_icontains\" ? { mode: \"insensitive\" } : {};\r\n\r\n where[field] = { [prismaOp]: parsedValue, ...extra };\r\n matched = true;\r\n break;\r\n }\r\n }\r\n\r\n // No operator — exact match\r\n if (!matched) {\r\n let parsedValue: any = value;\r\n\r\n // Coerce booleans\r\n if (value === \"true\") parsedValue = true;\r\n else if (value === \"false\") parsedValue = false;\r\n // Coerce numbers\r\n else if (!isNaN(Number(value)) && value !== \"\") {\r\n parsedValue = Number(value);\r\n }\r\n\r\n where[key] = parsedValue;\r\n }\r\n }\r\n\r\n return {\r\n where,\r\n orderBy,\r\n skip,\r\n take,\r\n cursor: parsedCursor,\r\n paginationMode,\r\n include,\r\n select\r\n };\r\n}","import type { GuardMap, HookFn, HookContext } from \"./types\";\r\n\r\n/**\r\n * Runs the guard for the given model+method combo.\r\n * Returns an error string if blocked, null if allowed.\r\n */\r\nexport async function runGuard(\r\n guards: GuardMap,\r\n model: string,\r\n method: string,\r\n ctx: { id?: string | null; body?: any }\r\n): Promise<string | null> {\r\n const modelGuards = guards[model];\r\n if (!modelGuards) return null;\r\n\r\n const fn = modelGuards[method as keyof typeof modelGuards];\r\n if (!fn) return null;\r\n\r\n return fn({ ...ctx, method });\r\n}\r\n\r\n/**\r\n * Runs a lifecycle hook (beforeOperation / afterOperation).\r\n * Silently swallows errors so hooks never crash the main flow.\r\n */\r\nexport async function runHook(\r\n hook: HookFn | undefined,\r\n ctx: HookContext\r\n): Promise<void> {\r\n if (!hook) return;\r\n try {\r\n await hook(ctx);\r\n } catch (e) {\r\n // Hooks should not crash the request\r\n console.error(\"[omni-rest] Hook error:\", e);\r\n }\r\n}","import type { ParsedQuery, ComplexityRules } from \"./types\";\n\n/**\n * Scores a parsed query based on the provided complexity rules.\n */\nexport function scoreQuery(\n parsedQuery: ParsedQuery,\n rules: ComplexityRules\n): number {\n let score = 0;\n\n if (rules.perInclude && parsedQuery.include) {\n score += Object.keys(parsedQuery.include).length * rules.perInclude;\n }\n\n if (rules.perFilter && parsedQuery.where) {\n // Approximate count of top-level filter keys (excludes OR, AND, etc. for simplicity, \n // but counts them as 1 top-level key which is fine for basic scoring)\n const filterCount = Object.keys(parsedQuery.where).filter(\n (k) => k !== \"OR\" && k !== \"AND\" && k !== \"NOT\"\n ).length;\n score += filterCount * rules.perFilter;\n }\n\n if (rules.perSort && parsedQuery.orderBy) {\n score += Object.keys(parsedQuery.orderBy).length * rules.perSort;\n }\n\n if (rules.perLimit100 && parsedQuery.take) {\n score += Math.ceil(parsedQuery.take / 100) * rules.perLimit100;\n }\n\n return score;\n}\n","import type { PrismaClient } from \"@prisma/client\";\nimport type { ModelMeta, SseEvent, SubscriptionOptions, FieldGuardConfig, GuardMap } from \"./types\";\nimport { getDelegate } from \"./introspect\";\nimport { runGuard } from \"./middleware-helpers\";\n\n// ─── Public helpers (adapters write these bytes to the response) ──────────────\n\n/** Formats a single SSE event line. */\nexport function formatSseEvent(event: SseEvent): string {\n return `data: ${JSON.stringify(event)}\\n\\n`;\n}\n\n/** Formats a heartbeat comment that keeps the TCP connection alive through proxies. */\nexport function formatSseHeartbeat(): string {\n return \": heartbeat\\n\\n\";\n}\n\n// ─── Subscription Bus ─────────────────────────────────────────────────────────\n\ntype Listener = (event: SseEvent) => void;\n\ninterface ModelBus {\n interval: ReturnType<typeof setInterval>;\n listeners: Set<Listener>;\n /** Timestamp of the last poll tick — used for watermark-based create/update detection. */\n watermark: Date;\n /** ID snapshot — used to detect hard-deletes by diffing current IDs against known ones. */\n knownIds: Set<unknown>;\n /** Whether the model has createdAt / updatedAt fields (determined once at bus init). */\n hasCreatedAt: boolean;\n hasUpdatedAt: boolean;\n}\n\n/**\n * SubscriptionBus manages one shared Prisma poll interval per model.\n *\n * Key performance properties:\n * - Zero DB activity for any model that has no active subscribers.\n * - When the first client subscribes to model X, one interval is started.\n * - Additional clients for the same model share that single interval (fan-out).\n * - When the last client disconnects, the interval is immediately cleared.\n *\n * This ensures CRUD routes for un-subscribed tables incur no extra overhead.\n */\nexport class SubscriptionBus {\n private buses = new Map<string, ModelBus>();\n\n constructor(\n private prisma: PrismaClient,\n private options: SubscriptionOptions = {}\n ) {}\n\n // ── Per-connection guard check ──────────────────────────────────────────────\n\n /**\n * Applies the GET guard for the model.\n * Returns an error string if the subscriber should be rejected, null if allowed.\n */\n async checkGuard(\n guards: GuardMap,\n modelRouteName: string,\n ctx: { id?: string | null; body?: any }\n ): Promise<string | null> {\n return runGuard(guards, modelRouteName, \"GET\", ctx);\n }\n\n // ── Bus lifecycle ───────────────────────────────────────────────────────────\n\n private async initBus(meta: ModelMeta, fg?: FieldGuardConfig): Promise<ModelBus> {\n const delegate = getDelegate(this.prisma, meta);\n const pollMs = this.options.pollInterval ?? 1_000;\n\n const hasCreatedAt = meta.fields.some((f) => f.name === \"createdAt\");\n const hasUpdatedAt = meta.fields.some((f) => f.name === \"updatedAt\");\n\n // Snapshot initial IDs so we can detect deletes on the first tick\n let initialIds: unknown[] = [];\n try {\n const rows = await (delegate as any).findMany({\n select: { [meta.idField]: true },\n });\n initialIds = rows.map((r: any) => r[meta.idField]);\n } catch {\n // Empty table or transient error — start with an empty set\n }\n\n const bus: ModelBus = {\n interval: null as any, // assigned below\n listeners: new Set(),\n watermark: new Date(),\n knownIds: new Set(initialIds),\n hasCreatedAt,\n hasUpdatedAt,\n };\n\n bus.interval = setInterval(async () => {\n // Skip work entirely when no clients are listening\n if (bus.listeners.size === 0) return;\n\n const tick = new Date();\n\n try {\n // ── 1. Watermark-based create / update detection ──────────────────────\n if (bus.hasCreatedAt && bus.hasUpdatedAt) {\n const [created, updated] = await Promise.all([\n // New records: createdAt after the last watermark\n (delegate as any).findMany({\n where: { createdAt: { gt: bus.watermark } },\n }),\n // Changed records: updatedAt after watermark but created before it\n (delegate as any).findMany({\n where: {\n updatedAt: { gt: bus.watermark },\n createdAt: { lte: bus.watermark },\n },\n }),\n ]);\n\n for (const record of created) {\n bus.knownIds.add(record[meta.idField]);\n const event: SseEvent = {\n event: \"create\",\n model: meta.name,\n record: stripFieldGuard(record, fg),\n };\n bus.listeners.forEach((l) => l(event));\n }\n\n for (const record of updated) {\n const event: SseEvent = {\n event: \"update\",\n model: meta.name,\n record: stripFieldGuard(record, fg),\n };\n bus.listeners.forEach((l) => l(event));\n }\n } else if (bus.hasUpdatedAt) {\n // No createdAt — only detect updates\n const updated = await (delegate as any).findMany({\n where: { updatedAt: { gt: bus.watermark } },\n });\n for (const record of updated) {\n const event: SseEvent = {\n event: \"update\",\n model: meta.name,\n record: stripFieldGuard(record, fg),\n };\n bus.listeners.forEach((l) => l(event));\n }\n }\n\n // ── 2. ID-set diff for delete detection ───────────────────────────────\n // This works regardless of whether the model has timestamp fields.\n // One extra SELECT(id) per tick — much cheaper than a full row fetch.\n const currentRows = await (delegate as any).findMany({\n select: { [meta.idField]: true },\n });\n const currentIds = new Set<unknown>(currentRows.map((r: any) => r[meta.idField]));\n\n // IDs we knew about but are gone → deleted\n for (const id of bus.knownIds) {\n if (!currentIds.has(id)) {\n bus.knownIds.delete(id);\n const event: SseEvent = { event: \"delete\", model: meta.name, id };\n bus.listeners.forEach((l) => l(event));\n }\n }\n\n // Absorb newly created IDs into the known set\n // (if timestamp-based path above already fired \"create\", this is a no-op for those IDs)\n for (const id of currentIds) {\n if (!bus.knownIds.has(id)) {\n bus.knownIds.add(id);\n // If we have no createdAt field we wouldn't have caught this above — emit now\n if (!bus.hasCreatedAt) {\n const row = await (delegate as any).findUnique({\n where: { [meta.idField]: id },\n }).catch(() => null);\n if (row) {\n const event: SseEvent = {\n event: \"create\",\n model: meta.name,\n record: stripFieldGuard(row, fg),\n };\n bus.listeners.forEach((l) => l(event));\n }\n }\n }\n }\n\n bus.watermark = tick;\n } catch {\n // Swallow individual poll errors — don't crash the bus\n }\n }, pollMs);\n\n return bus;\n }\n\n // ── Public API ──────────────────────────────────────────────────────────────\n\n /**\n * Subscribes a listener to events for the given model.\n *\n * If no bus exists for this model yet, one is created (starting the DB poll).\n * If a bus already exists, the listener is simply added to its fan-out set.\n *\n * Returns an unsubscribe function. Call it when the client disconnects — if\n * this was the last listener the poll interval is immediately cleared.\n */\n async subscribe(\n meta: ModelMeta,\n listener: Listener,\n fg?: FieldGuardConfig\n ): Promise<() => void> {\n let bus = this.buses.get(meta.routeName);\n\n if (!bus) {\n bus = await this.initBus(meta, fg);\n this.buses.set(meta.routeName, bus);\n }\n\n bus.listeners.add(listener);\n\n return () => {\n if (!bus) return;\n bus.listeners.delete(listener);\n\n // Tear down the poll when nobody is watching this model\n if (bus.listeners.size === 0) {\n clearInterval(bus.interval);\n this.buses.delete(meta.routeName);\n }\n };\n }\n\n /**\n * Returns the number of active listeners across all model buses.\n * Useful for diagnostics / metrics.\n */\n get activeSubscriberCount(): number {\n let total = 0;\n for (const bus of this.buses.values()) {\n total += bus.listeners.size;\n }\n return total;\n }\n\n /**\n * Returns a list of model route names that currently have active subscribers.\n */\n get activeModels(): string[] {\n return [...this.buses.keys()];\n }\n}\n\n// ─── Internal helpers ─────────────────────────────────────────────────────────\n\n/**\n * Strips hidden + writeOnly fields before sending a record over SSE.\n * Mirrors the same logic used in router.ts stripResponse.\n */\nfunction stripFieldGuard(record: any, fg?: FieldGuardConfig): any {\n if (!fg || !record || typeof record !== \"object\") return record;\n const blocked = new Set([...(fg.hidden ?? []), ...(fg.writeOnly ?? [])]);\n if (blocked.size === 0) return record;\n const out: Record<string, any> = {};\n for (const [k, v] of Object.entries(record)) {\n if (!blocked.has(k)) out[k] = v;\n }\n return out;\n}\n","import { PrismaClient } from \"@prisma/client\";\r\nimport { getModels, buildModelMap, getDelegate, detectSoftDeleteField } from \"./introspect\";\r\nimport { buildQuery } from \"./query-builder\";\r\nimport { runGuard, runHook } from \"./middleware-helpers\";\r\nimport { scoreQuery } from \"./complexity\";\r\nimport { SubscriptionBus } from \"./subscriptions\";\r\nimport type {\r\n PrismaRestOptions,\r\n HandlerResult,\r\n RouterInstance,\r\n ModelMeta,\r\n FieldGuardConfig,\r\n RateLimitFn,\r\n} from \"./types\";\r\n\r\n/**\r\n * Creates a framework-agnostic CRUD router powered by Prisma DMMF.\r\n *\r\n * All adapters (Express, Next.js, Fastify) use this under the hood.\r\n */\r\nexport function createRouter(\r\n prisma: PrismaClient,\r\n options: PrismaRestOptions = {}\r\n): RouterInstance {\r\n const {\r\n allow,\r\n guards = {},\r\n beforeOperation,\r\n afterOperation,\r\n defaultLimit = 20,\r\n maxLimit = 100,\r\n softDelete = false,\r\n softDeleteField,\r\n envelope = true,\r\n fieldGuards = {},\r\n rateLimit,\r\n subscription = {},\r\n paginationMode = \"offset\",\r\n features = { aggregation: true },\r\n complexity,\r\n } = options;\r\n\r\n // Introspect schema once at startup\r\n const models = getModels(prisma);\r\n const modelMap = buildModelMap(models, allow);\r\n\r\n // One shared subscription bus — zero overhead until a client actually connects\r\n const subscriptionBus = new SubscriptionBus(prisma, subscription);\r\n\r\n async function handle(\r\n method: string,\r\n modelName: string,\r\n id: string | null,\r\n body: any,\r\n searchParams: URLSearchParams,\r\n operation?: string\r\n ): Promise<HandlerResult> {\r\n // ── 1. Resolve model ───────────────────────────────────────────────────\r\n const meta = modelMap[modelName.toLowerCase()];\r\n if (!meta) {\r\n return {\r\n status: 404,\r\n data: {\r\n error: `Model \"${modelName}\" not found or not exposed.`,\r\n available: Object.keys(modelMap),\r\n },\r\n };\r\n }\r\n\r\n // ── 2. Rate limit check ────────────────────────────────────────────────\r\n if (rateLimit) {\r\n const rateLimitError = await rateLimit({ model: meta.name, method, id });\r\n if (rateLimitError) {\r\n return { status: 429, data: { error: rateLimitError } };\r\n }\r\n }\r\n\r\n // ── 3. Guard check ─────────────────────────────────────────────────────\r\n const guardError = await runGuard(guards, meta.routeName, method, {\r\n id,\r\n body,\r\n });\r\n if (guardError) {\r\n return { status: 403, data: { error: guardError } };\r\n }\r\n\r\n // ── 4. Before hook ─────────────────────────────────────────────────────\r\n await runHook(beforeOperation, { model: meta.name, method, id, body });\r\n\r\n // ── 5. Execute operation ───────────────────────────────────────────────\r\n let result: HandlerResult;\r\n\r\n try {\r\n result = await executeOperation(\r\n prisma,\r\n meta,\r\n method,\r\n id,\r\n body,\r\n searchParams,\r\n defaultLimit,\r\n maxLimit,\r\n operation,\r\n softDelete,\r\n softDeleteField,\r\n envelope,\r\n fieldGuards[meta.routeName],\r\n paginationMode,\r\n features,\r\n complexity\r\n );\r\n } catch (e: any) {\r\n return handlePrismaError(e);\r\n }\r\n\r\n // ── 6. After hook ──────────────────────────────────────────────────────\r\n await runHook(afterOperation, {\r\n model: meta.name,\r\n method,\r\n id,\r\n body,\r\n result: result.data,\r\n });\r\n\r\n return result;\r\n }\r\n\r\n return { handle, modelMap, models, subscriptionBus };\r\n}\r\n\r\n// ─── Operation executor ────────────────────────────────────────────────────────\r\n\r\nasync function executeOperation(\r\n prisma: PrismaClient,\r\n meta: ModelMeta,\r\n method: string,\r\n id: string | null,\r\n body: any,\r\n searchParams: URLSearchParams,\r\n defaultLimit: number,\r\n maxLimit: number,\r\n operation?: string,\r\n softDelete = false,\r\n softDeleteField?: string,\r\n envelope = true,\r\n fg?: FieldGuardConfig,\r\n defaultPaginationMode: \"offset\" | \"cursor\" = \"offset\",\r\n features?: { aggregation?: boolean },\r\n complexity?: import(\"./types\").ComplexityOptions\r\n): Promise<HandlerResult> {\r\n const delegate = getDelegate(prisma, meta);\r\n const { where, orderBy, skip, take, cursor, paginationMode, include, select } = buildQuery(\r\n searchParams,\r\n defaultLimit,\r\n maxLimit,\r\n meta.fields,\r\n defaultPaginationMode\r\n );\r\n\r\n // ── Complexity Check ───────────────────────────────────────────────────────\r\n if (complexity) {\r\n const score = scoreQuery({ where, orderBy, skip, take, cursor, paginationMode, include, select }, complexity.rules);\r\n if (score > complexity.maxScore) {\r\n return { status: 429, data: { error: \"Query too complex\", score, maxScore: complexity.maxScore } };\r\n }\r\n }\r\n\r\n // Build include/select args (mutually exclusive in Prisma)\r\n const includeArg = Object.keys(include).length > 0 ? include : undefined;\r\n const selectArg = select && Object.keys(select).length > 0 ? select : undefined;\r\n const projection = selectArg ? { select: selectArg } : includeArg ? { include: includeArg } : {};\r\n\r\n // Sanitize write body — strip readOnly fields before passing to Prisma\r\n const safeBody = sanitizeBody(body, fg);\r\n\r\n const parseAgg = (val: string | null) => {\r\n if (!val) return undefined;\r\n if (val === \"*\") return { _all: true };\r\n const res: Record<string, true> = {};\r\n val.split(\",\").forEach(f => res[f.trim()] = true);\r\n return res;\r\n };\r\n\r\n // ── GET /model/aggregate ───────────────────────────────────────────────────\r\n if (method === \"GET\" && id === \"aggregate\") {\r\n if (features?.aggregation === false) {\r\n return { status: 403, data: { error: \"Aggregation endpoints are disabled.\" } };\r\n }\r\n const result = await delegate.aggregate({\r\n where,\r\n _count: parseAgg(searchParams.get(\"_count\")),\r\n _sum: parseAgg(searchParams.get(\"_sum\")),\r\n _avg: parseAgg(searchParams.get(\"_avg\")),\r\n _min: parseAgg(searchParams.get(\"_min\")),\r\n _max: parseAgg(searchParams.get(\"_max\"))\r\n });\r\n return { status: 200, data: result };\r\n }\r\n\r\n // ── GET /model/groupBy ─────────────────────────────────────────────────────\r\n if (method === \"GET\" && id === \"groupBy\") {\r\n if (features?.aggregation === false) {\r\n return { status: 403, data: { error: \"Aggregation endpoints are disabled.\" } };\r\n }\r\n const byRaw = searchParams.get(\"by\");\r\n if (!byRaw) {\r\n return { status: 400, data: { error: \"groupBy requires a 'by' query parameter.\" } };\r\n }\r\n const result = await delegate.groupBy({\r\n by: byRaw.split(\",\").map(f => f.trim()),\r\n where,\r\n orderBy: Object.keys(orderBy).length > 0 ? orderBy : undefined,\r\n take: take !== defaultLimit ? take : undefined, // only apply if limit was set explicitly\r\n skip: skip > 0 ? skip : undefined,\r\n _count: parseAgg(searchParams.get(\"_count\")),\r\n _sum: parseAgg(searchParams.get(\"_sum\")),\r\n _avg: parseAgg(searchParams.get(\"_avg\")),\r\n _min: parseAgg(searchParams.get(\"_min\")),\r\n _max: parseAgg(searchParams.get(\"_max\"))\r\n });\r\n return { status: 200, data: result };\r\n }\r\n\r\n // ── POST /model/bulk — createMany ──────────────────────────────────────────\r\n if (method === \"POST\" && id === \"bulk\") {\r\n if (!Array.isArray(body) || body.length === 0) {\r\n return { status: 400, data: { error: \"Request body must be a non-empty array\" } };\r\n }\r\n const result = await delegate.createMany({ data: body });\r\n return { status: 201, data: { count: result.count } };\r\n }\r\n\r\n // ── PUT /model/bulk — updateMany ───────────────────────────────────────────\r\n if (method === \"PUT\" && id === \"bulk\") {\r\n const { where: bulkWhere, data: bulkData } = body || {};\r\n if (!bulkWhere || !bulkData) {\r\n return { status: 400, data: { error: \"Body must contain { where, data }\" } };\r\n }\r\n const result = await delegate.updateMany({ where: bulkWhere, data: bulkData });\r\n return { status: 200, data: { count: result.count } };\r\n }\r\n\r\n // ── DELETE /model/bulk — deleteMany ───────────────────────────────────────\r\n if (method === \"DELETE\" && id === \"bulk\") {\r\n const { where: bulkWhere } = body || {};\r\n if (!bulkWhere) {\r\n return { status: 400, data: { error: \"Body must contain { where }\" } };\r\n }\r\n const result = await delegate.deleteMany({ where: bulkWhere });\r\n return { status: 200, data: { count: result.count } };\r\n }\r\n\r\n // ── PATCH /model/bulk/update (legacy per-ID array) ─────────────────────────\r\n if (method === \"PATCH\" && operation === \"bulk-update\") {\r\n if (!Array.isArray(body) || body.length === 0) {\r\n return { status: 400, data: { error: \"Request body must be a non-empty array of update records\" } };\r\n }\r\n for (const item of body) {\r\n if (!item[meta.idField]) {\r\n return { status: 400, data: { error: `Each record must have an ${meta.idField} field` } };\r\n }\r\n }\r\n const results = await Promise.all(\r\n body.map((item) => {\r\n const itemId = item[meta.idField];\r\n const updateData = { ...item };\r\n delete updateData[meta.idField];\r\n return delegate.update({\r\n where: { [meta.idField]: coerceId(itemId) },\r\n data: updateData,\r\n ...projection,\r\n });\r\n })\r\n );\r\n return { status: 200, data: { updated: results.length, records: results } };\r\n }\r\n\r\n // ── DELETE /model/bulk/delete (legacy ID array) ────────────────────────────\r\n if (method === \"DELETE\" && operation === \"bulk-delete\") {\r\n if (!Array.isArray(body) || body.length === 0) {\r\n return { status: 400, data: { error: \"Request body must be a non-empty array of IDs\" } };\r\n }\r\n const ids = body.map((item: any) =>\r\n typeof item === \"object\" ? item[meta.idField] : item\r\n );\r\n const result = await delegate.deleteMany({\r\n where: { [meta.idField]: { in: ids.map(coerceId) } },\r\n });\r\n return { status: 200, data: { deleted: result.count } };\r\n }\r\n\r\n // ── GET /model ─────────────────────────────────────────────────────────────\r\n if (method === \"GET\" && !id) {\r\n const softDeleteInfo = softDelete\r\n ? detectSoftDeleteField(meta.fields, softDeleteField)\r\n : null;\r\n const listWhere = softDeleteInfo\r\n ? { ...where, [softDeleteInfo.field]: softDeleteInfo.field === \"isActive\" ? true : null }\r\n : where;\r\n\r\n let data: any[];\r\n let total: number | undefined;\r\n let nextCursor: string | null = null;\r\n let hasMore = false;\r\n\r\n if (paginationMode === \"cursor\") {\r\n try {\r\n data = await delegate.findMany({\r\n where: listWhere,\r\n orderBy,\r\n skip,\r\n take,\r\n cursor: cursor ? cursor : undefined,\r\n ...projection\r\n });\r\n hasMore = data.length === take;\r\n if (hasMore && data.length > 0) {\r\n const lastRecord = data[data.length - 1];\r\n nextCursor = Buffer.from(\r\n JSON.stringify({ [meta.idField]: lastRecord[meta.idField] })\r\n ).toString(\"base64\");\r\n }\r\n } catch (err: any) {\r\n // If cursor record is not found, Prisma throws P2025. Fallback gracefully.\r\n if (err?.code === \"P2025\") {\r\n data = [];\r\n hasMore = false;\r\n } else {\r\n throw err;\r\n }\r\n }\r\n } else {\r\n const [dataResult, totalResult] = await (prisma as any).$transaction([\r\n delegate.findMany({ where: listWhere, orderBy, skip, take, ...projection }),\r\n delegate.count({ where: listWhere }),\r\n ]);\r\n data = dataResult;\r\n total = totalResult;\r\n }\r\n\r\n const safeData = data.map((r: any) => stripResponse(r, fg));\r\n\r\n if (!envelope) {\r\n const headers: Record<string, string> = {};\r\n if (paginationMode === \"offset\" && total !== undefined) {\r\n headers[\"X-Total-Count\"] = String(total);\r\n } else if (paginationMode === \"cursor\") {\r\n headers[\"X-Has-More\"] = String(hasMore);\r\n if (nextCursor) headers[\"X-Next-Cursor\"] = nextCursor;\r\n }\r\n return { status: 200, data: safeData, headers };\r\n }\r\n\r\n const metaBlock = paginationMode === \"cursor\"\r\n ? { nextCursor, hasMore }\r\n : {\r\n total,\r\n page: Math.floor(skip / take) + 1,\r\n limit: take,\r\n totalPages: Math.ceil((total ?? 0) / take),\r\n };\r\n\r\n return {\r\n status: 200,\r\n data: {\r\n data: safeData,\r\n meta: metaBlock,\r\n },\r\n };\r\n }\r\n\r\n // ── GET /model/:id ─────────────────────────────────────────────────────────\r\n if (method === \"GET\" && id) {\r\n const record = await delegate.findUnique({\r\n where: { [meta.idField]: coerceId(id) },\r\n ...projection,\r\n });\r\n if (!record) {\r\n return { status: 404, data: { error: `${meta.name} with id \"${id}\" not found.` } };\r\n }\r\n return { status: 200, data: stripResponse(record, fg) };\r\n }\r\n\r\n // ── POST /model ────────────────────────────────────────────────────────────\r\n if (method === \"POST\" && !id) {\r\n const record = await delegate.create({ data: safeBody });\r\n return { status: 201, data: stripResponse(record, fg) };\r\n }\r\n\r\n // ── PUT /model/:id ─────────────────────────────────────────────────────────\r\n if ((method === \"PUT\" || method === \"PATCH\") && id) {\r\n const record = await delegate.update({\r\n where: { [meta.idField]: coerceId(id) },\r\n data: safeBody,\r\n });\r\n return { status: 200, data: stripResponse(record, fg) };\r\n }\r\n\r\n // ── DELETE /model/:id ──────────────────────────────────────────────────────\r\n if (method === \"DELETE\" && id) {\r\n const softDeleteInfo = softDelete\r\n ? detectSoftDeleteField(meta.fields, softDeleteField)\r\n : null;\r\n\r\n if (softDeleteInfo) {\r\n const record = await delegate.update({\r\n where: { [meta.idField]: coerceId(id) },\r\n data: { [softDeleteInfo.field]: softDeleteInfo.value },\r\n });\r\n return { status: 200, data: record };\r\n }\r\n\r\n await delegate.delete({ where: { [meta.idField]: coerceId(id) } });\r\n return { status: 204, data: null };\r\n }\r\n\r\n return { status: 405, data: { error: `Method ${method} not allowed.` } };\r\n}\r\n\r\n// ─── Helpers ──────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Strips hidden and writeOnly fields from a response record.\r\n */\r\nfunction stripResponse(record: any, fg?: FieldGuardConfig): any {\r\n if (!fg || !record || typeof record !== \"object\") return record;\r\n const blocked = new Set([...(fg.hidden ?? []), ...(fg.writeOnly ?? [])]);\r\n if (blocked.size === 0) return record;\r\n const out: Record<string, any> = {};\r\n for (const [k, v] of Object.entries(record)) {\r\n if (!blocked.has(k)) out[k] = v;\r\n }\r\n return out;\r\n}\r\n\r\n/**\r\n * Strips readOnly fields from a write body before passing to Prisma.\r\n */\r\nfunction sanitizeBody(body: any, fg?: FieldGuardConfig): any {\r\n if (!fg || !body || typeof body !== \"object\" || Array.isArray(body)) return body;\r\n const readOnly = new Set(fg.readOnly ?? []);\r\n if (readOnly.size === 0) return body;\r\n const out: Record<string, any> = {};\r\n for (const [k, v] of Object.entries(body)) {\r\n if (!readOnly.has(k)) out[k] = v;\r\n }\r\n return out;\r\n}\r\n\r\n/**\r\n * Coerces an ID string to number when possible (common with Int PKs).\r\n */\r\nfunction coerceId(id: string): string | number {\r\n const n = Number(id);\r\n return isNaN(n) ? id : n;\r\n}\r\n\r\n/**\r\n * Maps Prisma error codes to meaningful HTTP responses.\r\n */\r\nfunction handlePrismaError(e: any): HandlerResult {\r\n const code = e?.code;\r\n\r\n if (code === \"P2025\") {\r\n return { status: 404, data: { error: \"Record not found.\" } };\r\n }\r\n if (code === \"P2002\") {\r\n const fields = e?.meta?.target ?? \"unknown fields\";\r\n return { status: 409, data: { error: `Unique constraint failed on: ${fields}` } };\r\n }\r\n if (code === \"P2003\") {\r\n return { status: 400, data: { error: \"Foreign key constraint failed.\" } };\r\n }\r\n if (code === \"P2014\") {\r\n return { status: 400, data: { error: \"Relation violation.\" } };\r\n }\r\n\r\n return { status: 500, data: { error: e?.message ?? \"Internal server error.\" } };\r\n}\r\n","// @ts-nocheck\r\nimport { PrismaClient } from \"@prisma/client\";\r\nimport { createRouter } from \"../router\";\r\nimport { formatSseEvent, formatSseHeartbeat } from \"../subscriptions\";\r\nimport type { PrismaRestOptions } from \"../types\";\r\nimport { createRequire } from \"module\";\r\n\r\n/**\r\n * NestJS adapter for omni-rest.\r\n * Generates a dynamic controller block that maps wildcard routes directly into omni-rest handlers.\r\n *\r\n * @example\r\n * ```ts\r\n * import { Controller, Module, NestModule, MiddlewareConsumer } from '@nestjs/common';\r\n * import { PrismaClient } from '@prisma/client';\r\n * import { nestjsController } from 'omni-rest/nestjs';\r\n *\r\n * const prisma = new PrismaClient();\r\n *\r\n * // Create generating Controller natively via factory\r\n * export const OmniRestController = nestjsController(prisma, {\r\n * allow: [\"product\", \"category\"],\r\n * });\r\n *\r\n * @Module({\r\n * controllers: [OmniRestController],\r\n * })\r\n * export class AppModule {}\r\n * ```\r\n */\r\nexport function nestjsController(\r\n prisma: PrismaClient,\r\n options: PrismaRestOptions = {},\r\n prefix: string = \"api\"\r\n): any {\r\n // Resolve @nestjs/common and rxjs from the caller's project, not from\r\n // omni-rest's own node_modules. When omni-rest is installed as a file:\r\n // symlink the standard require() resolves from the wrong directory.\r\n // We walk up from cwd to find the project's node_modules.\r\n let nestRequire = require;\r\n try {\r\n // Try to create a require scoped to the calling project's cwd\r\n const callerRequire = createRequire(process.cwd() + \"/package.json\");\r\n // Verify it can actually find @nestjs/common before committing\r\n callerRequire.resolve(\"@nestjs/common\");\r\n nestRequire = callerRequire;\r\n } catch {\r\n // Fall back to the default require (works when omni-rest is installed normally)\r\n }\r\n\r\n // We lazily require NestJS specific decorators so they don't break applications that don't have `@nestjs/common`\r\n // eslint-disable-next-line @typescript-eslint/no-var-requires\r\n const { Controller, Get, Post, Put, Patch, Delete, Param, Body, Query, Req, Res, HttpStatus, Sse, MessageEvent } = nestRequire(\"@nestjs/common\");\r\n const { Observable } = nestRequire(\"rxjs\");\r\n const { handle, modelMap, subscriptionBus } = createRouter(prisma, options);\r\n const heartbeatMs = options.subscription?.heartbeatInterval ?? 30_000;\r\n const guards = (options.guards ?? {}) as Record<string, any>;\r\n const fieldGuards = (options.fieldGuards ?? {}) as Record<string, any>;\r\n\r\n const getSearchParams = (query: Record<string, string>): URLSearchParams => {\r\n return new URLSearchParams(\r\n Object.entries(query || {})\r\n .map(([k, v]) => `${k}=${v}`)\r\n .join(\"&\")\r\n );\r\n };\r\n\r\n @Controller(prefix)\r\n class OmniRestDynamicController {\r\n \r\n @Patch(\":model/bulk/update\")\r\n async bulkUpdate(\r\n @Param(\"model\") model: string,\r\n @Body() body: any[],\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n try {\r\n const { status, data } = await handle(\"PATCH\", model, null, body ?? [], getSearchParams(query), \"bulk-update\");\r\n if (status === 204) return res.status(HttpStatus.NO_CONTENT).send();\r\n return res.status(status).json(data);\r\n } catch (e: any) {\r\n return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: e.message });\r\n }\r\n }\r\n\r\n @Delete(\":model/bulk/delete\")\r\n async bulkDelete(\r\n @Param(\"model\") model: string,\r\n @Body() body: any[],\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n try {\r\n const { status, data } = await handle(\"DELETE\", model, null, body ?? [], getSearchParams(query), \"bulk-delete\");\r\n if (status === 204) return res.status(HttpStatus.NO_CONTENT).send();\r\n return res.status(status).json(data);\r\n } catch (e: any) {\r\n return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: e.message });\r\n }\r\n }\r\n\r\n // ── SSE: GET :model/subscribe ───────────────────────────────────────\r\n // Decorated with @Sse so NestJS handles Content-Type and streaming lifecycle.\r\n // Must appear before @Get(\":model\") to avoid route shadowing.\r\n @Sse(\":model/subscribe\")\r\n subscribe(\r\n @Param(\"model\") model: string,\r\n @Query() query: any,\r\n @Req() req: any\r\n ) {\r\n const meta = modelMap[model.toLowerCase()];\r\n return new Observable((subscriber: any) => {\r\n if (!meta) {\r\n subscriber.error(new Error(`Model \"${model}\" not found or not exposed.`));\r\n return;\r\n }\r\n\r\n const fg = fieldGuards[meta.routeName];\r\n let heartbeatTimer: ReturnType<typeof setInterval>;\r\n let unsubscribeFn: (() => void) | undefined;\r\n\r\n // Async setup inside the synchronous Observable factory\r\n subscriptionBus.checkGuard(guards, meta.routeName, { body: {} }).then((guardError: string | null) => {\r\n if (guardError) {\r\n subscriber.error(new Error(guardError));\r\n return;\r\n }\r\n\r\n subscriptionBus.subscribe(\r\n meta,\r\n (event: any) => {\r\n subscriber.next({ data: formatSseEvent(event) } as typeof MessageEvent);\r\n },\r\n fg\r\n ).then((unsub: () => void) => {\r\n unsubscribeFn = unsub;\r\n\r\n heartbeatTimer = setInterval(() => {\r\n subscriber.next({ data: formatSseHeartbeat() } as typeof MessageEvent);\r\n }, heartbeatMs);\r\n });\r\n });\r\n\r\n // Teardown: called when the client disconnects or Observable is unsubscribed\r\n return () => {\r\n if (heartbeatTimer) clearInterval(heartbeatTimer);\r\n if (unsubscribeFn) unsubscribeFn();\r\n };\r\n });\r\n }\r\n\r\n @Get(\":model\")\r\n async list(\r\n @Param(\"model\") model: string,\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n return await this._processRequest(\"GET\", model, null, {}, query, res);\r\n }\r\n\r\n @Post(\":model\")\r\n async create(\r\n @Param(\"model\") model: string,\r\n @Body() body: any,\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n return await this._processRequest(\"POST\", model, null, body, query, res);\r\n }\r\n\r\n @Get(\":model/:id\")\r\n async read(\r\n @Param(\"model\") model: string,\r\n @Param(\"id\") id: string,\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n return await this._processRequest(\"GET\", model, id, {}, query, res);\r\n }\r\n\r\n @Put(\":model/:id\")\r\n async replace(\r\n @Param(\"model\") model: string,\r\n @Param(\"id\") id: string,\r\n @Body() body: any,\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n return await this._processRequest(\"PUT\", model, id, body, query, res);\r\n }\r\n\r\n @Patch(\":model/:id\")\r\n async update(\r\n @Param(\"model\") model: string,\r\n @Param(\"id\") id: string,\r\n @Body() body: any,\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n return await this._processRequest(\"PATCH\", model, id, body, query, res);\r\n }\r\n\r\n @Delete(\":model/:id\")\r\n async remove(\r\n @Param(\"model\") model: string,\r\n @Param(\"id\") id: string,\r\n @Query() query: any,\r\n @Res() res: any\r\n ) {\r\n return await this._processRequest(\"DELETE\", model, id, {}, query, res);\r\n }\r\n\r\n private async _processRequest(\r\n method: string, \r\n model: string, \r\n id: string | null, \r\n body: any, \r\n query: any, \r\n res: any\r\n ) {\r\n try {\r\n const { status, data } = await handle(method, model, id, body ?? {}, getSearchParams(query));\r\n if (status === 204) {\r\n return res.status(HttpStatus.NO_CONTENT).send();\r\n }\r\n return res.status(status).json(data);\r\n } catch (e: any) {\r\n return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error: e.message });\r\n }\r\n }\r\n }\r\n\r\n return OmniRestDynamicController;\r\n}\r\n"]}
|
package/dist/adapters/nestjs.mjs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
|
|
1
3
|
var __defProp = Object.defineProperty;
|
|
2
4
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
5
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
@@ -1077,8 +1079,6 @@ function handlePrismaError(e) {
|
|
|
1077
1079
|
};
|
|
1078
1080
|
}
|
|
1079
1081
|
__name(handlePrismaError, "handlePrismaError");
|
|
1080
|
-
|
|
1081
|
-
// src/adapters/nestjs.ts
|
|
1082
1082
|
function _ts_decorate(decorators, target, key, desc) {
|
|
1083
1083
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1084
1084
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -1098,8 +1098,15 @@ function _ts_param(paramIndex, decorator) {
|
|
|
1098
1098
|
__name(_ts_param, "_ts_param");
|
|
1099
1099
|
function nestjsController(prisma, options = {}, prefix = "api") {
|
|
1100
1100
|
var _a;
|
|
1101
|
-
|
|
1102
|
-
|
|
1101
|
+
let nestRequire = __require;
|
|
1102
|
+
try {
|
|
1103
|
+
const callerRequire = createRequire(process.cwd() + "/package.json");
|
|
1104
|
+
callerRequire.resolve("@nestjs/common");
|
|
1105
|
+
nestRequire = callerRequire;
|
|
1106
|
+
} catch {
|
|
1107
|
+
}
|
|
1108
|
+
const { Controller, Get, Post, Put, Patch, Delete, Param, Body, Query, Req, Res, HttpStatus, Sse, MessageEvent } = nestRequire("@nestjs/common");
|
|
1109
|
+
const { Observable } = nestRequire("rxjs");
|
|
1103
1110
|
const { handle, modelMap, subscriptionBus } = createRouter(prisma, options);
|
|
1104
1111
|
const heartbeatMs = options.subscription?.heartbeatInterval ?? 3e4;
|
|
1105
1112
|
const guards = options.guards ?? {};
|