@gencow/core 0.1.16 → 0.1.17
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/crud.d.ts +12 -5
- package/dist/crud.js +20 -12
- package/package.json +1 -1
- package/src/crud.ts +28 -12
package/dist/crud.d.ts
CHANGED
|
@@ -48,6 +48,13 @@ type CrudOptions<T extends PgTable> = {
|
|
|
48
48
|
realtime?: boolean;
|
|
49
49
|
/** 키 접두사 오버라이드 (기본: 테이블명) */
|
|
50
50
|
prefix?: string;
|
|
51
|
+
/**
|
|
52
|
+
* 생성할 메서드 목록 (기본: 전체 5개)
|
|
53
|
+
* 지정하면 해당 메서드만 레지스트리에 등록되고 반환됨.
|
|
54
|
+
* api.ts codegen에도 지정된 메서드만 포함됨.
|
|
55
|
+
* @example crud(table, { methods: ['list', 'get', 'create'] })
|
|
56
|
+
*/
|
|
57
|
+
methods?: ('list' | 'get' | 'create' | 'update' | 'remove')[];
|
|
51
58
|
};
|
|
52
59
|
/** 지원 연산자 목록 */
|
|
53
60
|
declare const FILTER_OPS: readonly ["eq", "ne", "gt", "gte", "lt", "lte", "in", "nin", "like", "ilike"];
|
|
@@ -103,14 +110,14 @@ export declare function crud<T extends PgTable>(table: T, options?: CrudOptions<
|
|
|
103
110
|
}, {
|
|
104
111
|
data: any;
|
|
105
112
|
total: number;
|
|
106
|
-
}
|
|
113
|
+
}> | undefined;
|
|
107
114
|
get: import("./reactive").QueryDef<{
|
|
108
115
|
id: import("./v").Validator<string> | import("./v").Validator<number>;
|
|
109
|
-
}, any
|
|
110
|
-
create: import("./reactive").MutationDef<any, any
|
|
111
|
-
update: import("./reactive").MutationDef<any, any
|
|
116
|
+
}, any> | undefined;
|
|
117
|
+
create: import("./reactive").MutationDef<any, any> | undefined;
|
|
118
|
+
update: import("./reactive").MutationDef<any, any> | undefined;
|
|
112
119
|
remove: import("./reactive").MutationDef<any, {
|
|
113
120
|
success: boolean;
|
|
114
|
-
}
|
|
121
|
+
}> | undefined;
|
|
115
122
|
};
|
|
116
123
|
export {};
|
package/dist/crud.js
CHANGED
|
@@ -215,8 +215,11 @@ export function crud(table, options) {
|
|
|
215
215
|
const countResult = await db.select({ count: drizzleCount() }).from(anyTable).where(whereClause);
|
|
216
216
|
return { data, total: Number(countResult[0]?.count ?? 0) };
|
|
217
217
|
}
|
|
218
|
+
// ── methods 필터링: 지정된 메서드만 레지스트리 등록 ──
|
|
219
|
+
// methods 옵션 미지정 시 전체 5개 등록 (하위호환)
|
|
220
|
+
const enabledMethods = new Set(options?.methods ?? ['list', 'get', 'create', 'update', 'remove']);
|
|
218
221
|
// ── list ──────────────────────────────────────
|
|
219
|
-
const listDef = query(`${prefix}.list`, {
|
|
222
|
+
const listDef = !enabledMethods.has('list') ? undefined : query(`${prefix}.list`, {
|
|
220
223
|
public: isPublic,
|
|
221
224
|
args: {
|
|
222
225
|
page: v.optional(v.number()),
|
|
@@ -243,8 +246,6 @@ export function crud(table, options) {
|
|
|
243
246
|
orderByClause = desc(defaultOrderCol);
|
|
244
247
|
}
|
|
245
248
|
// SELECT + COUNT 순차 실행 — 소규모 커넥션 풀 환경에서 동시 점유 방지
|
|
246
|
-
// Note: data←→count 사이 INSERT/DELETE 시 total 불일치 가능 (BaaS 단일사용자/저부하에서 무시 가능)
|
|
247
|
-
// TODO(P2): 대규모 시 db.transaction() 래핑 검토
|
|
248
249
|
const results = await ctx.db.select()
|
|
249
250
|
.from(anyTable)
|
|
250
251
|
.where(whereClause)
|
|
@@ -261,7 +262,7 @@ export function crud(table, options) {
|
|
|
261
262
|
}
|
|
262
263
|
});
|
|
263
264
|
// ── get ───────────────────────────────────────
|
|
264
|
-
const getDef = query(`${prefix}.get`, {
|
|
265
|
+
const getDef = !enabledMethods.has('get') ? undefined : query(`${prefix}.get`, {
|
|
265
266
|
public: isPublic,
|
|
266
267
|
args: { id: idValidator },
|
|
267
268
|
handler: async (ctx, args) => {
|
|
@@ -277,7 +278,7 @@ export function crud(table, options) {
|
|
|
277
278
|
}
|
|
278
279
|
});
|
|
279
280
|
// ── create ────────────────────────────────────
|
|
280
|
-
const createDef = mutation(`${prefix}.create`, {
|
|
281
|
+
const createDef = !enabledMethods.has('create') ? undefined : mutation(`${prefix}.create`, {
|
|
281
282
|
public: isPublic,
|
|
282
283
|
invalidates: [],
|
|
283
284
|
handler: async (ctx, args) => {
|
|
@@ -293,7 +294,7 @@ export function crud(table, options) {
|
|
|
293
294
|
}
|
|
294
295
|
const [result] = await ctx.db.insert(anyTable).values(insertData).returning();
|
|
295
296
|
// Realtime push — { data, total } 형태로 emit
|
|
296
|
-
if (useRealtime) {
|
|
297
|
+
if (useRealtime && enabledMethods.has('list')) {
|
|
297
298
|
const listResult = await fetchListWithTotal(ctx.db);
|
|
298
299
|
ctx.realtime.emit(`${prefix}.list`, listResult);
|
|
299
300
|
}
|
|
@@ -301,7 +302,7 @@ export function crud(table, options) {
|
|
|
301
302
|
}
|
|
302
303
|
});
|
|
303
304
|
// ── update ────────────────────────────────────
|
|
304
|
-
const updateDef = mutation(`${prefix}.update`, {
|
|
305
|
+
const updateDef = !enabledMethods.has('update') ? undefined : mutation(`${prefix}.update`, {
|
|
305
306
|
public: isPublic,
|
|
306
307
|
invalidates: [],
|
|
307
308
|
handler: async (ctx, args) => {
|
|
@@ -323,15 +324,19 @@ export function crud(table, options) {
|
|
|
323
324
|
.returning();
|
|
324
325
|
// Realtime push (list + get 양쪽) — { data, total } 형태
|
|
325
326
|
if (useRealtime) {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
327
|
+
if (enabledMethods.has('list')) {
|
|
328
|
+
const listResult = await fetchListWithTotal(ctx.db);
|
|
329
|
+
ctx.realtime.emit(`${prefix}.list`, listResult);
|
|
330
|
+
}
|
|
331
|
+
if (enabledMethods.has('get')) {
|
|
332
|
+
ctx.realtime.emit(`${prefix}.get`, result);
|
|
333
|
+
}
|
|
329
334
|
}
|
|
330
335
|
return result;
|
|
331
336
|
}
|
|
332
337
|
});
|
|
333
338
|
// ── remove ────────────────────────────────────
|
|
334
|
-
const removeDef = mutation(`${prefix}.remove`, {
|
|
339
|
+
const removeDef = !enabledMethods.has('remove') ? undefined : mutation(`${prefix}.remove`, {
|
|
335
340
|
public: isPublic,
|
|
336
341
|
invalidates: [],
|
|
337
342
|
handler: async (ctx, args) => {
|
|
@@ -347,13 +352,16 @@ export function crud(table, options) {
|
|
|
347
352
|
await ctx.db.delete(anyTable).where(eq(pk, args.id));
|
|
348
353
|
}
|
|
349
354
|
// Realtime push — { data, total } 형태
|
|
350
|
-
if (useRealtime) {
|
|
355
|
+
if (useRealtime && enabledMethods.has('list')) {
|
|
351
356
|
const listResult = await fetchListWithTotal(ctx.db);
|
|
352
357
|
ctx.realtime.emit(`${prefix}.list`, listResult);
|
|
353
358
|
}
|
|
354
359
|
return { success: true };
|
|
355
360
|
}
|
|
356
361
|
});
|
|
362
|
+
// 반환 객체는 항상 5개 키를 가지지만, 비활성 메서드는 undefined.
|
|
363
|
+
// 사용자가 destructure 시 undefined를 받으면 export하지 않으므로
|
|
364
|
+
// codegen의 레지스트리에 등록되지 않아 api.ts 불일치가 해소됨.
|
|
357
365
|
return {
|
|
358
366
|
list: listDef,
|
|
359
367
|
get: getDef,
|
package/package.json
CHANGED
package/src/crud.ts
CHANGED
|
@@ -52,6 +52,13 @@ type CrudOptions<T extends PgTable> = {
|
|
|
52
52
|
realtime?: boolean;
|
|
53
53
|
/** 키 접두사 오버라이드 (기본: 테이블명) */
|
|
54
54
|
prefix?: string;
|
|
55
|
+
/**
|
|
56
|
+
* 생성할 메서드 목록 (기본: 전체 5개)
|
|
57
|
+
* 지정하면 해당 메서드만 레지스트리에 등록되고 반환됨.
|
|
58
|
+
* api.ts codegen에도 지정된 메서드만 포함됨.
|
|
59
|
+
* @example crud(table, { methods: ['list', 'get', 'create'] })
|
|
60
|
+
*/
|
|
61
|
+
methods?: ('list' | 'get' | 'create' | 'update' | 'remove')[];
|
|
55
62
|
};
|
|
56
63
|
|
|
57
64
|
// ─── Helpers ────────────────────────────────────────────
|
|
@@ -271,9 +278,13 @@ export function crud<T extends PgTable>(table: T, options?: CrudOptions<T>) {
|
|
|
271
278
|
return { data, total: Number(countResult[0]?.count ?? 0) };
|
|
272
279
|
}
|
|
273
280
|
|
|
281
|
+
// ── methods 필터링: 지정된 메서드만 레지스트리 등록 ──
|
|
282
|
+
// methods 옵션 미지정 시 전체 5개 등록 (하위호환)
|
|
283
|
+
const enabledMethods = new Set(options?.methods ?? ['list', 'get', 'create', 'update', 'remove']);
|
|
284
|
+
|
|
274
285
|
// ── list ──────────────────────────────────────
|
|
275
286
|
|
|
276
|
-
const listDef = query(`${prefix}.list`, {
|
|
287
|
+
const listDef = !enabledMethods.has('list') ? undefined : query(`${prefix}.list`, {
|
|
277
288
|
public: isPublic,
|
|
278
289
|
args: {
|
|
279
290
|
page: v.optional(v.number()),
|
|
@@ -302,8 +313,6 @@ export function crud<T extends PgTable>(table: T, options?: CrudOptions<T>) {
|
|
|
302
313
|
}
|
|
303
314
|
|
|
304
315
|
// SELECT + COUNT 순차 실행 — 소규모 커넥션 풀 환경에서 동시 점유 방지
|
|
305
|
-
// Note: data←→count 사이 INSERT/DELETE 시 total 불일치 가능 (BaaS 단일사용자/저부하에서 무시 가능)
|
|
306
|
-
// TODO(P2): 대규모 시 db.transaction() 래핑 검토
|
|
307
316
|
const results = await ctx.db.select()
|
|
308
317
|
.from(anyTable)
|
|
309
318
|
.where(whereClause)
|
|
@@ -323,7 +332,7 @@ export function crud<T extends PgTable>(table: T, options?: CrudOptions<T>) {
|
|
|
323
332
|
|
|
324
333
|
// ── get ───────────────────────────────────────
|
|
325
334
|
|
|
326
|
-
const getDef = query(`${prefix}.get`, {
|
|
335
|
+
const getDef = !enabledMethods.has('get') ? undefined : query(`${prefix}.get`, {
|
|
327
336
|
public: isPublic,
|
|
328
337
|
args: { id: idValidator },
|
|
329
338
|
handler: async (ctx: any, args: any) => {
|
|
@@ -343,7 +352,7 @@ export function crud<T extends PgTable>(table: T, options?: CrudOptions<T>) {
|
|
|
343
352
|
|
|
344
353
|
// ── create ────────────────────────────────────
|
|
345
354
|
|
|
346
|
-
const createDef = mutation(`${prefix}.create`, {
|
|
355
|
+
const createDef = !enabledMethods.has('create') ? undefined : mutation(`${prefix}.create`, {
|
|
347
356
|
public: isPublic,
|
|
348
357
|
invalidates: [],
|
|
349
358
|
handler: async (ctx: any, args: any) => {
|
|
@@ -364,7 +373,7 @@ export function crud<T extends PgTable>(table: T, options?: CrudOptions<T>) {
|
|
|
364
373
|
const [result] = await ctx.db.insert(anyTable).values(insertData).returning();
|
|
365
374
|
|
|
366
375
|
// Realtime push — { data, total } 형태로 emit
|
|
367
|
-
if (useRealtime) {
|
|
376
|
+
if (useRealtime && enabledMethods.has('list')) {
|
|
368
377
|
const listResult = await fetchListWithTotal(ctx.db);
|
|
369
378
|
ctx.realtime.emit(`${prefix}.list`, listResult);
|
|
370
379
|
}
|
|
@@ -375,7 +384,7 @@ export function crud<T extends PgTable>(table: T, options?: CrudOptions<T>) {
|
|
|
375
384
|
|
|
376
385
|
// ── update ────────────────────────────────────
|
|
377
386
|
|
|
378
|
-
const updateDef = mutation(`${prefix}.update`, {
|
|
387
|
+
const updateDef = !enabledMethods.has('update') ? undefined : mutation(`${prefix}.update`, {
|
|
379
388
|
public: isPublic,
|
|
380
389
|
invalidates: [],
|
|
381
390
|
handler: async (ctx: any, args: any) => {
|
|
@@ -402,9 +411,13 @@ export function crud<T extends PgTable>(table: T, options?: CrudOptions<T>) {
|
|
|
402
411
|
|
|
403
412
|
// Realtime push (list + get 양쪽) — { data, total } 형태
|
|
404
413
|
if (useRealtime) {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
414
|
+
if (enabledMethods.has('list')) {
|
|
415
|
+
const listResult = await fetchListWithTotal(ctx.db);
|
|
416
|
+
ctx.realtime.emit(`${prefix}.list`, listResult);
|
|
417
|
+
}
|
|
418
|
+
if (enabledMethods.has('get')) {
|
|
419
|
+
ctx.realtime.emit(`${prefix}.get`, result);
|
|
420
|
+
}
|
|
408
421
|
}
|
|
409
422
|
|
|
410
423
|
return result;
|
|
@@ -413,7 +426,7 @@ export function crud<T extends PgTable>(table: T, options?: CrudOptions<T>) {
|
|
|
413
426
|
|
|
414
427
|
// ── remove ────────────────────────────────────
|
|
415
428
|
|
|
416
|
-
const removeDef = mutation(`${prefix}.remove`, {
|
|
429
|
+
const removeDef = !enabledMethods.has('remove') ? undefined : mutation(`${prefix}.remove`, {
|
|
417
430
|
public: isPublic,
|
|
418
431
|
invalidates: [],
|
|
419
432
|
handler: async (ctx: any, args: any) => {
|
|
@@ -429,7 +442,7 @@ export function crud<T extends PgTable>(table: T, options?: CrudOptions<T>) {
|
|
|
429
442
|
}
|
|
430
443
|
|
|
431
444
|
// Realtime push — { data, total } 형태
|
|
432
|
-
if (useRealtime) {
|
|
445
|
+
if (useRealtime && enabledMethods.has('list')) {
|
|
433
446
|
const listResult = await fetchListWithTotal(ctx.db);
|
|
434
447
|
ctx.realtime.emit(`${prefix}.list`, listResult);
|
|
435
448
|
}
|
|
@@ -438,6 +451,9 @@ export function crud<T extends PgTable>(table: T, options?: CrudOptions<T>) {
|
|
|
438
451
|
}
|
|
439
452
|
});
|
|
440
453
|
|
|
454
|
+
// 반환 객체는 항상 5개 키를 가지지만, 비활성 메서드는 undefined.
|
|
455
|
+
// 사용자가 destructure 시 undefined를 받으면 export하지 않으므로
|
|
456
|
+
// codegen의 레지스트리에 등록되지 않아 api.ts 불일치가 해소됨.
|
|
441
457
|
return {
|
|
442
458
|
list: listDef,
|
|
443
459
|
get: getDef,
|