@adminiumjs/manifest 0.3.7 → 0.3.9
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/capacity.d.ts +6 -0
- package/dist/capacity.d.ts.map +1 -1
- package/dist/capacity.js +16 -2
- package/dist/capacity.js.map +1 -1
- package/dist/documents.d.ts +4 -0
- package/dist/documents.d.ts.map +1 -1
- package/dist/documents.js +4 -0
- package/dist/documents.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/public-access.d.ts +74 -6
- package/dist/public-access.d.ts.map +1 -1
- package/dist/public-access.js +83 -8
- package/dist/public-access.js.map +1 -1
- package/dist/roles.d.ts +4 -0
- package/dist/roles.d.ts.map +1 -1
- package/dist/roles.js +29 -1
- package/dist/roles.js.map +1 -1
- package/dist/sample.d.ts +1 -0
- package/dist/sample.d.ts.map +1 -1
- package/dist/sample.js +15 -1
- package/dist/sample.js.map +1 -1
- package/dist/schema.d.ts +686 -31
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +100 -19
- package/dist/schema.js.map +1 -1
- package/dist/states.d.ts +24 -1
- package/dist/states.d.ts.map +1 -1
- package/dist/states.js +17 -6
- package/dist/states.js.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +4 -1
- package/dist/validate.js.map +1 -1
- package/package.json +2 -2
package/dist/public-access.js
CHANGED
|
@@ -34,6 +34,31 @@ import { momentIssues, momentOffsetSchema, plainMomentSchema, wallTimeSchema } f
|
|
|
34
34
|
import { conditionIssues, linkedConditionSchema, reachedOnlyByUndo, stateConditionSchema } from './states.js';
|
|
35
35
|
/** The key every entry uses unless it names another. */
|
|
36
36
|
export const CUSTOMER_KEY = 'customer';
|
|
37
|
+
/** The longest a plain-text value may be unless its column says longer: a name. */
|
|
38
|
+
export const PLAIN_TEXT_MAX = 80;
|
|
39
|
+
/** The most digits a plain-text column may take in all: "table 12", "2 without onions", never a phone number. */
|
|
40
|
+
export const PLAIN_TEXT_DIGITS_MOST = 4;
|
|
41
|
+
/** The longest a plain-text column may say it runs: a note to the kitchen. */
|
|
42
|
+
export const PLAIN_TEXT_LONGEST = 200;
|
|
43
|
+
/**
|
|
44
|
+
* A column held to plain text: its ref (a name: no digits, 80 characters), or
|
|
45
|
+
* its ref with the digits it may hold in all and how long it may run (a note).
|
|
46
|
+
*/
|
|
47
|
+
const plainTextColumnSchema = z.union([
|
|
48
|
+
refSchema,
|
|
49
|
+
z
|
|
50
|
+
.object({
|
|
51
|
+
column: refSchema,
|
|
52
|
+
digits: z.number().int().min(1).max(PLAIN_TEXT_DIGITS_MOST).optional(),
|
|
53
|
+
max: z.number().int().min(1).max(PLAIN_TEXT_LONGEST).optional(),
|
|
54
|
+
})
|
|
55
|
+
.strict(),
|
|
56
|
+
]);
|
|
57
|
+
const plainTextSchema = z.array(plainTextColumnSchema).min(1).max(8);
|
|
58
|
+
/** The column a plain-text entry names. */
|
|
59
|
+
export const plainTextRef = (entry) => (typeof entry === 'string' ? entry : entry.column);
|
|
60
|
+
/** The longest a plain-text entry takes. */
|
|
61
|
+
export const plainTextMax = (entry) => (typeof entry === 'string' ? PLAIN_TEXT_MAX : (entry.max ?? PLAIN_TEXT_MAX));
|
|
37
62
|
const keyNameSchema = z.string().regex(/^[a-z][a-z0-9-]{0,31}$/, 'a key name is kebab-case');
|
|
38
63
|
const valueFilterSchema = z
|
|
39
64
|
.object({
|
|
@@ -323,7 +348,7 @@ const childEntryShape = {
|
|
|
323
348
|
agrees: z.array(agreeSchema).min(1).max(8).optional(),
|
|
324
349
|
counts: z.array(countsSchema).min(1).max(2).optional(),
|
|
325
350
|
/** Columns that hold plain text only (no links), as on a create nobody signed in for. */
|
|
326
|
-
plainText:
|
|
351
|
+
plainText: plainTextSchema.optional(),
|
|
327
352
|
/** The most a column may add up to across the rows of one write (a dozen items to an order). */
|
|
328
353
|
sumMax: sumMaxSchema.optional(),
|
|
329
354
|
};
|
|
@@ -499,7 +524,7 @@ export const publicAccessSchema = z
|
|
|
499
524
|
* visitor is held to on any key, only fewer.
|
|
500
525
|
*/
|
|
501
526
|
perIpHour: z.number().int().min(1).max(60).optional(),
|
|
502
|
-
plainText:
|
|
527
|
+
plainText: plainTextSchema.optional(),
|
|
503
528
|
})
|
|
504
529
|
.strict()
|
|
505
530
|
.optional(),
|
|
@@ -512,7 +537,7 @@ export const publicAccessSchema = z
|
|
|
512
537
|
limits: z
|
|
513
538
|
.object({
|
|
514
539
|
perValue: z.object({ columns: z.array(refSchema).min(1).max(4), n: z.number().int().min(1).max(20) }).strict().optional(),
|
|
515
|
-
plainText:
|
|
540
|
+
plainText: plainTextSchema.optional(),
|
|
516
541
|
})
|
|
517
542
|
.strict()
|
|
518
543
|
.refine((l) => l.perValue !== undefined || l.plainText !== undefined, { message: 'limits name a per-value cap, plain-text columns, or both' })
|
|
@@ -590,11 +615,22 @@ export const publicKeySchema = z
|
|
|
590
615
|
*/
|
|
591
616
|
requiresStaff: z.object({ role: z.string().regex(/^[a-z][a-z0-9-]*$/, 'a role key') }).strict().optional(),
|
|
592
617
|
enabledBy: settingRefSchema.optional(),
|
|
618
|
+
/**
|
|
619
|
+
* The key's budget a minute when its app meets its peak (a show going on
|
|
620
|
+
* sale): from Adminium's own (3,000 reads, 300 writes) up to five times
|
|
621
|
+
* that. Each visitor still gets a twelfth of it. Read at install.
|
|
622
|
+
*/
|
|
623
|
+
peak: z
|
|
624
|
+
.object({ reads: z.number().int().min(3000).max(15_000), writes: z.number().int().min(300).max(1500) })
|
|
625
|
+
.strict()
|
|
626
|
+
.optional(),
|
|
593
627
|
})
|
|
594
628
|
.strict();
|
|
595
629
|
export const publicKeysSchema = z
|
|
596
630
|
.record(keyNameSchema, publicKeySchema)
|
|
597
|
-
.refine((keys) => !(CUSTOMER_KEY in keys)
|
|
631
|
+
.refine((keys) => !(CUSTOMER_KEY in keys) || Object.keys(keys[CUSTOMER_KEY] ?? {}).every((field) => field === 'peak'), {
|
|
632
|
+
message: '"customer" is the app\'s own key: only its peak is said here',
|
|
633
|
+
});
|
|
598
634
|
/**
|
|
599
635
|
* The own links of the rows a person of `identityTable` holds: each table a
|
|
600
636
|
* token claims with `own: true`, by its code column, and the columns of it
|
|
@@ -667,6 +703,9 @@ export function publicAccessIssues(entries, ctx) {
|
|
|
667
703
|
const has = index.has;
|
|
668
704
|
for (const [name, key] of Object.entries(ctx.publicKeys ?? {})) {
|
|
669
705
|
const at = ['publicKeys', name];
|
|
706
|
+
// The app's own key, named only for its peak: nothing more to check.
|
|
707
|
+
if (name === CUSTOMER_KEY)
|
|
708
|
+
continue;
|
|
670
709
|
if (key.requiresStaff === undefined) {
|
|
671
710
|
// No one signs this key in: it may only open one row by its token, and read.
|
|
672
711
|
const identity = entries.find((entry) => (entry.key ?? CUSTOMER_KEY) === name && entry.claim !== undefined);
|
|
@@ -1161,7 +1200,7 @@ export function publicAccessIssues(entries, ctx) {
|
|
|
1161
1200
|
const caps = entry.anonymous;
|
|
1162
1201
|
if (!creates)
|
|
1163
1202
|
out.push({ path: at('anonymous'), message: 'anonymous limits a create' });
|
|
1164
|
-
for (const [name, columns] of [['perValue', caps.perValue?.columns ?? []], ['plainText', caps.plainText ?? []]]) {
|
|
1203
|
+
for (const [name, columns] of [['perValue', caps.perValue?.columns ?? []], ['plainText', (caps.plainText ?? []).map(plainTextRef)]]) {
|
|
1165
1204
|
for (const ref of columns) {
|
|
1166
1205
|
const found = column(ref);
|
|
1167
1206
|
if (found === undefined)
|
|
@@ -1175,7 +1214,7 @@ export function publicAccessIssues(entries, ctx) {
|
|
|
1175
1214
|
const limits = entry.limits;
|
|
1176
1215
|
if (!patches)
|
|
1177
1216
|
out.push({ path: at('limits'), message: 'limits apply to a change (PATCH); a create has anonymous' });
|
|
1178
|
-
for (const [name, columns] of [['perValue', limits.perValue?.columns ?? []], ['plainText', limits.plainText ?? []]]) {
|
|
1217
|
+
for (const [name, columns] of [['perValue', limits.perValue?.columns ?? []], ['plainText', (limits.plainText ?? []).map(plainTextRef)]]) {
|
|
1179
1218
|
for (const ref of columns) {
|
|
1180
1219
|
const found = column(ref);
|
|
1181
1220
|
if (found === undefined)
|
|
@@ -1709,7 +1748,7 @@ function treeIssues(entries, ctx, identities, shareCodes) {
|
|
|
1709
1748
|
['writable', child.writable],
|
|
1710
1749
|
['select', child.select ?? []],
|
|
1711
1750
|
['requires', child.requires ?? []],
|
|
1712
|
-
['plainText', child.plainText ?? []],
|
|
1751
|
+
['plainText', (child.plainText ?? []).map(plainTextRef)],
|
|
1713
1752
|
['defaults', Object.keys(child.defaults ?? {})],
|
|
1714
1753
|
['writableValues', Object.keys(child.writableValues ?? {})],
|
|
1715
1754
|
['position', child.position === undefined ? [] : [child.position]],
|
|
@@ -1745,7 +1784,7 @@ function treeIssues(entries, ctx, identities, shareCodes) {
|
|
|
1745
1784
|
out.push({ path: here('writableValues', ref), message: `${JSON.stringify(value)} is not a value of "${name}.${ref}"` });
|
|
1746
1785
|
}
|
|
1747
1786
|
}
|
|
1748
|
-
for (const ref of child.plainText ?? []) {
|
|
1787
|
+
for (const ref of (child.plainText ?? []).map(plainTextRef)) {
|
|
1749
1788
|
const column = index.column(name, ref);
|
|
1750
1789
|
if (column !== undefined && column.type !== 'text')
|
|
1751
1790
|
out.push({ path: here('plainText'), message: `"${name}.${ref}" is not a text column` });
|
|
@@ -2309,4 +2348,40 @@ function ownAddressAndWithholdIssues(entries, ctx, identities) {
|
|
|
2309
2348
|
});
|
|
2310
2349
|
return out;
|
|
2311
2350
|
}
|
|
2351
|
+
/**
|
|
2352
|
+
* Advice about a plain-text column that holds more than its plain text takes:
|
|
2353
|
+
* a guest who types to the column's `maxLength` is refused at the end of the
|
|
2354
|
+
* form ("orders.note" holds 140, its plain text takes 80).
|
|
2355
|
+
*/
|
|
2356
|
+
export function plainTextLengthWarnings(publicAccess, tables) {
|
|
2357
|
+
const out = [];
|
|
2358
|
+
const check = (table, list, path) => {
|
|
2359
|
+
(list ?? []).forEach((entry, k) => {
|
|
2360
|
+
const ref = plainTextRef(entry);
|
|
2361
|
+
const holds = tables.find((t) => t.ref === table)?.columns.find((c) => c.ref === ref)?.maxLength;
|
|
2362
|
+
const takes = plainTextMax(entry);
|
|
2363
|
+
if (holds === undefined || holds <= takes)
|
|
2364
|
+
return;
|
|
2365
|
+
out.push({
|
|
2366
|
+
path: `${path}.${String(k)}`,
|
|
2367
|
+
message: `"${table}.${ref}" holds ${String(holds)} characters but its plain text takes ${String(takes)}, so a guest who types more is refused: ` +
|
|
2368
|
+
`lower its maxLength to ${String(takes)}, or give it { "column": "${ref}", "max": ${String(Math.min(holds, PLAIN_TEXT_LONGEST))} }` +
|
|
2369
|
+
(holds > PLAIN_TEXT_LONGEST ? ` and a maxLength of ${String(PLAIN_TEXT_LONGEST)}` : ''),
|
|
2370
|
+
});
|
|
2371
|
+
});
|
|
2372
|
+
};
|
|
2373
|
+
const walk = (children, base) => {
|
|
2374
|
+
for (const [name, child] of Object.entries(children ?? {})) {
|
|
2375
|
+
check(name, child.plainText, `${base}.children.${name}.plainText`);
|
|
2376
|
+
walk(child.children, `${base}.children.${name}`);
|
|
2377
|
+
}
|
|
2378
|
+
};
|
|
2379
|
+
publicAccess.forEach((entry, e) => {
|
|
2380
|
+
const base = `publicAccess.${String(e)}`;
|
|
2381
|
+
check(entry.table, entry.anonymous?.plainText, `${base}.anonymous.plainText`);
|
|
2382
|
+
check(entry.table, entry.limits?.plainText, `${base}.limits.plainText`);
|
|
2383
|
+
walk(entry.children, base);
|
|
2384
|
+
});
|
|
2385
|
+
return out;
|
|
2386
|
+
}
|
|
2312
2387
|
//# sourceMappingURL=public-access.js.map
|