@adminiumjs/manifest 0.3.27 → 0.3.28

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 (78) hide show
  1. package/dist/app-grants.d.ts +134 -0
  2. package/dist/app-grants.d.ts.map +1 -0
  3. package/dist/app-grants.js +263 -0
  4. package/dist/app-grants.js.map +1 -0
  5. package/dist/automations.d.ts +2172 -56
  6. package/dist/automations.d.ts.map +1 -1
  7. package/dist/automations.js +438 -25
  8. package/dist/automations.js.map +1 -1
  9. package/dist/compose.d.ts.map +1 -1
  10. package/dist/compose.js +3 -0
  11. package/dist/compose.js.map +1 -1
  12. package/dist/documents.d.ts +1 -0
  13. package/dist/documents.d.ts.map +1 -1
  14. package/dist/documents.js +2 -0
  15. package/dist/documents.js.map +1 -1
  16. package/dist/index.d.ts +11 -5
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +10 -4
  19. package/dist/index.js.map +1 -1
  20. package/dist/ledgers.d.ts.map +1 -1
  21. package/dist/ledgers.js +2 -0
  22. package/dist/ledgers.js.map +1 -1
  23. package/dist/modules.d.ts +93 -0
  24. package/dist/modules.d.ts.map +1 -0
  25. package/dist/modules.js +489 -0
  26. package/dist/modules.js.map +1 -0
  27. package/dist/occupies.d.ts +50 -0
  28. package/dist/occupies.d.ts.map +1 -0
  29. package/dist/occupies.js +123 -0
  30. package/dist/occupies.js.map +1 -0
  31. package/dist/outbox.d.ts +223 -17
  32. package/dist/outbox.d.ts.map +1 -1
  33. package/dist/outbox.js +125 -13
  34. package/dist/outbox.js.map +1 -1
  35. package/dist/page-board.d.ts +144 -0
  36. package/dist/page-board.d.ts.map +1 -0
  37. package/dist/page-board.js +280 -0
  38. package/dist/page-board.js.map +1 -0
  39. package/dist/public-access.d.ts +6 -0
  40. package/dist/public-access.d.ts.map +1 -1
  41. package/dist/public-access.js +74 -0
  42. package/dist/public-access.js.map +1 -1
  43. package/dist/rail.d.ts +50 -0
  44. package/dist/rail.d.ts.map +1 -0
  45. package/dist/rail.js +122 -0
  46. package/dist/rail.js.map +1 -0
  47. package/dist/roles.d.ts +647 -1
  48. package/dist/roles.d.ts.map +1 -1
  49. package/dist/roles.js +459 -3
  50. package/dist/roles.js.map +1 -1
  51. package/dist/sample.d.ts +62 -0
  52. package/dist/sample.d.ts.map +1 -1
  53. package/dist/sample.js +203 -4
  54. package/dist/sample.js.map +1 -1
  55. package/dist/schema.d.ts +4277 -169
  56. package/dist/schema.d.ts.map +1 -1
  57. package/dist/schema.js +539 -40
  58. package/dist/schema.js.map +1 -1
  59. package/dist/shapes.d.ts +3 -2
  60. package/dist/shapes.d.ts.map +1 -1
  61. package/dist/shapes.js +76 -7
  62. package/dist/shapes.js.map +1 -1
  63. package/dist/state-actions.d.ts +4 -0
  64. package/dist/state-actions.d.ts.map +1 -1
  65. package/dist/state-actions.js +7 -0
  66. package/dist/state-actions.js.map +1 -1
  67. package/dist/states.d.ts +20 -1
  68. package/dist/states.d.ts.map +1 -1
  69. package/dist/states.js +47 -5
  70. package/dist/states.js.map +1 -1
  71. package/dist/validate.d.ts.map +1 -1
  72. package/dist/validate.js +41 -0
  73. package/dist/validate.js.map +1 -1
  74. package/dist/words.d.ts +1 -1
  75. package/dist/words.d.ts.map +1 -1
  76. package/dist/words.js +328 -1
  77. package/dist/words.js.map +1 -1
  78. package/package.json +2 -2
@@ -0,0 +1,144 @@
1
+ /**
2
+ * A board page's columns: `config.board` on a `page-board` page.
3
+ *
4
+ * Left to itself Adminium draws a board over the workflow enum it finds on the
5
+ * table, so a board's columns were a fixed list written into the app: a sales
6
+ * team could not add a stage of its own. An app says what the columns are
7
+ * instead:
8
+ *
9
+ * ```json
10
+ * "config": { "board": {
11
+ * "column": "stage_id",
12
+ * "columnsFrom": { "table": "crm_stages", "label": "name", "order": "position", "badge": { "column": "odds", "as": "percent" } },
13
+ * "title": "name",
14
+ * "totals": [{ "column": "amount", "fn": "sum" }, { "column": "weighted_value", "fn": "sum" }],
15
+ * "only": { "state": "open" },
16
+ * "card": { "link": "company_id.name", "person": "owner_id", "amount": "amount", "daysSince": { "column": "entered_stage_at", "warnFrom": 14, "alertFrom": 30 }, "date": "expected_close" },
17
+ * "note": { "text": "Columns come from Stages", "href": "/p/crm-stages" }
18
+ * } }
19
+ * ```
20
+ *
21
+ * - `column` (required): the column of the page's table a card is placed by.
22
+ * With `columnsFrom` it is a link to that table; without, an enum column,
23
+ * and the board's columns are the enum's values;
24
+ * - `columnsFrom`: the table whose rows are the board's columns — every row,
25
+ * a row with no card too — headed by its `label` column and ordered by its
26
+ * `order` column (left out: by its key). `badge` names one more column of
27
+ * those rows, shown small beside the heading: `as: "percent"` writes a
28
+ * share kept as a fraction (0.1) as "10%", `"number"` a plain number, and
29
+ * left out it is written as it is kept;
30
+ * - `title`: the column of the page's table a card is titled with;
31
+ * - `totals` (at most two): a number or money column of the page's table,
32
+ * summed or averaged over each column's cards and shown in its header;
33
+ * - `only` (one to three columns): which cards are on the board — a card is
34
+ * one when each column named holds its value, or one of its values. Both
35
+ * the cards listed and each header's count and totals are of those cards.
36
+ *
37
+ * - `card`: what a card shows under its title, each from a column of the
38
+ * page's table: `link` (`<link column>.<column of the row it points at>`:
39
+ * the company's name), `person` (a staff column, shown as the person's
40
+ * name), `amount` (a number or money), `daysSince` (days from a date or
41
+ * time column to today, by the server's clock; from `warnFrom` days the
42
+ * figure is amber and from `alertFrom` red; the longest-waiting cards come
43
+ * first) and `date` (a date or time, as a day);
44
+ * - `note`: one sentence drawn above the board, in the page's language
45
+ * (`text`, and `texts` by language as a page's `titles` are), with an
46
+ * optional `href` the whole note opens.
47
+ *
48
+ * Every figure and every name on the board is the READER's: a count and a
49
+ * total are of the cards their roles reach, a looked-up name is empty when
50
+ * its row is out of their reach, and a person is named as the people list
51
+ * names them.
52
+ *
53
+ * Every name is the app's own (a column ref), checked here against
54
+ * `requiredSchema`, so an app's CI refuses a typo long before an install.
55
+ */
56
+ import { z } from 'zod';
57
+ import { type ColumnShape, type ReferenceIssue, type TableIndex } from './refs.js';
58
+ /** How a header's figure is worked out of its cards. */
59
+ export declare const PAGE_BOARD_TOTAL_FNS: readonly ["sum", "avg"];
60
+ /** The most figures a column's header shows beside its count. */
61
+ export declare const PAGE_BOARD_TOTALS_MAX = 2;
62
+ /** The most columns `only` tests, and the most values one of them lists. */
63
+ export declare const PAGE_BOARD_ONLY_MAX = 3;
64
+ export declare const PAGE_BOARD_ONLY_VALUES_MAX = 20;
65
+ /** Column types `only` compares: a choice, a yes/no, a link, text, a whole number. */
66
+ export declare const PAGE_BOARD_ONLY_TYPES: readonly string[];
67
+ /** Column types a card's `daysSince` and `date` read. */
68
+ export declare const PAGE_BOARD_DAY_TYPES: readonly string[];
69
+ declare const onlyValueSchema: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>;
70
+ export declare const pageBoardOnlySchema: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>]>>;
71
+ /** One `only` entry's values as a list, whichever way it was written. */
72
+ export declare function pageBoardOnlyValues(value: z.infer<typeof onlyValueSchema> | z.infer<typeof onlyValueSchema>[]): (string | number | boolean)[];
73
+ /** How a column's badge is written. */
74
+ export declare const PAGE_BOARD_BADGE_AS: readonly ["text", "number", "percent"];
75
+ /** The most days a card's `warnFrom` / `alertFrom` names. */
76
+ export declare const PAGE_BOARD_DAYS_MAX = 3650;
77
+ export declare const pageBoardCardSchema: z.ZodObject<{
78
+ link: z.ZodOptional<z.ZodString>;
79
+ person: z.ZodOptional<z.ZodString>;
80
+ amount: z.ZodOptional<z.ZodString>;
81
+ daysSince: z.ZodOptional<z.ZodObject<{
82
+ column: z.ZodString;
83
+ warnFrom: z.ZodOptional<z.ZodNumber>;
84
+ alertFrom: z.ZodOptional<z.ZodNumber>;
85
+ }, z.core.$strict>>;
86
+ date: z.ZodOptional<z.ZodString>;
87
+ }, z.core.$strict>;
88
+ export declare const pageBoardNoteSchema: z.ZodObject<{
89
+ text: z.ZodString;
90
+ texts: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
91
+ href: z.ZodOptional<z.ZodString>;
92
+ }, z.core.$strict>;
93
+ export declare const pageBoardSchema: z.ZodObject<{
94
+ column: z.ZodString;
95
+ columnsFrom: z.ZodOptional<z.ZodObject<{
96
+ table: z.ZodString;
97
+ label: z.ZodString;
98
+ order: z.ZodOptional<z.ZodString>;
99
+ badge: z.ZodOptional<z.ZodObject<{
100
+ column: z.ZodString;
101
+ as: z.ZodOptional<z.ZodEnum<{
102
+ number: "number";
103
+ text: "text";
104
+ percent: "percent";
105
+ }>>;
106
+ }, z.core.$strict>>;
107
+ }, z.core.$strict>>;
108
+ card: z.ZodOptional<z.ZodObject<{
109
+ link: z.ZodOptional<z.ZodString>;
110
+ person: z.ZodOptional<z.ZodString>;
111
+ amount: z.ZodOptional<z.ZodString>;
112
+ daysSince: z.ZodOptional<z.ZodObject<{
113
+ column: z.ZodString;
114
+ warnFrom: z.ZodOptional<z.ZodNumber>;
115
+ alertFrom: z.ZodOptional<z.ZodNumber>;
116
+ }, z.core.$strict>>;
117
+ date: z.ZodOptional<z.ZodString>;
118
+ }, z.core.$strict>>;
119
+ note: z.ZodOptional<z.ZodObject<{
120
+ text: z.ZodString;
121
+ texts: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
122
+ href: z.ZodOptional<z.ZodString>;
123
+ }, z.core.$strict>>;
124
+ title: z.ZodOptional<z.ZodString>;
125
+ totals: z.ZodOptional<z.ZodArray<z.ZodObject<{
126
+ column: z.ZodString;
127
+ fn: z.ZodEnum<{
128
+ sum: "sum";
129
+ avg: "avg";
130
+ }>;
131
+ }, z.core.$strict>>>;
132
+ only: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>]>>>;
133
+ }, z.core.$strict>;
134
+ export type PageBoard = z.infer<typeof pageBoardSchema>;
135
+ /** What the check reads of a page. */
136
+ interface PageShape {
137
+ template: string;
138
+ bindings?: Readonly<Record<string, string>> | undefined;
139
+ config?: Readonly<Record<string, unknown>> | undefined;
140
+ }
141
+ /** Every problem with the pages' `config.board`, against the app's own tables. */
142
+ export declare function pageBoardIssues<C extends ColumnShape>(pages: readonly PageShape[], index: TableIndex<C>): ReferenceIssue[];
143
+ export {};
144
+ //# sourceMappingURL=page-board.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-board.d.ts","sourceRoot":"","sources":["../src/page-board.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAuC,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAExH,wDAAwD;AACxD,eAAO,MAAM,oBAAoB,yBAA0B,CAAC;AAE5D,iEAAiE;AACjE,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,sFAAsF;AACtF,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAAoD,CAAC;AAExG,yDAAyD;AACzD,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAAqD,CAAC;AAExG,QAAA,MAAM,eAAe,+DAA0E,CAAC;AAEhG,eAAO,MAAM,mBAAmB,2LAI5B,CAAC;AAEL,yEAAyE;AACzE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,EAAE,CAE7I;AAED,uCAAuC;AACvC,eAAO,MAAM,mBAAmB,wCAAyC,CAAC;AAE1E,6DAA6D;AAC7D,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAIxC,eAAO,MAAM,mBAAmB;;;;;;;;;;kBAayE,CAAC;AAE1G,eAAO,MAAM,mBAAmB;;;;kBAOrB,CAAC;AAEZ,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAiBjB,CAAC;AACZ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,sCAAsC;AACtC,UAAU,SAAS;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;IACxD,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;CACxD;AAQD,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,CAAC,SAAS,WAAW,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,cAAc,EAAE,CAgI1H"}
@@ -0,0 +1,280 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ /**
3
+ * A board page's columns: `config.board` on a `page-board` page.
4
+ *
5
+ * Left to itself Adminium draws a board over the workflow enum it finds on the
6
+ * table, so a board's columns were a fixed list written into the app: a sales
7
+ * team could not add a stage of its own. An app says what the columns are
8
+ * instead:
9
+ *
10
+ * ```json
11
+ * "config": { "board": {
12
+ * "column": "stage_id",
13
+ * "columnsFrom": { "table": "crm_stages", "label": "name", "order": "position", "badge": { "column": "odds", "as": "percent" } },
14
+ * "title": "name",
15
+ * "totals": [{ "column": "amount", "fn": "sum" }, { "column": "weighted_value", "fn": "sum" }],
16
+ * "only": { "state": "open" },
17
+ * "card": { "link": "company_id.name", "person": "owner_id", "amount": "amount", "daysSince": { "column": "entered_stage_at", "warnFrom": 14, "alertFrom": 30 }, "date": "expected_close" },
18
+ * "note": { "text": "Columns come from Stages", "href": "/p/crm-stages" }
19
+ * } }
20
+ * ```
21
+ *
22
+ * - `column` (required): the column of the page's table a card is placed by.
23
+ * With `columnsFrom` it is a link to that table; without, an enum column,
24
+ * and the board's columns are the enum's values;
25
+ * - `columnsFrom`: the table whose rows are the board's columns — every row,
26
+ * a row with no card too — headed by its `label` column and ordered by its
27
+ * `order` column (left out: by its key). `badge` names one more column of
28
+ * those rows, shown small beside the heading: `as: "percent"` writes a
29
+ * share kept as a fraction (0.1) as "10%", `"number"` a plain number, and
30
+ * left out it is written as it is kept;
31
+ * - `title`: the column of the page's table a card is titled with;
32
+ * - `totals` (at most two): a number or money column of the page's table,
33
+ * summed or averaged over each column's cards and shown in its header;
34
+ * - `only` (one to three columns): which cards are on the board — a card is
35
+ * one when each column named holds its value, or one of its values. Both
36
+ * the cards listed and each header's count and totals are of those cards.
37
+ *
38
+ * - `card`: what a card shows under its title, each from a column of the
39
+ * page's table: `link` (`<link column>.<column of the row it points at>`:
40
+ * the company's name), `person` (a staff column, shown as the person's
41
+ * name), `amount` (a number or money), `daysSince` (days from a date or
42
+ * time column to today, by the server's clock; from `warnFrom` days the
43
+ * figure is amber and from `alertFrom` red; the longest-waiting cards come
44
+ * first) and `date` (a date or time, as a day);
45
+ * - `note`: one sentence drawn above the board, in the page's language
46
+ * (`text`, and `texts` by language as a page's `titles` are), with an
47
+ * optional `href` the whole note opens.
48
+ *
49
+ * Every figure and every name on the board is the READER's: a count and a
50
+ * total are of the cards their roles reach, a looked-up name is empty when
51
+ * its row is out of their reach, and a person is named as the people list
52
+ * names them.
53
+ *
54
+ * Every name is the app's own (a column ref), checked here against
55
+ * `requiredSchema`, so an app's CI refuses a typo long before an install.
56
+ */
57
+ import { z } from 'zod';
58
+ import { NUMERIC_TYPES, refSchema, valueFits } from './refs.js';
59
+ /** How a header's figure is worked out of its cards. */
60
+ export const PAGE_BOARD_TOTAL_FNS = ['sum', 'avg'];
61
+ /** The most figures a column's header shows beside its count. */
62
+ export const PAGE_BOARD_TOTALS_MAX = 2;
63
+ /** The most columns `only` tests, and the most values one of them lists. */
64
+ export const PAGE_BOARD_ONLY_MAX = 3;
65
+ export const PAGE_BOARD_ONLY_VALUES_MAX = 20;
66
+ /** Column types `only` compares: a choice, a yes/no, a link, text, a whole number. */
67
+ export const PAGE_BOARD_ONLY_TYPES = ['enum', 'bool', 'fk', 'text', 'int', 'bigint'];
68
+ /** Column types a card's `daysSince` and `date` read. */
69
+ export const PAGE_BOARD_DAY_TYPES = ['date', 'timestamp', 'timestamptz', 'datetime'];
70
+ const onlyValueSchema = z.union([z.string().min(1).max(200), z.number().finite(), z.boolean()]);
71
+ export const pageBoardOnlySchema = z
72
+ .record(refSchema, z.union([onlyValueSchema, z.array(onlyValueSchema).min(1).max(PAGE_BOARD_ONLY_VALUES_MAX)]))
73
+ .refine((only) => Object.keys(only).length >= 1 && Object.keys(only).length <= PAGE_BOARD_ONLY_MAX, {
74
+ message: `only names one to ${String(PAGE_BOARD_ONLY_MAX)} columns`,
75
+ });
76
+ /** One `only` entry's values as a list, whichever way it was written. */
77
+ export function pageBoardOnlyValues(value) {
78
+ return Array.isArray(value) ? value : [value];
79
+ }
80
+ /** How a column's badge is written. */
81
+ export const PAGE_BOARD_BADGE_AS = ['text', 'number', 'percent'];
82
+ /** The most days a card's `warnFrom` / `alertFrom` names. */
83
+ export const PAGE_BOARD_DAYS_MAX = 3650;
84
+ const localeTag = z.string().regex(/^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$/);
85
+ export const pageBoardCardSchema = z
86
+ .object({
87
+ link: z.string().regex(/^[A-Za-z_][A-Za-z0-9_]*\.[A-Za-z_][A-Za-z0-9_]*$/).optional(),
88
+ person: refSchema.optional(),
89
+ amount: refSchema.optional(),
90
+ daysSince: z
91
+ .object({ column: refSchema, warnFrom: z.number().int().min(1).max(PAGE_BOARD_DAYS_MAX).optional(), alertFrom: z.number().int().min(1).max(PAGE_BOARD_DAYS_MAX).optional() })
92
+ .strict()
93
+ .refine((days) => days.warnFrom === undefined || days.alertFrom === undefined || days.warnFrom < days.alertFrom, { message: 'warnFrom comes before alertFrom' })
94
+ .optional(),
95
+ date: refSchema.optional(),
96
+ })
97
+ .strict()
98
+ .refine((card) => Object.keys(card).length > 0, { message: 'a card names at least one thing to show' });
99
+ export const pageBoardNoteSchema = z
100
+ .object({
101
+ text: z.string().min(1).max(200),
102
+ texts: z.record(localeTag, z.string().min(1).max(200)).optional(),
103
+ // A path of this workspace: never an address elsewhere, and never a script.
104
+ href: z.string().regex(/^\/(?!\/)[^\s\\]{0,299}$/).optional(),
105
+ })
106
+ .strict();
107
+ export const pageBoardSchema = z
108
+ .object({
109
+ column: refSchema,
110
+ columnsFrom: z
111
+ .object({ table: refSchema, label: refSchema, order: refSchema.optional(), badge: z.object({ column: refSchema, as: z.enum(PAGE_BOARD_BADGE_AS).optional() }).strict().optional() })
112
+ .strict()
113
+ .optional(),
114
+ card: pageBoardCardSchema.optional(),
115
+ note: pageBoardNoteSchema.optional(),
116
+ title: refSchema.optional(),
117
+ totals: z
118
+ .array(z.object({ column: refSchema, fn: z.enum(PAGE_BOARD_TOTAL_FNS) }).strict())
119
+ .min(1)
120
+ .max(PAGE_BOARD_TOTALS_MAX)
121
+ .optional(),
122
+ only: pageBoardOnlySchema.optional(),
123
+ })
124
+ .strict();
125
+ /** The table a page reads: its one binding, or the one keyed `rows`. */
126
+ function pageTable(page) {
127
+ const entries = Object.values(page.bindings ?? {});
128
+ return entries.length === 1 ? entries[0] : page.bindings?.['rows'];
129
+ }
130
+ /** Every problem with the pages' `config.board`, against the app's own tables. */
131
+ export function pageBoardIssues(pages, index) {
132
+ const out = [];
133
+ pages.forEach((page, p) => {
134
+ const raw = page.config?.['board'];
135
+ if (raw === undefined)
136
+ return;
137
+ const at = (...rest) => ['pages', p, 'config', 'board', ...rest];
138
+ const parsed = pageBoardSchema.safeParse(raw);
139
+ if (!parsed.success) {
140
+ for (const issue of parsed.error.issues)
141
+ out.push({ path: at(...issue.path.map((key) => (typeof key === 'symbol' ? String(key) : key))), message: issue.message });
142
+ return;
143
+ }
144
+ if (page.template !== 'page-board') {
145
+ out.push({ path: at(), message: `only a page-board takes its columns from config.board, not a ${page.template}` });
146
+ return;
147
+ }
148
+ const table = pageTable(page);
149
+ if (table === undefined || index.table(table) === undefined) {
150
+ out.push({ path: at(), message: 'a board names its columns on a page bound to a table of the app' });
151
+ return;
152
+ }
153
+ const board = parsed.data;
154
+ const column = index.column(table, board.column);
155
+ const from = board.columnsFrom;
156
+ if (column === undefined)
157
+ out.push({ path: at('column'), message: `"${table}" has no column "${board.column}"` });
158
+ else if (from === undefined) {
159
+ if (column.type !== 'enum')
160
+ out.push({ path: at('column'), message: `"${table}.${board.column}" is not an enum: name the table its columns come from in columnsFrom, or place cards by an enum column` });
161
+ }
162
+ else if (column.type !== 'fk' || column.references !== from.table) {
163
+ out.push({ path: at('column'), message: `"${table}.${board.column}" is not a link to "${from.table}"` });
164
+ }
165
+ if (from !== undefined) {
166
+ if (index.table(from.table) === undefined)
167
+ out.push({ path: at('columnsFrom', 'table'), message: `the app has no table "${from.table}"` });
168
+ else {
169
+ for (const key of ['label', 'order']) {
170
+ const name = from[key];
171
+ if (name !== undefined && !index.has(from.table, name))
172
+ out.push({ path: at('columnsFrom', key), message: `"${from.table}" has no column "${name}"` });
173
+ }
174
+ const badge = from.badge === undefined ? undefined : index.column(from.table, from.badge.column);
175
+ if (from.badge !== undefined && badge === undefined)
176
+ out.push({ path: at('columnsFrom', 'badge', 'column'), message: `"${from.table}" has no column "${from.badge.column}"` });
177
+ else if (badge !== undefined && from.badge?.as !== undefined && from.badge.as !== 'text' && !NUMERIC_TYPES.includes(badge.type)) {
178
+ out.push({ path: at('columnsFrom', 'badge', 'as'), message: `"${from.table}.${badge.ref}" is not a number, so it cannot be written as a ${from.badge.as}` });
179
+ }
180
+ }
181
+ }
182
+ if (board.title !== undefined && !index.has(table, board.title)) {
183
+ out.push({ path: at('title'), message: `"${table}" has no column "${board.title}"` });
184
+ }
185
+ (board.totals ?? []).forEach((total, t) => {
186
+ const summed = index.column(table, total.column);
187
+ if (summed === undefined)
188
+ out.push({ path: at('totals', t, 'column'), message: `"${table}" has no column "${total.column}"` });
189
+ else if (!NUMERIC_TYPES.includes(summed.type))
190
+ out.push({ path: at('totals', t, 'column'), message: `"${table}.${total.column}" is not a number or money, so it cannot be totalled` });
191
+ if ((board.totals ?? []).findIndex((other) => other.column === total.column && other.fn === total.fn) !== t) {
192
+ out.push({ path: at('totals', t), message: `"${total.column}" is totalled this way twice` });
193
+ }
194
+ });
195
+ const card = board.card ?? {};
196
+ if (card.link !== undefined) {
197
+ const [via, shown] = card.link.split('.');
198
+ const link = index.column(table, via);
199
+ if (link === undefined)
200
+ out.push({ path: at('card', 'link'), message: `"${table}" has no column "${via}"` });
201
+ else if (link.type !== 'fk' || link.references === undefined)
202
+ out.push({ path: at('card', 'link'), message: `"${table}.${via}" is not a link, so a card has no row to read "${shown}" from` });
203
+ // A link to a table the manifest cannot see (an add-on's) is judged at the install, by the real table.
204
+ else if (index.table(link.references) !== undefined && !index.has(link.references, shown))
205
+ out.push({ path: at('card', 'link'), message: `"${link.references}" has no column "${shown}"` });
206
+ }
207
+ if (card.person !== undefined) {
208
+ const person = index.column(table, card.person);
209
+ if (person === undefined)
210
+ out.push({ path: at('card', 'person'), message: `"${table}" has no column "${card.person}"` });
211
+ else if (person.rules?.staff !== true)
212
+ out.push({ path: at('card', 'person'), message: `"${table}.${card.person}" is not a staff column (rules.staff), so it holds no person to name` });
213
+ }
214
+ if (card.amount !== undefined) {
215
+ const amount = index.column(table, card.amount);
216
+ if (amount === undefined)
217
+ out.push({ path: at('card', 'amount'), message: `"${table}" has no column "${card.amount}"` });
218
+ else if (!NUMERIC_TYPES.includes(amount.type))
219
+ out.push({ path: at('card', 'amount'), message: `"${table}.${card.amount}" is not a number or money` });
220
+ }
221
+ for (const [key, name] of [['daysSince', card.daysSince?.column], ['date', card.date]]) {
222
+ if (name === undefined)
223
+ continue;
224
+ const day = index.column(table, name);
225
+ const here = key === 'daysSince' ? at('card', 'daysSince', 'column') : at('card', 'date');
226
+ if (day === undefined)
227
+ out.push({ path: here, message: `"${table}" has no column "${name}"` });
228
+ else if (!PAGE_BOARD_DAY_TYPES.includes(day.type))
229
+ out.push({ path: here, message: `"${table}.${name}" is a ${day.type}, not a date or a time` });
230
+ }
231
+ for (const [name, written] of Object.entries(board.only ?? {})) {
232
+ const tested = index.column(table, name);
233
+ if (tested === undefined) {
234
+ out.push({ path: at('only', name), message: `"${table}" has no column "${name}"` });
235
+ continue;
236
+ }
237
+ if (name === board.column) {
238
+ out.push({ path: at('only', name), message: `"${name}" is what the board's columns are: leave a column out of the board by its own table or enum, not by only` });
239
+ continue;
240
+ }
241
+ if (!PAGE_BOARD_ONLY_TYPES.includes(tested.type)) {
242
+ out.push({ path: at('only', name), message: `"${table}.${name}" is a ${tested.type}: only compares a choice, a yes/no, a link, text or a whole number` });
243
+ continue;
244
+ }
245
+ const values = pageBoardOnlyValues(written);
246
+ /*
247
+ * A link holds the key of the row it points at: a whole number or text,
248
+ * whichever that table is keyed by. Where the table is one of the app's
249
+ * own its key is known, and a value of the other kind is refused here:
250
+ * installed, the server could not compare it with the column, and every
251
+ * read of the board's columns would fail. A link to a table the manifest
252
+ * cannot see takes either, and the install judges it by the real column.
253
+ */
254
+ const linked = tested.type !== 'fk' || tested.references === undefined ? undefined : index.table(tested.references);
255
+ const key = linked === undefined ? undefined : (index.pk(linked.ref) ?? index.column(linked.ref, 'id'));
256
+ const fits = (value) => tested.type !== 'fk'
257
+ ? valueFits(tested, value)
258
+ : key === undefined
259
+ ? typeof value === 'string' || (typeof value === 'number' && Number.isInteger(value))
260
+ : valueFits({ ref: key.ref, type: key.type }, value);
261
+ const whole = key !== undefined && (key.type === 'int' || key.type === 'bigint');
262
+ for (const value of values) {
263
+ if (fits(value))
264
+ continue;
265
+ out.push({
266
+ path: at('only', name),
267
+ message: tested.type === 'enum' && typeof value === 'string'
268
+ ? `"${value}" is not one of the values of "${table}.${name}" (${(tested.enum ?? []).join(', ')})`
269
+ : key !== undefined && linked !== undefined
270
+ ? `${JSON.stringify(value)} is not a value "${table}.${name}" can hold: it links to "${linked.ref}", whose key is ${whole ? 'a whole number' : 'text'}`
271
+ : `${JSON.stringify(value)} is not a value "${table}.${name}" (${tested.type}) can hold`,
272
+ });
273
+ }
274
+ if (new Set(values).size !== values.length)
275
+ out.push({ path: at('only', name), message: `"${name}" lists a value twice` });
276
+ }
277
+ });
278
+ return out;
279
+ }
280
+ //# sourceMappingURL=page-board.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-board.js","sourceRoot":"","sources":["../src/page-board.ts"],"names":[],"mappings":"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"}
@@ -436,6 +436,7 @@ export declare const publicAccessSchema: z.ZodObject<{
436
436
  }, z.core.$strict>>;
437
437
  writableValues: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>>;
438
438
  requires: z.ZodOptional<z.ZodArray<z.ZodString>>;
439
+ requiresWhen: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>>>;
439
440
  writableWhen: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodArray<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodNull]>>, z.ZodLiteral<"from-now">, z.ZodLiteral<"from-today">, z.ZodLiteral<"before-today">, z.ZodObject<{
440
441
  within: z.ZodNumber;
441
442
  }, z.core.$strict>, z.ZodObject<{
@@ -684,6 +685,7 @@ export declare const publicAccessSchema: z.ZodObject<{
684
685
  when: z.ZodOptional<z.ZodLiteral<"anonymous">>;
685
686
  }, z.core.$strict>>>;
686
687
  key: z.ZodOptional<z.ZodString>;
688
+ module: z.ZodOptional<z.ZodString>;
687
689
  confirm: z.ZodOptional<z.ZodObject<{
688
690
  template: z.ZodEnum<{
689
691
  "booking-confirmation": "booking-confirmation";
@@ -841,6 +843,10 @@ interface PublicAccessContext {
841
843
  screensOnly?: boolean | undefined;
842
844
  cloneFrom?: string | undefined;
843
845
  permissions?: readonly string[] | undefined;
846
+ /** What the role is limited to, by table: read here only for whether its rows are (`rows`). */
847
+ limits?: Readonly<Record<string, {
848
+ rows?: unknown;
849
+ } | undefined>> | undefined;
844
850
  }[];
845
851
  /** The app's outbox, for a new link it emails (absent: the app has none). */
846
852
  outbox?: {
@@ -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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"}
@@ -476,6 +476,17 @@ export const publicAccessSchema = z
476
476
  * refused rather than stored half.
477
477
  */
478
478
  requires: z.array(refSchema).min(1).max(8).optional(),
479
+ /**
480
+ * Columns a write must fill only when it sets another column to one of
481
+ * some values, and may write at no other time: `{accepted_name: {status:
482
+ * [accepted]}}` — accepting carries the name typed, declining carries
483
+ * none, and a name sent with a decline is refused, so a declined quote
484
+ * never holds one a stranger typed.
485
+ */
486
+ requiresWhen: z
487
+ .record(refSchema, z.record(refSchema, valuesSchema).refine((when) => Object.keys(when).length === 1, { message: 'a column is asked for by one other column\'s values' }))
488
+ .refine((asked) => Object.keys(asked).length >= 1 && Object.keys(asked).length <= 8, { message: 'requiresWhen names 1 to 8 columns' })
489
+ .optional(),
479
490
  /**
480
491
  * The state a row must be IN to be changed — part of the update itself,
481
492
  * never of a read, so a finished visit still lists but cannot be moved.
@@ -551,6 +562,8 @@ export const publicAccessSchema = z
551
562
  .optional(),
552
563
  /** Which browser key serves the entry: `customer`, or one of `publicKeys`. */
553
564
  key: keyNameSchema.optional(),
565
+ /** The part of the app the entry belongs to: closed while it is off (see `modules.ts`). */
566
+ module: z.string().regex(/^[a-z][a-z0-9-]{0,39}$/, 'a module id is kebab-case').optional(),
554
567
  /**
555
568
  * The confirmation Adminium emails when a guest creates a row here: the
556
569
  * column holding their address, the columns the email shows, the app's
@@ -764,6 +777,27 @@ export function publicAccessIssues(entries, ctx) {
764
777
  message: `"${role.key}" signs in a screen anyone can walk up to, so it opens only the app's screens: screensOnly, and no grant but app:@:staff`,
765
778
  });
766
779
  }
780
+ /*
781
+ * A SCREEN'S KEY IS NOT HELD TO A PERSON'S ROWS: its entries show what
782
+ * they declare to everybody who signs the screen in. The screen's own role
783
+ * holds no table at all, so the person in front of it is somebody who
784
+ * also holds another role of the app — and where that role reaches only
785
+ * some rows of a table, the screen would show them the rest. So a table
786
+ * any role of the app limits by rows is not served through a screen's
787
+ * key: it is either shown on the screen to everybody, or limited by rows
788
+ * and kept off it.
789
+ */
790
+ entries.forEach((entry, i) => {
791
+ if (entry.key !== name)
792
+ return;
793
+ const limiting = ctx.roles.find((candidate) => candidate.limits?.[entry.table]?.rows !== undefined);
794
+ if (limiting !== undefined) {
795
+ out.push({
796
+ path: ['publicAccess', i, 'table'],
797
+ message: `"${name}" shows "${entry.table}" to everybody who signs the screen in, and "${limiting.key}" reaches only some of its rows: a screen's key is not held to a person's rows, so give the table one or the other`,
798
+ });
799
+ }
800
+ });
767
801
  if (key.enabledBy !== undefined) {
768
802
  const column = index.column(key.enabledBy.table, key.enabledBy.column);
769
803
  if (column?.type !== 'bool') {
@@ -877,6 +911,14 @@ export function publicAccessIssues(entries, ctx) {
877
911
  if (decided.has(ref))
878
912
  out.push({ path: at('writable'), message: `"${ref}" is decided by Adminium and cannot be written publicly` });
879
913
  }
914
+ // A file column names a file a signed-in staff member uploaded: a browser's key uploads nothing, so it names none.
915
+ for (const [list, refs] of [['writable', [...writable]], ['defaults', Object.keys(entry.defaults ?? {})]]) {
916
+ for (const ref of refs) {
917
+ const found = ctx.index.column(entry.table, ref);
918
+ if (found?.rules?.file !== undefined)
919
+ out.push({ path: at(list), message: `"${entry.table}.${ref}" holds files a signed-in person uploads, so a public write never sets it` });
920
+ }
921
+ }
880
922
  // A filter narrows every read AND write, so a column it names cannot also
881
923
  // change: the row would leave the endpoint mid-write — unless both ends
882
924
  // of the change are pinned, the state it starts from (`writableWhen`) and
@@ -1099,7 +1141,37 @@ export function publicAccessIssues(entries, ctx) {
1099
1141
  if (!writable.has(ref))
1100
1142
  out.push({ path: at('requires'), message: `"${ref}" is not writable, so a write cannot fill it` });
1101
1143
  }
1144
+ // A column asked for only with some values of another: both written here, and the values among those the other may take.
1145
+ for (const [ref, when] of Object.entries(entry.requiresWhen ?? {})) {
1146
+ const here = at('requiresWhen', ref);
1147
+ if (!writable.has(ref))
1148
+ out.push({ path: here, message: `"${ref}" is not writable, so a write cannot fill it` });
1149
+ if ((entry.requires ?? []).includes(ref))
1150
+ out.push({ path: here, message: `"${ref}" is required by every write already (requires): say one or the other` });
1151
+ for (const [other, values] of Object.entries(when)) {
1152
+ if (other === ref)
1153
+ out.push({ path: here, message: `"${ref}" is asked for by another column's values, not its own` });
1154
+ else if (!writable.has(other))
1155
+ out.push({ path: here, message: `"${other}" is not writable, so a write never sets it` });
1156
+ const pinned = entry.writableValues?.[other];
1157
+ if (pinned === undefined) {
1158
+ if (writable.has(other))
1159
+ out.push({ path: here, message: `"${other}" decides when "${ref}" is asked for: list the values it may take (writableValues)` });
1160
+ continue;
1161
+ }
1162
+ for (const value of values) {
1163
+ if (!pinned.some((allowed) => allowed === value))
1164
+ out.push({ path: here, message: `${JSON.stringify(value)} is not a value a write here may give "${other}"` });
1165
+ }
1166
+ }
1167
+ }
1102
1168
  const states = table.states;
1169
+ // The last day of a move of this table (`requires.notPast`) is the staff's to set: a guest who could write it would move their own deadline, then make the move.
1170
+ const lastDays = new Set(Object.values(states?.moves ?? {}).flatMap((moves) => moves.flatMap((move) => (typeof move === 'string' || move.requires?.notPast === undefined ? [] : [move.requires.notPast]))));
1171
+ for (const lastDay of lastDays) {
1172
+ if (writable.has(lastDay))
1173
+ out.push({ path: at('writable'), message: `"${lastDay}" is the last day of a move of "${entry.table}", so a write through this entry may not set it` });
1174
+ }
1103
1175
  for (const [ref, values] of Object.entries(entry.writableValues ?? {})) {
1104
1176
  if (!writable.has(ref))
1105
1177
  out.push({ path: at('writableValues', ref), message: `"${ref}" is not writable` });
@@ -2184,6 +2256,8 @@ function personIssues(entries, ctx, identities) {
2184
2256
  const declared = (box.producers ?? []).find((producer) => producer.kind === entry.newLink.kind);
2185
2257
  if (declared?.hold === true)
2186
2258
  out.push({ path: here('kind'), message: `"${entry.newLink.kind}" waits for a person to approve it, so it is never sent again from a link` });
2259
+ if (declared !== undefined && 'onDelete' in declared)
2260
+ out.push({ path: here('kind'), message: `"${entry.newLink.kind}" is written when a row is removed, so it is never sent from a link of a row that is there` });
2187
2261
  if (declared?.repeatBy !== undefined && declared.repeatBy !== entry.newLink.column) {
2188
2262
  out.push({ path: here('kind'), message: `"${entry.newLink.kind}" is sent once per "${declared.repeatBy}", so one sent again for a new "${entry.newLink.column}" would be skipped: its producer repeats by "${entry.newLink.column}" or by nothing` });
2189
2263
  }