@rapidd/build 1.1.2 → 1.1.3
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/package.json +1 -1
- package/src/commands/build.js +138 -138
- package/src/generators/modelGenerator.js +3 -3
package/package.json
CHANGED
package/src/commands/build.js
CHANGED
|
@@ -29,9 +29,16 @@ class Model {
|
|
|
29
29
|
this.user_id = this.user ? this.user.id : null;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
get primaryKey(){
|
|
33
|
+
const pkey = this.queryBuilder.getPrimaryKey();
|
|
34
|
+
return Array.isArray(pkey) ? pkey.join('_') : pkey;
|
|
35
|
+
}
|
|
36
|
+
|
|
32
37
|
_select = (fields) => this.queryBuilder.select(fields);
|
|
33
38
|
_filter = (q) => this.queryBuilder.filter(q);
|
|
34
39
|
_include = (include) => this.queryBuilder.include(include, this.user);
|
|
40
|
+
_queryCreate = (data) => this.queryBuilder.create(data, this.user);
|
|
41
|
+
_queryUpdate = (id, data) => this.queryBuilder.update(id, data, this.user);
|
|
35
42
|
// ACL METHODS
|
|
36
43
|
_canCreate = () => this.acl.canCreate(this.user);
|
|
37
44
|
_getAccessFilter = () => this.acl.getAccessFilter?.(this.user);
|
|
@@ -49,16 +56,16 @@ class Model {
|
|
|
49
56
|
* @param {'asc'|'desc'} sortOrder
|
|
50
57
|
* @returns {Promise<Object[]>}
|
|
51
58
|
*/
|
|
52
|
-
_getMany = async (q = {}, include = "", limit = 25, offset = 0, sortBy =
|
|
59
|
+
_getMany = async (q = {}, include = "", limit = 25, offset = 0, sortBy = this.primaryKey, sortOrder = "asc", options = {})=>{
|
|
53
60
|
const take = this.take(Number(limit));
|
|
54
61
|
const skip = this.skip(Number(offset));
|
|
55
62
|
|
|
56
|
-
sortBy = sortBy
|
|
57
|
-
sortOrder = sortOrder
|
|
63
|
+
sortBy = sortBy?.trim();
|
|
64
|
+
sortOrder = sortOrder?.trim();
|
|
58
65
|
if (!sortBy.includes('.') && this.fields[sortBy] == undefined) {
|
|
59
66
|
throw new ErrorResponse(400, "invalid_sort_field", {sortBy, modelName: this.constructor.name});
|
|
60
67
|
}
|
|
61
|
-
|
|
68
|
+
|
|
62
69
|
// Query the database using Prisma with filters, pagination, and limits
|
|
63
70
|
const [data, total] = await prismaTransaction([
|
|
64
71
|
(tx) => tx[this.name].findMany({
|
|
@@ -83,11 +90,11 @@ class Model {
|
|
|
83
90
|
*/
|
|
84
91
|
_get = async (id, include, options = {}) =>{
|
|
85
92
|
const {omit, ..._options} = options;
|
|
86
|
-
|
|
93
|
+
console.log(JSON.stringify(this.include(include)));
|
|
87
94
|
// To determine if the record is inaccessible, either due to non-existence or insufficient permissions, two simultaneous queries are performed.
|
|
88
95
|
const _response = this.prisma.findUnique({
|
|
89
96
|
'where': {
|
|
90
|
-
|
|
97
|
+
[this.primaryKey]: id,
|
|
91
98
|
},
|
|
92
99
|
'include': this.include(include),
|
|
93
100
|
'omit': {...this._omit(), ...omit},
|
|
@@ -96,7 +103,7 @@ class Model {
|
|
|
96
103
|
|
|
97
104
|
const _checkPermission = this.prisma.findUnique({
|
|
98
105
|
'where': {
|
|
99
|
-
|
|
106
|
+
[this.primaryKey]: id,
|
|
100
107
|
...this.getAccessFilter()
|
|
101
108
|
},
|
|
102
109
|
'select': {
|
|
@@ -107,16 +114,16 @@ class Model {
|
|
|
107
114
|
const [response, checkPermission] = await Promise.all([_response, _checkPermission]);
|
|
108
115
|
if(response){
|
|
109
116
|
if(checkPermission){
|
|
110
|
-
if(response.id !=
|
|
111
|
-
throw new ErrorResponse(
|
|
117
|
+
if(response.id != checkPermission?.id){ // IN CASE access_filter CONTAINS id FIELD
|
|
118
|
+
throw new ErrorResponse(403, "no_permission");
|
|
112
119
|
}
|
|
113
120
|
}
|
|
114
121
|
else{
|
|
115
|
-
throw new ErrorResponse(
|
|
122
|
+
throw new ErrorResponse(403, "no_permission");
|
|
116
123
|
}
|
|
117
124
|
}
|
|
118
125
|
else{
|
|
119
|
-
throw new ErrorResponse(
|
|
126
|
+
throw new ErrorResponse(404, "record_not_found");
|
|
120
127
|
}
|
|
121
128
|
return response;
|
|
122
129
|
}
|
|
@@ -131,7 +138,7 @@ class Model {
|
|
|
131
138
|
}
|
|
132
139
|
|
|
133
140
|
// VALIDATE PASSED FIELDS AND RELATIONSHIPS
|
|
134
|
-
this.
|
|
141
|
+
this._queryCreate(data);
|
|
135
142
|
|
|
136
143
|
// CREATE
|
|
137
144
|
return await this.prisma.create({
|
|
@@ -147,8 +154,8 @@ class Model {
|
|
|
147
154
|
* @returns {Promise<Object>}
|
|
148
155
|
*/
|
|
149
156
|
_update = async (id, data, options = {}) => {
|
|
150
|
-
|
|
151
|
-
|
|
157
|
+
delete data.createdAt;
|
|
158
|
+
delete data.createdBy;
|
|
152
159
|
// CHECK UPDATE PERMISSION
|
|
153
160
|
const updateFilter = this.getUpdateFilter();
|
|
154
161
|
if (updateFilter === false) {
|
|
@@ -156,10 +163,10 @@ class Model {
|
|
|
156
163
|
}
|
|
157
164
|
|
|
158
165
|
// VALIDATE PASSED FIELDS AND RELATIONSHIPS
|
|
159
|
-
this.
|
|
166
|
+
this._queryUpdate(id, data);
|
|
160
167
|
const response = await this.prisma.update({
|
|
161
168
|
'where': {
|
|
162
|
-
|
|
169
|
+
[this.primaryKey]: id,
|
|
163
170
|
...updateFilter
|
|
164
171
|
},
|
|
165
172
|
'data': data,
|
|
@@ -188,8 +195,6 @@ class Model {
|
|
|
188
195
|
* @returns {Promise<Object>}
|
|
189
196
|
*/
|
|
190
197
|
_delete = async (id, options = {}) => {
|
|
191
|
-
id = Number(id);
|
|
192
|
-
|
|
193
198
|
// CHECK DELETE PERMISSION
|
|
194
199
|
const deleteFilter = this.getDeleteFilter();
|
|
195
200
|
if (deleteFilter === false) {
|
|
@@ -198,7 +203,7 @@ class Model {
|
|
|
198
203
|
|
|
199
204
|
const response = await this.prisma.delete({
|
|
200
205
|
'where': {
|
|
201
|
-
|
|
206
|
+
[this.primaryKey]: id,
|
|
202
207
|
...deleteFilter
|
|
203
208
|
},
|
|
204
209
|
'select': this.select(),
|
|
@@ -229,7 +234,7 @@ class Model {
|
|
|
229
234
|
* @returns {Promise<{} | null>}
|
|
230
235
|
*/
|
|
231
236
|
async get(id, include, options = {}){
|
|
232
|
-
return await this._get(
|
|
237
|
+
return await this._get(id, include, options);
|
|
233
238
|
}
|
|
234
239
|
|
|
235
240
|
/**
|
|
@@ -238,7 +243,7 @@ class Model {
|
|
|
238
243
|
* @returns {Promise<Object>}
|
|
239
244
|
*/
|
|
240
245
|
async update(id, data, options = {}){
|
|
241
|
-
return await this._update(
|
|
246
|
+
return await this._update(id, data, options);
|
|
242
247
|
}
|
|
243
248
|
|
|
244
249
|
/**
|
|
@@ -255,7 +260,7 @@ class Model {
|
|
|
255
260
|
* @returns {Promise<Object>}
|
|
256
261
|
*/
|
|
257
262
|
async delete(id, data, options = {}){
|
|
258
|
-
return await this._delete(
|
|
263
|
+
return await this._delete(id, data, options);
|
|
259
264
|
}
|
|
260
265
|
|
|
261
266
|
select(fields){
|
|
@@ -359,7 +364,7 @@ function generateRapiddFile(rapiddJsPath, isPostgreSQL = true) {
|
|
|
359
364
|
|
|
360
365
|
if (isPostgreSQL) {
|
|
361
366
|
// PostgreSQL version with RLS support
|
|
362
|
-
content = `const { PrismaClient } = require('../prisma/client');
|
|
367
|
+
content = `const { PrismaClient, Prisma } = require('../prisma/client');
|
|
363
368
|
const { AsyncLocalStorage } = require('async_hooks');
|
|
364
369
|
const acl = require('./acl');
|
|
365
370
|
|
|
@@ -373,13 +378,49 @@ const RLS_CONFIG = {
|
|
|
373
378
|
userRole: process.env.RLS_USER_ROLE || 'current_user_role',
|
|
374
379
|
};
|
|
375
380
|
|
|
376
|
-
//
|
|
381
|
+
// =====================================================
|
|
382
|
+
// BASE PRISMA CLIENTS
|
|
383
|
+
// =====================================================
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* ADMIN CLIENT - Bypasses ALL RLS
|
|
387
|
+
* Uses DATABASE_URL_ADMIN connection (e.g., app_auth_proxy user)
|
|
388
|
+
* Use ONLY for authentication operations:
|
|
389
|
+
* - Login
|
|
390
|
+
* - Register
|
|
391
|
+
* - Email Verification
|
|
392
|
+
* - Password Reset
|
|
393
|
+
* - OAuth operations
|
|
394
|
+
*/
|
|
395
|
+
const authPrisma = new PrismaClient({
|
|
396
|
+
datasources: {
|
|
397
|
+
db: {
|
|
398
|
+
url: process.env.DATABASE_URL_ADMIN
|
|
399
|
+
}
|
|
400
|
+
},
|
|
401
|
+
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* BASE CLIENT - Regular user with RLS
|
|
406
|
+
* Uses DATABASE_URL connection
|
|
407
|
+
* Use for all business operations
|
|
408
|
+
*/
|
|
377
409
|
const basePrisma = new PrismaClient({
|
|
410
|
+
datasources: {
|
|
411
|
+
db: {
|
|
412
|
+
url: process.env.DATABASE_URL
|
|
413
|
+
}
|
|
414
|
+
},
|
|
378
415
|
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
|
|
379
416
|
});
|
|
380
417
|
|
|
418
|
+
// =====================================================
|
|
419
|
+
// RLS HELPER FUNCTIONS
|
|
420
|
+
// =====================================================
|
|
421
|
+
|
|
381
422
|
/**
|
|
382
|
-
*
|
|
423
|
+
* Set RLS Session Variables in PostgreSQL
|
|
383
424
|
* Execute each SET command separately to avoid prepared statement error
|
|
384
425
|
*/
|
|
385
426
|
async function setRLSVariables(tx, userId, userRole) {
|
|
@@ -387,27 +428,48 @@ async function setRLSVariables(tx, userId, userRole) {
|
|
|
387
428
|
const userIdVar = RLS_CONFIG.userId;
|
|
388
429
|
const userRoleVar = RLS_CONFIG.userRole;
|
|
389
430
|
|
|
390
|
-
// Execute SET commands separately
|
|
391
|
-
await tx.$executeRawUnsafe(\`SET LOCAL
|
|
392
|
-
await tx.$executeRawUnsafe(\`SET LOCAL
|
|
431
|
+
// Execute SET commands separately
|
|
432
|
+
await tx.$executeRawUnsafe(\`SET LOCAL \${namespace}.\${userIdVar} = '\${userId}'\`);
|
|
433
|
+
await tx.$executeRawUnsafe(\`SET LOCAL \${namespace}.\${userRoleVar} = '\${userRole}'\`);
|
|
393
434
|
}
|
|
394
435
|
|
|
395
|
-
|
|
436
|
+
/**
|
|
437
|
+
* Reset RLS Session Variables
|
|
438
|
+
*/
|
|
439
|
+
async function resetRLSVariables(tx) {
|
|
440
|
+
const namespace = RLS_CONFIG.namespace;
|
|
441
|
+
const userIdVar = RLS_CONFIG.userId;
|
|
442
|
+
const userRoleVar = RLS_CONFIG.userRole;
|
|
443
|
+
|
|
444
|
+
try {
|
|
445
|
+
await tx.$executeRawUnsafe(\`RESET \${namespace}.\${userIdVar}\`);
|
|
446
|
+
await tx.$executeRawUnsafe(\`RESET \${namespace}.\${userRoleVar}\`);
|
|
447
|
+
} catch (e) {
|
|
448
|
+
// Ignore errors on reset
|
|
449
|
+
console.error('Failed to reset RLS variables:', e);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// =====================================================
|
|
454
|
+
// EXTENDED PRISMA WITH AUTOMATIC RLS
|
|
455
|
+
// =====================================================
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Extended Prisma Client with automatic RLS context
|
|
459
|
+
* Automatically wraps all operations in RLS context from AsyncLocalStorage
|
|
460
|
+
*/
|
|
396
461
|
const prisma = basePrisma.$extends({
|
|
397
462
|
query: {
|
|
398
463
|
async $allOperations({ operation, args, query, model }) {
|
|
399
464
|
const context = requestContext.getStore();
|
|
400
465
|
|
|
401
|
-
//
|
|
466
|
+
// No context = no RLS (e.g., system operations)
|
|
402
467
|
if (!context?.userId || !context?.userRole) {
|
|
403
468
|
return query(args);
|
|
404
469
|
}
|
|
405
470
|
|
|
406
471
|
const { userId, userRole } = context;
|
|
407
472
|
|
|
408
|
-
// IMPORTANT: The entire operation must happen in ONE transaction
|
|
409
|
-
// We need to wrap the ENTIRE query execution in a single transaction
|
|
410
|
-
|
|
411
473
|
// For operations that are already transactions, just set the variables
|
|
412
474
|
if (operation === '$transaction') {
|
|
413
475
|
return basePrisma.$transaction(async (tx) => {
|
|
@@ -422,7 +484,6 @@ const prisma = basePrisma.$extends({
|
|
|
422
484
|
await setRLSVariables(tx, userId, userRole);
|
|
423
485
|
|
|
424
486
|
// Execute the original query using the transaction client
|
|
425
|
-
// This is the key: we need to use the transaction client for the query
|
|
426
487
|
if (model) {
|
|
427
488
|
// Model query (e.g., user.findMany())
|
|
428
489
|
return tx[model][operation](args);
|
|
@@ -435,70 +496,33 @@ const prisma = basePrisma.$extends({
|
|
|
435
496
|
},
|
|
436
497
|
});
|
|
437
498
|
|
|
438
|
-
//
|
|
499
|
+
// =====================================================
|
|
500
|
+
// TRANSACTION HELPERS
|
|
501
|
+
// =====================================================
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Helper for batch operations in single transaction
|
|
505
|
+
*/
|
|
439
506
|
async function prismaTransaction(operations) {
|
|
440
507
|
const context = requestContext.getStore();
|
|
441
|
-
|
|
508
|
+
|
|
442
509
|
if (!context?.userId || !context?.userRole) {
|
|
443
510
|
return Promise.all(operations);
|
|
444
511
|
}
|
|
445
|
-
|
|
512
|
+
|
|
446
513
|
return basePrisma.$transaction(async (tx) => {
|
|
447
514
|
await setRLSVariables(tx, context.userId, context.userRole);
|
|
448
515
|
return Promise.all(operations.map(op => op(tx)));
|
|
449
516
|
});
|
|
450
517
|
}
|
|
451
518
|
|
|
452
|
-
//
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
this.client = basePrisma;
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
/**
|
|
459
|
-
* Execute any Prisma operation with RLS context
|
|
460
|
-
*/
|
|
461
|
-
async withRLS(userId, userRole, callback) {
|
|
462
|
-
return this.client.$transaction(async (tx) => {
|
|
463
|
-
// Execute SET commands separately to avoid prepared statement error
|
|
464
|
-
await tx.$executeRawUnsafe(\`SET LOCAL app.current_user_id = '\${userId}'\`);
|
|
465
|
-
await tx.$executeRawUnsafe(\`SET LOCAL app.current_user_role = '\${userRole}'\`);
|
|
466
|
-
|
|
467
|
-
// Execute callback with transaction client
|
|
468
|
-
return callback(tx);
|
|
469
|
-
});
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
/**
|
|
473
|
-
* Get a proxy client for a specific user
|
|
474
|
-
* This wraps ALL operations in RLS context
|
|
475
|
-
*/
|
|
476
|
-
forUser(userId, userRole) {
|
|
477
|
-
const withRLS = this.withRLS.bind(this);
|
|
478
|
-
const client = this.client;
|
|
479
|
-
|
|
480
|
-
return new Proxy({}, {
|
|
481
|
-
get(target, model) {
|
|
482
|
-
// Return a proxy for the model
|
|
483
|
-
return new Proxy({}, {
|
|
484
|
-
get(modelTarget, operation) {
|
|
485
|
-
// Return a function that wraps the operation
|
|
486
|
-
return async (args) => {
|
|
487
|
-
return withRLS(userId, userRole, async (tx) => {
|
|
488
|
-
return tx[model][operation](args);
|
|
489
|
-
});
|
|
490
|
-
};
|
|
491
|
-
}
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
});
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
const prismaWithRLS = new PrismaWithRLS();
|
|
519
|
+
// =====================================================
|
|
520
|
+
// CONTEXT HELPERS
|
|
521
|
+
// =====================================================
|
|
499
522
|
|
|
500
523
|
/**
|
|
501
524
|
* Express Middleware: Set RLS context from authenticated user
|
|
525
|
+
* Use this AFTER your authentication middleware
|
|
502
526
|
*/
|
|
503
527
|
function setRLSContext(req, res, next) {
|
|
504
528
|
if (req.user) {
|
|
@@ -516,74 +540,50 @@ function setRLSContext(req, res, next) {
|
|
|
516
540
|
}
|
|
517
541
|
|
|
518
542
|
/**
|
|
519
|
-
*
|
|
520
|
-
*/
|
|
521
|
-
async function withSystemAccess(callback) {
|
|
522
|
-
// For system access, we might not want RLS at all
|
|
523
|
-
// So we use the base client directly
|
|
524
|
-
return callback(basePrisma);
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
/**
|
|
528
|
-
* Helper: Als bestimmter User ausführen (für Tests)
|
|
529
|
-
*/
|
|
530
|
-
async function withUser(userId, userRole, callback) {
|
|
531
|
-
return requestContext.run({ userId, userRole }, () => callback());
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
/**
|
|
535
|
-
* Helper: Direct transaction with RLS for complex operations
|
|
536
|
-
*/
|
|
537
|
-
async function transactionWithRLS(userId, userRole, callback) {
|
|
538
|
-
return basePrisma.$transaction(async (tx) => {
|
|
539
|
-
// Set RLS context for this transaction - execute separately
|
|
540
|
-
await tx.$executeRawUnsafe(\`SET LOCAL app.current_user_id = '\${userId}'\`);
|
|
541
|
-
await tx.$executeRawUnsafe(\`SET LOCAL app.current_user_role = '\${userRole}'\`);
|
|
542
|
-
|
|
543
|
-
// Execute callback with transaction client
|
|
544
|
-
return callback(tx);
|
|
545
|
-
});
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
/**
|
|
549
|
-
* Helper: Hole RLS Config (für SQL Generation)
|
|
543
|
+
* Get RLS Config (for SQL generation)
|
|
550
544
|
*/
|
|
551
545
|
function getRLSConfig() {
|
|
552
546
|
return RLS_CONFIG;
|
|
553
547
|
}
|
|
554
548
|
|
|
555
|
-
//
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
// Option 1: Using extended prisma (automatic RLS)
|
|
559
|
-
const users = await prisma.user.findMany();
|
|
549
|
+
// =====================================================
|
|
550
|
+
// GRACEFUL SHUTDOWN
|
|
551
|
+
// =====================================================
|
|
560
552
|
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
// Option 3: Using forUser helper
|
|
567
|
-
const userPrisma = prismaWithRLS.forUser(req.user.id, req.user.role);
|
|
568
|
-
const users = await userPrisma.user.findMany();
|
|
553
|
+
async function disconnectAll() {
|
|
554
|
+
await authPrisma.$disconnect();
|
|
555
|
+
await basePrisma.$disconnect();
|
|
556
|
+
}
|
|
569
557
|
|
|
570
|
-
|
|
558
|
+
process.on('beforeExit', async () => {
|
|
559
|
+
await disconnectAll();
|
|
571
560
|
});
|
|
572
|
-
|
|
561
|
+
|
|
562
|
+
// =====================================================
|
|
563
|
+
// EXPORTS
|
|
564
|
+
// =====================================================
|
|
573
565
|
|
|
574
566
|
module.exports = {
|
|
575
|
-
|
|
567
|
+
// Main clients
|
|
568
|
+
prisma, // Use for regular operations with automatic RLS from context
|
|
569
|
+
authPrisma, // Use ONLY for auth operations (login, register, etc.)
|
|
570
|
+
|
|
571
|
+
// Transaction helpers
|
|
576
572
|
prismaTransaction,
|
|
577
|
-
|
|
578
|
-
|
|
573
|
+
|
|
574
|
+
// Context helpers
|
|
579
575
|
requestContext,
|
|
580
576
|
setRLSContext,
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
transactionWithRLS,
|
|
584
|
-
prismaWithRLS,
|
|
585
|
-
getRLSConfig,
|
|
577
|
+
|
|
578
|
+
// RLS utilities
|
|
586
579
|
setRLSVariables,
|
|
580
|
+
resetRLSVariables,
|
|
581
|
+
getRLSConfig,
|
|
582
|
+
|
|
583
|
+
// Utilities
|
|
584
|
+
disconnectAll,
|
|
585
|
+
PrismaClient,
|
|
586
|
+
Prisma,
|
|
587
587
|
acl
|
|
588
588
|
};
|
|
589
589
|
`;
|
|
@@ -37,7 +37,7 @@ class ${className} extends Model {
|
|
|
37
37
|
* @returns {{} | null}
|
|
38
38
|
*/
|
|
39
39
|
async get(id, include){
|
|
40
|
-
return await this._get(
|
|
40
|
+
return await this._get(id, include);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/**
|
|
@@ -54,7 +54,7 @@ class ${className} extends Model {
|
|
|
54
54
|
* @returns {Object}
|
|
55
55
|
*/
|
|
56
56
|
async update(id, data){
|
|
57
|
-
return await this._update(
|
|
57
|
+
return await this._update(id, data);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
/**
|
|
@@ -62,7 +62,7 @@ class ${className} extends Model {
|
|
|
62
62
|
* @returns {Object}
|
|
63
63
|
*/
|
|
64
64
|
async delete(id){
|
|
65
|
-
return await this._delete(
|
|
65
|
+
return await this._delete(id);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
/**
|