@adminiumjs/manifest 0.3.27 → 0.3.29

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 (83) 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 +2255 -58
  6. package/dist/automations.d.ts.map +1 -1
  7. package/dist/automations.js +450 -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/plan-context.d.ts.map +1 -1
  40. package/dist/plan-context.js +3 -0
  41. package/dist/plan-context.js.map +1 -1
  42. package/dist/plan-model.d.ts +7 -0
  43. package/dist/plan-model.d.ts.map +1 -1
  44. package/dist/public-access.d.ts +6 -0
  45. package/dist/public-access.d.ts.map +1 -1
  46. package/dist/public-access.js +75 -1
  47. package/dist/public-access.js.map +1 -1
  48. package/dist/rail.d.ts +50 -0
  49. package/dist/rail.d.ts.map +1 -0
  50. package/dist/rail.js +122 -0
  51. package/dist/rail.js.map +1 -0
  52. package/dist/roles.d.ts +647 -1
  53. package/dist/roles.d.ts.map +1 -1
  54. package/dist/roles.js +459 -3
  55. package/dist/roles.js.map +1 -1
  56. package/dist/sample.d.ts +62 -0
  57. package/dist/sample.d.ts.map +1 -1
  58. package/dist/sample.js +203 -4
  59. package/dist/sample.js.map +1 -1
  60. package/dist/schema.d.ts +4349 -169
  61. package/dist/schema.d.ts.map +1 -1
  62. package/dist/schema.js +540 -41
  63. package/dist/schema.js.map +1 -1
  64. package/dist/shapes.d.ts +3 -2
  65. package/dist/shapes.d.ts.map +1 -1
  66. package/dist/shapes.js +76 -7
  67. package/dist/shapes.js.map +1 -1
  68. package/dist/state-actions.d.ts +4 -0
  69. package/dist/state-actions.d.ts.map +1 -1
  70. package/dist/state-actions.js +7 -0
  71. package/dist/state-actions.js.map +1 -1
  72. package/dist/states.d.ts +20 -1
  73. package/dist/states.d.ts.map +1 -1
  74. package/dist/states.js +47 -5
  75. package/dist/states.js.map +1 -1
  76. package/dist/validate.d.ts.map +1 -1
  77. package/dist/validate.js +110 -3
  78. package/dist/validate.js.map +1 -1
  79. package/dist/words.d.ts +1 -1
  80. package/dist/words.d.ts.map +1 -1
  81. package/dist/words.js +332 -1
  82. package/dist/words.js.map +1 -1
  83. package/package.json +2 -2
package/dist/rail.d.ts ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * The app's section of the sidebar, and where a record opens.
3
+ *
4
+ * Three words of a manifest are checked here:
5
+ *
6
+ * `pages[].nav.offRail` a page kept off the sidebar;
7
+ * `navLinks` an entry of the section that is not a page;
8
+ * `frontends[].records` where a table's record opens on the staff side.
9
+ *
10
+ * ── AN ADDRESS IS NEVER WRITTEN OUT ────────────────────────────────────────
11
+ * A link a manifest could spell freely is a link to anywhere: another app's
12
+ * screens, the dashboard's own, a look-alike host in an e-mail's button. So
13
+ * neither word takes an address. A record's address is a path under the side
14
+ * that declares it, made of plain segments and one `{id}`; an entry of the
15
+ * section names one of a closed list of places. The server joins the side's
16
+ * own base to the path, and reads the path again with {@link recordAddressOf}
17
+ * before it does (a stored manifest is data, not a promise).
18
+ *
19
+ * It reads the plain document, like `words.ts`, so `schema.ts` may import it.
20
+ */
21
+ /** The dashboard screens an entry of an app's section may open, each narrowed to that app. */
22
+ export declare const NAV_LINK_SCREENS: readonly ["automations", "email-templates", "settings"];
23
+ export type NavLinkScreen = (typeof NAV_LINK_SCREENS)[number];
24
+ /** A page link to the app's own staff side: `@staff` (its first screen) or `@staff/<path>` (one screen of it). */
25
+ export declare const STAFF_LINK = "@staff";
26
+ export declare const SIDE_PATH_MESSAGE = "a path under the side: \"/\" then plain segments (letters, digits, \".\", \"_\", \"~\", \"-\"), with no query, no \"#\" and no \"..\"";
27
+ export declare const RECORD_ADDRESS_MESSAGE = "a path under the side with one \"{id}\" segment, as in \"/deals/{id}\": plain segments only, no query, no \"#\" and no \"..\"";
28
+ /** Whether `value` is a path under a side: `/approvals`, `/settings/team`. */
29
+ export declare function isSidePath(value: unknown): value is string;
30
+ /** Whether `value` is a record's address under a side: a side path with exactly one `{id}` segment. */
31
+ export declare function isRecordAddress(value: unknown): value is string;
32
+ /**
33
+ * The path a record opens at, from its table's address and its id: null when
34
+ * the address is not one (a manifest stored by an older or a foreign hand).
35
+ * The id is one segment whatever it holds.
36
+ */
37
+ export declare function recordAddressOf(address: unknown, recordId: string): string | null;
38
+ /** The addresses the staff side of `document` declares, by table ref; none when it declares none. */
39
+ export declare function staffRecordAddresses(document: unknown): Readonly<Record<string, string>>;
40
+ export interface RailIssue {
41
+ path: (string | number)[];
42
+ message: string;
43
+ }
44
+ /**
45
+ * What the three words may not say: an address on a side that is not the
46
+ * staff side, or for a table the app does not have; two entries of one ref; an
47
+ * entry into a staff side the app does not declare.
48
+ */
49
+ export declare function railIssues(document: unknown): RailIssue[];
50
+ //# sourceMappingURL=rail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rail.d.ts","sourceRoot":"","sources":["../src/rail.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,8FAA8F;AAC9F,eAAO,MAAM,gBAAgB,yDAA0D,CAAC;AACxF,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAO9D,kHAAkH;AAClH,eAAO,MAAM,UAAU,WAAW,CAAC;AAEnC,eAAO,MAAM,iBAAiB,0IAA4H,CAAC;AAC3J,eAAO,MAAM,sBAAsB,kIAA0H,CAAC;AAE9J,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE1D;AAED,uGAAuG;AACvG,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMjF;AAMD,qGAAqG;AACrG,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAKxF;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,EAAE,CAgDzD"}
package/dist/rail.js ADDED
@@ -0,0 +1,122 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ /**
3
+ * The app's section of the sidebar, and where a record opens.
4
+ *
5
+ * Three words of a manifest are checked here:
6
+ *
7
+ * `pages[].nav.offRail` a page kept off the sidebar;
8
+ * `navLinks` an entry of the section that is not a page;
9
+ * `frontends[].records` where a table's record opens on the staff side.
10
+ *
11
+ * ── AN ADDRESS IS NEVER WRITTEN OUT ────────────────────────────────────────
12
+ * A link a manifest could spell freely is a link to anywhere: another app's
13
+ * screens, the dashboard's own, a look-alike host in an e-mail's button. So
14
+ * neither word takes an address. A record's address is a path under the side
15
+ * that declares it, made of plain segments and one `{id}`; an entry of the
16
+ * section names one of a closed list of places. The server joins the side's
17
+ * own base to the path, and reads the path again with {@link recordAddressOf}
18
+ * before it does (a stored manifest is data, not a promise).
19
+ *
20
+ * It reads the plain document, like `words.ts`, so `schema.ts` may import it.
21
+ */
22
+ /** The dashboard screens an entry of an app's section may open, each narrowed to that app. */
23
+ export const NAV_LINK_SCREENS = ['automations', 'email-templates', 'settings'];
24
+ /** One segment of a path: letters, digits and `. _ ~ -`, never starting with a dot (so no `.` and no `..`). */
25
+ const SEGMENT = '[A-Za-z0-9_~-][A-Za-z0-9._~-]*';
26
+ const SIDE_PATH = new RegExp(`^(?:/${SEGMENT})+$`);
27
+ const RECORD_ADDRESS = new RegExp(`^(?:/(?:${SEGMENT}|\\{id\\}))+$`);
28
+ /** A page link to the app's own staff side: `@staff` (its first screen) or `@staff/<path>` (one screen of it). */
29
+ export const STAFF_LINK = '@staff';
30
+ export const SIDE_PATH_MESSAGE = 'a path under the side: "/" then plain segments (letters, digits, ".", "_", "~", "-"), with no query, no "#" and no ".."';
31
+ export const RECORD_ADDRESS_MESSAGE = 'a path under the side with one "{id}" segment, as in "/deals/{id}": plain segments only, no query, no "#" and no ".."';
32
+ /** Whether `value` is a path under a side: `/approvals`, `/settings/team`. */
33
+ export function isSidePath(value) {
34
+ return typeof value === 'string' && value.length <= 200 && SIDE_PATH.test(value);
35
+ }
36
+ /** Whether `value` is a record's address under a side: a side path with exactly one `{id}` segment. */
37
+ export function isRecordAddress(value) {
38
+ return typeof value === 'string' && value.length <= 200 && RECORD_ADDRESS.test(value) && value.split('/').filter((segment) => segment === '{id}').length === 1;
39
+ }
40
+ /**
41
+ * The path a record opens at, from its table's address and its id: null when
42
+ * the address is not one (a manifest stored by an older or a foreign hand).
43
+ * The id is one segment whatever it holds.
44
+ */
45
+ export function recordAddressOf(address, recordId) {
46
+ if (!isRecordAddress(address) || recordId === '')
47
+ return null;
48
+ return address
49
+ .split('/')
50
+ .map((segment) => (segment === '{id}' ? encodeURIComponent(recordId) : segment))
51
+ .join('/');
52
+ }
53
+ const isDoc = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
54
+ const list = (value) => (Array.isArray(value) ? value : []);
55
+ /** The addresses the staff side of `document` declares, by table ref; none when it declares none. */
56
+ export function staffRecordAddresses(document) {
57
+ if (!isDoc(document))
58
+ return {};
59
+ const staff = list(document['frontends']).find((frontend) => isDoc(frontend) && frontend['side'] === 'staff');
60
+ const records = isDoc(staff) && isDoc(staff['records']) ? staff['records'] : {};
61
+ return Object.fromEntries(Object.entries(records).filter((entry) => isRecordAddress(entry[1])));
62
+ }
63
+ /**
64
+ * What the three words may not say: an address on a side that is not the
65
+ * staff side, or for a table the app does not have; two entries of one ref; an
66
+ * entry into a staff side the app does not declare.
67
+ */
68
+ export function railIssues(document) {
69
+ if (!isDoc(document))
70
+ return [];
71
+ const out = [];
72
+ const schema = isDoc(document['requiredSchema']) ? document['requiredSchema'] : {};
73
+ const tables = new Set(list(schema['tables']).flatMap((table) => (isDoc(table) && typeof table['ref'] === 'string' ? [table['ref']] : [])));
74
+ const frontends = list(document['frontends']);
75
+ frontends.forEach((frontend, f) => {
76
+ if (!isDoc(frontend) || frontend['records'] === undefined)
77
+ return;
78
+ if (frontend['side'] !== 'staff') {
79
+ out.push({ path: ['frontends', f, 'records'], message: `only the staff side says where a record opens: a notice and a search hit are a staff member's` });
80
+ return;
81
+ }
82
+ for (const ref of Object.keys(isDoc(frontend['records']) ? frontend['records'] : {})) {
83
+ if (!tables.has(ref))
84
+ out.push({ path: ['frontends', f, 'records', ref], message: `the app has no table "${ref}"` });
85
+ }
86
+ });
87
+ const hasStaff = frontends.some((frontend) => isDoc(frontend) && frontend['side'] === 'staff');
88
+ const seen = new Set();
89
+ list(document['navLinks']).forEach((link, l) => {
90
+ if (!isDoc(link))
91
+ return;
92
+ if (typeof link['ref'] === 'string') {
93
+ if (seen.has(link['ref']))
94
+ out.push({ path: ['navLinks', l, 'ref'], message: `"${link['ref']}" is named twice` });
95
+ seen.add(link['ref']);
96
+ }
97
+ if (isDoc(link['to']) && link['to']['side'] === 'staff' && !hasStaff) {
98
+ out.push({ path: ['navLinks', l, 'to', 'side'], message: 'the app declares no staff side to open' });
99
+ }
100
+ });
101
+ // A console page's link to one screen of the staff side (`@staff/approvals`): a path under the side, as a section's entry names one.
102
+ list(document['pages']).forEach((page, p) => {
103
+ const layout = isDoc(page) && isDoc(page['config']) && isDoc(page['config']['layout']) ? page['config']['layout'] : {};
104
+ const toolbar = isDoc(layout['toolbar']) ? layout['toolbar'] : {};
105
+ const at = ['pages', p, 'config', 'layout'];
106
+ const hrefs = [
107
+ [isDoc(toolbar['link']) ? toolbar['link']['href'] : undefined, [...at, 'toolbar', 'link', 'href']],
108
+ ...list(toolbar['links']).map((link, l) => [isDoc(link) ? link['href'] : undefined, [...at, 'toolbar', 'links', l, 'href']]),
109
+ ...list(layout['items']).map((item, i) => [isDoc(item) && isDoc(item['config']) ? item['config']['href'] : undefined, [...at, 'items', i, 'config', 'href']]),
110
+ ];
111
+ for (const [href, path] of hrefs) {
112
+ if (typeof href !== 'string' || !href.startsWith(`${STAFF_LINK}/`))
113
+ continue;
114
+ if (!isSidePath(href.slice(STAFF_LINK.length)))
115
+ out.push({ path, message: `"@staff/" is followed by ${SIDE_PATH_MESSAGE.replace('"/" then plain', 'plain')}` });
116
+ else if (!hasStaff)
117
+ out.push({ path, message: 'the app declares no staff side to open' });
118
+ }
119
+ });
120
+ return out;
121
+ }
122
+ //# sourceMappingURL=rail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rail.js","sourceRoot":"","sources":["../src/rail.ts"],"names":[],"mappings":"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"}