convex-verify 1.1.0 → 1.2.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/README.md +148 -80
- package/dist/core/index.d.mts +14 -55
- package/dist/core/index.d.ts +14 -55
- package/dist/core/index.js +492 -92
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +491 -92
- package/dist/core/index.mjs.map +1 -1
- package/dist/index.d.mts +9 -6
- package/dist/index.d.ts +9 -6
- package/dist/index.js +378 -271
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +378 -267
- package/dist/index.mjs.map +1 -1
- package/dist/types-B8ZkLuJ2.d.mts +141 -0
- package/dist/types-B8ZkLuJ2.d.ts +141 -0
- package/dist/utils/index.d.mts +3 -2
- package/dist/utils/index.d.ts +3 -2
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +1 -1
- package/dist/utils/index.mjs.map +1 -1
- package/dist/verifyConfig-CTrtqMr_.d.ts +94 -0
- package/dist/verifyConfig-Kn3Ikj00.d.mts +94 -0
- package/package.json +1 -16
- package/dist/configs/index.d.mts +0 -51
- package/dist/configs/index.d.ts +0 -51
- package/dist/configs/index.js +0 -38
- package/dist/configs/index.js.map +0 -1
- package/dist/configs/index.mjs +0 -11
- package/dist/configs/index.mjs.map +0 -1
- package/dist/plugin-BOb1Kw1A.d.ts +0 -47
- package/dist/plugin-DlsboiCF.d.mts +0 -47
- package/dist/plugins/index.d.mts +0 -85
- package/dist/plugins/index.d.ts +0 -85
- package/dist/plugins/index.js +0 -312
- package/dist/plugins/index.js.map +0 -1
- package/dist/plugins/index.mjs +0 -284
- package/dist/plugins/index.mjs.map +0 -1
- package/dist/transforms/index.d.mts +0 -38
- package/dist/transforms/index.d.ts +0 -38
- package/dist/transforms/index.js +0 -46
- package/dist/transforms/index.js.map +0 -1
- package/dist/transforms/index.mjs +0 -19
- package/dist/transforms/index.mjs.map +0 -1
- package/dist/types-DvJMYubf.d.mts +0 -151
- package/dist/types-DvJMYubf.d.ts +0 -151
package/dist/index.mjs
CHANGED
|
@@ -1,138 +1,5 @@
|
|
|
1
|
-
// src/core/
|
|
2
|
-
|
|
3
|
-
return {
|
|
4
|
-
_type: "extension",
|
|
5
|
-
verify(input) {
|
|
6
|
-
return verify(input);
|
|
7
|
-
}
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
function isExtension(value) {
|
|
11
|
-
return typeof value === "object" && value !== null && "verify" in value && typeof value.verify === "function";
|
|
12
|
-
}
|
|
13
|
-
async function runExtensions(extensions, input) {
|
|
14
|
-
let verifiedData = input.data;
|
|
15
|
-
for (const extension of extensions) {
|
|
16
|
-
verifiedData = await extension.verify({
|
|
17
|
-
...input,
|
|
18
|
-
data: verifiedData
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
return verifiedData;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// src/core/verifyConfig.ts
|
|
25
|
-
var verifyConfig = (_schema, configs) => {
|
|
26
|
-
const customExtensions = configs.extensions ?? [];
|
|
27
|
-
const builtInExtensions = [
|
|
28
|
-
...configs.uniqueRow ? [configs.uniqueRow] : [],
|
|
29
|
-
...configs.uniqueColumn ? [configs.uniqueColumn] : []
|
|
30
|
-
];
|
|
31
|
-
const extensions = [...customExtensions, ...builtInExtensions];
|
|
32
|
-
const protectedColumns = configs.protectedColumns?.config ?? {};
|
|
33
|
-
const stripProtectedPatchColumns = (tableName, data) => {
|
|
34
|
-
const protectedKeys = protectedColumns[tableName] ?? [];
|
|
35
|
-
if (protectedKeys.length === 0) {
|
|
36
|
-
return {
|
|
37
|
-
filteredData: data,
|
|
38
|
-
removedColumns: []
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
const removedColumns = protectedKeys.filter((key) => key in data).map(String);
|
|
42
|
-
if (removedColumns.length === 0) {
|
|
43
|
-
return {
|
|
44
|
-
filteredData: data,
|
|
45
|
-
removedColumns
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
const filteredData = Object.fromEntries(
|
|
49
|
-
Object.entries(data).filter(([key]) => !protectedKeys.includes(key))
|
|
50
|
-
);
|
|
51
|
-
return {
|
|
52
|
-
filteredData,
|
|
53
|
-
removedColumns
|
|
54
|
-
};
|
|
55
|
-
};
|
|
56
|
-
const insert = async (ctx, tableName, data, options) => {
|
|
57
|
-
let verifiedData = data;
|
|
58
|
-
if (configs.defaultValues) {
|
|
59
|
-
verifiedData = await configs.defaultValues.verify(tableName, verifiedData);
|
|
60
|
-
}
|
|
61
|
-
if (extensions.length > 0) {
|
|
62
|
-
verifiedData = await runExtensions(
|
|
63
|
-
extensions,
|
|
64
|
-
{
|
|
65
|
-
ctx,
|
|
66
|
-
tableName,
|
|
67
|
-
operation: "insert",
|
|
68
|
-
onFail: options?.onFail,
|
|
69
|
-
schema: _schema,
|
|
70
|
-
data: verifiedData
|
|
71
|
-
}
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
return await ctx.db.insert(tableName, verifiedData);
|
|
75
|
-
};
|
|
76
|
-
const patch = async (ctx, tableName, id, data, options) => {
|
|
77
|
-
let verifiedData = data;
|
|
78
|
-
const removedProtectedColumns = /* @__PURE__ */ new Set();
|
|
79
|
-
const stripProtectedColumns = () => {
|
|
80
|
-
const filtered = stripProtectedPatchColumns(tableName, verifiedData);
|
|
81
|
-
for (const column of filtered.removedColumns) {
|
|
82
|
-
removedProtectedColumns.add(column);
|
|
83
|
-
}
|
|
84
|
-
verifiedData = filtered.filteredData;
|
|
85
|
-
};
|
|
86
|
-
stripProtectedColumns();
|
|
87
|
-
if (extensions.length > 0) {
|
|
88
|
-
verifiedData = await runExtensions(
|
|
89
|
-
extensions,
|
|
90
|
-
{
|
|
91
|
-
ctx,
|
|
92
|
-
tableName,
|
|
93
|
-
operation: "patch",
|
|
94
|
-
patchId: id,
|
|
95
|
-
onFail: options?.onFail,
|
|
96
|
-
schema: _schema,
|
|
97
|
-
data: verifiedData
|
|
98
|
-
}
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
stripProtectedColumns();
|
|
102
|
-
if (removedProtectedColumns.size > 0) {
|
|
103
|
-
options?.onFail?.({
|
|
104
|
-
editableColumn: {
|
|
105
|
-
removedColumns: [...removedProtectedColumns],
|
|
106
|
-
filteredData: verifiedData
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
await ctx.db.patch(id, verifiedData);
|
|
111
|
-
};
|
|
112
|
-
const dangerouslyPatch = async (ctx, tableName, id, data, options) => {
|
|
113
|
-
let verifiedData = data;
|
|
114
|
-
if (extensions.length > 0) {
|
|
115
|
-
verifiedData = await runExtensions(
|
|
116
|
-
extensions,
|
|
117
|
-
{
|
|
118
|
-
ctx,
|
|
119
|
-
tableName,
|
|
120
|
-
operation: "patch",
|
|
121
|
-
patchId: id,
|
|
122
|
-
onFail: options?.onFail,
|
|
123
|
-
schema: _schema,
|
|
124
|
-
data: verifiedData
|
|
125
|
-
}
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
await ctx.db.patch(id, verifiedData);
|
|
129
|
-
};
|
|
130
|
-
return {
|
|
131
|
-
insert,
|
|
132
|
-
patch,
|
|
133
|
-
dangerouslyPatch
|
|
134
|
-
};
|
|
135
|
-
};
|
|
1
|
+
// src/core/builtins.ts
|
|
2
|
+
import { ConvexError } from "convex/values";
|
|
136
3
|
|
|
137
4
|
// src/core/types.ts
|
|
138
5
|
function normalizeIndexConfigEntry(entry, defaultIdentifiers = ["_id"]) {
|
|
@@ -150,33 +17,6 @@ function normalizeIndexConfigEntry(entry, defaultIdentifiers = ["_id"]) {
|
|
|
150
17
|
};
|
|
151
18
|
}
|
|
152
19
|
|
|
153
|
-
// src/transforms/defaultValuesConfig.ts
|
|
154
|
-
var defaultValuesConfig = (_schema, config) => {
|
|
155
|
-
const verify = async (tableName, data) => {
|
|
156
|
-
const resolvedConfig = typeof config === "function" ? await config() : config;
|
|
157
|
-
return {
|
|
158
|
-
...resolvedConfig[tableName],
|
|
159
|
-
...data
|
|
160
|
-
};
|
|
161
|
-
};
|
|
162
|
-
return {
|
|
163
|
-
_type: "defaultValues",
|
|
164
|
-
verify,
|
|
165
|
-
config
|
|
166
|
-
};
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
// src/configs/protectedColumnsConfig.ts
|
|
170
|
-
var protectedColumnsConfig = (_schema, config) => {
|
|
171
|
-
return {
|
|
172
|
-
_type: "protectedColumns",
|
|
173
|
-
config
|
|
174
|
-
};
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
// src/plugins/uniqueRowConfig.ts
|
|
178
|
-
import { ConvexError } from "convex/values";
|
|
179
|
-
|
|
180
20
|
// src/utils/helpers.ts
|
|
181
21
|
var getTableIndexes = (schema, tableName) => {
|
|
182
22
|
return schema.tables[tableName][" indexes"]();
|
|
@@ -189,7 +29,7 @@ var constructColumnData = (fields, data, {
|
|
|
189
29
|
const columnData = fields.map((_, index) => {
|
|
190
30
|
const column = fields?.[index];
|
|
191
31
|
const value = data?.[column];
|
|
192
|
-
if (!column || !allowNullishValue &&
|
|
32
|
+
if (!column || !allowNullishValue && (value === void 0 || value === null)) {
|
|
193
33
|
return;
|
|
194
34
|
}
|
|
195
35
|
return {
|
|
@@ -233,37 +73,108 @@ var constructIndexData = (schema, tableName, indexConfig) => {
|
|
|
233
73
|
});
|
|
234
74
|
};
|
|
235
75
|
|
|
236
|
-
// src/
|
|
237
|
-
var
|
|
76
|
+
// src/core/builtins.ts
|
|
77
|
+
var stripProtectedPatchColumns = (protectedColumns, tableName, data) => {
|
|
78
|
+
const protectedKeys = protectedColumns[tableName] ?? [];
|
|
79
|
+
if (protectedKeys.length === 0) {
|
|
80
|
+
return {
|
|
81
|
+
filteredData: data,
|
|
82
|
+
removedColumns: []
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const protectedKeyStrings = protectedKeys.map(String);
|
|
86
|
+
const protectedKeySet = new Set(protectedKeyStrings);
|
|
87
|
+
const removedColumns = protectedKeyStrings.filter((key) => key in data);
|
|
88
|
+
if (removedColumns.length === 0) {
|
|
89
|
+
return {
|
|
90
|
+
filteredData: data,
|
|
91
|
+
removedColumns
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
const filteredData = Object.fromEntries(
|
|
95
|
+
Object.entries(data).filter(([key]) => !protectedKeySet.has(key))
|
|
96
|
+
);
|
|
97
|
+
return {
|
|
98
|
+
filteredData,
|
|
99
|
+
removedColumns
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
var buildDefaultValuesVerifier = (config) => {
|
|
103
|
+
const verify = (async (...args) => {
|
|
104
|
+
const input = args.length === 2 ? {
|
|
105
|
+
tableName: args[0],
|
|
106
|
+
operation: "insert",
|
|
107
|
+
data: args[1]
|
|
108
|
+
} : args[0];
|
|
109
|
+
if (input.operation === "patch") {
|
|
110
|
+
return input.data;
|
|
111
|
+
}
|
|
112
|
+
const resolvedConfig = typeof config === "function" ? await config() : config;
|
|
113
|
+
return {
|
|
114
|
+
...resolvedConfig[input.tableName] ?? {},
|
|
115
|
+
...input.data
|
|
116
|
+
};
|
|
117
|
+
});
|
|
118
|
+
return {
|
|
119
|
+
_type: "defaultValues",
|
|
120
|
+
config,
|
|
121
|
+
verify
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
var buildProtectedColumnsVerifier = (config) => {
|
|
125
|
+
const verify = (async (...args) => {
|
|
126
|
+
const input = args.length === 2 ? {
|
|
127
|
+
tableName: args[0],
|
|
128
|
+
operation: "patch",
|
|
129
|
+
data: args[1]
|
|
130
|
+
} : args[0];
|
|
131
|
+
if (input.operation === "insert") {
|
|
132
|
+
return input.data;
|
|
133
|
+
}
|
|
134
|
+
return stripProtectedPatchColumns(config, input.tableName, input.data).filteredData;
|
|
135
|
+
});
|
|
136
|
+
return {
|
|
137
|
+
_type: "protectedColumns",
|
|
138
|
+
config,
|
|
139
|
+
verify
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
var buildUniqueRowVerifier = (schema, config) => {
|
|
238
143
|
const uniqueRowError = (message) => {
|
|
239
144
|
throw new ConvexError({
|
|
240
145
|
message,
|
|
241
146
|
code: "UNIQUE_ROW_VERIFICATION_ERROR"
|
|
242
147
|
});
|
|
243
148
|
};
|
|
244
|
-
const
|
|
245
|
-
const
|
|
149
|
+
const verify = (async (...args) => {
|
|
150
|
+
const input = args.length === 3 ? {
|
|
151
|
+
ctx: args[0],
|
|
152
|
+
tableName: args[1],
|
|
153
|
+
operation: "insert",
|
|
154
|
+
data: args[2]
|
|
155
|
+
} : args.length === 4 ? {
|
|
156
|
+
ctx: args[0],
|
|
157
|
+
tableName: args[1],
|
|
158
|
+
operation: "patch",
|
|
159
|
+
patchId: args[2],
|
|
160
|
+
data: args[3]
|
|
161
|
+
} : args[0];
|
|
162
|
+
const { ctx, tableName, operation, patchId, onFail, data } = input;
|
|
246
163
|
const indexesData = constructIndexData(schema, tableName, config);
|
|
247
|
-
if (!indexesData && !!config[tableName]) {
|
|
248
|
-
uniqueRowError(`Index data was not found where there should have been.`);
|
|
249
|
-
}
|
|
250
164
|
if (!indexesData) {
|
|
251
165
|
return data;
|
|
252
166
|
}
|
|
253
167
|
for (const indexInfo of indexesData) {
|
|
254
|
-
const { name, fields, identifiers
|
|
255
|
-
|
|
256
|
-
if (!fields[0] && !fields[1]) {
|
|
168
|
+
const { name, fields, identifiers } = indexInfo;
|
|
169
|
+
if (fields.length < 2) {
|
|
257
170
|
uniqueRowError(
|
|
258
|
-
`Error in 'verifyRowUniqueness()'. There must be two columns to test against. If you are attempting to enforce a unique column, use the '
|
|
171
|
+
`Error in 'verifyRowUniqueness()'. There must be two columns to test against. If you are attempting to enforce a unique column, use the 'uniqueColumn' config option.`
|
|
259
172
|
);
|
|
260
173
|
}
|
|
261
174
|
const columnData = constructColumnData(fields, data, {});
|
|
262
175
|
const getExisting = async (cd) => {
|
|
263
176
|
let existingByIndex = [];
|
|
264
|
-
if (
|
|
265
|
-
existingByIndex = [];
|
|
266
|
-
} else {
|
|
177
|
+
if (cd) {
|
|
267
178
|
existingByIndex = await ctx.db.query(tableName).withIndex(
|
|
268
179
|
name,
|
|
269
180
|
(q) => cd.reduce((query, { column, value }) => query.eq(column, value), q)
|
|
@@ -272,10 +183,10 @@ var uniqueRowConfig = (schema, config) => {
|
|
|
272
183
|
if (existingByIndex.length > 1) {
|
|
273
184
|
console.warn(
|
|
274
185
|
`There was more than one existing result found for index ${name}. Check the following IDs:`,
|
|
275
|
-
existingByIndex.map((
|
|
186
|
+
existingByIndex.map((row) => row._id)
|
|
276
187
|
);
|
|
277
188
|
console.warn(
|
|
278
|
-
|
|
189
|
+
"It is recommended that you triage the rows listed above since they have data that go against a rule of row uniqueness."
|
|
279
190
|
);
|
|
280
191
|
}
|
|
281
192
|
return existingByIndex.length > 0 ? existingByIndex[0] : null;
|
|
@@ -291,95 +202,89 @@ var uniqueRowConfig = (schema, config) => {
|
|
|
291
202
|
}
|
|
292
203
|
});
|
|
293
204
|
uniqueRowError(
|
|
294
|
-
`Unable to [${operation}] document. In table [${tableName}], there is an existing row that has the same data combination in the columns: [${fields.join(
|
|
205
|
+
`Unable to [${operation}] document. In table [${tableName}], there is an existing row that has the same data combination in the columns: [${fields.join(", ")}].`
|
|
295
206
|
);
|
|
296
207
|
}
|
|
297
|
-
if (
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
break;
|
|
308
|
-
}
|
|
208
|
+
if (!patchId) {
|
|
209
|
+
uniqueRowError("Unable to patch document without an id.");
|
|
210
|
+
}
|
|
211
|
+
const matchedToExisting = (_existing, _data) => {
|
|
212
|
+
let idMatchedToExisting = null;
|
|
213
|
+
if (_existing) {
|
|
214
|
+
for (const identifier of identifiers) {
|
|
215
|
+
if (_existing[identifier] !== void 0 && _data[identifier] !== void 0 && _existing[identifier] === _data[identifier] || identifier === "_id" && _existing[identifier] === patchId) {
|
|
216
|
+
idMatchedToExisting = String(identifier);
|
|
217
|
+
break;
|
|
309
218
|
}
|
|
310
219
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
uniqueRow: {
|
|
323
|
-
existingData: _existing
|
|
324
|
-
}
|
|
325
|
-
});
|
|
326
|
-
uniqueRowError(
|
|
327
|
-
`In '${tableName}' table, there already exists a value match of the columns: [${fields.join(`,`)}].`
|
|
328
|
-
);
|
|
329
|
-
}
|
|
330
|
-
};
|
|
331
|
-
if (!existing && !columnData && patchId) {
|
|
332
|
-
const match = await ctx.db.get(patchId);
|
|
333
|
-
if (!match) {
|
|
334
|
-
uniqueRowError(`No document found for id ${patchId}`);
|
|
335
|
-
return data;
|
|
336
|
-
}
|
|
337
|
-
const extensiveColumnData = constructColumnData(
|
|
338
|
-
fields,
|
|
339
|
-
{
|
|
340
|
-
...match,
|
|
341
|
-
...data
|
|
342
|
-
},
|
|
343
|
-
{}
|
|
344
|
-
);
|
|
345
|
-
if (extensiveColumnData) {
|
|
346
|
-
const extensiveExisting = await getExisting(extensiveColumnData);
|
|
347
|
-
checkExisting(extensiveExisting, data);
|
|
348
|
-
} else {
|
|
349
|
-
uniqueRowError(`Incomplete data when there should have been enough.`);
|
|
220
|
+
}
|
|
221
|
+
return idMatchedToExisting;
|
|
222
|
+
};
|
|
223
|
+
const checkExisting = (_existing, _data) => {
|
|
224
|
+
const matchedId = matchedToExisting(_existing, _data);
|
|
225
|
+
if (!_existing || matchedId) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
onFail?.({
|
|
229
|
+
uniqueRow: {
|
|
230
|
+
existingData: _existing
|
|
350
231
|
}
|
|
351
|
-
}
|
|
352
|
-
|
|
232
|
+
});
|
|
233
|
+
uniqueRowError(
|
|
234
|
+
`In '${tableName}' table, there already exists a value match of the columns: [${fields.join(",")}].`
|
|
235
|
+
);
|
|
236
|
+
};
|
|
237
|
+
if (!existing && !columnData) {
|
|
238
|
+
const match = await ctx.db.get(patchId);
|
|
239
|
+
if (!match) {
|
|
240
|
+
uniqueRowError(`No document found for id ${patchId}`);
|
|
241
|
+
}
|
|
242
|
+
const extensiveColumnData = constructColumnData(
|
|
243
|
+
fields,
|
|
244
|
+
{
|
|
245
|
+
...match,
|
|
246
|
+
...data
|
|
247
|
+
},
|
|
248
|
+
{}
|
|
249
|
+
);
|
|
250
|
+
if (!extensiveColumnData) {
|
|
251
|
+
uniqueRowError("Incomplete data when there should have been enough.");
|
|
353
252
|
}
|
|
253
|
+
const extensiveExisting = await getExisting(extensiveColumnData);
|
|
254
|
+
checkExisting(extensiveExisting, data);
|
|
255
|
+
continue;
|
|
354
256
|
}
|
|
257
|
+
checkExisting(existing, data);
|
|
355
258
|
}
|
|
356
259
|
return data;
|
|
357
|
-
};
|
|
358
|
-
|
|
260
|
+
});
|
|
261
|
+
return {
|
|
359
262
|
_type: "uniqueRow",
|
|
360
263
|
config,
|
|
361
|
-
|
|
362
|
-
return await verifyUniqueness(
|
|
363
|
-
input,
|
|
364
|
-
input.data,
|
|
365
|
-
input.tableName
|
|
366
|
-
);
|
|
367
|
-
}
|
|
264
|
+
verify
|
|
368
265
|
};
|
|
369
|
-
return extension;
|
|
370
266
|
};
|
|
371
|
-
|
|
372
|
-
// src/plugins/uniqueColumnConfig.ts
|
|
373
|
-
import { ConvexError as ConvexError2 } from "convex/values";
|
|
374
|
-
var uniqueColumnConfig = (_schema, config) => {
|
|
267
|
+
var buildUniqueColumnVerifier = (config) => {
|
|
375
268
|
const uniqueColumnError = (message) => {
|
|
376
|
-
throw new
|
|
269
|
+
throw new ConvexError({
|
|
377
270
|
message,
|
|
378
271
|
code: "UNIQUE_COLUMN_VERIFICATION_ERROR"
|
|
379
272
|
});
|
|
380
273
|
};
|
|
381
|
-
const
|
|
382
|
-
const
|
|
274
|
+
const verify = (async (...args) => {
|
|
275
|
+
const input = args.length === 3 ? {
|
|
276
|
+
ctx: args[0],
|
|
277
|
+
tableName: args[1],
|
|
278
|
+
operation: "insert",
|
|
279
|
+
data: args[2]
|
|
280
|
+
} : args.length === 4 ? {
|
|
281
|
+
ctx: args[0],
|
|
282
|
+
tableName: args[1],
|
|
283
|
+
operation: "patch",
|
|
284
|
+
patchId: args[2],
|
|
285
|
+
data: args[3]
|
|
286
|
+
} : args[0];
|
|
287
|
+
const { ctx, tableName, patchId, onFail, data } = input;
|
|
383
288
|
const tableConfig = config[tableName];
|
|
384
289
|
if (!tableConfig) {
|
|
385
290
|
return data;
|
|
@@ -403,9 +308,7 @@ var uniqueColumnConfig = (_schema, config) => {
|
|
|
403
308
|
isOwnDocument = true;
|
|
404
309
|
break;
|
|
405
310
|
}
|
|
406
|
-
|
|
407
|
-
const incomingValue = data[identifier];
|
|
408
|
-
if (existingValue !== void 0 && incomingValue !== void 0 && existingValue === incomingValue) {
|
|
311
|
+
if (existing[identifier] !== void 0 && data[identifier] !== void 0 && existing[identifier] === data[identifier]) {
|
|
409
312
|
isOwnDocument = true;
|
|
410
313
|
break;
|
|
411
314
|
}
|
|
@@ -424,31 +327,239 @@ var uniqueColumnConfig = (_schema, config) => {
|
|
|
424
327
|
);
|
|
425
328
|
}
|
|
426
329
|
return data;
|
|
427
|
-
};
|
|
428
|
-
|
|
330
|
+
});
|
|
331
|
+
return {
|
|
429
332
|
_type: "uniqueColumn",
|
|
430
333
|
config,
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
334
|
+
verify
|
|
335
|
+
};
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
// src/core/plugin.ts
|
|
339
|
+
function createExtension(schemaOrVerify, verify) {
|
|
340
|
+
const extensionVerify = typeof verify === "function" ? verify : schemaOrVerify;
|
|
341
|
+
return {
|
|
342
|
+
_type: "extension",
|
|
343
|
+
verify(input) {
|
|
344
|
+
return extensionVerify(input);
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
function isExtension(value) {
|
|
349
|
+
return typeof value === "object" && value !== null && "verify" in value && typeof value.verify === "function";
|
|
350
|
+
}
|
|
351
|
+
async function runExtensions(extensions, input) {
|
|
352
|
+
let verifiedData = input.data;
|
|
353
|
+
for (const extension of extensions) {
|
|
354
|
+
verifiedData = await extension.verify({
|
|
355
|
+
...input,
|
|
356
|
+
data: verifiedData
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
return verifiedData;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// src/core/verifyConfig.ts
|
|
363
|
+
var verifyConfig = (_schema, configs) => {
|
|
364
|
+
const builtins = {
|
|
365
|
+
...configs.defaultValues ? {
|
|
366
|
+
defaultValues: buildDefaultValuesVerifier(configs.defaultValues)
|
|
367
|
+
} : {},
|
|
368
|
+
...configs.protectedColumns ? {
|
|
369
|
+
protectedColumns: buildProtectedColumnsVerifier(configs.protectedColumns)
|
|
370
|
+
} : {},
|
|
371
|
+
...configs.uniqueRow ? {
|
|
372
|
+
uniqueRow: buildUniqueRowVerifier(
|
|
373
|
+
_schema,
|
|
374
|
+
configs.uniqueRow
|
|
375
|
+
)
|
|
376
|
+
} : {},
|
|
377
|
+
...configs.uniqueColumn ? {
|
|
378
|
+
uniqueColumn: buildUniqueColumnVerifier(configs.uniqueColumn)
|
|
379
|
+
} : {}
|
|
380
|
+
};
|
|
381
|
+
const verify = {
|
|
382
|
+
...builtins.defaultValues ? { defaultValues: builtins.defaultValues.verify } : {},
|
|
383
|
+
...builtins.protectedColumns ? { protectedColumns: builtins.protectedColumns.verify } : {},
|
|
384
|
+
...builtins.uniqueRow ? { uniqueRow: builtins.uniqueRow.verify } : {},
|
|
385
|
+
...builtins.uniqueColumn ? { uniqueColumn: builtins.uniqueColumn.verify } : {}
|
|
386
|
+
};
|
|
387
|
+
const config = {
|
|
388
|
+
...configs.defaultValues ? { defaultValues: configs.defaultValues } : {},
|
|
389
|
+
...configs.protectedColumns ? { protectedColumns: configs.protectedColumns } : {},
|
|
390
|
+
...configs.uniqueRow ? { uniqueRow: configs.uniqueRow } : {},
|
|
391
|
+
...configs.uniqueColumn ? { uniqueColumn: configs.uniqueColumn } : {}
|
|
392
|
+
};
|
|
393
|
+
const customExtensions = configs.extensions ?? [];
|
|
394
|
+
const insert = async (ctx, tableName, data, options) => {
|
|
395
|
+
let verifiedData = data;
|
|
396
|
+
if (builtins.defaultValues) {
|
|
397
|
+
verifiedData = await builtins.defaultValues.verify({
|
|
398
|
+
ctx,
|
|
399
|
+
tableName,
|
|
400
|
+
operation: "insert",
|
|
401
|
+
onFail: options?.onFail,
|
|
402
|
+
schema: _schema,
|
|
403
|
+
data: verifiedData
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
if (customExtensions.length > 0) {
|
|
407
|
+
verifiedData = await runExtensions(customExtensions, {
|
|
408
|
+
ctx,
|
|
409
|
+
tableName,
|
|
410
|
+
operation: "insert",
|
|
411
|
+
onFail: options?.onFail,
|
|
412
|
+
schema: _schema,
|
|
413
|
+
data: verifiedData
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
if (builtins.uniqueRow) {
|
|
417
|
+
verifiedData = await builtins.uniqueRow.verify({
|
|
418
|
+
ctx,
|
|
419
|
+
tableName,
|
|
420
|
+
operation: "insert",
|
|
421
|
+
onFail: options?.onFail,
|
|
422
|
+
schema: _schema,
|
|
423
|
+
data: verifiedData
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
if (builtins.uniqueColumn) {
|
|
427
|
+
verifiedData = await builtins.uniqueColumn.verify({
|
|
428
|
+
ctx,
|
|
429
|
+
tableName,
|
|
430
|
+
operation: "insert",
|
|
431
|
+
onFail: options?.onFail,
|
|
432
|
+
schema: _schema,
|
|
433
|
+
data: verifiedData
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
return await ctx.db.insert(tableName, verifiedData);
|
|
437
|
+
};
|
|
438
|
+
const patch = async (ctx, tableName, id, data, options) => {
|
|
439
|
+
let verifiedData = data;
|
|
440
|
+
const removedProtectedColumns = /* @__PURE__ */ new Set();
|
|
441
|
+
const stripProtectedColumns = () => {
|
|
442
|
+
if (!builtins.protectedColumns) {
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
const filtered = stripProtectedPatchColumns(
|
|
446
|
+
builtins.protectedColumns.config,
|
|
447
|
+
tableName,
|
|
448
|
+
verifiedData
|
|
435
449
|
);
|
|
450
|
+
for (const column of filtered.removedColumns) {
|
|
451
|
+
removedProtectedColumns.add(column);
|
|
452
|
+
}
|
|
453
|
+
verifiedData = filtered.filteredData;
|
|
454
|
+
};
|
|
455
|
+
stripProtectedColumns();
|
|
456
|
+
if (customExtensions.length > 0) {
|
|
457
|
+
verifiedData = await runExtensions(customExtensions, {
|
|
458
|
+
ctx,
|
|
459
|
+
tableName,
|
|
460
|
+
operation: "patch",
|
|
461
|
+
patchId: id,
|
|
462
|
+
onFail: options?.onFail,
|
|
463
|
+
schema: _schema,
|
|
464
|
+
data: verifiedData
|
|
465
|
+
});
|
|
436
466
|
}
|
|
467
|
+
if (builtins.uniqueRow) {
|
|
468
|
+
verifiedData = await builtins.uniqueRow.verify({
|
|
469
|
+
ctx,
|
|
470
|
+
tableName,
|
|
471
|
+
operation: "patch",
|
|
472
|
+
patchId: id,
|
|
473
|
+
onFail: options?.onFail,
|
|
474
|
+
schema: _schema,
|
|
475
|
+
data: verifiedData
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
if (builtins.uniqueColumn) {
|
|
479
|
+
verifiedData = await builtins.uniqueColumn.verify({
|
|
480
|
+
ctx,
|
|
481
|
+
tableName,
|
|
482
|
+
operation: "patch",
|
|
483
|
+
patchId: id,
|
|
484
|
+
onFail: options?.onFail,
|
|
485
|
+
schema: _schema,
|
|
486
|
+
data: verifiedData
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
stripProtectedColumns();
|
|
490
|
+
if (removedProtectedColumns.size > 0) {
|
|
491
|
+
options?.onFail?.({
|
|
492
|
+
editableColumn: {
|
|
493
|
+
removedColumns: [...removedProtectedColumns],
|
|
494
|
+
filteredData: verifiedData
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
await ctx.db.patch(id, verifiedData);
|
|
499
|
+
};
|
|
500
|
+
const dangerouslyPatch = async (ctx, tableName, id, data, options) => {
|
|
501
|
+
let verifiedData = data;
|
|
502
|
+
if (customExtensions.length > 0) {
|
|
503
|
+
verifiedData = await runExtensions(customExtensions, {
|
|
504
|
+
ctx,
|
|
505
|
+
tableName,
|
|
506
|
+
operation: "patch",
|
|
507
|
+
patchId: id,
|
|
508
|
+
onFail: options?.onFail,
|
|
509
|
+
schema: _schema,
|
|
510
|
+
data: verifiedData
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
if (builtins.uniqueRow) {
|
|
514
|
+
verifiedData = await builtins.uniqueRow.verify({
|
|
515
|
+
ctx,
|
|
516
|
+
tableName,
|
|
517
|
+
operation: "patch",
|
|
518
|
+
patchId: id,
|
|
519
|
+
onFail: options?.onFail,
|
|
520
|
+
schema: _schema,
|
|
521
|
+
data: verifiedData
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
if (builtins.uniqueColumn) {
|
|
525
|
+
verifiedData = await builtins.uniqueColumn.verify({
|
|
526
|
+
ctx,
|
|
527
|
+
tableName,
|
|
528
|
+
operation: "patch",
|
|
529
|
+
patchId: id,
|
|
530
|
+
onFail: options?.onFail,
|
|
531
|
+
schema: _schema,
|
|
532
|
+
data: verifiedData
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
await ctx.db.patch(id, verifiedData);
|
|
536
|
+
};
|
|
537
|
+
return {
|
|
538
|
+
insert,
|
|
539
|
+
patch,
|
|
540
|
+
dangerouslyPatch,
|
|
541
|
+
verify,
|
|
542
|
+
config
|
|
437
543
|
};
|
|
438
|
-
return extension;
|
|
439
544
|
};
|
|
545
|
+
|
|
546
|
+
// src/core/index.ts
|
|
547
|
+
var createExtension2 = createExtension;
|
|
548
|
+
var isExtension2 = isExtension;
|
|
549
|
+
var runExtensions2 = runExtensions;
|
|
550
|
+
|
|
551
|
+
// src/index.ts
|
|
552
|
+
var createExtension3 = createExtension2;
|
|
553
|
+
var isExtension3 = isExtension2;
|
|
554
|
+
var runExtensions3 = runExtensions2;
|
|
440
555
|
export {
|
|
441
556
|
constructColumnData,
|
|
442
557
|
constructIndexData,
|
|
443
|
-
createExtension,
|
|
444
|
-
defaultValuesConfig,
|
|
558
|
+
createExtension3 as createExtension,
|
|
445
559
|
getTableIndexes,
|
|
446
|
-
isExtension,
|
|
560
|
+
isExtension3 as isExtension,
|
|
447
561
|
normalizeIndexConfigEntry,
|
|
448
|
-
|
|
449
|
-
runExtensions,
|
|
450
|
-
uniqueColumnConfig,
|
|
451
|
-
uniqueRowConfig,
|
|
562
|
+
runExtensions3 as runExtensions,
|
|
452
563
|
verifyConfig
|
|
453
564
|
};
|
|
454
565
|
//# sourceMappingURL=index.mjs.map
|