@adminiumjs/manifest 0.3.42 → 0.3.44

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.
Files changed (47) hide show
  1. package/dist/automations.js +1 -1
  2. package/dist/automations.js.map +1 -1
  3. package/dist/change-guards.js +1 -1
  4. package/dist/change-guards.js.map +1 -1
  5. package/dist/check.d.ts +81 -0
  6. package/dist/check.d.ts.map +1 -0
  7. package/dist/check.js +130 -0
  8. package/dist/check.js.map +1 -0
  9. package/dist/expire.d.ts +46 -0
  10. package/dist/expire.d.ts.map +1 -0
  11. package/dist/expire.js +59 -0
  12. package/dist/expire.js.map +1 -0
  13. package/dist/formula.d.ts +6 -1
  14. package/dist/formula.d.ts.map +1 -1
  15. package/dist/formula.js +34 -6
  16. package/dist/formula.js.map +1 -1
  17. package/dist/index.d.ts +6 -4
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +6 -4
  20. package/dist/index.js.map +1 -1
  21. package/dist/page-config.d.ts +10 -1
  22. package/dist/page-config.d.ts.map +1 -1
  23. package/dist/page-config.js +81 -1
  24. package/dist/page-config.js.map +1 -1
  25. package/dist/people.d.ts +55 -4
  26. package/dist/people.d.ts.map +1 -1
  27. package/dist/people.js +88 -8
  28. package/dist/people.js.map +1 -1
  29. package/dist/public-access.d.ts +24 -1
  30. package/dist/public-access.d.ts.map +1 -1
  31. package/dist/public-access.js +201 -8
  32. package/dist/public-access.js.map +1 -1
  33. package/dist/roles.d.ts +4 -0
  34. package/dist/roles.d.ts.map +1 -1
  35. package/dist/roles.js +5 -0
  36. package/dist/roles.js.map +1 -1
  37. package/dist/schema.d.ts +822 -5
  38. package/dist/schema.d.ts.map +1 -1
  39. package/dist/schema.js +456 -20
  40. package/dist/schema.js.map +1 -1
  41. package/dist/validate.js +1 -1
  42. package/dist/validate.js.map +1 -1
  43. package/dist/words.d.ts +3 -1
  44. package/dist/words.d.ts.map +1 -1
  45. package/dist/words.js +167 -0
  46. package/dist/words.js.map +1 -1
  47. package/package.json +2 -2
@@ -181,11 +181,15 @@ export declare const codeWhereSchema: z.ZodArray<z.ZodUnion<readonly [z.ZodObjec
181
181
  * A value of the row that must agree with another: `column` (followed along
182
182
  * `path` through foreign keys) equals, is at most, or is at least the target.
183
183
  * `when` applies it only to rows whose value (along its own `path`) is one of
184
- * `in`.
184
+ * `in`. `length: true` compares how many characters a text value has, with
185
+ * `lte` alone: a line's lettering no longer than its product allows
186
+ * (`{ "column": "lettering", "length": true, "lte": { "via": "product_id",
187
+ * "column": "lettering_limit" } }`), refused as `too-long`.
185
188
  */
186
189
  export declare const agreeSchema: z.ZodObject<{
187
190
  column: z.ZodString;
188
191
  path: z.ZodOptional<z.ZodArray<z.ZodString>>;
192
+ length: z.ZodOptional<z.ZodLiteral<true>>;
189
193
  when: z.ZodOptional<z.ZodObject<{
190
194
  path: z.ZodOptional<z.ZodArray<z.ZodString>>;
191
195
  in: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
@@ -253,6 +257,7 @@ export declare const childEntrySchema: z.ZodObject<{
253
257
  agrees: z.ZodOptional<z.ZodArray<z.ZodObject<{
254
258
  column: z.ZodString;
255
259
  path: z.ZodOptional<z.ZodArray<z.ZodString>>;
260
+ length: z.ZodOptional<z.ZodLiteral<true>>;
256
261
  when: z.ZodOptional<z.ZodObject<{
257
262
  path: z.ZodOptional<z.ZodArray<z.ZodString>>;
258
263
  in: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
@@ -308,6 +313,7 @@ export declare const childEntrySchema: z.ZodObject<{
308
313
  column: z.ZodString;
309
314
  }, z.core.$strict>]>;
310
315
  }, z.core.$strict>>;
316
+ uploads: z.ZodOptional<z.ZodArray<z.ZodString>>;
311
317
  }, z.core.$strict>>>;
312
318
  via: z.ZodString;
313
319
  writable: z.ZodArray<z.ZodString>;
@@ -321,6 +327,7 @@ export declare const childEntrySchema: z.ZodObject<{
321
327
  agrees: z.ZodOptional<z.ZodArray<z.ZodObject<{
322
328
  column: z.ZodString;
323
329
  path: z.ZodOptional<z.ZodArray<z.ZodString>>;
330
+ length: z.ZodOptional<z.ZodLiteral<true>>;
324
331
  when: z.ZodOptional<z.ZodObject<{
325
332
  path: z.ZodOptional<z.ZodArray<z.ZodString>>;
326
333
  in: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
@@ -376,6 +383,7 @@ export declare const childEntrySchema: z.ZodObject<{
376
383
  column: z.ZodString;
377
384
  }, z.core.$strict>]>;
378
385
  }, z.core.$strict>>;
386
+ uploads: z.ZodOptional<z.ZodArray<z.ZodString>>;
379
387
  }, z.core.$strict>;
380
388
  export type ChildEntry = z.infer<typeof childEntrySchema>;
381
389
  export declare const publicAccessSchema: z.ZodObject<{
@@ -388,6 +396,7 @@ export declare const publicAccessSchema: z.ZodObject<{
388
396
  POST: "POST";
389
397
  PATCH: "PATCH";
390
398
  GET: "GET";
399
+ DELETE: "DELETE";
391
400
  }>>;
392
401
  select: z.ZodOptional<z.ZodArray<z.ZodString>>;
393
402
  writable: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -460,6 +469,7 @@ export declare const publicAccessSchema: z.ZodObject<{
460
469
  text: z.ZodRecord<z.ZodString, z.ZodString>;
461
470
  }, z.core.$strict>;
462
471
  }, z.core.$strict>>;
472
+ appColumn: z.ZodOptional<z.ZodString>;
463
473
  newLink: z.ZodOptional<z.ZodObject<{
464
474
  column: z.ZodString;
465
475
  kind: z.ZodString;
@@ -481,6 +491,7 @@ export declare const publicAccessSchema: z.ZodObject<{
481
491
  via: z.ZodString;
482
492
  }, z.core.$strict>>;
483
493
  files: z.ZodOptional<z.ZodArray<z.ZodString>>;
494
+ uploads: z.ZodOptional<z.ZodArray<z.ZodString>>;
484
495
  documents: z.ZodOptional<z.ZodArray<z.ZodString>>;
485
496
  sensitive: z.ZodOptional<z.ZodBoolean>;
486
497
  reason: z.ZodOptional<z.ZodString>;
@@ -533,6 +544,7 @@ export declare const publicAccessSchema: z.ZodObject<{
533
544
  agrees: z.ZodOptional<z.ZodArray<z.ZodObject<{
534
545
  column: z.ZodString;
535
546
  path: z.ZodOptional<z.ZodArray<z.ZodString>>;
547
+ length: z.ZodOptional<z.ZodLiteral<true>>;
536
548
  when: z.ZodOptional<z.ZodObject<{
537
549
  path: z.ZodOptional<z.ZodArray<z.ZodString>>;
538
550
  in: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
@@ -588,6 +600,7 @@ export declare const publicAccessSchema: z.ZodObject<{
588
600
  column: z.ZodString;
589
601
  }, z.core.$strict>]>;
590
602
  }, z.core.$strict>>;
603
+ uploads: z.ZodOptional<z.ZodArray<z.ZodString>>;
591
604
  }, z.core.$strict>>>;
592
605
  via: z.ZodString;
593
606
  writable: z.ZodArray<z.ZodString>;
@@ -601,6 +614,7 @@ export declare const publicAccessSchema: z.ZodObject<{
601
614
  agrees: z.ZodOptional<z.ZodArray<z.ZodObject<{
602
615
  column: z.ZodString;
603
616
  path: z.ZodOptional<z.ZodArray<z.ZodString>>;
617
+ length: z.ZodOptional<z.ZodLiteral<true>>;
604
618
  when: z.ZodOptional<z.ZodObject<{
605
619
  path: z.ZodOptional<z.ZodArray<z.ZodString>>;
606
620
  in: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
@@ -656,10 +670,12 @@ export declare const publicAccessSchema: z.ZodObject<{
656
670
  column: z.ZodString;
657
671
  }, z.core.$strict>]>;
658
672
  }, z.core.$strict>>;
673
+ uploads: z.ZodOptional<z.ZodArray<z.ZodString>>;
659
674
  }, z.core.$strict>>>;
660
675
  agrees: z.ZodOptional<z.ZodArray<z.ZodObject<{
661
676
  column: z.ZodString;
662
677
  path: z.ZodOptional<z.ZodArray<z.ZodString>>;
678
+ length: z.ZodOptional<z.ZodLiteral<true>>;
663
679
  when: z.ZodOptional<z.ZodObject<{
664
680
  path: z.ZodOptional<z.ZodArray<z.ZodString>>;
665
681
  in: z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
@@ -812,6 +828,7 @@ export declare const publicAccessSchema: z.ZodObject<{
812
828
  }, z.core.$strict>]>>>;
813
829
  }, z.core.$strict>]>>;
814
830
  pictures: z.ZodOptional<z.ZodArray<z.ZodString>>;
831
+ assets: z.ZodOptional<z.ZodArray<z.ZodString>>;
815
832
  withhold: z.ZodOptional<z.ZodObject<{
816
833
  columns: z.ZodArray<z.ZodString>;
817
834
  unlessHolder: z.ZodOptional<z.ZodString>;
@@ -891,6 +908,12 @@ interface PublicAccessContext {
891
908
  answersAvailability: (table: string) => boolean;
892
909
  /** The add-ons whose stock words an entry may be answered by: the ones the manifest names, and itself when it is one. Absent: not checked. */
893
910
  addOns?: ReadonlySet<string> | undefined;
911
+ /**
912
+ * The manifest is an add-on's: its entries with no key ride the `customer`
913
+ * key of each app it is attached to, whose own sign-in opens the sessions
914
+ * they are read with.
915
+ */
916
+ ridesAppKeys?: boolean | undefined;
894
917
  /** The table's limits, as it declares them (absent: the caller does not say). */
895
918
  capacityOf?: (table: string) => Capacity | undefined;
896
919
  publicKeys: Readonly<Record<string, PublicKey>> | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"public-access.d.ts","sourceRoot":"","sources":["../src/public-access.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"public-access.d.ts","sourceRoot":"","sources":["../src/public-access.ts"],"names":[],"mappings":"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"}
@@ -338,12 +338,16 @@ const agreeTargetSchema = z.union([
338
338
  * A value of the row that must agree with another: `column` (followed along
339
339
  * `path` through foreign keys) equals, is at most, or is at least the target.
340
340
  * `when` applies it only to rows whose value (along its own `path`) is one of
341
- * `in`.
341
+ * `in`. `length: true` compares how many characters a text value has, with
342
+ * `lte` alone: a line's lettering no longer than its product allows
343
+ * (`{ "column": "lettering", "length": true, "lte": { "via": "product_id",
344
+ * "column": "lettering_limit" } }`), refused as `too-long`.
342
345
  */
343
346
  export const agreeSchema = z
344
347
  .object({
345
348
  column: refSchema,
346
349
  path: pathSchema.optional(),
350
+ length: z.literal(true).optional(),
347
351
  when: z.object({ path: pathSchema.optional(), in: z.array(scalarSchema).min(1).max(32) }).strict().optional(),
348
352
  eq: agreeTargetSchema.optional(),
349
353
  lte: agreeTargetSchema.optional(),
@@ -390,6 +394,8 @@ const childEntryShape = {
390
394
  plainText: plainTextSchema.optional(),
391
395
  /** The most a column may add up to across the rows of one write (a dozen items to an order). */
392
396
  sumMax: sumMaxSchema.optional(),
397
+ /** File columns of the child a guest may upload into (`POST /public/uploads`), as on the entry itself. */
398
+ uploads: z.array(refSchema).min(1).max(8).optional(),
393
399
  };
394
400
  const childTablesSchema = (entry) => z.record(refSchema, entry).refine((children) => {
395
401
  const count = Object.keys(children).length;
@@ -462,7 +468,8 @@ export const publicAccessSchema = z
462
468
  .object({
463
469
  table: refSchema,
464
470
  kind: z.enum(['records', 'availability']).optional(),
465
- methods: z.array(z.enum(['GET', 'POST', 'PATCH'])).min(1),
471
+ /** `DELETE` only on an add-on's own link: its holder removes their own row while it is in a state the entry names. */
472
+ methods: z.array(z.enum(['GET', 'POST', 'PATCH', 'DELETE'])).min(1),
466
473
  select: z.array(refSchema).optional(),
467
474
  writable: z.array(refSchema).optional(),
468
475
  filters: z.array(z.union([valueFilterSchema, relativeFilterSchema])).optional(),
@@ -494,6 +501,14 @@ export const publicAccessSchema = z
494
501
  * unticked writes nothing: it takes back no earlier yes.
495
502
  */
496
503
  consent: publicConsentSchema.optional(),
504
+ /**
505
+ * On an add-on's entry, which rides the key of every app it is attached
506
+ * to: a text column of the table that holds the key of the app a row is
507
+ * for (`app`). Through an app's key the entry reads only the rows whose
508
+ * column holds that app's key, a create writes that key there (the
509
+ * browser cannot choose it), and a change never moves it.
510
+ */
511
+ appColumn: refSchema.optional(),
497
512
  /** On a signed-in person's rows: "Make a new link" for a row's own link. */
498
513
  newLink: newLinkSchema.optional(),
499
514
  /**
@@ -504,6 +519,14 @@ export const publicAccessSchema = z
504
519
  visibleWith: z.object({ table: refSchema, via: refSchema }).strict().optional(),
505
520
  /** File columns a claimed person may download (the file the row names, never by its id). */
506
521
  files: z.array(refSchema).min(1).max(8).optional(),
522
+ /**
523
+ * File columns a guest may upload into (`POST /public/uploads`): each a
524
+ * `writable` file column whose rule says what a guest may send
525
+ * (`rules.file.upload`). The upload is kept for a day; the guest's next
526
+ * create or change through this entry names it in the column, and it
527
+ * becomes the row's own file.
528
+ */
529
+ uploads: z.array(refSchema).min(1).max(8).optional(),
507
530
  /** The kinds of document a claimed person may list and open for these rows. */
508
531
  documents: z.array(z.string().regex(/^[a-z][a-z0-9-]*$/, 'a document kind')).min(1).max(8).optional(),
509
532
  /**
@@ -685,6 +708,13 @@ export const publicAccessSchema = z
685
708
  .optional(),
686
709
  /** Image columns any visitor may see, through the rows this entry reads. */
687
710
  pictures: z.array(refSchema).min(1).max(4).optional(),
711
+ /**
712
+ * File columns of product assets every visitor's browser may load,
713
+ * through the rows this entry reads (`GET /public/assets`): a preview
714
+ * model (GLB), a print model (STL, 3MF), a web font (WOFF2), an SVG piece.
715
+ * Each column holds files by a `file` rule that takes only those kinds.
716
+ */
717
+ assets: z.array(refSchema).min(1).max(8).optional(),
688
718
  /**
689
719
  * On rows reached through a parent: `columns` are left out unless
690
720
  * `unlessHolder` is empty or names the session's own person (a ticket
@@ -851,11 +881,40 @@ function formsEntryIssues(entry, i, entries, appKey, index) {
851
881
  }
852
882
  return out;
853
883
  }
884
+ /**
885
+ * An entry held to the app whose key serves it (`appColumn`): a text column
886
+ * of its table, never one a browser writes or a value the entry sets, and
887
+ * only on an entry that rides each app's own key (no key of the add-on's,
888
+ * no sign-in of its own).
889
+ */
890
+ function appColumnIssues(entries, index) {
891
+ const out = [];
892
+ entries.forEach((entry, i) => {
893
+ const column = entry.appColumn;
894
+ if (column === undefined)
895
+ return;
896
+ const at = ['publicAccess', i, 'appColumn'];
897
+ const found = index.column(entry.table, column);
898
+ if (found === undefined)
899
+ out.push({ path: at, message: `"${entry.table}" has no column "${column}"` });
900
+ else if (found.type !== 'text')
901
+ out.push({ path: at, message: `"${entry.table}.${column}" is not a text column, so it cannot hold an app's key` });
902
+ if ((entry.writable ?? []).includes(column) || Object.prototype.hasOwnProperty.call(entry.defaults ?? {}, column)) {
903
+ out.push({ path: at, message: `"${column}" holds the app whose key serves the entry: Adminium writes it, so it is neither writable nor a default` });
904
+ }
905
+ if ((entry.key ?? CUSTOMER_KEY) !== CUSTOMER_KEY)
906
+ out.push({ path: at, message: `an entry on "${String(entry.key)}" is served by no app's key, so it has no app to be held to` });
907
+ if (entry.claim !== undefined || entry.identity !== undefined)
908
+ out.push({ path: at, message: 'a sign-in entry is the key\'s own, and is held to no app' });
909
+ });
910
+ return out;
911
+ }
854
912
  /** Everything in `publicAccess` and `publicKeys` that names something undeclared, or breaks a rule. */
855
913
  export function publicAccessIssues(entries, ctx) {
856
914
  const out = [];
857
915
  const { index } = ctx;
858
916
  const has = index.has;
917
+ out.push(...appColumnIssues(entries, index));
859
918
  for (const [name, key] of Object.entries(ctx.publicKeys ?? {})) {
860
919
  const at = ['publicKeys', name];
861
920
  // The app's own key, named only for its peak: nothing more to check.
@@ -1030,14 +1089,25 @@ export function publicAccessIssues(entries, ctx) {
1030
1089
  if (patches && entry.claim === undefined && entry.visibleWith === undefined && (entry.claimedBy === undefined || entry.claimedBy.optional === true)) {
1031
1090
  out.push({ path: at('methods'), message: 'PATCH is allowed only with a claim' });
1032
1091
  }
1092
+ /*
1093
+ * A removal from a browser: only through an add-on's own link (a shopper
1094
+ * deleting their own saved draft), on the entry that opens the row by it.
1095
+ * Nothing else a guest holds removes a row.
1096
+ */
1097
+ if (entry.methods.includes('DELETE')) {
1098
+ const ownLink = ctx.ridesAppKeys === true && entry.key !== undefined && entry.claim !== undefined && 'by' in entry.claim && entry.claim.own === true;
1099
+ if (!ownLink)
1100
+ out.push({ path: at('methods'), message: "DELETE is allowed only on an add-on's own link, the entry that opens the row by it (claim by token, own)" });
1101
+ }
1033
1102
  // Nothing a server decides may be written by a browser.
1034
1103
  const decided = ctx.decided(entry.table);
1035
1104
  for (const ref of writable) {
1036
1105
  if (decided.has(ref))
1037
1106
  out.push({ path: at('writable'), message: `"${ref}" is decided by Adminium and cannot be written publicly` });
1038
1107
  }
1039
- // A file column names a file a signed-in staff member uploaded: a browser's key uploads nothing, so it names none.
1040
- for (const [list, refs] of [['writable', [...writable]], ['defaults', Object.keys(entry.defaults ?? {})]]) {
1108
+ // A file column names a file a signed-in staff member uploaded: a browser's key uploads nothing, so it names none —
1109
+ // but a guest's own upload, in a column the entry lets them upload into (`uploads`).
1110
+ for (const [list, refs] of [['writable', [...writable].filter((ref) => !(entry.uploads ?? []).includes(ref))], ['defaults', Object.keys(entry.defaults ?? {})]]) {
1041
1111
  for (const ref of refs) {
1042
1112
  const found = ctx.index.column(entry.table, ref);
1043
1113
  if (found?.rules?.file !== undefined)
@@ -1220,7 +1290,8 @@ export function publicAccessIssues(entries, ctx) {
1220
1290
  out.push({ path: at('visibleWith'), message: 'the entries it is visible with lead to no claimed person' });
1221
1291
  }
1222
1292
  for (const ref of entry.files ?? []) {
1223
- if (writable.has(ref))
1293
+ // A guest's own upload is written by naming it, and only a file they uploaded for the column is taken there.
1294
+ if (writable.has(ref) && !(entry.uploads ?? []).includes(ref))
1224
1295
  out.push({ path: at('files'), message: `"${ref}" is offered for download, so a browser never writes it` });
1225
1296
  const found = column(ref);
1226
1297
  if (found === undefined)
@@ -1325,7 +1396,7 @@ export function publicAccessIssues(entries, ctx) {
1325
1396
  !('within' in when) &&
1326
1397
  [when.after, when.before].some((end) => end !== undefined) &&
1327
1398
  [when.after, when.before].every((end) => end === undefined || end.column !== undefined));
1328
- if (entry.writableWhen !== undefined && !patches && !createWindow) {
1399
+ if (entry.writableWhen !== undefined && !patches && !entry.methods.includes('DELETE') && !createWindow) {
1329
1400
  out.push({ path: at('writableWhen'), message: "writableWhen limits a change, and this entry changes nothing (a child's create takes a window read from its parent, keyed by the link)" });
1330
1401
  }
1331
1402
  for (const [ref, when] of Object.entries(entry.writableWhen ?? {})) {
@@ -1505,6 +1576,13 @@ export function publicAccessIssues(entries, ctx) {
1505
1576
  out.push(...unlockIssues(entry, entry.unlockBy, entries, ctx, at));
1506
1577
  if (entry.pictures !== undefined)
1507
1578
  out.push(...pictureIssues(entry, entry.pictures, entries, ctx, at));
1579
+ if (entry.uploads !== undefined) {
1580
+ if (!entry.methods.includes('POST') && !entry.methods.includes('PATCH'))
1581
+ out.push({ path: at('uploads'), message: "a guest's upload is named by a create or a change, and this entry makes neither" });
1582
+ out.push(...uploadIssues(ctx.index, entry.table, entry.uploads, entry.writable ?? [], at('uploads')));
1583
+ }
1584
+ if (entry.assets !== undefined)
1585
+ out.push(...assetIssues(entry, entry.assets, entries, ctx, at));
1508
1586
  });
1509
1587
  out.push(...treeIssues(entries, ctx, identities, shareCodes));
1510
1588
  out.push(...personIssues(entries, ctx, identities));
@@ -1686,6 +1764,105 @@ function pictureIssues(entry, pictures, entries, ctx, at) {
1686
1764
  }
1687
1765
  return out;
1688
1766
  }
1767
+ /** The kinds of file a product asset may be (`ASSET_FILE_KINDS` in `schema.ts`, which imports this file). */
1768
+ const ASSET_KINDS = ['svg', 'glb', 'stl', '3mf', 'woff2'];
1769
+ /**
1770
+ * Product assets every visitor's browser loads: file columns the entry shows,
1771
+ * held to a model's, a font's or an SVG's kinds, which no browser writes. The
1772
+ * same shape as pictures: a viewer `fetch`es a model and `@font-face` loads a
1773
+ * font with no session, so the rows are read by every visitor alike.
1774
+ */
1775
+ function assetIssues(entry, assets, entries, ctx, at) {
1776
+ const out = [];
1777
+ if (entry.methods.length !== 1 || entry.methods[0] !== 'GET' || entry.kind === 'availability') {
1778
+ out.push({ path: at('assets'), message: 'assets are served through an entry that only reads rows' });
1779
+ }
1780
+ if (entry.claim !== undefined || entry.claimedBy !== undefined || entry.visibleWith !== undefined) {
1781
+ out.push({ path: at('assets'), message: "assets are for every visitor; a signed-in person's own files are `files`" });
1782
+ }
1783
+ if (entry.unlockBy !== undefined)
1784
+ out.push({ path: at('assets'), message: 'assets are for every visitor; rows a code unlocks are read only by whoever gave the code' });
1785
+ if (entry.level !== undefined && entry.claim === undefined && entry.claimedBy === undefined && entry.visibleWith === undefined) {
1786
+ out.push({ path: at('assets'), message: 'assets are for every visitor; rows read by a signed-in session alone are no asset a page loads for anyone' });
1787
+ }
1788
+ if ((entry.key ?? CUSTOMER_KEY) !== CUSTOMER_KEY)
1789
+ out.push({ path: at('key'), message: "assets are served through the app's customer key" });
1790
+ const writes = new Set([...(entry.writable ?? []), ...Object.keys(entry.defaults ?? {})]);
1791
+ const shareCodes = shareCodeColumns(entries, entry.table, ctx.index);
1792
+ const guests = guestUploadColumns(entries, entry.table);
1793
+ if (new Set(assets).size !== assets.length)
1794
+ out.push({ path: at('assets'), message: 'an asset column is named twice' });
1795
+ for (const ref of assets) {
1796
+ const found = ctx.index.column(entry.table, ref);
1797
+ if (found === undefined) {
1798
+ out.push({ path: at('assets'), message: `"${entry.table}" has no column "${ref}"` });
1799
+ continue;
1800
+ }
1801
+ const accept = found.rules?.file?.accept;
1802
+ if (accept === undefined || accept.length === 0 || accept.some((kind) => !ASSET_KINDS.includes(kind))) {
1803
+ out.push({ path: at('assets'), message: `"${entry.table}.${ref}" is not a column of assets: a file rule that takes only ${ASSET_KINDS.join(', ')}` });
1804
+ }
1805
+ if (writes.has(ref))
1806
+ out.push({ path: at('assets'), message: `"${ref}" is an asset every visitor loads, so a browser never writes it` });
1807
+ if (entry.select !== undefined && !entry.select.includes(ref))
1808
+ out.push({ path: at('assets'), message: `"${ref}" is not one of the columns the entry shows` });
1809
+ if ((entry.files ?? []).includes(ref))
1810
+ out.push({ path: at('assets'), message: `"${ref}" is a signed-in person's file, not an asset for everyone` });
1811
+ if ((entry.pictures ?? []).includes(ref))
1812
+ out.push({ path: at('assets'), message: `"${ref}" is a picture already; a column is one or the other` });
1813
+ if (found.rules?.secret === true || found.rules?.code !== undefined || shareCodes.includes(ref)) {
1814
+ out.push({ path: at('assets'), message: `"${entry.table}.${ref}" is kept from readers, so it is no asset for everyone` });
1815
+ }
1816
+ if (found.rules?.personal === true)
1817
+ out.push({ path: at('assets'), message: `"${entry.table}.${ref}" is personal data, so it is no asset for everyone` });
1818
+ if (guests.has(ref))
1819
+ out.push({ path: at('assets'), message: `guests upload into "${entry.table}.${ref}", and a guest's file is kept private, so it is no asset for everyone` });
1820
+ }
1821
+ return out;
1822
+ }
1823
+ /** The columns of `table` any entry lets a guest upload into, on the entry itself or on a level of its child rows. */
1824
+ function guestUploadColumns(entries, table) {
1825
+ const out = new Set();
1826
+ const walk = (children) => {
1827
+ for (const [name, child] of Object.entries(children ?? {})) {
1828
+ if (name === table)
1829
+ for (const ref of child.uploads ?? [])
1830
+ out.add(ref);
1831
+ walk(child.children);
1832
+ }
1833
+ };
1834
+ for (const entry of entries) {
1835
+ if (entry.table === table)
1836
+ for (const ref of entry.uploads ?? [])
1837
+ out.add(ref);
1838
+ walk(entry.children);
1839
+ }
1840
+ return out;
1841
+ }
1842
+ /**
1843
+ * The file columns a guest may upload into, at one level of an entry: each a
1844
+ * column of the table, written there, whose file rule says what a guest may
1845
+ * send (`rules.file.upload`). Named once each.
1846
+ */
1847
+ function uploadIssues(index, table, uploads, writable, path) {
1848
+ const out = [];
1849
+ if (new Set(uploads).size !== uploads.length)
1850
+ out.push({ path, message: 'each column is named once' });
1851
+ for (const ref of uploads) {
1852
+ const found = ruledColumn(index, table, ref);
1853
+ if (found === undefined) {
1854
+ out.push({ path, message: `"${table}" has no column "${ref}"` });
1855
+ continue;
1856
+ }
1857
+ if (found.rules?.file === undefined)
1858
+ out.push({ path, message: `"${table}.${ref}" holds no files: give it a file rule (rules.file)` });
1859
+ else if (found.rules.file.upload === undefined)
1860
+ out.push({ path, message: `"${table}.${ref}" does not say what a guest may upload: give its file rule an upload (kinds, maxBytes)` });
1861
+ if (!writable.includes(ref))
1862
+ out.push({ path, message: `"${ref}" is filled by naming the upload, so it is writable` });
1863
+ }
1864
+ return out;
1865
+ }
1689
1866
  /**
1690
1867
  * Whether an entry reads a table's rows: a GET that is not an availability
1691
1868
  * answer (free or full per slot, never a row), so it can be a child's parent.
@@ -1850,9 +2027,21 @@ function agreeIssues(index, table, parent, agree, at) {
1850
2027
  out.push({ path: at(test, 'column'), message: `"${via.references}" has no column "${target.column}"` });
1851
2028
  }
1852
2029
  }
1853
- else if (typeof reached !== 'string' && !agreeValueFits(reached.column, target.value)) {
2030
+ else if (agree.length !== true && typeof reached !== 'string' && !agreeValueFits(reached.column, target.value)) {
1854
2031
  out.push({ path: at(test, 'value'), message: `${JSON.stringify(target.value)} is not a value of "${reached.table}.${reached.column.ref}"` });
1855
2032
  }
2033
+ if (agree.length === true) {
2034
+ // How many characters a text has, at most a number: the text is the row's, the most is a number.
2035
+ if (test !== 'lte')
2036
+ out.push({ path: at(test), message: 'a length is compared with lte (at most so many characters)' });
2037
+ if (typeof reached !== 'string' && reached.column.type !== 'text')
2038
+ out.push({ path: at('length'), message: `"${reached.table}.${reached.column.ref}" is not text, so it has no length` });
2039
+ if (other !== undefined && !NUMBERS.includes(other.type))
2040
+ out.push({ path: at(test), message: `"${other.ref}" is not a number, so it is no most characters` });
2041
+ if ('value' in target && (typeof target.value !== 'number' || !Number.isInteger(target.value) || target.value < 0))
2042
+ out.push({ path: at(test, 'value'), message: 'the most characters is a whole number' });
2043
+ return out;
2044
+ }
1856
2045
  if (typeof reached !== 'string') {
1857
2046
  if (test !== 'eq' && !NUMBERS.includes(reached.column.type)) {
1858
2047
  out.push({ path: at(test), message: `"${reached.table}.${reached.column.ref}" is not a number, so it is not at most or at least another` });
@@ -2093,6 +2282,8 @@ function treeIssues(entries, ctx, identities, shareCodes) {
2093
2282
  }
2094
2283
  }
2095
2284
  out.push(...boundIssues(index, ctx, name, child.writable, here('writable')));
2285
+ if (child.uploads !== undefined)
2286
+ out.push(...uploadIssues(index, name, child.uploads, child.writable, here('uploads')));
2096
2287
  (child.agrees ?? []).forEach((agree, a) => out.push(...agreeIssues(index, name, parent, agree, (...rest) => here('agrees', a, ...rest))));
2097
2288
  (child.counts ?? []).forEach((counts, c) => out.push(...countsIssues(index, name, parent, counts, (...rest) => here('counts', c, ...rest))));
2098
2289
  if (child.children !== undefined) {
@@ -2429,7 +2620,9 @@ function personIssues(entries, ctx, identities) {
2429
2620
  if (entry.level !== undefined && entry.claim === undefined && entry.claimedBy === undefined && entry.visibleWith === undefined) {
2430
2621
  if (entry.methods.length !== 1 || entry.methods[0] !== 'GET')
2431
2622
  out.push({ path: at('methods'), message: 'a read for a signed-in guest alone only reads' });
2432
- if (!identities.has(key))
2623
+ // An add-on's entry on an app's key is read with a session the app's own sign-in opened (a guest who found their order).
2624
+ const appSignsIn = ctx.ridesAppKeys === true && key === CUSTOMER_KEY;
2625
+ if (!identities.has(key) && !appSignsIn)
2433
2626
  out.push({ path: at('level'), message: `the "${key}" key signs nobody in, so no session could read this` });
2434
2627
  if (entry.select === undefined)
2435
2628
  out.push({ path: at('select'), message: 'a read for a signed-in guest lists what it shows; without select it would show every column' });