@adminiumjs/manifest 0.3.0-rc.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/booking.d.ts +100 -0
- package/dist/booking.d.ts.map +1 -0
- package/dist/booking.js +237 -0
- package/dist/booking.js.map +1 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/outbox.d.ts +198 -0
- package/dist/outbox.d.ts.map +1 -0
- package/dist/outbox.js +355 -0
- package/dist/outbox.js.map +1 -0
- package/dist/page-calendar.d.ts +42 -0
- package/dist/page-calendar.d.ts.map +1 -0
- package/dist/page-calendar.js +95 -0
- package/dist/page-calendar.js.map +1 -0
- package/dist/plan-context.d.ts +51 -0
- package/dist/plan-context.d.ts.map +1 -0
- package/dist/plan-context.js +356 -0
- package/dist/plan-context.js.map +1 -0
- package/dist/plan-model.d.ts +197 -0
- package/dist/plan-model.d.ts.map +1 -0
- package/dist/plan-model.js +11 -0
- package/dist/plan-model.js.map +1 -0
- package/dist/plan-types.d.ts +12 -0
- package/dist/plan-types.d.ts.map +1 -0
- package/dist/plan-types.js +71 -0
- package/dist/plan-types.js.map +1 -0
- package/dist/plan.d.ts +9 -90
- package/dist/plan.d.ts.map +1 -1
- package/dist/plan.js +48 -1
- package/dist/plan.js.map +1 -1
- package/dist/public-access.d.ts +167 -0
- package/dist/public-access.d.ts.map +1 -0
- package/dist/public-access.js +475 -0
- package/dist/public-access.js.map +1 -0
- package/dist/refs.d.ts +74 -0
- package/dist/refs.d.ts.map +1 -0
- package/dist/refs.js +70 -0
- package/dist/refs.js.map +1 -0
- package/dist/roles.d.ts +44 -0
- package/dist/roles.d.ts.map +1 -0
- package/dist/roles.js +75 -0
- package/dist/roles.js.map +1 -0
- package/dist/sample.d.ts +200 -0
- package/dist/sample.d.ts.map +1 -0
- package/dist/sample.js +208 -0
- package/dist/sample.js.map +1 -0
- package/dist/schema.d.ts +2031 -51
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +559 -18
- package/dist/schema.js.map +1 -1
- package/dist/semver.d.ts +28 -0
- package/dist/semver.d.ts.map +1 -0
- package/dist/semver.js +85 -0
- package/dist/semver.js.map +1 -0
- package/package.json +2 -2
package/dist/refs.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
/**
|
|
3
|
+
* The small shapes every block of a manifest reuses: a snake_case name, a
|
|
4
|
+
* label in several languages, a number that may come from the app's settings
|
|
5
|
+
* row, and the structural view of a table the cross-reference checks read.
|
|
6
|
+
*
|
|
7
|
+
* A module of its own so `schema.ts` and the blocks split out of it
|
|
8
|
+
* (`booking.ts`, `outbox.ts`, `public-access.ts`) import one definition
|
|
9
|
+
* without importing each other.
|
|
10
|
+
*/
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
/** A snake_case identifier: a table or column ref. */
|
|
13
|
+
export const refSchema = z.string().regex(/^[a-z][a-z0-9_]*$/, 'must be a snake_case identifier');
|
|
14
|
+
/** A BCP 47 tag, the way every label map in a manifest is keyed (`de-DE`). */
|
|
15
|
+
export const bcp47TagSchema = z.string().regex(/^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$/, 'keyed by BCP 47 tag');
|
|
16
|
+
/** A label in several languages. US English is the one every reader falls back to. */
|
|
17
|
+
export const labelsSchema = z
|
|
18
|
+
.record(bcp47TagSchema, z.string().min(1).max(120))
|
|
19
|
+
.refine((labels) => labels['en-US'] !== undefined, { message: 'labels must include en-US' });
|
|
20
|
+
/** A text that is either one string, or the same text in several languages. */
|
|
21
|
+
export const textOrLabels = z.union([z.string().min(1).max(256), labelsSchema]);
|
|
22
|
+
/** One column of the app's one-row settings table, read when the rule runs. */
|
|
23
|
+
export const settingRefSchema = z.object({ table: refSchema, column: refSchema }).strict();
|
|
24
|
+
/**
|
|
25
|
+
* A number the manifest states, or one the app's own settings row holds — so
|
|
26
|
+
* a venue can change its capacity without a new release. `{table, column}`
|
|
27
|
+
* reads the one row of that (one-row) table at write time.
|
|
28
|
+
*/
|
|
29
|
+
export const numberOrSetting = z.union([z.number().int().nonnegative(), settingRefSchema]);
|
|
30
|
+
/** A value a rule compares a column with. */
|
|
31
|
+
export const scalarSchema = z.union([z.string(), z.number(), z.boolean()]);
|
|
32
|
+
/**
|
|
33
|
+
* Lookups over the manifest's tables, shared by every block's checks so each
|
|
34
|
+
* says "no such column" the same way.
|
|
35
|
+
*/
|
|
36
|
+
export function tableIndex(tables) {
|
|
37
|
+
const byRef = new Map(tables.map((t) => [t.ref, t]));
|
|
38
|
+
const column = (table, ref) => byRef.get(table)?.columns.find((c) => c.ref === ref);
|
|
39
|
+
return {
|
|
40
|
+
table: (ref) => byRef.get(ref),
|
|
41
|
+
column,
|
|
42
|
+
has: (table, ref) => column(table, ref) !== undefined,
|
|
43
|
+
/** The table's primary key column, when it declares one. */
|
|
44
|
+
pk: (table) => byRef.get(table)?.columns.find((c) => c.role === 'pk'),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/** Column types a total, a price or a count can be kept in. */
|
|
48
|
+
export const NUMERIC_TYPES = ['int', 'bigint', 'decimal', 'money', 'float'];
|
|
49
|
+
/**
|
|
50
|
+
* Whether `value` is one a column of this shape can hold: one of an enum's
|
|
51
|
+
* values, a boolean for a bool, a number for a number, any text for text.
|
|
52
|
+
*/
|
|
53
|
+
export function valueFits(column, value) {
|
|
54
|
+
switch (column.type) {
|
|
55
|
+
case 'enum':
|
|
56
|
+
return typeof value === 'string' && (column.enum ?? []).includes(value);
|
|
57
|
+
case 'bool':
|
|
58
|
+
return typeof value === 'boolean';
|
|
59
|
+
case 'int':
|
|
60
|
+
case 'bigint':
|
|
61
|
+
return typeof value === 'number' && Number.isInteger(value);
|
|
62
|
+
case 'decimal':
|
|
63
|
+
case 'money':
|
|
64
|
+
case 'float':
|
|
65
|
+
return typeof value === 'number';
|
|
66
|
+
default:
|
|
67
|
+
return typeof value === 'string';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=refs.js.map
|
package/dist/refs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refs.js","sourceRoot":"","sources":["../src/refs.ts"],"names":[],"mappings":"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"}
|
package/dist/roles.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `roles[].limits` — what a role's `update` on one of the app's tables may
|
|
3
|
+
* write, when it may not write everything.
|
|
4
|
+
*
|
|
5
|
+
* A clinician moves a visit along and does nothing else to it:
|
|
6
|
+
*
|
|
7
|
+
* ```json
|
|
8
|
+
* "limits": {
|
|
9
|
+
* "appointments": {
|
|
10
|
+
* "writable": ["status"],
|
|
11
|
+
* "writableValues": { "status": ["roomed", "with_clinician", "ready"] }
|
|
12
|
+
* }
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* The names are the public-access entries' (`writable`, `writableValues`).
|
|
17
|
+
* A limit narrows the role's own `table:@<ref>:update`, so a role must grant
|
|
18
|
+
* that update (itself or through `cloneFrom`) for a limit on the table to
|
|
19
|
+
* mean anything. Roles add up: someone who also holds a role with a plain
|
|
20
|
+
* update on the table is not held to the limit. Creating rows is not limited.
|
|
21
|
+
*/
|
|
22
|
+
import { z } from 'zod';
|
|
23
|
+
import { type ColumnShape, type ReferenceIssue, type TableIndex } from './refs.js';
|
|
24
|
+
/** One table's limit. */
|
|
25
|
+
export declare const roleLimitSchema: z.ZodObject<{
|
|
26
|
+
writable: z.ZodArray<z.ZodString>;
|
|
27
|
+
writableValues: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>>;
|
|
28
|
+
}, z.core.$strict>;
|
|
29
|
+
export type RoleLimit = z.infer<typeof roleLimitSchema>;
|
|
30
|
+
/** Per table ref, the limit on the role's update there. */
|
|
31
|
+
export declare const roleLimitsSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
32
|
+
writable: z.ZodArray<z.ZodString>;
|
|
33
|
+
writableValues: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>>;
|
|
34
|
+
}, z.core.$strict>>;
|
|
35
|
+
/** What the checks read of a role. */
|
|
36
|
+
export interface RoleShape {
|
|
37
|
+
key: string;
|
|
38
|
+
cloneFrom?: string | undefined;
|
|
39
|
+
permissions?: readonly string[] | undefined;
|
|
40
|
+
limits?: Readonly<Record<string, RoleLimit>> | undefined;
|
|
41
|
+
}
|
|
42
|
+
/** Every `limits` problem across the app's roles. */
|
|
43
|
+
export declare function roleLimitIssues<C extends ColumnShape>(roles: readonly RoleShape[], index: TableIndex<C>): ReferenceIssue[];
|
|
44
|
+
//# sourceMappingURL=roles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../src/roles.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAsC,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvH,yBAAyB;AACzB,eAAO,MAAM,eAAe;;;kBAOjB,CAAC;AACZ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,2DAA2D;AAC3D,eAAO,MAAM,gBAAgB;;;mBAAuC,CAAC;AAErE,sCAAsC;AACtC,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAC5C,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC;CAC1D;AAQD,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,CAAC,SAAS,WAAW,EAAE,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,cAAc,EAAE,CA4B1H"}
|
package/dist/roles.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
/**
|
|
3
|
+
* `roles[].limits` — what a role's `update` on one of the app's tables may
|
|
4
|
+
* write, when it may not write everything.
|
|
5
|
+
*
|
|
6
|
+
* A clinician moves a visit along and does nothing else to it:
|
|
7
|
+
*
|
|
8
|
+
* ```json
|
|
9
|
+
* "limits": {
|
|
10
|
+
* "appointments": {
|
|
11
|
+
* "writable": ["status"],
|
|
12
|
+
* "writableValues": { "status": ["roomed", "with_clinician", "ready"] }
|
|
13
|
+
* }
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* The names are the public-access entries' (`writable`, `writableValues`).
|
|
18
|
+
* A limit narrows the role's own `table:@<ref>:update`, so a role must grant
|
|
19
|
+
* that update (itself or through `cloneFrom`) for a limit on the table to
|
|
20
|
+
* mean anything. Roles add up: someone who also holds a role with a plain
|
|
21
|
+
* update on the table is not held to the limit. Creating rows is not limited.
|
|
22
|
+
*/
|
|
23
|
+
import { z } from 'zod';
|
|
24
|
+
import { refSchema, scalarSchema, valueFits } from './refs.js';
|
|
25
|
+
/** One table's limit. */
|
|
26
|
+
export const roleLimitSchema = z
|
|
27
|
+
.object({
|
|
28
|
+
/** The only columns the update may change. */
|
|
29
|
+
writable: z.array(refSchema).min(1),
|
|
30
|
+
/** For some of those columns, the only values it may set. */
|
|
31
|
+
writableValues: z.record(refSchema, z.array(scalarSchema).min(1).max(32)).optional(),
|
|
32
|
+
})
|
|
33
|
+
.strict();
|
|
34
|
+
/** Per table ref, the limit on the role's update there. */
|
|
35
|
+
export const roleLimitsSchema = z.record(refSchema, roleLimitSchema);
|
|
36
|
+
/** The grants a role ends up with: its own and the ones of the role it clones. */
|
|
37
|
+
function grantsOf(role, roles) {
|
|
38
|
+
const from = role.cloneFrom === undefined ? undefined : roles.find((other) => other.key === role.cloneFrom);
|
|
39
|
+
return new Set([...(from?.permissions ?? []), ...(role.permissions ?? [])]);
|
|
40
|
+
}
|
|
41
|
+
/** Every `limits` problem across the app's roles. */
|
|
42
|
+
export function roleLimitIssues(roles, index) {
|
|
43
|
+
const out = [];
|
|
44
|
+
roles.forEach((role, r) => {
|
|
45
|
+
const grants = grantsOf(role, roles);
|
|
46
|
+
for (const [ref, limit] of Object.entries(role.limits ?? {})) {
|
|
47
|
+
const at = (...rest) => ['roles', r, 'limits', ref, ...rest];
|
|
48
|
+
if (index.table(ref) === undefined) {
|
|
49
|
+
out.push({ path: at(), message: `"${ref}" is not a table of this app` });
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (!grants.has(`table:@${ref}:update`)) {
|
|
53
|
+
out.push({ path: at(), message: `the role does not grant table:@${ref}:update, so there is nothing to limit` });
|
|
54
|
+
}
|
|
55
|
+
const writable = new Set(limit.writable);
|
|
56
|
+
for (const column of limit.writable) {
|
|
57
|
+
if (index.column(ref, column) === undefined)
|
|
58
|
+
out.push({ path: at('writable'), message: `"${ref}" has no column "${column}"` });
|
|
59
|
+
}
|
|
60
|
+
for (const [column, values] of Object.entries(limit.writableValues ?? {})) {
|
|
61
|
+
if (!writable.has(column))
|
|
62
|
+
out.push({ path: at('writableValues', column), message: `"${column}" is not writable` });
|
|
63
|
+
const found = index.column(ref, column);
|
|
64
|
+
if (found === undefined)
|
|
65
|
+
continue;
|
|
66
|
+
for (const value of values) {
|
|
67
|
+
if (!valueFits(found, value))
|
|
68
|
+
out.push({ path: at('writableValues', column), message: `${JSON.stringify(value)} is not a value of "${ref}.${column}"` });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=roles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles.js","sourceRoot":"","sources":["../src/roles.ts"],"names":[],"mappings":"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"}
|
package/dist/sample.d.ts
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `adminium.sample/1` — an app's sample data, shipped in its package and named
|
|
3
|
+
* by the manifest's `sampleData.file`.
|
|
4
|
+
*
|
|
5
|
+
* Rows are written in the order the tables are listed, parents first, and
|
|
6
|
+
* removed in reverse. A value is a plain JSON value or one of these directives:
|
|
7
|
+
*
|
|
8
|
+
* `{"@ref": "<label>"}` the key of an earlier row with that `@label`
|
|
9
|
+
* `{"@ago": "PT19M"}` an ISO-8601 duration before now
|
|
10
|
+
* `{"@day": -1, "@time": "09:30"}` a wall time in the venue's own zone,
|
|
11
|
+
* days from today
|
|
12
|
+
* `{"@day": 3}` a date in the venue's own zone
|
|
13
|
+
* `{"@t": {"en-US": "…"}}` the adding person's language
|
|
14
|
+
* `{"@asset": "<label>"}` a file from `assets`, added to the Files library
|
|
15
|
+
*
|
|
16
|
+
* A `@day` may add `"@workdays": true`: its days count Monday to Friday, and
|
|
17
|
+
* day 0 on a weekend is the Monday after — so "today's" busy day is never a
|
|
18
|
+
* Saturday.
|
|
19
|
+
*
|
|
20
|
+
* A row may carry, beside its `@label`, one ROW directive: `@byClock`
|
|
21
|
+
* `{at, before, around, after}` merges one of three sets of columns into the
|
|
22
|
+
* row, by where its time `at` (a column of the row, or a `@day`/`@time`)
|
|
23
|
+
* falls against the adding moment — more than half an hour before, within
|
|
24
|
+
* half an hour, or later — so a sample day's statuses match the clock it is
|
|
25
|
+
* added at. A set with `"@skip": true` leaves the row out (a payment for a
|
|
26
|
+
* visit that has not happened yet).
|
|
27
|
+
*
|
|
28
|
+
* Pure: a format and its checks, no I/O. The server resolves the directives.
|
|
29
|
+
*/
|
|
30
|
+
import { z } from 'zod';
|
|
31
|
+
import type { Manifest } from './schema.js';
|
|
32
|
+
export declare const SAMPLE_FORMAT = "adminium.sample/1";
|
|
33
|
+
/** A column's value: a plain value, a directive, or (for a json column) any object or array. */
|
|
34
|
+
export declare const sampleValueSchema: z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>, z.ZodUnion<readonly [z.ZodObject<{
|
|
35
|
+
'@ref': z.ZodString;
|
|
36
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
37
|
+
'@ago': z.ZodString;
|
|
38
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
39
|
+
'@day': z.ZodNumber;
|
|
40
|
+
'@time': z.ZodString;
|
|
41
|
+
'@workdays': z.ZodOptional<z.ZodLiteral<true>>;
|
|
42
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
43
|
+
'@day': z.ZodNumber;
|
|
44
|
+
'@workdays': z.ZodOptional<z.ZodLiteral<true>>;
|
|
45
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
46
|
+
'@t': z.ZodRecord<z.ZodString, z.ZodString>;
|
|
47
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
48
|
+
'@asset': z.ZodString;
|
|
49
|
+
}, z.core.$strict>]>, z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>;
|
|
50
|
+
export declare const sampleRowSchema: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>, z.ZodUnion<readonly [z.ZodObject<{
|
|
51
|
+
'@ref': z.ZodString;
|
|
52
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
53
|
+
'@ago': z.ZodString;
|
|
54
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
55
|
+
'@day': z.ZodNumber;
|
|
56
|
+
'@time': z.ZodString;
|
|
57
|
+
'@workdays': z.ZodOptional<z.ZodLiteral<true>>;
|
|
58
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
59
|
+
'@day': z.ZodNumber;
|
|
60
|
+
'@workdays': z.ZodOptional<z.ZodLiteral<true>>;
|
|
61
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
62
|
+
'@t': z.ZodRecord<z.ZodString, z.ZodString>;
|
|
63
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
64
|
+
'@asset': z.ZodString;
|
|
65
|
+
}, z.core.$strict>]>, z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
|
|
66
|
+
/** `@byClock`: a row's columns by where its time falls against the adding moment. */
|
|
67
|
+
export declare const byClockSchema: z.ZodObject<{
|
|
68
|
+
at: z.ZodUnion<readonly [z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
|
|
69
|
+
'@ref': z.ZodString;
|
|
70
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
71
|
+
'@ago': z.ZodString;
|
|
72
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
73
|
+
'@day': z.ZodNumber;
|
|
74
|
+
'@time': z.ZodString;
|
|
75
|
+
'@workdays': z.ZodOptional<z.ZodLiteral<true>>;
|
|
76
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
77
|
+
'@day': z.ZodNumber;
|
|
78
|
+
'@workdays': z.ZodOptional<z.ZodLiteral<true>>;
|
|
79
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
80
|
+
'@t': z.ZodRecord<z.ZodString, z.ZodString>;
|
|
81
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
82
|
+
'@asset': z.ZodString;
|
|
83
|
+
}, z.core.$strict>]>]>;
|
|
84
|
+
before: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>, z.ZodUnion<readonly [z.ZodObject<{
|
|
85
|
+
'@ref': z.ZodString;
|
|
86
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
87
|
+
'@ago': z.ZodString;
|
|
88
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
89
|
+
'@day': z.ZodNumber;
|
|
90
|
+
'@time': z.ZodString;
|
|
91
|
+
'@workdays': z.ZodOptional<z.ZodLiteral<true>>;
|
|
92
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
93
|
+
'@day': z.ZodNumber;
|
|
94
|
+
'@workdays': z.ZodOptional<z.ZodLiteral<true>>;
|
|
95
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
96
|
+
'@t': z.ZodRecord<z.ZodString, z.ZodString>;
|
|
97
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
98
|
+
'@asset': z.ZodString;
|
|
99
|
+
}, z.core.$strict>]>, z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>>;
|
|
100
|
+
around: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>, z.ZodUnion<readonly [z.ZodObject<{
|
|
101
|
+
'@ref': z.ZodString;
|
|
102
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
103
|
+
'@ago': z.ZodString;
|
|
104
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
105
|
+
'@day': z.ZodNumber;
|
|
106
|
+
'@time': z.ZodString;
|
|
107
|
+
'@workdays': z.ZodOptional<z.ZodLiteral<true>>;
|
|
108
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
109
|
+
'@day': z.ZodNumber;
|
|
110
|
+
'@workdays': z.ZodOptional<z.ZodLiteral<true>>;
|
|
111
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
112
|
+
'@t': z.ZodRecord<z.ZodString, z.ZodString>;
|
|
113
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
114
|
+
'@asset': z.ZodString;
|
|
115
|
+
}, z.core.$strict>]>, z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>>;
|
|
116
|
+
after: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>, z.ZodUnion<readonly [z.ZodObject<{
|
|
117
|
+
'@ref': z.ZodString;
|
|
118
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
119
|
+
'@ago': z.ZodString;
|
|
120
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
121
|
+
'@day': z.ZodNumber;
|
|
122
|
+
'@time': z.ZodString;
|
|
123
|
+
'@workdays': z.ZodOptional<z.ZodLiteral<true>>;
|
|
124
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
125
|
+
'@day': z.ZodNumber;
|
|
126
|
+
'@workdays': z.ZodOptional<z.ZodLiteral<true>>;
|
|
127
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
128
|
+
'@t': z.ZodRecord<z.ZodString, z.ZodString>;
|
|
129
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
130
|
+
'@asset': z.ZodString;
|
|
131
|
+
}, z.core.$strict>]>, z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>>;
|
|
132
|
+
}, z.core.$strict>;
|
|
133
|
+
export type ByClock = z.infer<typeof byClockSchema>;
|
|
134
|
+
/** The keys of a row that are directives about the row, not columns. */
|
|
135
|
+
export declare const ROW_DIRECTIVES: ReadonlySet<string>;
|
|
136
|
+
export declare const sampleBundleSchema: z.ZodObject<{
|
|
137
|
+
format: z.ZodLiteral<"adminium.sample/1">;
|
|
138
|
+
app: z.ZodString;
|
|
139
|
+
assets: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
140
|
+
file: z.ZodString;
|
|
141
|
+
sha256: z.ZodString;
|
|
142
|
+
}, z.core.$strict>>>;
|
|
143
|
+
tables: z.ZodArray<z.ZodObject<{
|
|
144
|
+
ref: z.ZodString;
|
|
145
|
+
rows: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>, z.ZodUnion<readonly [z.ZodObject<{
|
|
146
|
+
'@ref': z.ZodString;
|
|
147
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
148
|
+
'@ago': z.ZodString;
|
|
149
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
150
|
+
'@day': z.ZodNumber;
|
|
151
|
+
'@time': z.ZodString;
|
|
152
|
+
'@workdays': z.ZodOptional<z.ZodLiteral<true>>;
|
|
153
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
154
|
+
'@day': z.ZodNumber;
|
|
155
|
+
'@workdays': z.ZodOptional<z.ZodLiteral<true>>;
|
|
156
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
157
|
+
'@t': z.ZodRecord<z.ZodString, z.ZodString>;
|
|
158
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
159
|
+
'@asset': z.ZodString;
|
|
160
|
+
}, z.core.$strict>]>, z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>>;
|
|
161
|
+
}, z.core.$strict>>;
|
|
162
|
+
}, z.core.$strict>;
|
|
163
|
+
export type SampleBundle = z.infer<typeof sampleBundleSchema>;
|
|
164
|
+
export type SampleValue = z.infer<typeof sampleValueSchema>;
|
|
165
|
+
/** A value's directive, when it is one. */
|
|
166
|
+
export declare function sampleDirective(value: unknown): {
|
|
167
|
+
kind: 'ref';
|
|
168
|
+
label: string;
|
|
169
|
+
} | {
|
|
170
|
+
kind: 'ago';
|
|
171
|
+
duration: string;
|
|
172
|
+
} | {
|
|
173
|
+
kind: 'wall';
|
|
174
|
+
day: number;
|
|
175
|
+
time: string;
|
|
176
|
+
workdays: boolean;
|
|
177
|
+
} | {
|
|
178
|
+
kind: 'date';
|
|
179
|
+
day: number;
|
|
180
|
+
workdays: boolean;
|
|
181
|
+
} | {
|
|
182
|
+
kind: 't';
|
|
183
|
+
texts: Record<string, string>;
|
|
184
|
+
} | {
|
|
185
|
+
kind: 'asset';
|
|
186
|
+
label: string;
|
|
187
|
+
} | null;
|
|
188
|
+
/** An ISO-8601 duration in milliseconds. */
|
|
189
|
+
export declare function isoDurationMs(duration: string): number;
|
|
190
|
+
export interface SampleIssue {
|
|
191
|
+
path: string;
|
|
192
|
+
message: string;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Everything wrong with a bundle for this manifest: a table it does not
|
|
196
|
+
* declare, a column the table does not have, a label used twice, a `@ref` to
|
|
197
|
+
* a row that comes later or not at all, an `@asset` it does not list.
|
|
198
|
+
*/
|
|
199
|
+
export declare function sampleBundleIssues(bundle: SampleBundle, manifest: Manifest): SampleIssue[];
|
|
200
|
+
//# sourceMappingURL=sample.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sample.d.ts","sourceRoot":"","sources":["../src/sample.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,eAAO,MAAM,aAAa,sBAAsB,CAAC;AAwBjD,gGAAgG;AAChG,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;wFAAuF,CAAC;AAEtH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;yFAA0C,CAAC;AAKvE,qFAAqF;AACrF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAQf,CAAC;AACZ,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD,wEAAwE;AACxE,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CAAmC,CAAC;AAEnF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;kBAWpB,CAAC;AAEZ,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,2CAA2C;AAC3C,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAC1C;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,GAAG,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC,IAAI,CAcP;AAED,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUtD;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,GAAG,WAAW,EAAE,CAqF1F"}
|
package/dist/sample.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
/**
|
|
3
|
+
* `adminium.sample/1` — an app's sample data, shipped in its package and named
|
|
4
|
+
* by the manifest's `sampleData.file`.
|
|
5
|
+
*
|
|
6
|
+
* Rows are written in the order the tables are listed, parents first, and
|
|
7
|
+
* removed in reverse. A value is a plain JSON value or one of these directives:
|
|
8
|
+
*
|
|
9
|
+
* `{"@ref": "<label>"}` the key of an earlier row with that `@label`
|
|
10
|
+
* `{"@ago": "PT19M"}` an ISO-8601 duration before now
|
|
11
|
+
* `{"@day": -1, "@time": "09:30"}` a wall time in the venue's own zone,
|
|
12
|
+
* days from today
|
|
13
|
+
* `{"@day": 3}` a date in the venue's own zone
|
|
14
|
+
* `{"@t": {"en-US": "…"}}` the adding person's language
|
|
15
|
+
* `{"@asset": "<label>"}` a file from `assets`, added to the Files library
|
|
16
|
+
*
|
|
17
|
+
* A `@day` may add `"@workdays": true`: its days count Monday to Friday, and
|
|
18
|
+
* day 0 on a weekend is the Monday after — so "today's" busy day is never a
|
|
19
|
+
* Saturday.
|
|
20
|
+
*
|
|
21
|
+
* A row may carry, beside its `@label`, one ROW directive: `@byClock`
|
|
22
|
+
* `{at, before, around, after}` merges one of three sets of columns into the
|
|
23
|
+
* row, by where its time `at` (a column of the row, or a `@day`/`@time`)
|
|
24
|
+
* falls against the adding moment — more than half an hour before, within
|
|
25
|
+
* half an hour, or later — so a sample day's statuses match the clock it is
|
|
26
|
+
* added at. A set with `"@skip": true` leaves the row out (a payment for a
|
|
27
|
+
* visit that has not happened yet).
|
|
28
|
+
*
|
|
29
|
+
* Pure: a format and its checks, no I/O. The server resolves the directives.
|
|
30
|
+
*/
|
|
31
|
+
import { z } from 'zod';
|
|
32
|
+
export const SAMPLE_FORMAT = 'adminium.sample/1';
|
|
33
|
+
const label = z.string().regex(/^[A-Za-z0-9][A-Za-z0-9:._-]{0,95}$/, 'a label of letters, digits and : . _ -');
|
|
34
|
+
/** `P[nW][nD][T[nH][nM][nS]]`, with at least one part. */
|
|
35
|
+
const ISO_DURATION = /^P(?!$)(\d+W)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+(\.\d+)?S)?)?$/;
|
|
36
|
+
const directive = z.union([
|
|
37
|
+
z.object({ '@ref': label }).strict(),
|
|
38
|
+
z.object({ '@ago': z.string().regex(ISO_DURATION, 'an ISO-8601 duration such as PT19M') }).strict(),
|
|
39
|
+
z
|
|
40
|
+
.object({
|
|
41
|
+
'@day': z.number().int().min(-366).max(366),
|
|
42
|
+
'@time': z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, 'a time such as 09:30'),
|
|
43
|
+
'@workdays': z.literal(true).optional(),
|
|
44
|
+
})
|
|
45
|
+
.strict(),
|
|
46
|
+
z.object({ '@day': z.number().int().min(-366).max(366), '@workdays': z.literal(true).optional() }).strict(),
|
|
47
|
+
z.object({ '@t': z.record(z.string().regex(/^[a-z]{2}(-[A-Z]{2})?$/), z.string()).refine((m) => Object.keys(m).length > 0) }).strict(),
|
|
48
|
+
z.object({ '@asset': label }).strict(),
|
|
49
|
+
]);
|
|
50
|
+
const plain = z.union([z.string(), z.number(), z.boolean(), z.null()]);
|
|
51
|
+
/** A column's value: a plain value, a directive, or (for a json column) any object or array. */
|
|
52
|
+
export const sampleValueSchema = z.union([plain, directive, z.array(z.unknown()), z.record(z.string(), z.unknown())]);
|
|
53
|
+
export const sampleRowSchema = z.record(z.string(), sampleValueSchema);
|
|
54
|
+
/** One of `@byClock`'s three sets: columns to merge, or `"@skip": true` to leave the row out. */
|
|
55
|
+
const clockBranchSchema = z.record(z.string(), sampleValueSchema);
|
|
56
|
+
/** `@byClock`: a row's columns by where its time falls against the adding moment. */
|
|
57
|
+
export const byClockSchema = z
|
|
58
|
+
.object({
|
|
59
|
+
/** A column of the row holding its time, or the time itself. */
|
|
60
|
+
at: z.union([z.string().min(1), directive]),
|
|
61
|
+
before: clockBranchSchema.optional(),
|
|
62
|
+
around: clockBranchSchema.optional(),
|
|
63
|
+
after: clockBranchSchema.optional(),
|
|
64
|
+
})
|
|
65
|
+
.strict();
|
|
66
|
+
/** The keys of a row that are directives about the row, not columns. */
|
|
67
|
+
export const ROW_DIRECTIVES = new Set(['@label', '@byClock']);
|
|
68
|
+
export const sampleBundleSchema = z
|
|
69
|
+
.object({
|
|
70
|
+
format: z.literal(SAMPLE_FORMAT),
|
|
71
|
+
app: z.string().min(1),
|
|
72
|
+
assets: z
|
|
73
|
+
.record(label, z.object({ file: z.string().regex(/^seeds\/[a-z0-9][a-z0-9._/-]*$/), sha256: z.string().regex(/^[a-f0-9]{64}$/) }).strict())
|
|
74
|
+
.default({}),
|
|
75
|
+
tables: z
|
|
76
|
+
.array(z.object({ ref: z.string().min(1), rows: z.array(sampleRowSchema).min(1).max(5000) }).strict())
|
|
77
|
+
.min(1),
|
|
78
|
+
})
|
|
79
|
+
.strict();
|
|
80
|
+
/** A value's directive, when it is one. */
|
|
81
|
+
export function sampleDirective(value) {
|
|
82
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
83
|
+
return null;
|
|
84
|
+
const record = value;
|
|
85
|
+
if (typeof record['@ref'] === 'string')
|
|
86
|
+
return { kind: 'ref', label: record['@ref'] };
|
|
87
|
+
if (typeof record['@ago'] === 'string')
|
|
88
|
+
return { kind: 'ago', duration: record['@ago'] };
|
|
89
|
+
if (typeof record['@day'] === 'number' && typeof record['@time'] === 'string') {
|
|
90
|
+
return { kind: 'wall', day: record['@day'], time: record['@time'], workdays: record['@workdays'] === true };
|
|
91
|
+
}
|
|
92
|
+
if (typeof record['@day'] === 'number')
|
|
93
|
+
return { kind: 'date', day: record['@day'], workdays: record['@workdays'] === true };
|
|
94
|
+
if (typeof record['@t'] === 'object' && record['@t'] !== null) {
|
|
95
|
+
return { kind: 't', texts: record['@t'] };
|
|
96
|
+
}
|
|
97
|
+
if (typeof record['@asset'] === 'string')
|
|
98
|
+
return { kind: 'asset', label: record['@asset'] };
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
/** An ISO-8601 duration in milliseconds. */
|
|
102
|
+
export function isoDurationMs(duration) {
|
|
103
|
+
const match = ISO_DURATION.exec(duration);
|
|
104
|
+
if (match === null)
|
|
105
|
+
throw new Error(`"${duration}" is not an ISO-8601 duration`);
|
|
106
|
+
const n = (part) => (part === undefined ? 0 : Number.parseFloat(part));
|
|
107
|
+
const weeks = n(match[1]);
|
|
108
|
+
const days = n(match[2]);
|
|
109
|
+
const hours = n(match[4]);
|
|
110
|
+
const minutes = n(match[5]);
|
|
111
|
+
const seconds = n(match[6]);
|
|
112
|
+
return ((((weeks * 7 + days) * 24 + hours) * 60 + minutes) * 60 + seconds) * 1000;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Everything wrong with a bundle for this manifest: a table it does not
|
|
116
|
+
* declare, a column the table does not have, a label used twice, a `@ref` to
|
|
117
|
+
* a row that comes later or not at all, an `@asset` it does not list.
|
|
118
|
+
*/
|
|
119
|
+
export function sampleBundleIssues(bundle, manifest) {
|
|
120
|
+
const issues = [];
|
|
121
|
+
if (bundle.app !== manifest.key) {
|
|
122
|
+
issues.push({ path: 'app', message: `The bundle is for "${bundle.app}", not "${manifest.key}".` });
|
|
123
|
+
}
|
|
124
|
+
const declared = new Map((manifest.requiredSchema?.tables ?? []).map((table) => [table.ref, table]));
|
|
125
|
+
const seen = new Set();
|
|
126
|
+
for (const [t, table] of bundle.tables.entries()) {
|
|
127
|
+
const shape = declared.get(table.ref);
|
|
128
|
+
if (shape === undefined) {
|
|
129
|
+
issues.push({ path: `tables.${String(t)}.ref`, message: `"${table.ref}" is not a table this app declares.` });
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const columns = new Set(shape.columns.map((column) => column.ref));
|
|
133
|
+
for (const [r, row] of table.rows.entries()) {
|
|
134
|
+
const at = `tables.${String(t)}.rows.${String(r)}`;
|
|
135
|
+
for (const [column, value] of Object.entries(row)) {
|
|
136
|
+
if (column === '@label') {
|
|
137
|
+
if (typeof value !== 'string' || !label.safeParse(value).success) {
|
|
138
|
+
issues.push({ path: `${at}.@label`, message: 'A label is letters, digits and : . _ -.' });
|
|
139
|
+
}
|
|
140
|
+
else if (seen.has(value)) {
|
|
141
|
+
issues.push({ path: `${at}.@label`, message: `The label "${value}" is used twice.` });
|
|
142
|
+
}
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (column === '@byClock') {
|
|
146
|
+
const clock = byClockSchema.safeParse(value);
|
|
147
|
+
if (!clock.success) {
|
|
148
|
+
issues.push({ path: `${at}.@byClock`, message: '@byClock names its time (`at`) and up to three sets: before, around, after.' });
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
const when = clock.data.at;
|
|
152
|
+
if (typeof when === 'string' && !(columns.has(when) && when in row)) {
|
|
153
|
+
issues.push({ path: `${at}.@byClock.at`, message: `"${when}" is not a column this row sets.` });
|
|
154
|
+
}
|
|
155
|
+
else if (typeof when !== 'string' && sampleDirective(when)?.kind !== 'wall') {
|
|
156
|
+
issues.push({ path: `${at}.@byClock.at`, message: 'The time is a column of the row or a `@day` with a `@time`.' });
|
|
157
|
+
}
|
|
158
|
+
for (const branch of ['before', 'around', 'after']) {
|
|
159
|
+
for (const [name, part] of Object.entries(clock.data[branch] ?? {})) {
|
|
160
|
+
if (name === '@skip') {
|
|
161
|
+
if (part !== true)
|
|
162
|
+
issues.push({ path: `${at}.@byClock.${branch}.@skip`, message: '"@skip" is true, or absent.' });
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (!columns.has(name))
|
|
166
|
+
issues.push({ path: `${at}.@byClock.${branch}.${name}`, message: `"${table.ref}" has no column "${name}".` });
|
|
167
|
+
const found = sampleDirective(part);
|
|
168
|
+
if (found?.kind === 'ref' && !seen.has(found.label)) {
|
|
169
|
+
issues.push({ path: `${at}.@byClock.${branch}.${name}`, message: `"${found.label}" is not an earlier row: a referenced row must come first.` });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (!columns.has(column)) {
|
|
176
|
+
issues.push({ path: `${at}.${column}`, message: `"${table.ref}" has no column "${column}".` });
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
// An object that looks like a directive must BE one: a malformed
|
|
180
|
+
// `@ago` would otherwise be written into the column as JSON.
|
|
181
|
+
if (typeof value === 'object' &&
|
|
182
|
+
value !== null &&
|
|
183
|
+
!Array.isArray(value) &&
|
|
184
|
+
Object.keys(value).some((key) => key.startsWith('@')) &&
|
|
185
|
+
!directive.safeParse(value).success) {
|
|
186
|
+
issues.push({ path: `${at}.${column}`, message: `"${column}" holds a directive that is not well formed.` });
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
const found = sampleDirective(value);
|
|
190
|
+
if (found?.kind === 'ref' && !seen.has(found.label)) {
|
|
191
|
+
issues.push({
|
|
192
|
+
path: `${at}.${column}`,
|
|
193
|
+
message: `"${found.label}" is not an earlier row: a referenced row must come first.`,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
if (found?.kind === 'asset' && bundle.assets[found.label] === undefined) {
|
|
197
|
+
issues.push({ path: `${at}.${column}`, message: `"${found.label}" is not one of the bundle’s assets.` });
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Labelled AFTER its own values are checked: a row cannot refer to itself.
|
|
201
|
+
const own = row['@label'];
|
|
202
|
+
if (typeof own === 'string')
|
|
203
|
+
seen.add(own);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return issues;
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=sample.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sample.js","sourceRoot":"","sources":["../src/sample.ts"],"names":[],"mappings":"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"}
|