@flaredev/core 0.1.1 → 0.2.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/chunk-434JXSDV.js +410 -0
- package/dist/index.d.ts +39 -39
- package/dist/index.js +63 -81
- package/dist/{define-D5CtCkOm.d.ts → policy-BqRg9RVM.d.ts} +80 -4
- package/dist/server.d.ts +29 -2
- package/dist/server.js +1448 -3
- package/package.json +2 -13
- package/dist/chunk-DARDHZPX.js +0 -192
package/dist/server.js
CHANGED
|
@@ -1,10 +1,1190 @@
|
|
|
1
1
|
import {
|
|
2
|
+
can,
|
|
2
3
|
createValidators,
|
|
3
4
|
storedFields
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-434JXSDV.js";
|
|
5
6
|
|
|
6
|
-
//
|
|
7
|
-
|
|
7
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/entity.js
|
|
8
|
+
var entityKind = /* @__PURE__ */ Symbol.for("drizzle:entityKind");
|
|
9
|
+
function is(value, type) {
|
|
10
|
+
if (!value || typeof value !== "object") {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
if (value instanceof type) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
if (!Object.prototype.hasOwnProperty.call(type, entityKind)) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Class "${type.name ?? "<unknown>"}" doesn't look like a Drizzle entity. If this is incorrect and the class is provided by Drizzle, please report this as a bug.`
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
let cls = Object.getPrototypeOf(value).constructor;
|
|
22
|
+
if (cls) {
|
|
23
|
+
while (cls) {
|
|
24
|
+
if (entityKind in cls && cls[entityKind] === type[entityKind]) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
cls = Object.getPrototypeOf(cls);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/column.js
|
|
34
|
+
var Column = class {
|
|
35
|
+
constructor(table, config) {
|
|
36
|
+
this.table = table;
|
|
37
|
+
this.config = config;
|
|
38
|
+
this.name = config.name;
|
|
39
|
+
this.keyAsName = config.keyAsName;
|
|
40
|
+
this.notNull = config.notNull;
|
|
41
|
+
this.default = config.default;
|
|
42
|
+
this.defaultFn = config.defaultFn;
|
|
43
|
+
this.onUpdateFn = config.onUpdateFn;
|
|
44
|
+
this.hasDefault = config.hasDefault;
|
|
45
|
+
this.primary = config.primaryKey;
|
|
46
|
+
this.isUnique = config.isUnique;
|
|
47
|
+
this.uniqueName = config.uniqueName;
|
|
48
|
+
this.uniqueType = config.uniqueType;
|
|
49
|
+
this.dataType = config.dataType;
|
|
50
|
+
this.columnType = config.columnType;
|
|
51
|
+
this.generated = config.generated;
|
|
52
|
+
this.generatedIdentity = config.generatedIdentity;
|
|
53
|
+
}
|
|
54
|
+
static [entityKind] = "Column";
|
|
55
|
+
name;
|
|
56
|
+
keyAsName;
|
|
57
|
+
primary;
|
|
58
|
+
notNull;
|
|
59
|
+
default;
|
|
60
|
+
defaultFn;
|
|
61
|
+
onUpdateFn;
|
|
62
|
+
hasDefault;
|
|
63
|
+
isUnique;
|
|
64
|
+
uniqueName;
|
|
65
|
+
uniqueType;
|
|
66
|
+
dataType;
|
|
67
|
+
columnType;
|
|
68
|
+
enumValues = void 0;
|
|
69
|
+
generated = void 0;
|
|
70
|
+
generatedIdentity = void 0;
|
|
71
|
+
config;
|
|
72
|
+
mapFromDriverValue(value) {
|
|
73
|
+
return value;
|
|
74
|
+
}
|
|
75
|
+
mapToDriverValue(value) {
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
// ** @internal */
|
|
79
|
+
shouldDisableInsert() {
|
|
80
|
+
return this.config.generated !== void 0 && this.config.generated.type !== "byDefault";
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/column-builder.js
|
|
85
|
+
var ColumnBuilder = class {
|
|
86
|
+
static [entityKind] = "ColumnBuilder";
|
|
87
|
+
config;
|
|
88
|
+
constructor(name, dataType, columnType) {
|
|
89
|
+
this.config = {
|
|
90
|
+
name,
|
|
91
|
+
keyAsName: name === "",
|
|
92
|
+
notNull: false,
|
|
93
|
+
default: void 0,
|
|
94
|
+
hasDefault: false,
|
|
95
|
+
primaryKey: false,
|
|
96
|
+
isUnique: false,
|
|
97
|
+
uniqueName: void 0,
|
|
98
|
+
uniqueType: void 0,
|
|
99
|
+
dataType,
|
|
100
|
+
columnType,
|
|
101
|
+
generated: void 0
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Changes the data type of the column. Commonly used with `json` columns. Also, useful for branded types.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* const users = pgTable('users', {
|
|
110
|
+
* id: integer('id').$type<UserId>().primaryKey(),
|
|
111
|
+
* details: json('details').$type<UserDetails>().notNull(),
|
|
112
|
+
* });
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
$type() {
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Adds a `not null` clause to the column definition.
|
|
120
|
+
*
|
|
121
|
+
* Affects the `select` model of the table - columns *without* `not null` will be nullable on select.
|
|
122
|
+
*/
|
|
123
|
+
notNull() {
|
|
124
|
+
this.config.notNull = true;
|
|
125
|
+
return this;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Adds a `default <value>` clause to the column definition.
|
|
129
|
+
*
|
|
130
|
+
* Affects the `insert` model of the table - columns *with* `default` are optional on insert.
|
|
131
|
+
*
|
|
132
|
+
* If you need to set a dynamic default value, use {@link $defaultFn} instead.
|
|
133
|
+
*/
|
|
134
|
+
default(value) {
|
|
135
|
+
this.config.default = value;
|
|
136
|
+
this.config.hasDefault = true;
|
|
137
|
+
return this;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Adds a dynamic default value to the column.
|
|
141
|
+
* The function will be called when the row is inserted, and the returned value will be used as the column value.
|
|
142
|
+
*
|
|
143
|
+
* **Note:** This value does not affect the `drizzle-kit` behavior, it is only used at runtime in `drizzle-orm`.
|
|
144
|
+
*/
|
|
145
|
+
$defaultFn(fn) {
|
|
146
|
+
this.config.defaultFn = fn;
|
|
147
|
+
this.config.hasDefault = true;
|
|
148
|
+
return this;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Alias for {@link $defaultFn}.
|
|
152
|
+
*/
|
|
153
|
+
$default = this.$defaultFn;
|
|
154
|
+
/**
|
|
155
|
+
* Adds a dynamic update value to the column.
|
|
156
|
+
* The function will be called when the row is updated, and the returned value will be used as the column value if none is provided.
|
|
157
|
+
* If no `default` (or `$defaultFn`) value is provided, the function will be called when the row is inserted as well, and the returned value will be used as the column value.
|
|
158
|
+
*
|
|
159
|
+
* **Note:** This value does not affect the `drizzle-kit` behavior, it is only used at runtime in `drizzle-orm`.
|
|
160
|
+
*/
|
|
161
|
+
$onUpdateFn(fn) {
|
|
162
|
+
this.config.onUpdateFn = fn;
|
|
163
|
+
this.config.hasDefault = true;
|
|
164
|
+
return this;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Alias for {@link $onUpdateFn}.
|
|
168
|
+
*/
|
|
169
|
+
$onUpdate = this.$onUpdateFn;
|
|
170
|
+
/**
|
|
171
|
+
* Adds a `primary key` clause to the column definition. This implicitly makes the column `not null`.
|
|
172
|
+
*
|
|
173
|
+
* In SQLite, `integer primary key` implicitly makes the column auto-incrementing.
|
|
174
|
+
*/
|
|
175
|
+
primaryKey() {
|
|
176
|
+
this.config.primaryKey = true;
|
|
177
|
+
this.config.notNull = true;
|
|
178
|
+
return this;
|
|
179
|
+
}
|
|
180
|
+
/** @internal Sets the name of the column to the key within the table definition if a name was not given. */
|
|
181
|
+
setName(name) {
|
|
182
|
+
if (this.config.name !== "") return;
|
|
183
|
+
this.config.name = name;
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/table.utils.js
|
|
188
|
+
var TableName = /* @__PURE__ */ Symbol.for("drizzle:Name");
|
|
189
|
+
|
|
190
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/pg-core/foreign-keys.js
|
|
191
|
+
var ForeignKeyBuilder = class {
|
|
192
|
+
static [entityKind] = "PgForeignKeyBuilder";
|
|
193
|
+
/** @internal */
|
|
194
|
+
reference;
|
|
195
|
+
/** @internal */
|
|
196
|
+
_onUpdate = "no action";
|
|
197
|
+
/** @internal */
|
|
198
|
+
_onDelete = "no action";
|
|
199
|
+
constructor(config, actions) {
|
|
200
|
+
this.reference = () => {
|
|
201
|
+
const { name, columns, foreignColumns } = config();
|
|
202
|
+
return { name, columns, foreignTable: foreignColumns[0].table, foreignColumns };
|
|
203
|
+
};
|
|
204
|
+
if (actions) {
|
|
205
|
+
this._onUpdate = actions.onUpdate;
|
|
206
|
+
this._onDelete = actions.onDelete;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
onUpdate(action) {
|
|
210
|
+
this._onUpdate = action === void 0 ? "no action" : action;
|
|
211
|
+
return this;
|
|
212
|
+
}
|
|
213
|
+
onDelete(action) {
|
|
214
|
+
this._onDelete = action === void 0 ? "no action" : action;
|
|
215
|
+
return this;
|
|
216
|
+
}
|
|
217
|
+
/** @internal */
|
|
218
|
+
build(table) {
|
|
219
|
+
return new ForeignKey(table, this);
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
var ForeignKey = class {
|
|
223
|
+
constructor(table, builder) {
|
|
224
|
+
this.table = table;
|
|
225
|
+
this.reference = builder.reference;
|
|
226
|
+
this.onUpdate = builder._onUpdate;
|
|
227
|
+
this.onDelete = builder._onDelete;
|
|
228
|
+
}
|
|
229
|
+
static [entityKind] = "PgForeignKey";
|
|
230
|
+
reference;
|
|
231
|
+
onUpdate;
|
|
232
|
+
onDelete;
|
|
233
|
+
getName() {
|
|
234
|
+
const { name, columns, foreignColumns } = this.reference();
|
|
235
|
+
const columnNames = columns.map((column) => column.name);
|
|
236
|
+
const foreignColumnNames = foreignColumns.map((column) => column.name);
|
|
237
|
+
const chunks = [
|
|
238
|
+
this.table[TableName],
|
|
239
|
+
...columnNames,
|
|
240
|
+
foreignColumns[0].table[TableName],
|
|
241
|
+
...foreignColumnNames
|
|
242
|
+
];
|
|
243
|
+
return name ?? `${chunks.join("_")}_fk`;
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/tracing-utils.js
|
|
248
|
+
function iife(fn, ...args) {
|
|
249
|
+
return fn(...args);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/pg-core/unique-constraint.js
|
|
253
|
+
function uniqueKeyName(table, columns) {
|
|
254
|
+
return `${table[TableName]}_${columns.join("_")}_unique`;
|
|
255
|
+
}
|
|
256
|
+
var UniqueConstraintBuilder = class {
|
|
257
|
+
constructor(columns, name) {
|
|
258
|
+
this.name = name;
|
|
259
|
+
this.columns = columns;
|
|
260
|
+
}
|
|
261
|
+
static [entityKind] = "PgUniqueConstraintBuilder";
|
|
262
|
+
/** @internal */
|
|
263
|
+
columns;
|
|
264
|
+
/** @internal */
|
|
265
|
+
nullsNotDistinctConfig = false;
|
|
266
|
+
nullsNotDistinct() {
|
|
267
|
+
this.nullsNotDistinctConfig = true;
|
|
268
|
+
return this;
|
|
269
|
+
}
|
|
270
|
+
/** @internal */
|
|
271
|
+
build(table) {
|
|
272
|
+
return new UniqueConstraint(table, this.columns, this.nullsNotDistinctConfig, this.name);
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
var UniqueOnConstraintBuilder = class {
|
|
276
|
+
static [entityKind] = "PgUniqueOnConstraintBuilder";
|
|
277
|
+
/** @internal */
|
|
278
|
+
name;
|
|
279
|
+
constructor(name) {
|
|
280
|
+
this.name = name;
|
|
281
|
+
}
|
|
282
|
+
on(...columns) {
|
|
283
|
+
return new UniqueConstraintBuilder(columns, this.name);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
var UniqueConstraint = class {
|
|
287
|
+
constructor(table, columns, nullsNotDistinct, name) {
|
|
288
|
+
this.table = table;
|
|
289
|
+
this.columns = columns;
|
|
290
|
+
this.name = name ?? uniqueKeyName(this.table, this.columns.map((column) => column.name));
|
|
291
|
+
this.nullsNotDistinct = nullsNotDistinct;
|
|
292
|
+
}
|
|
293
|
+
static [entityKind] = "PgUniqueConstraint";
|
|
294
|
+
columns;
|
|
295
|
+
name;
|
|
296
|
+
nullsNotDistinct = false;
|
|
297
|
+
getName() {
|
|
298
|
+
return this.name;
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/pg-core/utils/array.js
|
|
303
|
+
function parsePgArrayValue(arrayString, startFrom, inQuotes) {
|
|
304
|
+
for (let i = startFrom; i < arrayString.length; i++) {
|
|
305
|
+
const char = arrayString[i];
|
|
306
|
+
if (char === "\\") {
|
|
307
|
+
i++;
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
if (char === '"') {
|
|
311
|
+
return [arrayString.slice(startFrom, i).replace(/\\/g, ""), i + 1];
|
|
312
|
+
}
|
|
313
|
+
if (inQuotes) {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
if (char === "," || char === "}") {
|
|
317
|
+
return [arrayString.slice(startFrom, i).replace(/\\/g, ""), i];
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return [arrayString.slice(startFrom).replace(/\\/g, ""), arrayString.length];
|
|
321
|
+
}
|
|
322
|
+
function parsePgNestedArray(arrayString, startFrom = 0) {
|
|
323
|
+
const result = [];
|
|
324
|
+
let i = startFrom;
|
|
325
|
+
let lastCharIsComma = false;
|
|
326
|
+
while (i < arrayString.length) {
|
|
327
|
+
const char = arrayString[i];
|
|
328
|
+
if (char === ",") {
|
|
329
|
+
if (lastCharIsComma || i === startFrom) {
|
|
330
|
+
result.push("");
|
|
331
|
+
}
|
|
332
|
+
lastCharIsComma = true;
|
|
333
|
+
i++;
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
lastCharIsComma = false;
|
|
337
|
+
if (char === "\\") {
|
|
338
|
+
i += 2;
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
if (char === '"') {
|
|
342
|
+
const [value2, startFrom2] = parsePgArrayValue(arrayString, i + 1, true);
|
|
343
|
+
result.push(value2);
|
|
344
|
+
i = startFrom2;
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
if (char === "}") {
|
|
348
|
+
return [result, i + 1];
|
|
349
|
+
}
|
|
350
|
+
if (char === "{") {
|
|
351
|
+
const [value2, startFrom2] = parsePgNestedArray(arrayString, i + 1);
|
|
352
|
+
result.push(value2);
|
|
353
|
+
i = startFrom2;
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
const [value, newStartFrom] = parsePgArrayValue(arrayString, i, false);
|
|
357
|
+
result.push(value);
|
|
358
|
+
i = newStartFrom;
|
|
359
|
+
}
|
|
360
|
+
return [result, i];
|
|
361
|
+
}
|
|
362
|
+
function parsePgArray(arrayString) {
|
|
363
|
+
const [result] = parsePgNestedArray(arrayString, 1);
|
|
364
|
+
return result;
|
|
365
|
+
}
|
|
366
|
+
function makePgArray(array) {
|
|
367
|
+
return `{${array.map((item) => {
|
|
368
|
+
if (Array.isArray(item)) {
|
|
369
|
+
return makePgArray(item);
|
|
370
|
+
}
|
|
371
|
+
if (typeof item === "string") {
|
|
372
|
+
return `"${item.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
373
|
+
}
|
|
374
|
+
return `${item}`;
|
|
375
|
+
}).join(",")}}`;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/pg-core/columns/common.js
|
|
379
|
+
var PgColumnBuilder = class extends ColumnBuilder {
|
|
380
|
+
foreignKeyConfigs = [];
|
|
381
|
+
static [entityKind] = "PgColumnBuilder";
|
|
382
|
+
array(size) {
|
|
383
|
+
return new PgArrayBuilder(this.config.name, this, size);
|
|
384
|
+
}
|
|
385
|
+
references(ref2, actions = {}) {
|
|
386
|
+
this.foreignKeyConfigs.push({ ref: ref2, actions });
|
|
387
|
+
return this;
|
|
388
|
+
}
|
|
389
|
+
unique(name, config) {
|
|
390
|
+
this.config.isUnique = true;
|
|
391
|
+
this.config.uniqueName = name;
|
|
392
|
+
this.config.uniqueType = config?.nulls;
|
|
393
|
+
return this;
|
|
394
|
+
}
|
|
395
|
+
generatedAlwaysAs(as) {
|
|
396
|
+
this.config.generated = {
|
|
397
|
+
as,
|
|
398
|
+
type: "always",
|
|
399
|
+
mode: "stored"
|
|
400
|
+
};
|
|
401
|
+
return this;
|
|
402
|
+
}
|
|
403
|
+
/** @internal */
|
|
404
|
+
buildForeignKeys(column, table) {
|
|
405
|
+
return this.foreignKeyConfigs.map(({ ref: ref2, actions }) => {
|
|
406
|
+
return iife(
|
|
407
|
+
(ref22, actions2) => {
|
|
408
|
+
const builder = new ForeignKeyBuilder(() => {
|
|
409
|
+
const foreignColumn = ref22();
|
|
410
|
+
return { columns: [column], foreignColumns: [foreignColumn] };
|
|
411
|
+
});
|
|
412
|
+
if (actions2.onUpdate) {
|
|
413
|
+
builder.onUpdate(actions2.onUpdate);
|
|
414
|
+
}
|
|
415
|
+
if (actions2.onDelete) {
|
|
416
|
+
builder.onDelete(actions2.onDelete);
|
|
417
|
+
}
|
|
418
|
+
return builder.build(table);
|
|
419
|
+
},
|
|
420
|
+
ref2,
|
|
421
|
+
actions
|
|
422
|
+
);
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
/** @internal */
|
|
426
|
+
buildExtraConfigColumn(table) {
|
|
427
|
+
return new ExtraConfigColumn(table, this.config);
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
var PgColumn = class extends Column {
|
|
431
|
+
constructor(table, config) {
|
|
432
|
+
if (!config.uniqueName) {
|
|
433
|
+
config.uniqueName = uniqueKeyName(table, [config.name]);
|
|
434
|
+
}
|
|
435
|
+
super(table, config);
|
|
436
|
+
this.table = table;
|
|
437
|
+
}
|
|
438
|
+
static [entityKind] = "PgColumn";
|
|
439
|
+
};
|
|
440
|
+
var ExtraConfigColumn = class extends PgColumn {
|
|
441
|
+
static [entityKind] = "ExtraConfigColumn";
|
|
442
|
+
getSQLType() {
|
|
443
|
+
return this.getSQLType();
|
|
444
|
+
}
|
|
445
|
+
indexConfig = {
|
|
446
|
+
order: this.config.order ?? "asc",
|
|
447
|
+
nulls: this.config.nulls ?? "last",
|
|
448
|
+
opClass: this.config.opClass
|
|
449
|
+
};
|
|
450
|
+
defaultConfig = {
|
|
451
|
+
order: "asc",
|
|
452
|
+
nulls: "last",
|
|
453
|
+
opClass: void 0
|
|
454
|
+
};
|
|
455
|
+
asc() {
|
|
456
|
+
this.indexConfig.order = "asc";
|
|
457
|
+
return this;
|
|
458
|
+
}
|
|
459
|
+
desc() {
|
|
460
|
+
this.indexConfig.order = "desc";
|
|
461
|
+
return this;
|
|
462
|
+
}
|
|
463
|
+
nullsFirst() {
|
|
464
|
+
this.indexConfig.nulls = "first";
|
|
465
|
+
return this;
|
|
466
|
+
}
|
|
467
|
+
nullsLast() {
|
|
468
|
+
this.indexConfig.nulls = "last";
|
|
469
|
+
return this;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* ### PostgreSQL documentation quote
|
|
473
|
+
*
|
|
474
|
+
* > An operator class with optional parameters can be specified for each column of an index.
|
|
475
|
+
* The operator class identifies the operators to be used by the index for that column.
|
|
476
|
+
* For example, a B-tree index on four-byte integers would use the int4_ops class;
|
|
477
|
+
* this operator class includes comparison functions for four-byte integers.
|
|
478
|
+
* In practice the default operator class for the column's data type is usually sufficient.
|
|
479
|
+
* The main point of having operator classes is that for some data types, there could be more than one meaningful ordering.
|
|
480
|
+
* For example, we might want to sort a complex-number data type either by absolute value or by real part.
|
|
481
|
+
* We could do this by defining two operator classes for the data type and then selecting the proper class when creating an index.
|
|
482
|
+
* More information about operator classes check:
|
|
483
|
+
*
|
|
484
|
+
* ### Useful links
|
|
485
|
+
* https://www.postgresql.org/docs/current/sql-createindex.html
|
|
486
|
+
*
|
|
487
|
+
* https://www.postgresql.org/docs/current/indexes-opclass.html
|
|
488
|
+
*
|
|
489
|
+
* https://www.postgresql.org/docs/current/xindex.html
|
|
490
|
+
*
|
|
491
|
+
* ### Additional types
|
|
492
|
+
* If you have the `pg_vector` extension installed in your database, you can use the
|
|
493
|
+
* `vector_l2_ops`, `vector_ip_ops`, `vector_cosine_ops`, `vector_l1_ops`, `bit_hamming_ops`, `bit_jaccard_ops`, `halfvec_l2_ops`, `sparsevec_l2_ops` options, which are predefined types.
|
|
494
|
+
*
|
|
495
|
+
* **You can always specify any string you want in the operator class, in case Drizzle doesn't have it natively in its types**
|
|
496
|
+
*
|
|
497
|
+
* @param opClass
|
|
498
|
+
* @returns
|
|
499
|
+
*/
|
|
500
|
+
op(opClass) {
|
|
501
|
+
this.indexConfig.opClass = opClass;
|
|
502
|
+
return this;
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
var IndexedColumn = class {
|
|
506
|
+
static [entityKind] = "IndexedColumn";
|
|
507
|
+
constructor(name, keyAsName, type, indexConfig) {
|
|
508
|
+
this.name = name;
|
|
509
|
+
this.keyAsName = keyAsName;
|
|
510
|
+
this.type = type;
|
|
511
|
+
this.indexConfig = indexConfig;
|
|
512
|
+
}
|
|
513
|
+
name;
|
|
514
|
+
keyAsName;
|
|
515
|
+
type;
|
|
516
|
+
indexConfig;
|
|
517
|
+
};
|
|
518
|
+
var PgArrayBuilder = class extends PgColumnBuilder {
|
|
519
|
+
static [entityKind] = "PgArrayBuilder";
|
|
520
|
+
constructor(name, baseBuilder, size) {
|
|
521
|
+
super(name, "array", "PgArray");
|
|
522
|
+
this.config.baseBuilder = baseBuilder;
|
|
523
|
+
this.config.size = size;
|
|
524
|
+
}
|
|
525
|
+
/** @internal */
|
|
526
|
+
build(table) {
|
|
527
|
+
const baseColumn = this.config.baseBuilder.build(table);
|
|
528
|
+
return new PgArray(
|
|
529
|
+
table,
|
|
530
|
+
this.config,
|
|
531
|
+
baseColumn
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
};
|
|
535
|
+
var PgArray = class _PgArray extends PgColumn {
|
|
536
|
+
constructor(table, config, baseColumn, range) {
|
|
537
|
+
super(table, config);
|
|
538
|
+
this.baseColumn = baseColumn;
|
|
539
|
+
this.range = range;
|
|
540
|
+
this.size = config.size;
|
|
541
|
+
}
|
|
542
|
+
size;
|
|
543
|
+
static [entityKind] = "PgArray";
|
|
544
|
+
getSQLType() {
|
|
545
|
+
return `${this.baseColumn.getSQLType()}[${typeof this.size === "number" ? this.size : ""}]`;
|
|
546
|
+
}
|
|
547
|
+
mapFromDriverValue(value) {
|
|
548
|
+
if (typeof value === "string") {
|
|
549
|
+
value = parsePgArray(value);
|
|
550
|
+
}
|
|
551
|
+
return value.map((v) => this.baseColumn.mapFromDriverValue(v));
|
|
552
|
+
}
|
|
553
|
+
mapToDriverValue(value, isNestedArray = false) {
|
|
554
|
+
const a = value.map(
|
|
555
|
+
(v) => v === null ? null : is(this.baseColumn, _PgArray) ? this.baseColumn.mapToDriverValue(v, true) : this.baseColumn.mapToDriverValue(v)
|
|
556
|
+
);
|
|
557
|
+
if (isNestedArray) return a;
|
|
558
|
+
return makePgArray(a);
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/pg-core/columns/enum.js
|
|
563
|
+
var PgEnumObjectColumnBuilder = class extends PgColumnBuilder {
|
|
564
|
+
static [entityKind] = "PgEnumObjectColumnBuilder";
|
|
565
|
+
constructor(name, enumInstance) {
|
|
566
|
+
super(name, "string", "PgEnumObjectColumn");
|
|
567
|
+
this.config.enum = enumInstance;
|
|
568
|
+
}
|
|
569
|
+
/** @internal */
|
|
570
|
+
build(table) {
|
|
571
|
+
return new PgEnumObjectColumn(
|
|
572
|
+
table,
|
|
573
|
+
this.config
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
var PgEnumObjectColumn = class extends PgColumn {
|
|
578
|
+
static [entityKind] = "PgEnumObjectColumn";
|
|
579
|
+
enum;
|
|
580
|
+
enumValues = this.config.enum.enumValues;
|
|
581
|
+
constructor(table, config) {
|
|
582
|
+
super(table, config);
|
|
583
|
+
this.enum = config.enum;
|
|
584
|
+
}
|
|
585
|
+
getSQLType() {
|
|
586
|
+
return this.enum.enumName;
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
var isPgEnumSym = /* @__PURE__ */ Symbol.for("drizzle:isPgEnum");
|
|
590
|
+
function isPgEnum(obj) {
|
|
591
|
+
return !!obj && typeof obj === "function" && isPgEnumSym in obj && obj[isPgEnumSym] === true;
|
|
592
|
+
}
|
|
593
|
+
var PgEnumColumnBuilder = class extends PgColumnBuilder {
|
|
594
|
+
static [entityKind] = "PgEnumColumnBuilder";
|
|
595
|
+
constructor(name, enumInstance) {
|
|
596
|
+
super(name, "string", "PgEnumColumn");
|
|
597
|
+
this.config.enum = enumInstance;
|
|
598
|
+
}
|
|
599
|
+
/** @internal */
|
|
600
|
+
build(table) {
|
|
601
|
+
return new PgEnumColumn(
|
|
602
|
+
table,
|
|
603
|
+
this.config
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
};
|
|
607
|
+
var PgEnumColumn = class extends PgColumn {
|
|
608
|
+
static [entityKind] = "PgEnumColumn";
|
|
609
|
+
enum = this.config.enum;
|
|
610
|
+
enumValues = this.config.enum.enumValues;
|
|
611
|
+
constructor(table, config) {
|
|
612
|
+
super(table, config);
|
|
613
|
+
this.enum = config.enum;
|
|
614
|
+
}
|
|
615
|
+
getSQLType() {
|
|
616
|
+
return this.enum.enumName;
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
|
|
620
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/subquery.js
|
|
621
|
+
var Subquery = class {
|
|
622
|
+
static [entityKind] = "Subquery";
|
|
623
|
+
constructor(sql2, fields, alias, isWith = false, usedTables = []) {
|
|
624
|
+
this._ = {
|
|
625
|
+
brand: "Subquery",
|
|
626
|
+
sql: sql2,
|
|
627
|
+
selectedFields: fields,
|
|
628
|
+
alias,
|
|
629
|
+
isWith,
|
|
630
|
+
usedTables
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
// getSQL(): SQL<unknown> {
|
|
634
|
+
// return new SQL([this]);
|
|
635
|
+
// }
|
|
636
|
+
};
|
|
637
|
+
var WithSubquery = class extends Subquery {
|
|
638
|
+
static [entityKind] = "WithSubquery";
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/version.js
|
|
642
|
+
var version = "0.45.2";
|
|
643
|
+
|
|
644
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/tracing.js
|
|
645
|
+
var otel;
|
|
646
|
+
var rawTracer;
|
|
647
|
+
var tracer = {
|
|
648
|
+
startActiveSpan(name, fn) {
|
|
649
|
+
if (!otel) {
|
|
650
|
+
return fn();
|
|
651
|
+
}
|
|
652
|
+
if (!rawTracer) {
|
|
653
|
+
rawTracer = otel.trace.getTracer("drizzle-orm", version);
|
|
654
|
+
}
|
|
655
|
+
return iife(
|
|
656
|
+
(otel2, rawTracer2) => rawTracer2.startActiveSpan(
|
|
657
|
+
name,
|
|
658
|
+
(span) => {
|
|
659
|
+
try {
|
|
660
|
+
return fn(span);
|
|
661
|
+
} catch (e) {
|
|
662
|
+
span.setStatus({
|
|
663
|
+
code: otel2.SpanStatusCode.ERROR,
|
|
664
|
+
message: e instanceof Error ? e.message : "Unknown error"
|
|
665
|
+
// eslint-disable-line no-instanceof/no-instanceof
|
|
666
|
+
});
|
|
667
|
+
throw e;
|
|
668
|
+
} finally {
|
|
669
|
+
span.end();
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
),
|
|
673
|
+
otel,
|
|
674
|
+
rawTracer
|
|
675
|
+
);
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
|
|
679
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/view-common.js
|
|
680
|
+
var ViewBaseConfig = /* @__PURE__ */ Symbol.for("drizzle:ViewBaseConfig");
|
|
681
|
+
|
|
682
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/table.js
|
|
683
|
+
var Schema = /* @__PURE__ */ Symbol.for("drizzle:Schema");
|
|
684
|
+
var Columns = /* @__PURE__ */ Symbol.for("drizzle:Columns");
|
|
685
|
+
var ExtraConfigColumns = /* @__PURE__ */ Symbol.for("drizzle:ExtraConfigColumns");
|
|
686
|
+
var OriginalName = /* @__PURE__ */ Symbol.for("drizzle:OriginalName");
|
|
687
|
+
var BaseName = /* @__PURE__ */ Symbol.for("drizzle:BaseName");
|
|
688
|
+
var IsAlias = /* @__PURE__ */ Symbol.for("drizzle:IsAlias");
|
|
689
|
+
var ExtraConfigBuilder = /* @__PURE__ */ Symbol.for("drizzle:ExtraConfigBuilder");
|
|
690
|
+
var IsDrizzleTable = /* @__PURE__ */ Symbol.for("drizzle:IsDrizzleTable");
|
|
691
|
+
var Table = class {
|
|
692
|
+
static [entityKind] = "Table";
|
|
693
|
+
/** @internal */
|
|
694
|
+
static Symbol = {
|
|
695
|
+
Name: TableName,
|
|
696
|
+
Schema,
|
|
697
|
+
OriginalName,
|
|
698
|
+
Columns,
|
|
699
|
+
ExtraConfigColumns,
|
|
700
|
+
BaseName,
|
|
701
|
+
IsAlias,
|
|
702
|
+
ExtraConfigBuilder
|
|
703
|
+
};
|
|
704
|
+
/**
|
|
705
|
+
* @internal
|
|
706
|
+
* Can be changed if the table is aliased.
|
|
707
|
+
*/
|
|
708
|
+
[TableName];
|
|
709
|
+
/**
|
|
710
|
+
* @internal
|
|
711
|
+
* Used to store the original name of the table, before any aliasing.
|
|
712
|
+
*/
|
|
713
|
+
[OriginalName];
|
|
714
|
+
/** @internal */
|
|
715
|
+
[Schema];
|
|
716
|
+
/** @internal */
|
|
717
|
+
[Columns];
|
|
718
|
+
/** @internal */
|
|
719
|
+
[ExtraConfigColumns];
|
|
720
|
+
/**
|
|
721
|
+
* @internal
|
|
722
|
+
* Used to store the table name before the transformation via the `tableCreator` functions.
|
|
723
|
+
*/
|
|
724
|
+
[BaseName];
|
|
725
|
+
/** @internal */
|
|
726
|
+
[IsAlias] = false;
|
|
727
|
+
/** @internal */
|
|
728
|
+
[IsDrizzleTable] = true;
|
|
729
|
+
/** @internal */
|
|
730
|
+
[ExtraConfigBuilder] = void 0;
|
|
731
|
+
constructor(name, schema, baseName) {
|
|
732
|
+
this[TableName] = this[OriginalName] = name;
|
|
733
|
+
this[Schema] = schema;
|
|
734
|
+
this[BaseName] = baseName;
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
|
|
738
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/sql/sql.js
|
|
739
|
+
var FakePrimitiveParam = class {
|
|
740
|
+
static [entityKind] = "FakePrimitiveParam";
|
|
741
|
+
};
|
|
742
|
+
function isSQLWrapper(value) {
|
|
743
|
+
return value !== null && value !== void 0 && typeof value.getSQL === "function";
|
|
744
|
+
}
|
|
745
|
+
function mergeQueries(queries) {
|
|
746
|
+
const result = { sql: "", params: [] };
|
|
747
|
+
for (const query of queries) {
|
|
748
|
+
result.sql += query.sql;
|
|
749
|
+
result.params.push(...query.params);
|
|
750
|
+
if (query.typings?.length) {
|
|
751
|
+
if (!result.typings) {
|
|
752
|
+
result.typings = [];
|
|
753
|
+
}
|
|
754
|
+
result.typings.push(...query.typings);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
return result;
|
|
758
|
+
}
|
|
759
|
+
var StringChunk = class {
|
|
760
|
+
static [entityKind] = "StringChunk";
|
|
761
|
+
value;
|
|
762
|
+
constructor(value) {
|
|
763
|
+
this.value = Array.isArray(value) ? value : [value];
|
|
764
|
+
}
|
|
765
|
+
getSQL() {
|
|
766
|
+
return new SQL([this]);
|
|
767
|
+
}
|
|
768
|
+
};
|
|
769
|
+
var SQL = class _SQL {
|
|
770
|
+
constructor(queryChunks) {
|
|
771
|
+
this.queryChunks = queryChunks;
|
|
772
|
+
for (const chunk of queryChunks) {
|
|
773
|
+
if (is(chunk, Table)) {
|
|
774
|
+
const schemaName = chunk[Table.Symbol.Schema];
|
|
775
|
+
this.usedTables.push(
|
|
776
|
+
schemaName === void 0 ? chunk[Table.Symbol.Name] : schemaName + "." + chunk[Table.Symbol.Name]
|
|
777
|
+
);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
static [entityKind] = "SQL";
|
|
782
|
+
/** @internal */
|
|
783
|
+
decoder = noopDecoder;
|
|
784
|
+
shouldInlineParams = false;
|
|
785
|
+
/** @internal */
|
|
786
|
+
usedTables = [];
|
|
787
|
+
append(query) {
|
|
788
|
+
this.queryChunks.push(...query.queryChunks);
|
|
789
|
+
return this;
|
|
790
|
+
}
|
|
791
|
+
toQuery(config) {
|
|
792
|
+
return tracer.startActiveSpan("drizzle.buildSQL", (span) => {
|
|
793
|
+
const query = this.buildQueryFromSourceParams(this.queryChunks, config);
|
|
794
|
+
span?.setAttributes({
|
|
795
|
+
"drizzle.query.text": query.sql,
|
|
796
|
+
"drizzle.query.params": JSON.stringify(query.params)
|
|
797
|
+
});
|
|
798
|
+
return query;
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
buildQueryFromSourceParams(chunks, _config) {
|
|
802
|
+
const config = Object.assign({}, _config, {
|
|
803
|
+
inlineParams: _config.inlineParams || this.shouldInlineParams,
|
|
804
|
+
paramStartIndex: _config.paramStartIndex || { value: 0 }
|
|
805
|
+
});
|
|
806
|
+
const {
|
|
807
|
+
casing,
|
|
808
|
+
escapeName,
|
|
809
|
+
escapeParam,
|
|
810
|
+
prepareTyping,
|
|
811
|
+
inlineParams,
|
|
812
|
+
paramStartIndex
|
|
813
|
+
} = config;
|
|
814
|
+
return mergeQueries(chunks.map((chunk) => {
|
|
815
|
+
if (is(chunk, StringChunk)) {
|
|
816
|
+
return { sql: chunk.value.join(""), params: [] };
|
|
817
|
+
}
|
|
818
|
+
if (is(chunk, Name)) {
|
|
819
|
+
return { sql: escapeName(chunk.value), params: [] };
|
|
820
|
+
}
|
|
821
|
+
if (chunk === void 0) {
|
|
822
|
+
return { sql: "", params: [] };
|
|
823
|
+
}
|
|
824
|
+
if (Array.isArray(chunk)) {
|
|
825
|
+
const result = [new StringChunk("(")];
|
|
826
|
+
for (const [i, p] of chunk.entries()) {
|
|
827
|
+
result.push(p);
|
|
828
|
+
if (i < chunk.length - 1) {
|
|
829
|
+
result.push(new StringChunk(", "));
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
result.push(new StringChunk(")"));
|
|
833
|
+
return this.buildQueryFromSourceParams(result, config);
|
|
834
|
+
}
|
|
835
|
+
if (is(chunk, _SQL)) {
|
|
836
|
+
return this.buildQueryFromSourceParams(chunk.queryChunks, {
|
|
837
|
+
...config,
|
|
838
|
+
inlineParams: inlineParams || chunk.shouldInlineParams
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
if (is(chunk, Table)) {
|
|
842
|
+
const schemaName = chunk[Table.Symbol.Schema];
|
|
843
|
+
const tableName = chunk[Table.Symbol.Name];
|
|
844
|
+
return {
|
|
845
|
+
sql: schemaName === void 0 || chunk[IsAlias] ? escapeName(tableName) : escapeName(schemaName) + "." + escapeName(tableName),
|
|
846
|
+
params: []
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
if (is(chunk, Column)) {
|
|
850
|
+
const columnName = casing.getColumnCasing(chunk);
|
|
851
|
+
if (_config.invokeSource === "indexes") {
|
|
852
|
+
return { sql: escapeName(columnName), params: [] };
|
|
853
|
+
}
|
|
854
|
+
const schemaName = chunk.table[Table.Symbol.Schema];
|
|
855
|
+
return {
|
|
856
|
+
sql: chunk.table[IsAlias] || schemaName === void 0 ? escapeName(chunk.table[Table.Symbol.Name]) + "." + escapeName(columnName) : escapeName(schemaName) + "." + escapeName(chunk.table[Table.Symbol.Name]) + "." + escapeName(columnName),
|
|
857
|
+
params: []
|
|
858
|
+
};
|
|
859
|
+
}
|
|
860
|
+
if (is(chunk, View)) {
|
|
861
|
+
const schemaName = chunk[ViewBaseConfig].schema;
|
|
862
|
+
const viewName = chunk[ViewBaseConfig].name;
|
|
863
|
+
return {
|
|
864
|
+
sql: schemaName === void 0 || chunk[ViewBaseConfig].isAlias ? escapeName(viewName) : escapeName(schemaName) + "." + escapeName(viewName),
|
|
865
|
+
params: []
|
|
866
|
+
};
|
|
867
|
+
}
|
|
868
|
+
if (is(chunk, Param)) {
|
|
869
|
+
if (is(chunk.value, Placeholder)) {
|
|
870
|
+
return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
|
|
871
|
+
}
|
|
872
|
+
const mappedValue = chunk.value === null ? null : chunk.encoder.mapToDriverValue(chunk.value);
|
|
873
|
+
if (is(mappedValue, _SQL)) {
|
|
874
|
+
return this.buildQueryFromSourceParams([mappedValue], config);
|
|
875
|
+
}
|
|
876
|
+
if (inlineParams) {
|
|
877
|
+
return { sql: this.mapInlineParam(mappedValue, config), params: [] };
|
|
878
|
+
}
|
|
879
|
+
let typings = ["none"];
|
|
880
|
+
if (prepareTyping) {
|
|
881
|
+
typings = [prepareTyping(chunk.encoder)];
|
|
882
|
+
}
|
|
883
|
+
return { sql: escapeParam(paramStartIndex.value++, mappedValue), params: [mappedValue], typings };
|
|
884
|
+
}
|
|
885
|
+
if (is(chunk, Placeholder)) {
|
|
886
|
+
return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
|
|
887
|
+
}
|
|
888
|
+
if (is(chunk, _SQL.Aliased) && chunk.fieldAlias !== void 0) {
|
|
889
|
+
return { sql: escapeName(chunk.fieldAlias), params: [] };
|
|
890
|
+
}
|
|
891
|
+
if (is(chunk, Subquery)) {
|
|
892
|
+
if (chunk._.isWith) {
|
|
893
|
+
return { sql: escapeName(chunk._.alias), params: [] };
|
|
894
|
+
}
|
|
895
|
+
return this.buildQueryFromSourceParams([
|
|
896
|
+
new StringChunk("("),
|
|
897
|
+
chunk._.sql,
|
|
898
|
+
new StringChunk(") "),
|
|
899
|
+
new Name(chunk._.alias)
|
|
900
|
+
], config);
|
|
901
|
+
}
|
|
902
|
+
if (isPgEnum(chunk)) {
|
|
903
|
+
if (chunk.schema) {
|
|
904
|
+
return { sql: escapeName(chunk.schema) + "." + escapeName(chunk.enumName), params: [] };
|
|
905
|
+
}
|
|
906
|
+
return { sql: escapeName(chunk.enumName), params: [] };
|
|
907
|
+
}
|
|
908
|
+
if (isSQLWrapper(chunk)) {
|
|
909
|
+
if (chunk.shouldOmitSQLParens?.()) {
|
|
910
|
+
return this.buildQueryFromSourceParams([chunk.getSQL()], config);
|
|
911
|
+
}
|
|
912
|
+
return this.buildQueryFromSourceParams([
|
|
913
|
+
new StringChunk("("),
|
|
914
|
+
chunk.getSQL(),
|
|
915
|
+
new StringChunk(")")
|
|
916
|
+
], config);
|
|
917
|
+
}
|
|
918
|
+
if (inlineParams) {
|
|
919
|
+
return { sql: this.mapInlineParam(chunk, config), params: [] };
|
|
920
|
+
}
|
|
921
|
+
return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
|
|
922
|
+
}));
|
|
923
|
+
}
|
|
924
|
+
mapInlineParam(chunk, { escapeString }) {
|
|
925
|
+
if (chunk === null) {
|
|
926
|
+
return "null";
|
|
927
|
+
}
|
|
928
|
+
if (typeof chunk === "number" || typeof chunk === "boolean") {
|
|
929
|
+
return chunk.toString();
|
|
930
|
+
}
|
|
931
|
+
if (typeof chunk === "string") {
|
|
932
|
+
return escapeString(chunk);
|
|
933
|
+
}
|
|
934
|
+
if (typeof chunk === "object") {
|
|
935
|
+
const mappedValueAsString = chunk.toString();
|
|
936
|
+
if (mappedValueAsString === "[object Object]") {
|
|
937
|
+
return escapeString(JSON.stringify(chunk));
|
|
938
|
+
}
|
|
939
|
+
return escapeString(mappedValueAsString);
|
|
940
|
+
}
|
|
941
|
+
throw new Error("Unexpected param value: " + chunk);
|
|
942
|
+
}
|
|
943
|
+
getSQL() {
|
|
944
|
+
return this;
|
|
945
|
+
}
|
|
946
|
+
as(alias) {
|
|
947
|
+
if (alias === void 0) {
|
|
948
|
+
return this;
|
|
949
|
+
}
|
|
950
|
+
return new _SQL.Aliased(this, alias);
|
|
951
|
+
}
|
|
952
|
+
mapWith(decoder) {
|
|
953
|
+
this.decoder = typeof decoder === "function" ? { mapFromDriverValue: decoder } : decoder;
|
|
954
|
+
return this;
|
|
955
|
+
}
|
|
956
|
+
inlineParams() {
|
|
957
|
+
this.shouldInlineParams = true;
|
|
958
|
+
return this;
|
|
959
|
+
}
|
|
960
|
+
/**
|
|
961
|
+
* This method is used to conditionally include a part of the query.
|
|
962
|
+
*
|
|
963
|
+
* @param condition - Condition to check
|
|
964
|
+
* @returns itself if the condition is `true`, otherwise `undefined`
|
|
965
|
+
*/
|
|
966
|
+
if(condition) {
|
|
967
|
+
return condition ? this : void 0;
|
|
968
|
+
}
|
|
969
|
+
};
|
|
970
|
+
var Name = class {
|
|
971
|
+
constructor(value) {
|
|
972
|
+
this.value = value;
|
|
973
|
+
}
|
|
974
|
+
static [entityKind] = "Name";
|
|
975
|
+
brand;
|
|
976
|
+
getSQL() {
|
|
977
|
+
return new SQL([this]);
|
|
978
|
+
}
|
|
979
|
+
};
|
|
980
|
+
function isDriverValueEncoder(value) {
|
|
981
|
+
return typeof value === "object" && value !== null && "mapToDriverValue" in value && typeof value.mapToDriverValue === "function";
|
|
982
|
+
}
|
|
983
|
+
var noopDecoder = {
|
|
984
|
+
mapFromDriverValue: (value) => value
|
|
985
|
+
};
|
|
986
|
+
var noopEncoder = {
|
|
987
|
+
mapToDriverValue: (value) => value
|
|
988
|
+
};
|
|
989
|
+
var noopMapper = {
|
|
990
|
+
...noopDecoder,
|
|
991
|
+
...noopEncoder
|
|
992
|
+
};
|
|
993
|
+
var Param = class {
|
|
994
|
+
/**
|
|
995
|
+
* @param value - Parameter value
|
|
996
|
+
* @param encoder - Encoder to convert the value to a driver parameter
|
|
997
|
+
*/
|
|
998
|
+
constructor(value, encoder = noopEncoder) {
|
|
999
|
+
this.value = value;
|
|
1000
|
+
this.encoder = encoder;
|
|
1001
|
+
}
|
|
1002
|
+
static [entityKind] = "Param";
|
|
1003
|
+
brand;
|
|
1004
|
+
getSQL() {
|
|
1005
|
+
return new SQL([this]);
|
|
1006
|
+
}
|
|
1007
|
+
};
|
|
1008
|
+
function sql(strings, ...params) {
|
|
1009
|
+
const queryChunks = [];
|
|
1010
|
+
if (params.length > 0 || strings.length > 0 && strings[0] !== "") {
|
|
1011
|
+
queryChunks.push(new StringChunk(strings[0]));
|
|
1012
|
+
}
|
|
1013
|
+
for (const [paramIndex, param2] of params.entries()) {
|
|
1014
|
+
queryChunks.push(param2, new StringChunk(strings[paramIndex + 1]));
|
|
1015
|
+
}
|
|
1016
|
+
return new SQL(queryChunks);
|
|
1017
|
+
}
|
|
1018
|
+
((sql2) => {
|
|
1019
|
+
function empty() {
|
|
1020
|
+
return new SQL([]);
|
|
1021
|
+
}
|
|
1022
|
+
sql2.empty = empty;
|
|
1023
|
+
function fromList(list) {
|
|
1024
|
+
return new SQL(list);
|
|
1025
|
+
}
|
|
1026
|
+
sql2.fromList = fromList;
|
|
1027
|
+
function raw(str) {
|
|
1028
|
+
return new SQL([new StringChunk(str)]);
|
|
1029
|
+
}
|
|
1030
|
+
sql2.raw = raw;
|
|
1031
|
+
function join(chunks, separator) {
|
|
1032
|
+
const result = [];
|
|
1033
|
+
for (const [i, chunk] of chunks.entries()) {
|
|
1034
|
+
if (i > 0 && separator !== void 0) {
|
|
1035
|
+
result.push(separator);
|
|
1036
|
+
}
|
|
1037
|
+
result.push(chunk);
|
|
1038
|
+
}
|
|
1039
|
+
return new SQL(result);
|
|
1040
|
+
}
|
|
1041
|
+
sql2.join = join;
|
|
1042
|
+
function identifier(value) {
|
|
1043
|
+
return new Name(value);
|
|
1044
|
+
}
|
|
1045
|
+
sql2.identifier = identifier;
|
|
1046
|
+
function placeholder2(name2) {
|
|
1047
|
+
return new Placeholder(name2);
|
|
1048
|
+
}
|
|
1049
|
+
sql2.placeholder = placeholder2;
|
|
1050
|
+
function param2(value, encoder) {
|
|
1051
|
+
return new Param(value, encoder);
|
|
1052
|
+
}
|
|
1053
|
+
sql2.param = param2;
|
|
1054
|
+
})(sql || (sql = {}));
|
|
1055
|
+
((SQL2) => {
|
|
1056
|
+
class Aliased {
|
|
1057
|
+
constructor(sql2, fieldAlias) {
|
|
1058
|
+
this.sql = sql2;
|
|
1059
|
+
this.fieldAlias = fieldAlias;
|
|
1060
|
+
}
|
|
1061
|
+
static [entityKind] = "SQL.Aliased";
|
|
1062
|
+
/** @internal */
|
|
1063
|
+
isSelectionField = false;
|
|
1064
|
+
getSQL() {
|
|
1065
|
+
return this.sql;
|
|
1066
|
+
}
|
|
1067
|
+
/** @internal */
|
|
1068
|
+
clone() {
|
|
1069
|
+
return new Aliased(this.sql, this.fieldAlias);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
SQL2.Aliased = Aliased;
|
|
1073
|
+
})(SQL || (SQL = {}));
|
|
1074
|
+
var Placeholder = class {
|
|
1075
|
+
constructor(name2) {
|
|
1076
|
+
this.name = name2;
|
|
1077
|
+
}
|
|
1078
|
+
static [entityKind] = "Placeholder";
|
|
1079
|
+
getSQL() {
|
|
1080
|
+
return new SQL([this]);
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
var IsDrizzleView = /* @__PURE__ */ Symbol.for("drizzle:IsDrizzleView");
|
|
1084
|
+
var View = class {
|
|
1085
|
+
static [entityKind] = "View";
|
|
1086
|
+
/** @internal */
|
|
1087
|
+
[ViewBaseConfig];
|
|
1088
|
+
/** @internal */
|
|
1089
|
+
[IsDrizzleView] = true;
|
|
1090
|
+
constructor({ name: name2, schema, selectedFields, query }) {
|
|
1091
|
+
this[ViewBaseConfig] = {
|
|
1092
|
+
name: name2,
|
|
1093
|
+
originalName: name2,
|
|
1094
|
+
schema,
|
|
1095
|
+
selectedFields,
|
|
1096
|
+
query,
|
|
1097
|
+
isExisting: !query,
|
|
1098
|
+
isAlias: false
|
|
1099
|
+
};
|
|
1100
|
+
}
|
|
1101
|
+
getSQL() {
|
|
1102
|
+
return new SQL([this]);
|
|
1103
|
+
}
|
|
1104
|
+
};
|
|
1105
|
+
Column.prototype.getSQL = function() {
|
|
1106
|
+
return new SQL([this]);
|
|
1107
|
+
};
|
|
1108
|
+
Table.prototype.getSQL = function() {
|
|
1109
|
+
return new SQL([this]);
|
|
1110
|
+
};
|
|
1111
|
+
Subquery.prototype.getSQL = function() {
|
|
1112
|
+
return new SQL([this]);
|
|
1113
|
+
};
|
|
1114
|
+
|
|
1115
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/utils.js
|
|
1116
|
+
function getTableColumns(table) {
|
|
1117
|
+
return table[Table.Symbol.Columns];
|
|
1118
|
+
}
|
|
1119
|
+
var textDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder();
|
|
1120
|
+
|
|
1121
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/sql/expressions/conditions.js
|
|
1122
|
+
function bindIfParam(value, column) {
|
|
1123
|
+
if (isDriverValueEncoder(column) && !isSQLWrapper(value) && !is(value, Param) && !is(value, Placeholder) && !is(value, Column) && !is(value, Table) && !is(value, View)) {
|
|
1124
|
+
return new Param(value, column);
|
|
1125
|
+
}
|
|
1126
|
+
return value;
|
|
1127
|
+
}
|
|
1128
|
+
var eq = (left, right) => {
|
|
1129
|
+
return sql`${left} = ${bindIfParam(right, left)}`;
|
|
1130
|
+
};
|
|
1131
|
+
function and(...unfilteredConditions) {
|
|
1132
|
+
const conditions = unfilteredConditions.filter(
|
|
1133
|
+
(c) => c !== void 0
|
|
1134
|
+
);
|
|
1135
|
+
if (conditions.length === 0) {
|
|
1136
|
+
return void 0;
|
|
1137
|
+
}
|
|
1138
|
+
if (conditions.length === 1) {
|
|
1139
|
+
return new SQL(conditions);
|
|
1140
|
+
}
|
|
1141
|
+
return new SQL([
|
|
1142
|
+
new StringChunk("("),
|
|
1143
|
+
sql.join(conditions, new StringChunk(" and ")),
|
|
1144
|
+
new StringChunk(")")
|
|
1145
|
+
]);
|
|
1146
|
+
}
|
|
1147
|
+
function or(...unfilteredConditions) {
|
|
1148
|
+
const conditions = unfilteredConditions.filter(
|
|
1149
|
+
(c) => c !== void 0
|
|
1150
|
+
);
|
|
1151
|
+
if (conditions.length === 0) {
|
|
1152
|
+
return void 0;
|
|
1153
|
+
}
|
|
1154
|
+
if (conditions.length === 1) {
|
|
1155
|
+
return new SQL(conditions);
|
|
1156
|
+
}
|
|
1157
|
+
return new SQL([
|
|
1158
|
+
new StringChunk("("),
|
|
1159
|
+
sql.join(conditions, new StringChunk(" or ")),
|
|
1160
|
+
new StringChunk(")")
|
|
1161
|
+
]);
|
|
1162
|
+
}
|
|
1163
|
+
function inArray(column, values) {
|
|
1164
|
+
if (Array.isArray(values)) {
|
|
1165
|
+
if (values.length === 0) {
|
|
1166
|
+
return sql`false`;
|
|
1167
|
+
}
|
|
1168
|
+
return sql`${column} in ${values.map((v) => bindIfParam(v, column))}`;
|
|
1169
|
+
}
|
|
1170
|
+
return sql`${column} in ${bindIfParam(values, column)}`;
|
|
1171
|
+
}
|
|
1172
|
+
function isNull(value) {
|
|
1173
|
+
return sql`${value} is null`;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/sql/expressions/select.js
|
|
1177
|
+
function asc(column) {
|
|
1178
|
+
return sql`${column} asc`;
|
|
1179
|
+
}
|
|
1180
|
+
function desc(column) {
|
|
1181
|
+
return sql`${column} desc`;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
// ../../node_modules/.pnpm/drizzle-orm@0.45.2_@cloudfl_b372b29e6d5511672c7f9f9d2ac40572/node_modules/drizzle-orm/sql/functions/aggregate.js
|
|
1185
|
+
function count(expression) {
|
|
1186
|
+
return sql`count(${expression || sql.raw("*")})`.mapWith(Number);
|
|
1187
|
+
}
|
|
8
1188
|
|
|
9
1189
|
// src/server/query.ts
|
|
10
1190
|
var TIMESTAMP_FIELDS = ["createdAt", "updatedAt"];
|
|
@@ -309,11 +1489,276 @@ function createResourceHandlers(options) {
|
|
|
309
1489
|
store
|
|
310
1490
|
};
|
|
311
1491
|
}
|
|
1492
|
+
|
|
1493
|
+
// src/server/openapi.ts
|
|
1494
|
+
var E164 = "^\\+[1-9]\\d{6,14}$";
|
|
1495
|
+
function fieldJsonSchema(def) {
|
|
1496
|
+
const base = {};
|
|
1497
|
+
if (def.helpText) base.description = def.helpText;
|
|
1498
|
+
switch (def.kind) {
|
|
1499
|
+
case "string": {
|
|
1500
|
+
const schema = { ...base, type: "string", maxLength: def.maxLength ?? 255 };
|
|
1501
|
+
if (def.minLength !== void 0) schema.minLength = def.minLength;
|
|
1502
|
+
if (def.pattern) schema.pattern = def.pattern;
|
|
1503
|
+
switch (def.format) {
|
|
1504
|
+
case "email":
|
|
1505
|
+
return { ...schema, format: "email", examples: ["ada@example.com"] };
|
|
1506
|
+
case "url":
|
|
1507
|
+
return { ...schema, format: "uri", examples: ["https://example.com"] };
|
|
1508
|
+
case "tel":
|
|
1509
|
+
return { ...schema, pattern: E164, description: "International number in E.164 form.", examples: ["+256772123456"] };
|
|
1510
|
+
case "domain":
|
|
1511
|
+
return { ...schema, format: "hostname", description: "A hostname, stored lowercase without scheme or path.", examples: ["example.com"] };
|
|
1512
|
+
case "country":
|
|
1513
|
+
return { ...schema, pattern: "^[A-Z]{2}$", description: "ISO 3166-1 alpha-2 country code.", examples: ["UG"] };
|
|
1514
|
+
case "color":
|
|
1515
|
+
return { ...schema, pattern: "^#[0-9a-f]{6}$", description: "Hex colour.", examples: ["#f2541d"] };
|
|
1516
|
+
case "slug":
|
|
1517
|
+
return { ...schema, pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$", examples: ["my-first-post"] };
|
|
1518
|
+
default:
|
|
1519
|
+
return schema;
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1522
|
+
case "text":
|
|
1523
|
+
return { ...base, type: "string", maxLength: def.maxLength ?? 65535 };
|
|
1524
|
+
case "int":
|
|
1525
|
+
case "float": {
|
|
1526
|
+
const schema = { ...base, type: def.kind === "int" ? "integer" : "number" };
|
|
1527
|
+
if (def.min !== void 0) schema.minimum = def.min;
|
|
1528
|
+
if (def.max !== void 0) schema.maximum = def.max;
|
|
1529
|
+
return schema;
|
|
1530
|
+
}
|
|
1531
|
+
case "boolean":
|
|
1532
|
+
return { ...base, type: "boolean" };
|
|
1533
|
+
case "date":
|
|
1534
|
+
return { ...base, type: "string", format: "date" };
|
|
1535
|
+
case "datetime":
|
|
1536
|
+
return { ...base, type: "string", format: "date-time" };
|
|
1537
|
+
case "enum":
|
|
1538
|
+
return { ...base, type: "string", enum: [...def.options] };
|
|
1539
|
+
case "multiselect": {
|
|
1540
|
+
const schema = { ...base, type: "array", items: { type: "string", enum: [...def.options] }, uniqueItems: true };
|
|
1541
|
+
if (def.minItems !== void 0) schema.minItems = def.minItems;
|
|
1542
|
+
if (def.maxItems !== void 0) schema.maxItems = def.maxItems;
|
|
1543
|
+
return schema;
|
|
1544
|
+
}
|
|
1545
|
+
case "file":
|
|
1546
|
+
return { ...base, type: "string", description: base.description ?? "Storage key of an uploaded file." };
|
|
1547
|
+
case "belongsTo":
|
|
1548
|
+
return { ...base, type: "string", description: base.description ?? `id of a ${def.target}.` };
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
var nullable = (schema) => ({ ...schema, type: [schema.type, "null"] });
|
|
1552
|
+
function resourceSchemas(resource) {
|
|
1553
|
+
const record = { id: { type: "string", format: "uuid", readOnly: true } };
|
|
1554
|
+
const create = {};
|
|
1555
|
+
const required = [];
|
|
1556
|
+
const recordRequired = ["id", "createdAt", "updatedAt"];
|
|
1557
|
+
for (const [key, def] of storedFields(resource)) {
|
|
1558
|
+
const value = { ...fieldJsonSchema(def), title: def.label ?? key };
|
|
1559
|
+
record[key] = def.required ? value : nullable(value);
|
|
1560
|
+
create[key] = def.required ? value : nullable(value);
|
|
1561
|
+
if ("default" in def && def.default !== void 0) create[key] = { ...create[key], default: def.default };
|
|
1562
|
+
if (def.required) recordRequired.push(key);
|
|
1563
|
+
if (def.required && !("default" in def && def.default !== void 0)) required.push(key);
|
|
1564
|
+
}
|
|
1565
|
+
record.createdAt = { type: "string", format: "date-time", readOnly: true };
|
|
1566
|
+
record.updatedAt = { type: "string", format: "date-time", readOnly: true };
|
|
1567
|
+
return {
|
|
1568
|
+
[resource.name]: { type: "object", properties: record, required: recordRequired },
|
|
1569
|
+
[`${resource.name}Create`]: { type: "object", properties: create, required, additionalProperties: false },
|
|
1570
|
+
[`${resource.name}Update`]: { type: "object", properties: create, additionalProperties: false, description: "Only the fields to change." },
|
|
1571
|
+
[`${resource.name}Page`]: {
|
|
1572
|
+
type: "object",
|
|
1573
|
+
properties: {
|
|
1574
|
+
data: { type: "array", items: { $ref: `#/components/schemas/${resource.name}` } },
|
|
1575
|
+
meta: { $ref: "#/components/schemas/PageMeta" }
|
|
1576
|
+
},
|
|
1577
|
+
required: ["data", "meta"]
|
|
1578
|
+
}
|
|
1579
|
+
};
|
|
1580
|
+
}
|
|
1581
|
+
var json = (schema) => ({ "application/json": { schema } });
|
|
1582
|
+
var ref = (name) => ({ $ref: `#/components/schemas/${name}` });
|
|
1583
|
+
var problem2 = (description) => ({ description, content: json(ref("Problem")) });
|
|
1584
|
+
function rolesNote(policy, action) {
|
|
1585
|
+
if (!policy) return "Any signed-in user.";
|
|
1586
|
+
const roles = policy[action === "list" ? "read" : action];
|
|
1587
|
+
if (roles.includes("*")) return "Any signed-in user.";
|
|
1588
|
+
return roles.length ? `Roles: ${roles.join(", ")}.` : "No role may do this.";
|
|
1589
|
+
}
|
|
1590
|
+
function listParameters(resource) {
|
|
1591
|
+
const fields = storedFields(resource);
|
|
1592
|
+
const sortable = ["createdAt", "updatedAt", ...fields.filter(([, def]) => isSortable(def)).map(([key]) => key)];
|
|
1593
|
+
const parameters = [
|
|
1594
|
+
{ name: "page", in: "query", schema: { type: "integer", minimum: 1, default: 1 } },
|
|
1595
|
+
{ name: "perPage", in: "query", schema: { type: "integer", minimum: 1, maximum: 100, default: resource.perPage } },
|
|
1596
|
+
{
|
|
1597
|
+
name: "sort",
|
|
1598
|
+
in: "query",
|
|
1599
|
+
description: "Field to sort by; prefix with - for descending.",
|
|
1600
|
+
schema: { type: "string", enum: sortable.flatMap((key) => [key, `-${key}`]) }
|
|
1601
|
+
}
|
|
1602
|
+
];
|
|
1603
|
+
if (fields.some(([, def]) => isSearchable(def))) {
|
|
1604
|
+
parameters.push({ name: "q", in: "query", description: "Free-text search across the searchable fields.", schema: { type: "string", maxLength: 200 } });
|
|
1605
|
+
}
|
|
1606
|
+
for (const [key, def] of fields) {
|
|
1607
|
+
if (!isFilterable(def)) continue;
|
|
1608
|
+
parameters.push({ name: `filter[${key}]`, in: "query", description: `Only records whose ${key} equals this.`, schema: fieldJsonSchema(def) });
|
|
1609
|
+
}
|
|
1610
|
+
return parameters;
|
|
1611
|
+
}
|
|
1612
|
+
function openApiDocument(options) {
|
|
1613
|
+
const { resources, policies = {}, role, visibility = "role" } = options;
|
|
1614
|
+
const allowed = (resource, action) => visibility === "public" || role !== null && can(policies[resource.name], role, action);
|
|
1615
|
+
const paths = {};
|
|
1616
|
+
const schemas = {
|
|
1617
|
+
Problem: {
|
|
1618
|
+
type: "object",
|
|
1619
|
+
properties: {
|
|
1620
|
+
error: { type: "string", examples: ["Validation failed."] },
|
|
1621
|
+
issues: { type: "array", items: { type: "object", properties: { path: { type: "string" }, message: { type: "string" } } } },
|
|
1622
|
+
field: { type: "string", description: "The field a uniqueness conflict is about." }
|
|
1623
|
+
},
|
|
1624
|
+
required: ["error"]
|
|
1625
|
+
},
|
|
1626
|
+
PageMeta: {
|
|
1627
|
+
type: "object",
|
|
1628
|
+
properties: { page: { type: "integer" }, perPage: { type: "integer" }, total: { type: "integer" }, totalPages: { type: "integer" } },
|
|
1629
|
+
required: ["page", "perPage", "total", "totalPages"]
|
|
1630
|
+
}
|
|
1631
|
+
};
|
|
1632
|
+
const tags = [{ name: "Authentication", description: "Sign in here first: the session cookie authorizes every other request." }];
|
|
1633
|
+
const auth = {
|
|
1634
|
+
"/api/auth/sign-up/email": {
|
|
1635
|
+
post: {
|
|
1636
|
+
operationId: "signUp",
|
|
1637
|
+
tags: ["Authentication"],
|
|
1638
|
+
summary: "Create an account",
|
|
1639
|
+
security: [],
|
|
1640
|
+
requestBody: { required: true, content: json({ type: "object", properties: { name: { type: "string" }, email: { type: "string", format: "email" }, password: { type: "string", minLength: 8 } }, required: ["name", "email", "password"] }) },
|
|
1641
|
+
responses: { "200": { description: "Signed up and signed in; sets the session cookie." }, "422": problem2("The email is taken or the password too short.") }
|
|
1642
|
+
}
|
|
1643
|
+
},
|
|
1644
|
+
"/api/auth/sign-in/email": {
|
|
1645
|
+
post: {
|
|
1646
|
+
operationId: "signIn",
|
|
1647
|
+
tags: ["Authentication"],
|
|
1648
|
+
summary: "Sign in",
|
|
1649
|
+
security: [],
|
|
1650
|
+
requestBody: { required: true, content: json({ type: "object", properties: { email: { type: "string", format: "email" }, password: { type: "string" } }, required: ["email", "password"] }) },
|
|
1651
|
+
responses: { "200": { description: "Signed in; sets the session cookie." }, "401": problem2("Wrong email or password.") }
|
|
1652
|
+
}
|
|
1653
|
+
},
|
|
1654
|
+
"/api/auth/get-session": {
|
|
1655
|
+
get: { operationId: "getSession", tags: ["Authentication"], summary: "The current session", responses: { "200": { description: "The signed-in user and session, or null." } } }
|
|
1656
|
+
},
|
|
1657
|
+
"/api/auth/sign-out": {
|
|
1658
|
+
post: { operationId: "signOut", tags: ["Authentication"], summary: "Sign out", responses: { "200": { description: "Signed out; clears the session cookie." } } }
|
|
1659
|
+
}
|
|
1660
|
+
};
|
|
1661
|
+
Object.assign(paths, auth);
|
|
1662
|
+
for (const resource of resources) {
|
|
1663
|
+
const policy = policies[resource.name];
|
|
1664
|
+
const can2 = (action) => allowed(resource, action);
|
|
1665
|
+
if (!["list", "read", "create", "update", "delete"].some(can2)) continue;
|
|
1666
|
+
Object.assign(schemas, resourceSchemas(resource));
|
|
1667
|
+
const tag = resource.pluralLabel;
|
|
1668
|
+
const plural = tag.replace(/(?:^|\s+)(\w)/g, (_, letter) => letter.toUpperCase());
|
|
1669
|
+
tags.push({ name: tag, description: `The ${resource.pluralLabel.toLowerCase()} API, generated from resources/${resource.slug}.` });
|
|
1670
|
+
const denied = { "401": problem2("Sign in first."), "403": problem2("Your role can't do this.") };
|
|
1671
|
+
const collection = {};
|
|
1672
|
+
const item = {};
|
|
1673
|
+
const idParam = { name: "id", in: "path", required: true, schema: { type: "string" } };
|
|
1674
|
+
if (can2("list")) {
|
|
1675
|
+
collection.get = {
|
|
1676
|
+
operationId: `list${plural}`,
|
|
1677
|
+
tags: [tag],
|
|
1678
|
+
summary: `List ${resource.pluralLabel.toLowerCase()}`,
|
|
1679
|
+
description: rolesNote(policy, "list"),
|
|
1680
|
+
parameters: listParameters(resource),
|
|
1681
|
+
responses: { "200": { description: "One page of records.", content: json(ref(`${resource.name}Page`)) }, "400": problem2("A query parameter isn't accepted."), ...denied }
|
|
1682
|
+
};
|
|
1683
|
+
}
|
|
1684
|
+
if (can2("create")) {
|
|
1685
|
+
collection.post = {
|
|
1686
|
+
operationId: `create${resource.name}`,
|
|
1687
|
+
tags: [tag],
|
|
1688
|
+
summary: `Create a ${resource.label.toLowerCase()}`,
|
|
1689
|
+
description: rolesNote(policy, "create"),
|
|
1690
|
+
requestBody: { required: true, content: json(ref(`${resource.name}Create`)) },
|
|
1691
|
+
responses: {
|
|
1692
|
+
"201": { description: "Created. The Location header points at it.", content: json(ref(resource.name)) },
|
|
1693
|
+
"409": problem2("A unique field already has this value."),
|
|
1694
|
+
"422": problem2("Validation failed; `issues` lists each field."),
|
|
1695
|
+
...denied
|
|
1696
|
+
}
|
|
1697
|
+
};
|
|
1698
|
+
}
|
|
1699
|
+
if (can2("read")) {
|
|
1700
|
+
item.get = {
|
|
1701
|
+
operationId: `get${resource.name}`,
|
|
1702
|
+
tags: [tag],
|
|
1703
|
+
summary: `Get a ${resource.label.toLowerCase()}`,
|
|
1704
|
+
description: rolesNote(policy, "read"),
|
|
1705
|
+
parameters: [idParam],
|
|
1706
|
+
responses: { "200": { description: "The record.", content: json(ref(resource.name)) }, "404": problem2("No record with this id."), ...denied }
|
|
1707
|
+
};
|
|
1708
|
+
}
|
|
1709
|
+
if (can2("update")) {
|
|
1710
|
+
const body = (name) => ({ required: true, content: json(ref(name)) });
|
|
1711
|
+
const responses = {
|
|
1712
|
+
"200": { description: "The updated record.", content: json(ref(resource.name)) },
|
|
1713
|
+
"404": problem2("No record with this id."),
|
|
1714
|
+
"409": problem2("A unique field already has this value."),
|
|
1715
|
+
"422": problem2("Validation failed; `issues` lists each field."),
|
|
1716
|
+
...denied
|
|
1717
|
+
};
|
|
1718
|
+
item.patch = { operationId: `update${resource.name}`, tags: [tag], summary: `Update a ${resource.label.toLowerCase()}`, description: `Send only the fields to change. ${rolesNote(policy, "update")}`, parameters: [idParam], requestBody: body(`${resource.name}Update`), responses };
|
|
1719
|
+
item.put = { operationId: `replace${resource.name}`, tags: [tag], summary: `Replace a ${resource.label.toLowerCase()}`, description: `Send every field. ${rolesNote(policy, "update")}`, parameters: [idParam], requestBody: body(`${resource.name}Create`), responses };
|
|
1720
|
+
}
|
|
1721
|
+
if (can2("delete")) {
|
|
1722
|
+
item.delete = {
|
|
1723
|
+
operationId: `delete${resource.name}`,
|
|
1724
|
+
tags: [tag],
|
|
1725
|
+
summary: `Delete a ${resource.label.toLowerCase()}`,
|
|
1726
|
+
description: rolesNote(policy, "delete"),
|
|
1727
|
+
parameters: [idParam],
|
|
1728
|
+
responses: { "204": { description: "Deleted." }, "404": problem2("No record with this id."), "409": problem2("Other records still point at this one."), ...denied }
|
|
1729
|
+
};
|
|
1730
|
+
}
|
|
1731
|
+
if (Object.keys(collection).length) paths[`/api/${resource.slug}`] = collection;
|
|
1732
|
+
if (Object.keys(item).length) paths[`/api/${resource.slug}/{id}`] = item;
|
|
1733
|
+
}
|
|
1734
|
+
const visible = tags.length - 1;
|
|
1735
|
+
const intro = role === null && visibility === "role" ? "Sign in to see the endpoints available to you: use **Authentication \u2192 Sign in** below, or sign in to the app in this browser, then reload." : `${visible} resource API${visible === 1 ? "" : "s"} available to ${visibility === "public" ? "everyone" : `the **${role}** role`}.`;
|
|
1736
|
+
return {
|
|
1737
|
+
openapi: "3.1.0",
|
|
1738
|
+
info: {
|
|
1739
|
+
title: options.title ?? "API",
|
|
1740
|
+
version: options.version ?? "1.0.0",
|
|
1741
|
+
description: [options.description, intro, "Requests are authorized by the session cookie. Writes must be same-origin JSON (`Content-Type: application/json`)."].filter(Boolean).join("\n\n")
|
|
1742
|
+
},
|
|
1743
|
+
servers: options.serverUrl ? [{ url: options.serverUrl }] : void 0,
|
|
1744
|
+
security: [{ session: [] }],
|
|
1745
|
+
tags,
|
|
1746
|
+
paths,
|
|
1747
|
+
components: {
|
|
1748
|
+
schemas,
|
|
1749
|
+
securitySchemes: {
|
|
1750
|
+
session: { type: "apiKey", in: "cookie", name: "better-auth.session_token", description: "Set by signing in. Browsers send it automatically on same-origin requests." }
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
};
|
|
1754
|
+
}
|
|
312
1755
|
export {
|
|
313
1756
|
createResourceHandlers,
|
|
314
1757
|
createResourceStore,
|
|
1758
|
+
fieldJsonSchema,
|
|
315
1759
|
isFilterable,
|
|
316
1760
|
isSearchable,
|
|
317
1761
|
isSortable,
|
|
1762
|
+
openApiDocument,
|
|
318
1763
|
parseListQuery
|
|
319
1764
|
};
|