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.
@@ -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({ where: { id: input.questionId } });
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({ where: { id: input.choiceId } });
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
- where: { id: choice.id },
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
- limit?: number;
22
- offset?: number;
23
- order?: Order<Schema, Table>;
24
- where?: Where<Schema, Table>;
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(query: {
31
- set: Partial<InferOutput<Schema[Table]>>;
32
- where: Where<Schema, Table>;
33
- }): void;
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
- | { [K in keyof Schema[Table]["entries"]]?: null | { desc: true } }
107
- | { [K in keyof Schema[Table]["entries"]]?: null | { desc: true } }[];
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
- : // Question.quizId, Quiz.id -> Question.Quiz.
200
- Own extends `${Uncapitalize<Other>}${Capitalize<Its>}`
201
- ? Other
202
- : // Quiz.coverId, Image.id -> Quiz.cover.
203
- Own extends `${infer R}${Capitalize<Its>}`
204
- ? R
205
- : // Image.id, Quiz.coverId -> Image.CoverQuiz.
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 Its == `${uncapitalize(Self)}${capitalize(Own)}`
112
- ? Other
113
- : // Question.quizId, Quiz.id -> Question.Quiz.
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "evikit",
3
3
  "description": "Preact/SQLite SSR framework for small web apps",
4
- "version": "2.11.0",
4
+ "version": "2.12.0",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": "./index.js",
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({ where }))
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: import("./db.d.ts").Where<typeof schema, typeof table> }} props */
339
- update({ set, where }) {
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({ where }),
347
+ whereQuery(wherePropertyOrSelf(query)),
348
348
  )
349
349
  .run(
350
350
  ...[
351
- ...Object.values(set).map((value) => value ?? null),
352
- ...whereValues(where),
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({ where: props.join?.where }) +
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?.where));
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
- /** @param {{ alias?: string, where: import("./db.js").Where<any, string> | undefined }} props */
547
- function whereQuery({ alias, where }) {
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.values(where || {})
583
- .flatMap((values) =>
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"