@stonyx/orm 0.3.2-beta.6 → 0.3.2-beta.60
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/index.d.ts +1 -0
- package/dist/main.d.ts +16 -0
- package/dist/main.js +30 -0
- package/dist/manage-record.js +17 -5
- package/dist/mysql/mysql-db.d.ts +1 -0
- package/dist/mysql/mysql-db.js +4 -2
- package/dist/postgres/postgres-db.js +4 -2
- package/dist/store.js +6 -1
- package/dist/types/orm-types.d.ts +2 -0
- package/package.json +8 -7
- package/src/index.ts +1 -0
- package/src/main.ts +40 -0
- package/src/manage-record.ts +18 -5
- package/src/mysql/mysql-db.ts +5 -2
- package/src/postgres/postgres-db.ts +4 -2
- package/src/store.ts +6 -1
- package/src/types/orm-types.ts +2 -0
- package/src/types/stonyx.d.ts +7 -1
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { createRecord, updateRecord } from './manage-record.js';
|
|
|
8
8
|
import { count, avg, sum, min, max } from './aggregates.js';
|
|
9
9
|
export { default } from './main.js';
|
|
10
10
|
export { store, relationships } from './main.js';
|
|
11
|
+
export type { PersistErrorDetail } from './main.js';
|
|
11
12
|
export { Model, View, Serializer };
|
|
12
13
|
export { attr, belongsTo, hasMany, createRecord, updateRecord };
|
|
13
14
|
export { count, avg, sum, min, max };
|
package/dist/main.d.ts
CHANGED
|
@@ -15,6 +15,12 @@ export interface OrmDB {
|
|
|
15
15
|
save(): Promise<void>;
|
|
16
16
|
init(): Promise<void>;
|
|
17
17
|
}
|
|
18
|
+
export interface PersistErrorDetail {
|
|
19
|
+
operation: 'create' | 'update' | 'delete';
|
|
20
|
+
modelName: string;
|
|
21
|
+
recordId: unknown;
|
|
22
|
+
error: Error;
|
|
23
|
+
}
|
|
18
24
|
export default class Orm {
|
|
19
25
|
static initialized: boolean;
|
|
20
26
|
static relationships: Map<string, Map<string, unknown>>;
|
|
@@ -29,6 +35,7 @@ export default class Orm {
|
|
|
29
35
|
options: OrmOptions;
|
|
30
36
|
sqlDb?: SqlDb;
|
|
31
37
|
db?: OrmDB | SqlDb;
|
|
38
|
+
private _persistErrorHandler;
|
|
32
39
|
constructor(options?: OrmOptions);
|
|
33
40
|
init(): Promise<void>;
|
|
34
41
|
startup(): Promise<void>;
|
|
@@ -39,6 +46,15 @@ export default class Orm {
|
|
|
39
46
|
serializerClass: unknown;
|
|
40
47
|
};
|
|
41
48
|
isView(modelName: string): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Register a callback to be invoked when a fire-and-forget SQL persist fails.
|
|
51
|
+
* Without a handler, persist errors are logged via log.error (backwards-compatible).
|
|
52
|
+
*/
|
|
53
|
+
onPersistError(handler: ((detail: PersistErrorDetail) => void) | null): void;
|
|
54
|
+
/**
|
|
55
|
+
* Emit a persist error to the registered handler, or fall back to log.error.
|
|
56
|
+
*/
|
|
57
|
+
emitPersistError(detail: PersistErrorDetail): void;
|
|
42
58
|
warn(message: string): void;
|
|
43
59
|
}
|
|
44
60
|
export declare const store: Store;
|
package/dist/main.js
CHANGED
|
@@ -41,6 +41,7 @@ export default class Orm {
|
|
|
41
41
|
options;
|
|
42
42
|
sqlDb;
|
|
43
43
|
db;
|
|
44
|
+
_persistErrorHandler = null;
|
|
44
45
|
constructor(options = {}) {
|
|
45
46
|
if (Orm.instance)
|
|
46
47
|
return Orm.instance;
|
|
@@ -53,6 +54,10 @@ export default class Orm {
|
|
|
53
54
|
Orm.instance = this;
|
|
54
55
|
}
|
|
55
56
|
async init() {
|
|
57
|
+
// Self-register so log.db works even when @stonyx/orm is in the
|
|
58
|
+
// consumer's `dependencies` (stonyx loader only merges devDependencies).
|
|
59
|
+
const { logColor = 'white', logMethod = 'db' } = config.orm;
|
|
60
|
+
log.defineType(logMethod, logColor);
|
|
56
61
|
const { paths, restServer } = config.orm;
|
|
57
62
|
const promises = ['Model', 'Serializer', 'Transform'].map(type => {
|
|
58
63
|
const lowerCaseType = type.toLowerCase();
|
|
@@ -168,6 +173,31 @@ export default class Orm {
|
|
|
168
173
|
const modelClassPrefix = kebabCaseToPascalCase(modelName);
|
|
169
174
|
return !!this.views[`${modelClassPrefix}View`];
|
|
170
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Register a callback to be invoked when a fire-and-forget SQL persist fails.
|
|
178
|
+
* Without a handler, persist errors are logged via log.error (backwards-compatible).
|
|
179
|
+
*/
|
|
180
|
+
onPersistError(handler) {
|
|
181
|
+
this._persistErrorHandler = handler;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Emit a persist error to the registered handler, or fall back to log.error.
|
|
185
|
+
*/
|
|
186
|
+
emitPersistError(detail) {
|
|
187
|
+
const fallbackLog = () => log.error?.(`[ORM] Failed to persist ${detail.operation} for ${detail.modelName}:${String(detail.recordId)}: ${detail.error.message}`);
|
|
188
|
+
if (this._persistErrorHandler) {
|
|
189
|
+
try {
|
|
190
|
+
this._persistErrorHandler(detail);
|
|
191
|
+
}
|
|
192
|
+
catch (handlerError) {
|
|
193
|
+
fallbackLog();
|
|
194
|
+
log.error?.(`[ORM] onPersistError handler threw: ${handlerError instanceof Error ? handlerError.message : String(handlerError)}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
fallbackLog();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
171
201
|
// Queue warnings to avoid the same error from being logged in the same iteration
|
|
172
202
|
warn(message) {
|
|
173
203
|
this.warnings.add(message);
|
package/dist/manage-record.js
CHANGED
|
@@ -2,12 +2,12 @@ import Orm, { store } from '@stonyx/orm';
|
|
|
2
2
|
import OrmRecord from './record.js';
|
|
3
3
|
import { getGlobalRegistry, getPendingRegistry, getPendingBelongsToRegistry, getBelongsToRegistry, getHasManyRegistry } from './relationships.js';
|
|
4
4
|
import { isOrmRecord } from './utils.js';
|
|
5
|
-
import log from 'stonyx/log';
|
|
6
5
|
const defaultOptions = {
|
|
7
6
|
isDbRecord: false,
|
|
8
7
|
serialize: true,
|
|
9
8
|
transform: true
|
|
10
9
|
};
|
|
10
|
+
let pendingIdCounter = 0;
|
|
11
11
|
export function createRecord(modelName, rawData = {}, userOptions = {}) {
|
|
12
12
|
const orm = Orm.instance;
|
|
13
13
|
const { initialized } = Orm;
|
|
@@ -85,7 +85,12 @@ export function createRecord(modelName, rawData = {}, userOptions = {}) {
|
|
|
85
85
|
if (shouldPersist) {
|
|
86
86
|
const response = { data: { id: record.id } };
|
|
87
87
|
orm.sqlDb.persist('create', modelName, { rawData }, response).catch((err) => {
|
|
88
|
-
|
|
88
|
+
orm.emitPersistError({
|
|
89
|
+
operation: 'create',
|
|
90
|
+
modelName,
|
|
91
|
+
recordId: record.id,
|
|
92
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
93
|
+
});
|
|
89
94
|
});
|
|
90
95
|
}
|
|
91
96
|
return record;
|
|
@@ -107,7 +112,12 @@ export function updateRecord(record, rawData, userOptions = {}) {
|
|
|
107
112
|
const shouldPersist = orm?.sqlDb && !options.isDbRecord && !userOptions._relationshipKey && !options._skipAutoPersist;
|
|
108
113
|
if (shouldPersist && modelName) {
|
|
109
114
|
orm.sqlDb.persist('update', modelName, { record, oldState }, {}).catch((err) => {
|
|
110
|
-
|
|
115
|
+
orm.emitPersistError({
|
|
116
|
+
operation: 'update',
|
|
117
|
+
modelName,
|
|
118
|
+
recordId: record.id,
|
|
119
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
120
|
+
});
|
|
111
121
|
});
|
|
112
122
|
}
|
|
113
123
|
}
|
|
@@ -120,9 +130,11 @@ export function updateRecord(record, rawData, userOptions = {}) {
|
|
|
120
130
|
function assignRecordId(modelName, rawData) {
|
|
121
131
|
if (rawData.id)
|
|
122
132
|
return;
|
|
123
|
-
// In SQL mode with numeric IDs, defer to database auto-increment
|
|
133
|
+
// In SQL mode with numeric IDs, defer to database auto-increment.
|
|
134
|
+
// Use unique negative integers — they survive the number transform (parseInt preserves negatives)
|
|
135
|
+
// and avoid NaN store-key collisions that string pending IDs caused.
|
|
124
136
|
if (Orm.instance?.sqlDb && !isStringIdModel(modelName)) {
|
|
125
|
-
rawData.id =
|
|
137
|
+
rawData.id = -(++pendingIdCounter);
|
|
126
138
|
rawData.__pendingSqlId = true;
|
|
127
139
|
return;
|
|
128
140
|
}
|
package/dist/mysql/mysql-db.d.ts
CHANGED
package/dist/mysql/mysql-db.js
CHANGED
|
@@ -321,8 +321,10 @@ export default class MysqlDB {
|
|
|
321
321
|
if (!record)
|
|
322
322
|
return;
|
|
323
323
|
const insertData = this._recordToRow(record, schema);
|
|
324
|
-
// For auto-increment models, remove the pending ID
|
|
325
|
-
|
|
324
|
+
// For auto-increment models, remove the pending ID.
|
|
325
|
+
// Check context.rawData (not record.__data) because __pendingSqlId is not a model
|
|
326
|
+
// attribute and gets lost during serialization.
|
|
327
|
+
const isPendingId = context.rawData?.__pendingSqlId === true;
|
|
326
328
|
if (isPendingId) {
|
|
327
329
|
delete insertData.id;
|
|
328
330
|
}
|
|
@@ -376,8 +376,10 @@ export default class PostgresDB {
|
|
|
376
376
|
if (!record)
|
|
377
377
|
return;
|
|
378
378
|
const insertData = this._recordToRow(record, schema, context.rawData);
|
|
379
|
-
// For auto-increment models, remove the pending ID
|
|
380
|
-
|
|
379
|
+
// For auto-increment models, remove the pending ID.
|
|
380
|
+
// Check context.rawData (not record.__data) because __pendingSqlId is not a model
|
|
381
|
+
// attribute and gets lost during serialization.
|
|
382
|
+
const isPendingId = context.rawData?.__pendingSqlId === true;
|
|
381
383
|
if (isPendingId) {
|
|
382
384
|
delete insertData.id;
|
|
383
385
|
}
|
package/dist/store.js
CHANGED
|
@@ -115,7 +115,12 @@ export default class Store {
|
|
|
115
115
|
// Auto-persist delete to SQL
|
|
116
116
|
if (id && Orm.instance?.sqlDb) {
|
|
117
117
|
Orm.instance.sqlDb.persist('delete', key, { recordId: id }, {}).catch((err) => {
|
|
118
|
-
|
|
118
|
+
Orm.instance.emitPersistError({
|
|
119
|
+
operation: 'delete',
|
|
120
|
+
modelName: key,
|
|
121
|
+
recordId: id,
|
|
122
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
123
|
+
});
|
|
119
124
|
});
|
|
120
125
|
}
|
|
121
126
|
if (id)
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"stonyx-async",
|
|
5
5
|
"stonyx-module"
|
|
6
6
|
],
|
|
7
|
-
"version": "0.3.2-beta.
|
|
7
|
+
"version": "0.3.2-beta.60",
|
|
8
8
|
"description": "",
|
|
9
9
|
"main": "dist/index.js",
|
|
10
10
|
"type": "module",
|
|
@@ -61,9 +61,9 @@
|
|
|
61
61
|
},
|
|
62
62
|
"homepage": "https://github.com/abofs/stonyx-orm#readme",
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@stonyx/cron": "0.2.1-beta.
|
|
65
|
-
"@stonyx/events": "0.1.1-beta.
|
|
66
|
-
"stonyx": "0.2.3-beta.
|
|
64
|
+
"@stonyx/cron": "0.2.1-beta.63",
|
|
65
|
+
"@stonyx/events": "0.1.1-beta.49",
|
|
66
|
+
"stonyx": "0.2.3-beta.64"
|
|
67
67
|
},
|
|
68
68
|
"peerDependencies": {
|
|
69
69
|
"@stonyx/rest-server": ">=0.2.1-beta.14",
|
|
@@ -82,18 +82,19 @@
|
|
|
82
82
|
}
|
|
83
83
|
},
|
|
84
84
|
"devDependencies": {
|
|
85
|
-
"@stonyx/rest-server": "0.2.1-beta.
|
|
86
|
-
"@stonyx/utils": "0.2.3-beta.
|
|
85
|
+
"@stonyx/rest-server": "0.2.1-beta.64",
|
|
86
|
+
"@stonyx/utils": "0.2.3-beta.24",
|
|
87
87
|
"@types/node": "^25.6.0",
|
|
88
88
|
"mysql2": "^3.20.0",
|
|
89
89
|
"pg": "^8.20.0",
|
|
90
90
|
"qunit": "^2.24.1",
|
|
91
91
|
"sinon": "^21.0.0",
|
|
92
|
+
"tsx": "^4.21.0",
|
|
92
93
|
"typescript": "^5.8.3"
|
|
93
94
|
},
|
|
94
95
|
"scripts": {
|
|
95
96
|
"build": "tsc",
|
|
96
97
|
"build:test": "tsc -p tsconfig.test.json",
|
|
97
|
-
"test": "
|
|
98
|
+
"test": "pnpm build && NODE_ENV=test node --import tsx/esm --import ./test/setup.ts node_modules/qunit/bin/qunit.js 'test/**/*-test.ts'"
|
|
98
99
|
}
|
|
99
100
|
}
|
package/src/index.ts
CHANGED
|
@@ -26,6 +26,7 @@ import { count, avg, sum, min, max } from './aggregates.js';
|
|
|
26
26
|
|
|
27
27
|
export { default } from './main.js';
|
|
28
28
|
export { store, relationships } from './main.js';
|
|
29
|
+
export type { PersistErrorDetail } from './main.js';
|
|
29
30
|
export { Model, View, Serializer }; // base classes
|
|
30
31
|
export { attr, belongsTo, hasMany, createRecord, updateRecord }; // helpers
|
|
31
32
|
export { count, avg, sum, min, max }; // aggregate helpers
|
package/src/main.ts
CHANGED
|
@@ -49,6 +49,13 @@ const defaultOptions: OrmOptions = {
|
|
|
49
49
|
dbType: 'json'
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
export interface PersistErrorDetail {
|
|
53
|
+
operation: 'create' | 'update' | 'delete';
|
|
54
|
+
modelName: string;
|
|
55
|
+
recordId: unknown;
|
|
56
|
+
error: Error;
|
|
57
|
+
}
|
|
58
|
+
|
|
52
59
|
export default class Orm {
|
|
53
60
|
static initialized: boolean = false;
|
|
54
61
|
static relationships: Map<string, Map<string, unknown>> = new Map();
|
|
@@ -65,6 +72,8 @@ export default class Orm {
|
|
|
65
72
|
sqlDb?: SqlDb;
|
|
66
73
|
db?: OrmDB | SqlDb;
|
|
67
74
|
|
|
75
|
+
private _persistErrorHandler: ((detail: PersistErrorDetail) => void) | null = null;
|
|
76
|
+
|
|
68
77
|
constructor(options: OrmOptions = {}) {
|
|
69
78
|
if (Orm.instance) return Orm.instance;
|
|
70
79
|
|
|
@@ -81,6 +90,11 @@ export default class Orm {
|
|
|
81
90
|
}
|
|
82
91
|
|
|
83
92
|
async init(): Promise<void> {
|
|
93
|
+
// Self-register so log.db works even when @stonyx/orm is in the
|
|
94
|
+
// consumer's `dependencies` (stonyx loader only merges devDependencies).
|
|
95
|
+
const { logColor = 'white', logMethod = 'db' } = config.orm;
|
|
96
|
+
log.defineType(logMethod, logColor);
|
|
97
|
+
|
|
84
98
|
const { paths, restServer } = config.orm;
|
|
85
99
|
|
|
86
100
|
const promises: Promise<unknown>[] = ['Model', 'Serializer', 'Transform'].map(type => {
|
|
@@ -214,6 +228,32 @@ export default class Orm {
|
|
|
214
228
|
return !!this.views[`${modelClassPrefix}View`];
|
|
215
229
|
}
|
|
216
230
|
|
|
231
|
+
/**
|
|
232
|
+
* Register a callback to be invoked when a fire-and-forget SQL persist fails.
|
|
233
|
+
* Without a handler, persist errors are logged via log.error (backwards-compatible).
|
|
234
|
+
*/
|
|
235
|
+
onPersistError(handler: ((detail: PersistErrorDetail) => void) | null): void {
|
|
236
|
+
this._persistErrorHandler = handler;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Emit a persist error to the registered handler, or fall back to log.error.
|
|
241
|
+
*/
|
|
242
|
+
emitPersistError(detail: PersistErrorDetail): void {
|
|
243
|
+
const fallbackLog = () => log.error?.(`[ORM] Failed to persist ${detail.operation} for ${detail.modelName}:${String(detail.recordId)}: ${detail.error.message}`);
|
|
244
|
+
|
|
245
|
+
if (this._persistErrorHandler) {
|
|
246
|
+
try {
|
|
247
|
+
this._persistErrorHandler(detail);
|
|
248
|
+
} catch (handlerError) {
|
|
249
|
+
fallbackLog();
|
|
250
|
+
log.error?.(`[ORM] onPersistError handler threw: ${handlerError instanceof Error ? handlerError.message : String(handlerError)}`);
|
|
251
|
+
}
|
|
252
|
+
} else {
|
|
253
|
+
fallbackLog();
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
217
257
|
// Queue warnings to avoid the same error from being logged in the same iteration
|
|
218
258
|
warn(message: string): void {
|
|
219
259
|
this.warnings.add(message);
|
package/src/manage-record.ts
CHANGED
|
@@ -3,7 +3,6 @@ import OrmRecord from './record.js';
|
|
|
3
3
|
import { getGlobalRegistry, getPendingRegistry, getPendingBelongsToRegistry, getBelongsToRegistry, getHasManyRegistry } from './relationships.js';
|
|
4
4
|
import type Serializer from './serializer.js';
|
|
5
5
|
import { isOrmRecord } from './utils.js';
|
|
6
|
-
import log from 'stonyx/log';
|
|
7
6
|
|
|
8
7
|
interface CreateRecordOptions {
|
|
9
8
|
isDbRecord?: boolean;
|
|
@@ -27,6 +26,8 @@ const defaultOptions: CreateRecordOptions = {
|
|
|
27
26
|
transform: true
|
|
28
27
|
};
|
|
29
28
|
|
|
29
|
+
let pendingIdCounter = 0;
|
|
30
|
+
|
|
30
31
|
export function createRecord(modelName: string, rawData: { [key: string]: unknown } = {}, userOptions: CreateRecordOptions = {}): OrmRecord {
|
|
31
32
|
const orm = Orm.instance;
|
|
32
33
|
const { initialized } = Orm;
|
|
@@ -118,7 +119,12 @@ export function createRecord(modelName: string, rawData: { [key: string]: unknow
|
|
|
118
119
|
if (shouldPersist) {
|
|
119
120
|
const response = { data: { id: record.id } };
|
|
120
121
|
orm!.sqlDb!.persist('create', modelName, { rawData }, response).catch((err: unknown) => {
|
|
121
|
-
|
|
122
|
+
orm!.emitPersistError({
|
|
123
|
+
operation: 'create',
|
|
124
|
+
modelName,
|
|
125
|
+
recordId: record.id,
|
|
126
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
127
|
+
});
|
|
122
128
|
});
|
|
123
129
|
}
|
|
124
130
|
|
|
@@ -146,7 +152,12 @@ export function updateRecord(record: OrmRecord, rawData: unknown, userOptions: C
|
|
|
146
152
|
const shouldPersist = orm?.sqlDb && !options.isDbRecord && !userOptions._relationshipKey && !options._skipAutoPersist;
|
|
147
153
|
if (shouldPersist && modelName) {
|
|
148
154
|
orm!.sqlDb!.persist('update', modelName, { record, oldState }, {}).catch((err: unknown) => {
|
|
149
|
-
|
|
155
|
+
orm!.emitPersistError({
|
|
156
|
+
operation: 'update',
|
|
157
|
+
modelName,
|
|
158
|
+
recordId: record.id,
|
|
159
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
160
|
+
});
|
|
150
161
|
});
|
|
151
162
|
}
|
|
152
163
|
}
|
|
@@ -160,9 +171,11 @@ export function updateRecord(record: OrmRecord, rawData: unknown, userOptions: C
|
|
|
160
171
|
function assignRecordId(modelName: string, rawData: { [key: string]: unknown }): void {
|
|
161
172
|
if (rawData.id) return;
|
|
162
173
|
|
|
163
|
-
// In SQL mode with numeric IDs, defer to database auto-increment
|
|
174
|
+
// In SQL mode with numeric IDs, defer to database auto-increment.
|
|
175
|
+
// Use unique negative integers — they survive the number transform (parseInt preserves negatives)
|
|
176
|
+
// and avoid NaN store-key collisions that string pending IDs caused.
|
|
164
177
|
if (Orm.instance?.sqlDb && !isStringIdModel(modelName)) {
|
|
165
|
-
rawData.id =
|
|
178
|
+
rawData.id = -(++pendingIdCounter);
|
|
166
179
|
rawData.__pendingSqlId = true;
|
|
167
180
|
return;
|
|
168
181
|
}
|
package/src/mysql/mysql-db.ts
CHANGED
|
@@ -21,6 +21,7 @@ interface PersistContext {
|
|
|
21
21
|
record?: OrmRecord;
|
|
22
22
|
recordId?: unknown;
|
|
23
23
|
oldState?: Record<string, unknown>;
|
|
24
|
+
rawData?: Record<string, unknown>;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
interface PersistResponse {
|
|
@@ -420,8 +421,10 @@ export default class MysqlDB {
|
|
|
420
421
|
|
|
421
422
|
const insertData = this._recordToRow(record, schema);
|
|
422
423
|
|
|
423
|
-
// For auto-increment models, remove the pending ID
|
|
424
|
-
|
|
424
|
+
// For auto-increment models, remove the pending ID.
|
|
425
|
+
// Check context.rawData (not record.__data) because __pendingSqlId is not a model
|
|
426
|
+
// attribute and gets lost during serialization.
|
|
427
|
+
const isPendingId = context.rawData?.__pendingSqlId === true;
|
|
425
428
|
|
|
426
429
|
if (isPendingId) {
|
|
427
430
|
delete insertData.id;
|
|
@@ -494,8 +494,10 @@ export default class PostgresDB {
|
|
|
494
494
|
|
|
495
495
|
const insertData = this._recordToRow(record, schema, context.rawData);
|
|
496
496
|
|
|
497
|
-
// For auto-increment models, remove the pending ID
|
|
498
|
-
|
|
497
|
+
// For auto-increment models, remove the pending ID.
|
|
498
|
+
// Check context.rawData (not record.__data) because __pendingSqlId is not a model
|
|
499
|
+
// attribute and gets lost during serialization.
|
|
500
|
+
const isPendingId = context.rawData?.__pendingSqlId === true;
|
|
499
501
|
|
|
500
502
|
if (isPendingId) {
|
|
501
503
|
delete insertData.id;
|
package/src/store.ts
CHANGED
|
@@ -179,7 +179,12 @@ export default class Store {
|
|
|
179
179
|
// Auto-persist delete to SQL
|
|
180
180
|
if (id && Orm.instance?.sqlDb) {
|
|
181
181
|
Orm.instance.sqlDb.persist('delete', key, { recordId: id }, {}).catch((err: unknown) => {
|
|
182
|
-
|
|
182
|
+
Orm.instance.emitPersistError({
|
|
183
|
+
operation: 'delete',
|
|
184
|
+
modelName: key,
|
|
185
|
+
recordId: id,
|
|
186
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
187
|
+
});
|
|
183
188
|
});
|
|
184
189
|
}
|
|
185
190
|
|
package/src/types/orm-types.ts
CHANGED
package/src/types/stonyx.d.ts
CHANGED
|
@@ -5,7 +5,13 @@ declare module 'stonyx/config' {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
declare module 'stonyx/log' {
|
|
8
|
-
|
|
8
|
+
interface Log {
|
|
9
|
+
db(message: string): void;
|
|
10
|
+
error(message: string, ...args: unknown[]): void;
|
|
11
|
+
defineType(type: string, setting: string, options?: Record<string, unknown> | null): void;
|
|
12
|
+
[key: string]: ((...args: unknown[]) => void) | undefined;
|
|
13
|
+
}
|
|
14
|
+
const log: Log;
|
|
9
15
|
export default log;
|
|
10
16
|
}
|
|
11
17
|
|