evikit 2.11.0 → 2.12.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/.woodpecker/test.yaml +12 -0
- package/README.md +6 -6
- package/db.d.ts +26 -22
- package/db.js +5 -5
- package/package.json +1 -1
- package/sqlite.js +34 -18
package/.woodpecker/test.yaml
CHANGED
|
@@ -24,3 +24,15 @@ steps:
|
|
|
24
24
|
- (cd lanquiz/node_modules; git clone ../.. evikit)
|
|
25
25
|
- (cd lanquiz; npm run build)
|
|
26
26
|
- (cd lanquiz; npm test -- --test-concurrency=1)
|
|
27
|
+
# Do other real-world applications build? 1/2
|
|
28
|
+
- git clone https://codeberg.org/nykula/mobhub
|
|
29
|
+
- (cd mobhub; npm i)
|
|
30
|
+
- rm -rf mobhub/node_modules/evikit
|
|
31
|
+
- (cd mobhub/node_modules; git clone ../.. evikit)
|
|
32
|
+
- (cd mobhub; npm run build)
|
|
33
|
+
# Do other real-world applications build? 2/2
|
|
34
|
+
- git clone https://codeberg.org/nykula/yoself
|
|
35
|
+
- (cd yoself; npm i)
|
|
36
|
+
- rm -rf yoself/node_modules/evikit
|
|
37
|
+
- (cd yoself/node_modules; git clone ../.. evikit)
|
|
38
|
+
- (cd yoself; npm run build)
|
package/README.md
CHANGED
|
@@ -473,8 +473,8 @@ export const QuestionIdServer = {
|
|
|
473
473
|
get: endpoint(QuestionIdGet, async ({ input }) => {
|
|
474
474
|
const i18n = await getI18n(input.lang);
|
|
475
475
|
const [question] = db.Question.select({
|
|
476
|
+
id: input.id,
|
|
476
477
|
with: { Choice: true },
|
|
477
|
-
where: { id: input.id },
|
|
478
478
|
});
|
|
479
479
|
// It maps join results to objects, for example you can get:
|
|
480
480
|
// question?.Choice[0]?.text
|
|
@@ -557,7 +557,7 @@ export const ChoiceServer = {
|
|
|
557
557
|
post: endpoint(ChoicePost, async ({ input }) => {
|
|
558
558
|
const i18n = await getI18n(input.lang);
|
|
559
559
|
|
|
560
|
-
const [question] = db.Question.select({
|
|
560
|
+
const [question] = db.Question.select({ id: input.questionId });
|
|
561
561
|
if (!question) {
|
|
562
562
|
return text(i18n.gettext("Question does not exist"), 400);
|
|
563
563
|
}
|
|
@@ -638,7 +638,7 @@ export const VoteServer = {
|
|
|
638
638
|
post: endpoint(VotePost, async ({ input }) => {
|
|
639
639
|
const i18n = await getI18n(input.lang);
|
|
640
640
|
|
|
641
|
-
const [choice] = db.Choice.select({
|
|
641
|
+
const [choice] = db.Choice.select({ id: input.choiceId });
|
|
642
642
|
if (!choice) {
|
|
643
643
|
return text(i18n.gettext("You didn't select a choice"), 400);
|
|
644
644
|
}
|
|
@@ -648,9 +648,9 @@ export const VoteServer = {
|
|
|
648
648
|
}
|
|
649
649
|
|
|
650
650
|
db.Choice.update({
|
|
651
|
+
id: choice.id,
|
|
651
652
|
set: { votes: choice.votes + 1 },
|
|
652
|
-
|
|
653
|
-
// To update multiple choices, pass an array of ids to `where.id`.
|
|
653
|
+
// To update multiple choices, pass an array of ids to `id`.
|
|
654
654
|
});
|
|
655
655
|
// To delete a choice: `db.Choice.delete({ id: choice.id })`.
|
|
656
656
|
// To delete multiple choices, pass an array of ids to `id`.
|
|
@@ -790,8 +790,8 @@ import { ok } from "node:assert/strict";
|
|
|
790
790
|
// ...
|
|
791
791
|
|
|
792
792
|
const [question] = db.Question.select({
|
|
793
|
+
id: input.id,
|
|
793
794
|
with: { Choice: { with: { iconStorage: true } } },
|
|
794
|
-
where: { id: input.id },
|
|
795
795
|
});
|
|
796
796
|
|
|
797
797
|
// ...
|
package/db.d.ts
CHANGED
|
@@ -17,20 +17,23 @@ export type Db<
|
|
|
17
17
|
delete(where: Where<Schema, Table>): void;
|
|
18
18
|
|
|
19
19
|
select<
|
|
20
|
-
W extends Partial<Join<R, Table>> &
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
W extends Partial<Join<R, Table>> &
|
|
21
|
+
Where<Schema, Table> & {
|
|
22
|
+
limit?: number;
|
|
23
|
+
offset?: number;
|
|
24
|
+
order?: Order<Schema, Table>;
|
|
25
|
+
/** @deprecated */ where?: Where<Schema, Table>;
|
|
26
|
+
},
|
|
26
27
|
>(
|
|
27
28
|
props?: W,
|
|
28
29
|
): Select<Schema, R, F, Table, W>[];
|
|
29
30
|
|
|
30
|
-
update(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
update(
|
|
32
|
+
query: Where<Schema, Table> & {
|
|
33
|
+
set: Partial<InferOutput<Schema[Table]>>;
|
|
34
|
+
/** @deprecated */ where?: Where<Schema, Table>;
|
|
35
|
+
},
|
|
36
|
+
): void;
|
|
34
37
|
|
|
35
38
|
upsert(
|
|
36
39
|
...values: InferInput<Schema[Table]>[]
|
|
@@ -103,8 +106,12 @@ export type Order<
|
|
|
103
106
|
Schema extends Record<string, ObjectSchema<any, any>>,
|
|
104
107
|
Table extends keyof Schema,
|
|
105
108
|
> =
|
|
106
|
-
| {
|
|
107
|
-
|
|
109
|
+
| {
|
|
110
|
+
[K in keyof Schema[Table]["entries"]]?: null | true | { desc: true };
|
|
111
|
+
}
|
|
112
|
+
| {
|
|
113
|
+
[K in keyof Schema[Table]["entries"]]?: null | true | { desc: true };
|
|
114
|
+
}[];
|
|
108
115
|
|
|
109
116
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
110
117
|
export type Relations<Schema extends Record<string, ObjectSchema<any, any>>> = {
|
|
@@ -196,16 +203,13 @@ type Rewrite<
|
|
|
196
203
|
// Image.id, Question.imageId -> Image.Question.
|
|
197
204
|
Its extends `${Uncapitalize<Self>}${Capitalize<Own>}`
|
|
198
205
|
? Other
|
|
199
|
-
: //
|
|
200
|
-
Own extends `${
|
|
201
|
-
?
|
|
202
|
-
: //
|
|
203
|
-
|
|
204
|
-
? R
|
|
205
|
-
:
|
|
206
|
-
Its extends `${infer R}${Capitalize<Own>}`
|
|
207
|
-
? `${Capitalize<R>}${Other}`
|
|
208
|
-
: never;
|
|
206
|
+
: // Quiz.coverId, Image.id -> Quiz.cover.
|
|
207
|
+
Own extends `${infer R}${Capitalize<Its>}`
|
|
208
|
+
? R
|
|
209
|
+
: // Image.id, Quiz.coverId -> Image.CoverQuiz.
|
|
210
|
+
Its extends `${infer R}${Capitalize<Own>}`
|
|
211
|
+
? `${Capitalize<R>}${Other}`
|
|
212
|
+
: never;
|
|
209
213
|
|
|
210
214
|
type Select<
|
|
211
215
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
package/db.js
CHANGED
|
@@ -108,10 +108,9 @@ function capitalize(input) {
|
|
|
108
108
|
* @param {string} Its
|
|
109
109
|
*/
|
|
110
110
|
function rewrite(Self, Own, Other, Its) {
|
|
111
|
-
return
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
Own == `${uncapitalize(Other)}${capitalize(Its)}`
|
|
111
|
+
return (
|
|
112
|
+
// Image.id, Question.imageId -> Image.Question.
|
|
113
|
+
Its == `${uncapitalize(Self)}${capitalize(Own)}`
|
|
115
114
|
? Other
|
|
116
115
|
: // Quiz.coverId, Image.id -> Quiz.cover.
|
|
117
116
|
Own.endsWith(capitalize(Its))
|
|
@@ -119,7 +118,8 @@ function rewrite(Self, Own, Other, Its) {
|
|
|
119
118
|
: // Image.id, Quiz.coverId -> Image.CoverQuiz.
|
|
120
119
|
Its.endsWith(capitalize(Own))
|
|
121
120
|
? `${capitalize(Its.slice(0, -Own.length))}${Other}`
|
|
122
|
-
: undefined
|
|
121
|
+
: undefined
|
|
122
|
+
);
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
/** @param {string} input */
|
package/package.json
CHANGED
package/sqlite.js
CHANGED
|
@@ -323,7 +323,7 @@ export function sqlite({ pkg, schema }) {
|
|
|
323
323
|
delete(where) {
|
|
324
324
|
if (
|
|
325
325
|
database
|
|
326
|
-
.prepare(`delete from ${table}` + whereQuery(
|
|
326
|
+
.prepare(`delete from ${table}` + whereQuery(where))
|
|
327
327
|
.run(...whereValues(where)).changes
|
|
328
328
|
) {
|
|
329
329
|
publish({ table });
|
|
@@ -335,21 +335,23 @@ export function sqlite({ pkg, schema }) {
|
|
|
335
335
|
return select({ database, flat, join, schema, table });
|
|
336
336
|
},
|
|
337
337
|
|
|
338
|
-
/** @param {{ set: Partial<import("valibot").InferOutput<(typeof schema)[typeof table]>>, where
|
|
339
|
-
update(
|
|
338
|
+
/** @param {import("./db.d.ts").Where<typeof schema, typeof table> & { set: Partial<import("valibot").InferOutput<(typeof schema)[typeof table]>>, where?: import("./db.d.ts").Where<typeof schema, typeof table> }} query */
|
|
339
|
+
update(query) {
|
|
340
340
|
if (
|
|
341
341
|
database
|
|
342
342
|
.prepare(
|
|
343
343
|
`update ${table} set\n` +
|
|
344
|
-
Object.keys(set)
|
|
344
|
+
Object.keys(query.set)
|
|
345
345
|
.map((name) => `${name} = ?`)
|
|
346
346
|
.join(",\n") +
|
|
347
|
-
whereQuery(
|
|
347
|
+
whereQuery(wherePropertyOrSelf(query)),
|
|
348
348
|
)
|
|
349
349
|
.run(
|
|
350
350
|
...[
|
|
351
|
-
...Object.values(set).map(
|
|
352
|
-
|
|
351
|
+
...Object.values(query.set).map(
|
|
352
|
+
(value) => value ?? null,
|
|
353
|
+
),
|
|
354
|
+
...whereValues(wherePropertyOrSelf(query)),
|
|
353
355
|
],
|
|
354
356
|
).changes
|
|
355
357
|
) {
|
|
@@ -391,12 +393,12 @@ export function sqlite({ pkg, schema }) {
|
|
|
391
393
|
};
|
|
392
394
|
}
|
|
393
395
|
|
|
394
|
-
/** @type {<Schema extends Record<string, import("valibot").ObjectSchema<any, any>>, R extends import("./db.d.ts").Relations<Schema> = import("./db.d.ts").Relations<Schema>, F extends import("./db.d.ts").Flatten<Schema> = import("./db.d.ts").Flatten<Schema>, Table extends keyof F & keyof Schema = keyof F & keyof Schema >(props: { database: DatabaseSync; flat: F; join?: import("./db.d.ts").Join<R, Table> & { limit?: number, offset?: number, order?: import("./db.d.ts").Order<Schema, Table>, where?: import("./db.d.ts").Where<Schema, Table> }; schema: Schema; table: Table; }) => any[]} */
|
|
396
|
+
/** @type {<Schema extends Record<string, import("valibot").ObjectSchema<any, any>>, R extends import("./db.d.ts").Relations<Schema> = import("./db.d.ts").Relations<Schema>, F extends import("./db.d.ts").Flatten<Schema> = import("./db.d.ts").Flatten<Schema>, Table extends keyof F & keyof Schema = keyof F & keyof Schema >(props: { database: DatabaseSync; flat: F; join?: import("./db.d.ts").Join<R, Table> & import("./db.d.ts").Where<Schema, Table> & { limit?: number, offset?: number, order?: import("./db.d.ts").Order<Schema, Table>, where?: import("./db.d.ts").Where<Schema, Table> }; schema: Schema; table: Table; }) => any[]} */
|
|
395
397
|
function select(props) {
|
|
396
398
|
ok(typeof props.table == "string");
|
|
397
399
|
let sql =
|
|
398
400
|
`select * from ${props.table}` +
|
|
399
|
-
whereQuery(
|
|
401
|
+
whereQuery(wherePropertyOrSelf(props.join)) +
|
|
400
402
|
(props.join?.order
|
|
401
403
|
? "\norder by " +
|
|
402
404
|
(Array.isArray(props.join.order)
|
|
@@ -405,7 +407,7 @@ function select(props) {
|
|
|
405
407
|
)
|
|
406
408
|
.flatMap((column) =>
|
|
407
409
|
Object.entries(column).map(([name, props]) =>
|
|
408
|
-
props?.desc ? `${name} desc` : name,
|
|
410
|
+
typeof props == "object" && props?.desc ? `${name} desc` : name,
|
|
409
411
|
),
|
|
410
412
|
)
|
|
411
413
|
.join(", ")
|
|
@@ -469,7 +471,7 @@ function select(props) {
|
|
|
469
471
|
|
|
470
472
|
const rows = props.database
|
|
471
473
|
.prepare(sql)
|
|
472
|
-
.all(...whereValues(props.join
|
|
474
|
+
.all(...whereValues(wherePropertyOrSelf(props.join)));
|
|
473
475
|
if (!(/** @type {any} */ (props.join)?.with)) {
|
|
474
476
|
for (const row of rows) {
|
|
475
477
|
for (const name of Object.keys(row)) {
|
|
@@ -543,15 +545,28 @@ function select(props) {
|
|
|
543
545
|
return state.entities;
|
|
544
546
|
}
|
|
545
547
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
+
let deprecatedFound = false;
|
|
549
|
+
/** @param {{ where?: any } | undefined} props */
|
|
550
|
+
function wherePropertyOrSelf(props) {
|
|
551
|
+
if (props?.where) {
|
|
552
|
+
if (!deprecatedFound) {
|
|
553
|
+
deprecatedFound = true;
|
|
554
|
+
console.error(
|
|
555
|
+
"`where: {}` is deprecated, move its properties one level above",
|
|
556
|
+
);
|
|
557
|
+
}
|
|
558
|
+
return props.where;
|
|
559
|
+
}
|
|
560
|
+
return props;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/** @param {import("./db.js").Where<any, string> | undefined} where */
|
|
564
|
+
function whereQuery(where) {
|
|
548
565
|
return (
|
|
549
566
|
"\nwhere true\n" +
|
|
550
567
|
Object.entries(where || {})
|
|
568
|
+
.filter(([name]) => !/^(limit|offset|order|set|with)$/.test(name))
|
|
551
569
|
.map(([name, values]) => {
|
|
552
|
-
if (alias) {
|
|
553
|
-
name = `${alias}.${name}`;
|
|
554
|
-
}
|
|
555
570
|
return Array.isArray(values)
|
|
556
571
|
? `and ${name} in (${values.map(() => "?").join(", ")})`
|
|
557
572
|
: typeof values == "number" || typeof values == "string"
|
|
@@ -579,8 +594,9 @@ function whereQuery({ alias, where }) {
|
|
|
579
594
|
|
|
580
595
|
/** @param {import("./db.js").Where<any, string> | undefined} where */
|
|
581
596
|
function whereValues(where) {
|
|
582
|
-
return Object.
|
|
583
|
-
.
|
|
597
|
+
return Object.entries(where || {})
|
|
598
|
+
.filter(([name]) => !/^(limit|offset|order|set|with)$/.test(name))
|
|
599
|
+
.flatMap(([, values]) =>
|
|
584
600
|
Array.isArray(values)
|
|
585
601
|
? values
|
|
586
602
|
: typeof values == "number" || typeof values == "string"
|