crudora 0.2.0 → 0.3.0
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/cli.js +55 -65
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +1732 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +438 -0
- package/dist/index.d.ts +438 -15
- package/dist/index.js +1725 -27
- package/dist/index.js.map +1 -1
- package/dist/scripts/copy-assets.js +0 -21
- package/package.json +5 -4
- package/scripts/copy-assets.js +0 -21
- package/dist/core/crudora.d.ts +0 -49
- package/dist/core/crudora.d.ts.map +0 -1
- package/dist/core/crudora.js +0 -370
- package/dist/core/crudora.js.map +0 -1
- package/dist/core/crudoraServer.d.ts +0 -84
- package/dist/core/crudoraServer.d.ts.map +0 -1
- package/dist/core/crudoraServer.js +0 -202
- package/dist/core/crudoraServer.js.map +0 -1
- package/dist/core/drizzleTableBuilder.d.ts +0 -6
- package/dist/core/drizzleTableBuilder.d.ts.map +0 -1
- package/dist/core/drizzleTableBuilder.js +0 -175
- package/dist/core/drizzleTableBuilder.js.map +0 -1
- package/dist/core/model.d.ts +0 -58
- package/dist/core/model.d.ts.map +0 -1
- package/dist/core/model.js +0 -64
- package/dist/core/model.js.map +0 -1
- package/dist/core/repository.d.ts +0 -106
- package/dist/core/repository.d.ts.map +0 -1
- package/dist/core/repository.js +0 -607
- package/dist/core/repository.js.map +0 -1
- package/dist/core/schemaGenerator.d.ts +0 -6
- package/dist/core/schemaGenerator.d.ts.map +0 -1
- package/dist/core/schemaGenerator.js +0 -248
- package/dist/core/schemaGenerator.js.map +0 -1
- package/dist/decorators/model.d.ts +0 -64
- package/dist/decorators/model.d.ts.map +0 -1
- package/dist/decorators/model.js +0 -138
- package/dist/decorators/model.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/types/logger.type.d.ts +0 -7
- package/dist/types/logger.type.d.ts.map +0 -1
- package/dist/types/logger.type.js +0 -3
- package/dist/types/logger.type.js.map +0 -1
- package/dist/types/model.type.d.ts +0 -38
- package/dist/types/model.type.d.ts.map +0 -1
- package/dist/types/model.type.js +0 -3
- package/dist/types/model.type.js.map +0 -1
- package/dist/utils/validation.d.ts +0 -7
- package/dist/utils/validation.d.ts.map +0 -1
- package/dist/utils/validation.js +0 -107
- package/dist/utils/validation.js.map +0 -1
package/dist/core/crudora.js
DELETED
|
@@ -1,370 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Crudora = void 0;
|
|
4
|
-
const zod_1 = require("zod");
|
|
5
|
-
const repository_1 = require("./repository");
|
|
6
|
-
const schemaGenerator_1 = require("./schemaGenerator");
|
|
7
|
-
const validation_1 = require("../utils/validation");
|
|
8
|
-
const drizzleTableBuilder_1 = require("./drizzleTableBuilder");
|
|
9
|
-
const MAX_LIMIT = 1000;
|
|
10
|
-
const MAX_RELATIONS = 5;
|
|
11
|
-
/** Validates a query-param key: alphanumeric/underscore with optional operator suffix. */
|
|
12
|
-
const SAFE_KEY_RE = /^[a-zA-Z_][a-zA-Z0-9_]*(_gt|_gte|_lt|_lte|_ne|_like|_in)?$/;
|
|
13
|
-
// ─── Response helpers ─────────────────────────────────────────────────────────
|
|
14
|
-
function ok(data, meta) {
|
|
15
|
-
return meta !== undefined ? { success: true, data, meta } : { success: true, data };
|
|
16
|
-
}
|
|
17
|
-
function fail(code, message, details) {
|
|
18
|
-
const error = { code, message };
|
|
19
|
-
if (details !== undefined)
|
|
20
|
-
error.details = details;
|
|
21
|
-
return { success: false, error };
|
|
22
|
-
}
|
|
23
|
-
function zodDetails(issues) {
|
|
24
|
-
return issues.map((issue) => ({
|
|
25
|
-
field: issue.path.length ? issue.path.join('.') : '_root',
|
|
26
|
-
message: issue.message,
|
|
27
|
-
}));
|
|
28
|
-
}
|
|
29
|
-
class Crudora {
|
|
30
|
-
constructor(db, dialect, logger) {
|
|
31
|
-
this.models = new Map();
|
|
32
|
-
this.tables = new Map();
|
|
33
|
-
this.repositories = new Map();
|
|
34
|
-
this.customRoutes = [];
|
|
35
|
-
if (!db) {
|
|
36
|
-
throw new Error('Crudora: db is required. Provide a Drizzle db instance:\n' +
|
|
37
|
-
' import { drizzle } from "drizzle-orm/node-postgres";\n' +
|
|
38
|
-
' import { Pool } from "pg";\n' +
|
|
39
|
-
' const db = drizzle(new Pool({ connectionString: process.env.DATABASE_URL }));');
|
|
40
|
-
}
|
|
41
|
-
if (typeof db.select !== 'function' || typeof db.insert !== 'function') {
|
|
42
|
-
throw new Error('Crudora: the provided db object does not look like a Drizzle ORM instance. ' +
|
|
43
|
-
'Make sure drizzle-orm is installed (npm install drizzle-orm) and that you are ' +
|
|
44
|
-
'passing the result of drizzle(pool) or drizzle(client), not a raw pool/connection.');
|
|
45
|
-
}
|
|
46
|
-
this.db = db;
|
|
47
|
-
this.dialect = dialect;
|
|
48
|
-
this.logger = logger;
|
|
49
|
-
}
|
|
50
|
-
registerModel(...modelClasses) {
|
|
51
|
-
for (const modelClass of modelClasses) {
|
|
52
|
-
const table = drizzleTableBuilder_1.DrizzleTableBuilder.build(modelClass, this.dialect);
|
|
53
|
-
// Pass the shared repositories Map so each repo can resolve siblings lazily
|
|
54
|
-
const repository = new repository_1.Repository(modelClass, this.db, table, this.repositories);
|
|
55
|
-
this.models.set(modelClass.name, modelClass);
|
|
56
|
-
this.tables.set(modelClass.name, table);
|
|
57
|
-
this.repositories.set(modelClass.name, repository);
|
|
58
|
-
}
|
|
59
|
-
return this;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Register a model against a pre-built Drizzle table object (e.g. from `drizzle-kit introspect`).
|
|
63
|
-
* Skips `DrizzleTableBuilder` — useful when the database already exists and the schema
|
|
64
|
-
* was generated via introspection rather than Crudora decorators.
|
|
65
|
-
*
|
|
66
|
-
* Validation works if the model defines `@Field()` decorators matching the table columns.
|
|
67
|
-
* Without decorators, POST/PUT bodies pass through without Zod validation.
|
|
68
|
-
*/
|
|
69
|
-
registerTable(modelClass, table) {
|
|
70
|
-
const repository = new repository_1.Repository(modelClass, this.db, table, this.repositories);
|
|
71
|
-
this.models.set(modelClass.name, modelClass);
|
|
72
|
-
this.tables.set(modelClass.name, table);
|
|
73
|
-
this.repositories.set(modelClass.name, repository);
|
|
74
|
-
return this;
|
|
75
|
-
}
|
|
76
|
-
getRepository(modelClass) {
|
|
77
|
-
const repository = this.repositories.get(modelClass.name);
|
|
78
|
-
if (!repository) {
|
|
79
|
-
throw new Error(`Repository for ${modelClass.name} not found. Did you register the model?`);
|
|
80
|
-
}
|
|
81
|
-
return repository;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Returns the Drizzle table object for a registered model.
|
|
85
|
-
* Useful for raw queries that need access to columns excluded by `hidden`
|
|
86
|
-
* (e.g. fetching a password hash for authentication).
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* const usersTable = crudora.getTable(User);
|
|
90
|
-
* const [row] = await db.select().from(usersTable).where(eq(usersTable.email, email)).limit(1);
|
|
91
|
-
*/
|
|
92
|
-
getTable(modelClass) {
|
|
93
|
-
const table = this.tables.get(modelClass.name);
|
|
94
|
-
if (!table) {
|
|
95
|
-
throw new Error(`Table for ${modelClass.name} not found. Did you register the model?`);
|
|
96
|
-
}
|
|
97
|
-
return table;
|
|
98
|
-
}
|
|
99
|
-
generateDrizzleSchema() {
|
|
100
|
-
const modelClasses = Array.from(this.models.values());
|
|
101
|
-
return schemaGenerator_1.SchemaGenerator.generateDrizzleSchema(modelClasses, this.dialect);
|
|
102
|
-
}
|
|
103
|
-
getValidationSchema(modelClass) {
|
|
104
|
-
return validation_1.ValidationGenerator.generateZodSchema(modelClass);
|
|
105
|
-
}
|
|
106
|
-
getStrictValidationSchema(modelClass) {
|
|
107
|
-
return validation_1.ValidationGenerator.generateStrictZodSchema(modelClass);
|
|
108
|
-
}
|
|
109
|
-
get(path, ...handlers) {
|
|
110
|
-
this.customRoutes.push({ method: 'GET', path, handlers });
|
|
111
|
-
return this;
|
|
112
|
-
}
|
|
113
|
-
post(path, ...handlers) {
|
|
114
|
-
this.customRoutes.push({ method: 'POST', path, handlers });
|
|
115
|
-
return this;
|
|
116
|
-
}
|
|
117
|
-
put(path, ...handlers) {
|
|
118
|
-
this.customRoutes.push({ method: 'PUT', path, handlers });
|
|
119
|
-
return this;
|
|
120
|
-
}
|
|
121
|
-
delete(path, ...handlers) {
|
|
122
|
-
this.customRoutes.push({ method: 'DELETE', path, handlers });
|
|
123
|
-
return this;
|
|
124
|
-
}
|
|
125
|
-
patch(path, ...handlers) {
|
|
126
|
-
this.customRoutes.push({ method: 'PATCH', path, handlers });
|
|
127
|
-
return this;
|
|
128
|
-
}
|
|
129
|
-
/** Runs `fn` inside a database transaction and returns its result. */
|
|
130
|
-
async transaction(fn) {
|
|
131
|
-
return this.db.transaction(fn);
|
|
132
|
-
}
|
|
133
|
-
generateRoutes(app, basePath = '/api') {
|
|
134
|
-
// Route discovery endpoint
|
|
135
|
-
app.get(basePath, (_req, res) => {
|
|
136
|
-
const routes = [];
|
|
137
|
-
for (const [, modelClass] of this.models) {
|
|
138
|
-
const routePath = `${basePath}/${modelClass.getTableName()}`;
|
|
139
|
-
routes.push({ method: 'GET', path: routePath, description: `List all ${modelClass.getTableName()}`, type: 'CRUD' }, { method: 'GET', path: `${routePath}/:id`, description: `Get ${modelClass.getTableName()} by ID`, type: 'CRUD' }, { method: 'POST', path: routePath, description: `Create new ${modelClass.getTableName()}`, type: 'CRUD' }, { method: 'PUT', path: `${routePath}/:id`, description: `Replace ${modelClass.getTableName()} by ID`, type: 'CRUD' }, { method: 'PATCH', path: `${routePath}/:id`, description: `Partial update ${modelClass.getTableName()} by ID`, type: 'CRUD' }, { method: 'DELETE', path: `${routePath}/:id`, description: `Delete ${modelClass.getTableName()} by ID`, type: 'CRUD' });
|
|
140
|
-
}
|
|
141
|
-
for (const route of this.customRoutes) {
|
|
142
|
-
routes.push({
|
|
143
|
-
method: route.method,
|
|
144
|
-
path: `${basePath}${route.path}`,
|
|
145
|
-
description: `Custom ${route.method} route`,
|
|
146
|
-
type: 'Custom',
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
res.json(ok({ routes }));
|
|
150
|
-
});
|
|
151
|
-
// CRUD routes per model
|
|
152
|
-
for (const [, modelClass] of this.models) {
|
|
153
|
-
const repository = this.getRepository(modelClass);
|
|
154
|
-
const validationSchema = this.getValidationSchema(modelClass);
|
|
155
|
-
const strictValidationSchema = this.getStrictValidationSchema(modelClass);
|
|
156
|
-
const routePath = `${basePath}/${modelClass.getTableName()}`;
|
|
157
|
-
// ── GET /resource ──────────────────────────────────────────────────────
|
|
158
|
-
app.get(routePath, async (req, res) => {
|
|
159
|
-
try {
|
|
160
|
-
const { page, limit = '10', orderBy, order, cursor, // presence triggers cursor mode
|
|
161
|
-
cursorField, select, // comma-separated field names
|
|
162
|
-
with: withStr, // comma-separated relation names
|
|
163
|
-
withDeleted, ...filters } = req.query;
|
|
164
|
-
const selectFields = select
|
|
165
|
-
? select.split(',').map((f) => f.trim()).filter((f) => SAFE_KEY_RE.test(f))
|
|
166
|
-
: undefined;
|
|
167
|
-
const withRelations = withStr
|
|
168
|
-
? withStr.split(',').map((r) => r.trim()).filter((r) => SAFE_KEY_RE.test(r)).slice(0, MAX_RELATIONS)
|
|
169
|
-
: undefined;
|
|
170
|
-
// Sanitize filter keys to prevent prototype pollution
|
|
171
|
-
const safeFilters = {};
|
|
172
|
-
for (const [k, v] of Object.entries(filters)) {
|
|
173
|
-
if (SAFE_KEY_RE.test(k))
|
|
174
|
-
safeFilters[k] = v;
|
|
175
|
-
}
|
|
176
|
-
const whereFilters = Object.keys(safeFilters).length ? safeFilters : undefined;
|
|
177
|
-
// Clamp limit: reject NaN, 0, negatives; cap at MAX_LIMIT
|
|
178
|
-
const rawLimit = Number(limit);
|
|
179
|
-
const limitNum = Number.isFinite(rawLimit) && rawLimit > 0
|
|
180
|
-
? Math.min(rawLimit, MAX_LIMIT)
|
|
181
|
-
: 10;
|
|
182
|
-
const includeDeleted = withDeleted === 'true';
|
|
183
|
-
// Multiple orderBy: ?orderBy=createdAt,name&order=desc,asc
|
|
184
|
-
const orderByFields = orderBy ? orderBy.split(',').map((f) => f.trim()).filter(Boolean) : undefined;
|
|
185
|
-
const orderValues = order
|
|
186
|
-
? order.split(',').map((o) => o.trim()).filter(Boolean)
|
|
187
|
-
: undefined;
|
|
188
|
-
const orderByArg = orderByFields && orderByFields.length === 1 ? orderByFields[0] : orderByFields;
|
|
189
|
-
const orderArg = orderValues && orderValues.length === 1 ? orderValues[0] : orderValues;
|
|
190
|
-
if (cursor !== undefined) {
|
|
191
|
-
// ── Cursor-based pagination ────────────────────────────────────
|
|
192
|
-
const result = await repository.findWithCursor({
|
|
193
|
-
take: limitNum,
|
|
194
|
-
cursor: cursor || null,
|
|
195
|
-
cursorField,
|
|
196
|
-
order: (orderValues?.[0]) ?? (order === 'desc' ? 'desc' : 'asc'),
|
|
197
|
-
where: whereFilters,
|
|
198
|
-
select: selectFields,
|
|
199
|
-
with: withRelations,
|
|
200
|
-
withDeleted: includeDeleted,
|
|
201
|
-
});
|
|
202
|
-
return res.json(ok(result.data, {
|
|
203
|
-
cursor: { next: result.nextCursor, hasMore: result.hasMore },
|
|
204
|
-
}));
|
|
205
|
-
}
|
|
206
|
-
// ── Offset-based pagination ────────────────────────────────────
|
|
207
|
-
const rawPage = Number(page ?? 1);
|
|
208
|
-
const pageNum = Number.isFinite(rawPage) && rawPage > 0 ? Math.floor(rawPage) : 1;
|
|
209
|
-
const skip = (pageNum - 1) * limitNum;
|
|
210
|
-
const items = await repository.findAll({
|
|
211
|
-
skip,
|
|
212
|
-
take: limitNum,
|
|
213
|
-
where: whereFilters,
|
|
214
|
-
orderBy: orderByArg,
|
|
215
|
-
order: orderArg,
|
|
216
|
-
select: selectFields,
|
|
217
|
-
with: withRelations,
|
|
218
|
-
withDeleted: includeDeleted,
|
|
219
|
-
});
|
|
220
|
-
const total = await repository.count(whereFilters, includeDeleted);
|
|
221
|
-
return res.json(ok(items, {
|
|
222
|
-
pagination: { page: pageNum, limit: limitNum, total, pages: total === 0 ? 0 : Math.ceil(total / limitNum) },
|
|
223
|
-
}));
|
|
224
|
-
}
|
|
225
|
-
catch (err) {
|
|
226
|
-
this.logger?.error('GET request failed', {
|
|
227
|
-
path: routePath,
|
|
228
|
-
correlationId: req.correlationId,
|
|
229
|
-
error: err instanceof Error ? err.message : String(err),
|
|
230
|
-
});
|
|
231
|
-
res.status(500).json(fail('INTERNAL_ERROR', 'Internal server error'));
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
// ── GET /resource/:id ──────────────────────────────────────────────────
|
|
235
|
-
app.get(`${routePath}/:id`, async (req, res) => {
|
|
236
|
-
try {
|
|
237
|
-
const { select, with: withStr, withDeleted } = req.query;
|
|
238
|
-
const selectFields = select
|
|
239
|
-
? select.split(',').map((f) => f.trim()).filter((f) => SAFE_KEY_RE.test(f))
|
|
240
|
-
: undefined;
|
|
241
|
-
const withRelations = withStr
|
|
242
|
-
? withStr.split(',').map((r) => r.trim()).filter((r) => SAFE_KEY_RE.test(r)).slice(0, MAX_RELATIONS)
|
|
243
|
-
: undefined;
|
|
244
|
-
const item = await repository.findById(req.params.id, {
|
|
245
|
-
select: selectFields,
|
|
246
|
-
with: withRelations,
|
|
247
|
-
withDeleted: withDeleted === 'true',
|
|
248
|
-
});
|
|
249
|
-
if (!item)
|
|
250
|
-
return res.status(404).json(fail('NOT_FOUND', 'Resource not found'));
|
|
251
|
-
return res.json(ok(item));
|
|
252
|
-
}
|
|
253
|
-
catch (err) {
|
|
254
|
-
this.logger?.error('GET by ID request failed', {
|
|
255
|
-
path: `${routePath}/:id`,
|
|
256
|
-
id: req.params.id,
|
|
257
|
-
correlationId: req.correlationId,
|
|
258
|
-
error: err instanceof Error ? err.message : String(err),
|
|
259
|
-
});
|
|
260
|
-
res.status(500).json(fail('INTERNAL_ERROR', 'Internal server error'));
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
// ── POST /resource ─────────────────────────────────────────────────────
|
|
264
|
-
app.post(routePath, async (req, res) => {
|
|
265
|
-
try {
|
|
266
|
-
const validatedData = strictValidationSchema.parse(req.body);
|
|
267
|
-
const item = await repository.create(validatedData);
|
|
268
|
-
return res.status(201).json(ok(item));
|
|
269
|
-
}
|
|
270
|
-
catch (error) {
|
|
271
|
-
if (error instanceof zod_1.z.ZodError) {
|
|
272
|
-
return res.status(422).json(fail('VALIDATION_ERROR', 'Validation failed', zodDetails(error.issues)));
|
|
273
|
-
}
|
|
274
|
-
this.logger?.error('POST request failed', {
|
|
275
|
-
path: routePath,
|
|
276
|
-
correlationId: req.correlationId,
|
|
277
|
-
error: error instanceof Error ? error.message : String(error),
|
|
278
|
-
});
|
|
279
|
-
res.status(500).json(fail('INTERNAL_ERROR', 'Internal server error'));
|
|
280
|
-
}
|
|
281
|
-
});
|
|
282
|
-
// ── PUT /resource/:id ──────────────────────────────────────────────────
|
|
283
|
-
app.put(`${routePath}/:id`, async (req, res) => {
|
|
284
|
-
try {
|
|
285
|
-
const validatedData = strictValidationSchema.parse(req.body);
|
|
286
|
-
const item = await repository.update(req.params.id, validatedData);
|
|
287
|
-
return res.json(ok(item));
|
|
288
|
-
}
|
|
289
|
-
catch (error) {
|
|
290
|
-
if (error instanceof repository_1.NotFoundError)
|
|
291
|
-
return res.status(404).json(fail('NOT_FOUND', error.message));
|
|
292
|
-
if (error instanceof zod_1.z.ZodError) {
|
|
293
|
-
return res.status(422).json(fail('VALIDATION_ERROR', 'Validation failed', zodDetails(error.issues)));
|
|
294
|
-
}
|
|
295
|
-
this.logger?.error('PUT request failed', {
|
|
296
|
-
path: `${routePath}/:id`,
|
|
297
|
-
id: req.params.id,
|
|
298
|
-
correlationId: req.correlationId,
|
|
299
|
-
error: error instanceof Error ? error.message : String(error),
|
|
300
|
-
});
|
|
301
|
-
res.status(500).json(fail('INTERNAL_ERROR', 'Internal server error'));
|
|
302
|
-
}
|
|
303
|
-
});
|
|
304
|
-
// ── PATCH /resource/:id ── partial update ─────────────────────────────
|
|
305
|
-
app.patch(`${routePath}/:id`, async (req, res) => {
|
|
306
|
-
try {
|
|
307
|
-
const validatedData = validationSchema.parse(req.body);
|
|
308
|
-
const item = await repository.update(req.params.id, validatedData);
|
|
309
|
-
return res.json(ok(item));
|
|
310
|
-
}
|
|
311
|
-
catch (error) {
|
|
312
|
-
if (error instanceof repository_1.NotFoundError)
|
|
313
|
-
return res.status(404).json(fail('NOT_FOUND', error.message));
|
|
314
|
-
if (error instanceof zod_1.z.ZodError) {
|
|
315
|
-
return res.status(422).json(fail('VALIDATION_ERROR', 'Validation failed', zodDetails(error.issues)));
|
|
316
|
-
}
|
|
317
|
-
this.logger?.error('PATCH request failed', {
|
|
318
|
-
path: `${routePath}/:id`,
|
|
319
|
-
id: req.params.id,
|
|
320
|
-
correlationId: req.correlationId,
|
|
321
|
-
error: error instanceof Error ? error.message : String(error),
|
|
322
|
-
});
|
|
323
|
-
res.status(500).json(fail('INTERNAL_ERROR', 'Internal server error'));
|
|
324
|
-
}
|
|
325
|
-
});
|
|
326
|
-
// ── DELETE /resource/:id ───────────────────────────────────────────────
|
|
327
|
-
app.delete(`${routePath}/:id`, async (req, res) => {
|
|
328
|
-
try {
|
|
329
|
-
await repository.delete(req.params.id);
|
|
330
|
-
return res.status(204).send();
|
|
331
|
-
}
|
|
332
|
-
catch (error) {
|
|
333
|
-
if (error instanceof repository_1.NotFoundError)
|
|
334
|
-
return res.status(404).json(fail('NOT_FOUND', error.message));
|
|
335
|
-
this.logger?.error('DELETE request failed', {
|
|
336
|
-
path: `${routePath}/:id`,
|
|
337
|
-
id: req.params.id,
|
|
338
|
-
correlationId: req.correlationId,
|
|
339
|
-
error: error instanceof Error ? error.message : String(error),
|
|
340
|
-
});
|
|
341
|
-
res.status(500).json(fail('INTERNAL_ERROR', 'Internal server error'));
|
|
342
|
-
}
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
// Custom routes
|
|
346
|
-
for (const route of this.customRoutes) {
|
|
347
|
-
const fullPath = `${basePath}${route.path}`;
|
|
348
|
-
const { method, handlers } = route;
|
|
349
|
-
switch (method.toLowerCase()) {
|
|
350
|
-
case 'get':
|
|
351
|
-
app.get(fullPath, ...handlers);
|
|
352
|
-
break;
|
|
353
|
-
case 'post':
|
|
354
|
-
app.post(fullPath, ...handlers);
|
|
355
|
-
break;
|
|
356
|
-
case 'put':
|
|
357
|
-
app.put(fullPath, ...handlers);
|
|
358
|
-
break;
|
|
359
|
-
case 'delete':
|
|
360
|
-
app.delete(fullPath, ...handlers);
|
|
361
|
-
break;
|
|
362
|
-
case 'patch':
|
|
363
|
-
app.patch(fullPath, ...handlers);
|
|
364
|
-
break;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
exports.Crudora = Crudora;
|
|
370
|
-
//# sourceMappingURL=crudora.js.map
|
package/dist/core/crudora.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crudora.js","sourceRoot":"","sources":["../../src/core/crudora.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { Express } from 'express';
|
|
2
|
-
import { Crudora } from './crudora';
|
|
3
|
-
import { Model, ModelConstructor } from './model';
|
|
4
|
-
import { Dialect } from '../types/model.type';
|
|
5
|
-
import { CrudoraLogger } from '../types/logger.type';
|
|
6
|
-
export type { CrudoraLogger };
|
|
7
|
-
export interface RateLimitConfig {
|
|
8
|
-
/** Sliding-window duration in milliseconds. Default: `60_000` (1 minute). */
|
|
9
|
-
windowMs?: number;
|
|
10
|
-
/** Maximum number of requests per key per window. Default: `100`. */
|
|
11
|
-
max?: number;
|
|
12
|
-
/** Message body returned with 429 responses. Default: `'Too many requests'`. */
|
|
13
|
-
message?: string;
|
|
14
|
-
/**
|
|
15
|
-
* Function that extracts the rate-limit key from a request.
|
|
16
|
-
* Default: `req.ip` (the direct connection IP, or `X-Forwarded-For` if `trust proxy` is set on Express).
|
|
17
|
-
*/
|
|
18
|
-
keyGenerator?: (req: any) => string;
|
|
19
|
-
}
|
|
20
|
-
export interface CrudoraServerConfig {
|
|
21
|
-
port?: number;
|
|
22
|
-
/**
|
|
23
|
-
* CORS configuration.
|
|
24
|
-
* - `true` (default): allow all origins (`*`)
|
|
25
|
-
* - `false`: disable CORS headers entirely
|
|
26
|
-
* - `string`: allow a single specific origin, e.g. `'https://app.example.com'`
|
|
27
|
-
* - `string[]`: allow a list of origins; the request's Origin is reflected if it matches
|
|
28
|
-
*/
|
|
29
|
-
cors?: boolean | string | string[];
|
|
30
|
-
bodyParser?: boolean;
|
|
31
|
-
/**
|
|
32
|
-
* Maximum request body size accepted by the JSON and URL-encoded body parsers.
|
|
33
|
-
* Accepts a number (bytes) or a string with a unit suffix (`'100kb'`, `'5mb'`).
|
|
34
|
-
* Default: `'100kb'`.
|
|
35
|
-
*/
|
|
36
|
-
bodyParserLimit?: string | number;
|
|
37
|
-
db: any;
|
|
38
|
-
dialect: Dialect;
|
|
39
|
-
basePath?: string;
|
|
40
|
-
/**
|
|
41
|
-
* Logger for request errors and lifecycle events.
|
|
42
|
-
* - Omit (default): structured JSON written to console (compatible with log aggregators).
|
|
43
|
-
* - Pass a pino/winston instance or any object with `error`, `warn`, `info`, `debug` methods.
|
|
44
|
-
* - Pass `false` to disable all Crudora logging.
|
|
45
|
-
*/
|
|
46
|
-
logger?: CrudoraLogger | false;
|
|
47
|
-
/**
|
|
48
|
-
* Built-in sliding-window rate limiter applied to every route.
|
|
49
|
-
* - Omit / `undefined` (default): enabled with 100 requests per minute per IP.
|
|
50
|
-
* - Pass a `RateLimitConfig` object to customise the window, limit, or key function.
|
|
51
|
-
* - Pass `false` to disable rate limiting entirely (e.g. when using an external proxy-level limiter).
|
|
52
|
-
*/
|
|
53
|
-
rateLimit?: RateLimitConfig | false;
|
|
54
|
-
}
|
|
55
|
-
export declare class CrudoraServer {
|
|
56
|
-
private app;
|
|
57
|
-
private crudora;
|
|
58
|
-
private config;
|
|
59
|
-
constructor(config: CrudoraServerConfig);
|
|
60
|
-
private setupMiddleware;
|
|
61
|
-
registerModel(...modelClasses: ModelConstructor[]): this;
|
|
62
|
-
registerTable<T extends Model>(modelClass: ModelConstructor<T>, table: any): this;
|
|
63
|
-
generateRoutes(): this;
|
|
64
|
-
use(middleware: any): this;
|
|
65
|
-
listen(callback?: () => void): void;
|
|
66
|
-
getApp(): Express;
|
|
67
|
-
getCrudora(): Crudora;
|
|
68
|
-
/**
|
|
69
|
-
* Returns the Drizzle table object for a registered model — delegates to `Crudora.getTable()`.
|
|
70
|
-
* Use this when you need raw DB access to columns excluded by `static hidden`
|
|
71
|
-
* (e.g. a login route that must read the password hash).
|
|
72
|
-
*
|
|
73
|
-
* @example
|
|
74
|
-
* const usersTable = server.getTable(User);
|
|
75
|
-
* const [row] = await db.select().from(usersTable).where(eq(usersTable.email, email)).limit(1);
|
|
76
|
-
*/
|
|
77
|
-
getTable<T extends Model>(modelClass: ModelConstructor<T>): any;
|
|
78
|
-
get(path: string, ...handlers: Array<(req: any, res: any, next?: any) => void>): this;
|
|
79
|
-
post(path: string, ...handlers: Array<(req: any, res: any, next?: any) => void>): this;
|
|
80
|
-
put(path: string, ...handlers: Array<(req: any, res: any, next?: any) => void>): this;
|
|
81
|
-
delete(path: string, ...handlers: Array<(req: any, res: any, next?: any) => void>): this;
|
|
82
|
-
patch(path: string, ...handlers: Array<(req: any, res: any, next?: any) => void>): this;
|
|
83
|
-
}
|
|
84
|
-
//# sourceMappingURL=crudoraServer.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crudoraServer.d.ts","sourceRoot":"","sources":["../../src/core/crudoraServer.ts"],"names":[],"mappings":"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"}
|