@brydio/manifest 0.1.0-alpha.59 → 0.1.0-alpha.61
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/package.json +6 -2
- package/src/bundle.d.ts +14 -1
- package/src/bundle.js +65 -8
- package/src/frame-checks.d.ts +13 -0
- package/src/frame-checks.js +35 -0
- package/src/index.d.ts +4 -1
- package/src/index.js +6 -1
- package/src/look.d.ts +196 -0
- package/src/look.js +744 -0
- package/src/schema.d.ts +36 -5
- package/src/schema.js +32 -3
- package/src/screen-kinds.d.ts +18 -0
- package/src/screen-kinds.js +30 -0
- package/src/validate.d.ts +4 -1
package/src/schema.d.ts
CHANGED
|
@@ -112,8 +112,8 @@ declare const extensionShape: {
|
|
|
112
112
|
screen: z.ZodString;
|
|
113
113
|
sizes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
114
114
|
small: "small";
|
|
115
|
-
medium: "medium";
|
|
116
115
|
large: "large";
|
|
116
|
+
medium: "medium";
|
|
117
117
|
}>>>;
|
|
118
118
|
label: z.ZodOptional<z.ZodString>;
|
|
119
119
|
icon: z.ZodOptional<z.ZodString>;
|
|
@@ -185,6 +185,10 @@ declare const extensionShape: {
|
|
|
185
185
|
}, z.core.$strip>>;
|
|
186
186
|
screens: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
187
187
|
entry: z.ZodString;
|
|
188
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
189
|
+
tree: "tree";
|
|
190
|
+
frame: "frame";
|
|
191
|
+
}>>;
|
|
188
192
|
}, z.core.$strip>>>;
|
|
189
193
|
grants: z.ZodOptional<z.ZodObject<{
|
|
190
194
|
tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -249,6 +253,13 @@ declare const extensionShape: {
|
|
|
249
253
|
* still loads; `POST /apps/publish` requires it and checks it (A5-F04-S03).
|
|
250
254
|
*/
|
|
251
255
|
sdk: z.ZodOptional<z.ZodString>;
|
|
256
|
+
/**
|
|
257
|
+
* The app's own colours and shape (PB21): an accent, named colours each
|
|
258
|
+
* with a light and a dark value, a rounding and a density. No font: every
|
|
259
|
+
* app uses Brydio's. Checked by `themeProblems` (`look.ts`), Brydio's one
|
|
260
|
+
* rule set, copied.
|
|
261
|
+
*/
|
|
262
|
+
theme: z.ZodOptional<z.ZodUnknown>;
|
|
252
263
|
};
|
|
253
264
|
/** One problem with an app's additions, named down to the field. */
|
|
254
265
|
export interface DataProblem {
|
|
@@ -301,8 +312,8 @@ export declare const manifestExtensionsSchema: z.ZodObject<{
|
|
|
301
312
|
screen: z.ZodString;
|
|
302
313
|
sizes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
303
314
|
small: "small";
|
|
304
|
-
medium: "medium";
|
|
305
315
|
large: "large";
|
|
316
|
+
medium: "medium";
|
|
306
317
|
}>>>;
|
|
307
318
|
label: z.ZodOptional<z.ZodString>;
|
|
308
319
|
icon: z.ZodOptional<z.ZodString>;
|
|
@@ -374,6 +385,10 @@ export declare const manifestExtensionsSchema: z.ZodObject<{
|
|
|
374
385
|
}, z.core.$strip>>;
|
|
375
386
|
screens: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
376
387
|
entry: z.ZodString;
|
|
388
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
389
|
+
tree: "tree";
|
|
390
|
+
frame: "frame";
|
|
391
|
+
}>>;
|
|
377
392
|
}, z.core.$strip>>>;
|
|
378
393
|
grants: z.ZodOptional<z.ZodObject<{
|
|
379
394
|
tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -421,6 +436,7 @@ export declare const manifestExtensionsSchema: z.ZodObject<{
|
|
|
421
436
|
}, z.core.$strip>], "op">>;
|
|
422
437
|
}, z.core.$strip>>>;
|
|
423
438
|
sdk: z.ZodOptional<z.ZodString>;
|
|
439
|
+
theme: z.ZodOptional<z.ZodUnknown>;
|
|
424
440
|
}, z.core.$strip>;
|
|
425
441
|
/**
|
|
426
442
|
* The additions as code reads a manifest that was checked whole when it was
|
|
@@ -443,8 +459,8 @@ export declare const storedExtensionsSchema: z.ZodObject<{
|
|
|
443
459
|
screen: z.ZodString;
|
|
444
460
|
sizes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
445
461
|
small: "small";
|
|
446
|
-
medium: "medium";
|
|
447
462
|
large: "large";
|
|
463
|
+
medium: "medium";
|
|
448
464
|
}>>>;
|
|
449
465
|
label: z.ZodOptional<z.ZodString>;
|
|
450
466
|
icon: z.ZodOptional<z.ZodString>;
|
|
@@ -516,6 +532,10 @@ export declare const storedExtensionsSchema: z.ZodObject<{
|
|
|
516
532
|
}, z.core.$strip>>;
|
|
517
533
|
screens: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
518
534
|
entry: z.ZodString;
|
|
535
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
536
|
+
tree: "tree";
|
|
537
|
+
frame: "frame";
|
|
538
|
+
}>>;
|
|
519
539
|
}, z.core.$strip>>>;
|
|
520
540
|
grants: z.ZodOptional<z.ZodObject<{
|
|
521
541
|
tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -563,6 +583,7 @@ export declare const storedExtensionsSchema: z.ZodObject<{
|
|
|
563
583
|
}, z.core.$strip>], "op">>;
|
|
564
584
|
}, z.core.$strip>>>;
|
|
565
585
|
sdk: z.ZodOptional<z.ZodString>;
|
|
586
|
+
theme: z.ZodOptional<z.ZodUnknown>;
|
|
566
587
|
}, z.core.$strip>;
|
|
567
588
|
/** E5's manifest with the additions: the whole `.brydio/app.json` of an app. */
|
|
568
589
|
export declare const appManifestSchema: z.ZodObject<{
|
|
@@ -620,8 +641,8 @@ export declare const appManifestSchema: z.ZodObject<{
|
|
|
620
641
|
screen: z.ZodString;
|
|
621
642
|
sizes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
622
643
|
small: "small";
|
|
623
|
-
medium: "medium";
|
|
624
644
|
large: "large";
|
|
645
|
+
medium: "medium";
|
|
625
646
|
}>>>;
|
|
626
647
|
label: z.ZodOptional<z.ZodString>;
|
|
627
648
|
icon: z.ZodOptional<z.ZodString>;
|
|
@@ -693,6 +714,10 @@ export declare const appManifestSchema: z.ZodObject<{
|
|
|
693
714
|
}, z.core.$strip>>;
|
|
694
715
|
screens: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
695
716
|
entry: z.ZodString;
|
|
717
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
718
|
+
tree: "tree";
|
|
719
|
+
frame: "frame";
|
|
720
|
+
}>>;
|
|
696
721
|
}, z.core.$strip>>>;
|
|
697
722
|
grants: z.ZodOptional<z.ZodObject<{
|
|
698
723
|
tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -740,6 +765,7 @@ export declare const appManifestSchema: z.ZodObject<{
|
|
|
740
765
|
}, z.core.$strip>], "op">>;
|
|
741
766
|
}, z.core.$strip>>>;
|
|
742
767
|
sdk: z.ZodOptional<z.ZodString>;
|
|
768
|
+
theme: z.ZodOptional<z.ZodUnknown>;
|
|
743
769
|
}, z.core.$strip>;
|
|
744
770
|
/**
|
|
745
771
|
* A manifest being written now, as `brydio validate`, `build` and `dev` read
|
|
@@ -801,8 +827,8 @@ export declare const newAppManifestSchema: z.ZodObject<{
|
|
|
801
827
|
screen: z.ZodString;
|
|
802
828
|
sizes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
803
829
|
small: "small";
|
|
804
|
-
medium: "medium";
|
|
805
830
|
large: "large";
|
|
831
|
+
medium: "medium";
|
|
806
832
|
}>>>;
|
|
807
833
|
label: z.ZodOptional<z.ZodString>;
|
|
808
834
|
icon: z.ZodOptional<z.ZodString>;
|
|
@@ -874,6 +900,10 @@ export declare const newAppManifestSchema: z.ZodObject<{
|
|
|
874
900
|
}, z.core.$strip>>;
|
|
875
901
|
screens: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
876
902
|
entry: z.ZodString;
|
|
903
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
904
|
+
tree: "tree";
|
|
905
|
+
frame: "frame";
|
|
906
|
+
}>>;
|
|
877
907
|
}, z.core.$strip>>>;
|
|
878
908
|
grants: z.ZodOptional<z.ZodObject<{
|
|
879
909
|
tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
@@ -921,6 +951,7 @@ export declare const newAppManifestSchema: z.ZodObject<{
|
|
|
921
951
|
}, z.core.$strip>], "op">>;
|
|
922
952
|
}, z.core.$strip>>>;
|
|
923
953
|
sdk: z.ZodOptional<z.ZodString>;
|
|
954
|
+
theme: z.ZodOptional<z.ZodUnknown>;
|
|
924
955
|
}, z.core.$strip>;
|
|
925
956
|
export type ManifestExtensions = z.infer<typeof manifestExtensionsSchema>;
|
|
926
957
|
export type AppManifestWithData = z.infer<typeof appManifestSchema>;
|
package/src/schema.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { MANIFEST_LIMITS, SEMVER_FORMAT, baseManifestSchema as manifestSchema } from "./base.js";
|
|
3
3
|
import { COLLECTION_NAME, FIELD_LIMITS, FIELD_NAME, FieldTypeInvalid, isSearchable, isSortable, isStructured, parseFieldType, RESERVED_FIELDS, } from "./field-types.js";
|
|
4
|
+
import { themeProblems } from "./look.js";
|
|
5
|
+
import { SCREEN_KINDS } from "./screen-kinds.js";
|
|
4
6
|
import { migrationsSchema } from "./migrations.js";
|
|
5
7
|
import { openSchemaProblems } from "./open-schema.js";
|
|
6
8
|
import { confirmEmailProblems, confirmEmailSchema } from "./confirm-email.js";
|
|
@@ -162,17 +164,34 @@ const collectionSchema = z.object({
|
|
|
162
164
|
/** One of its string[] fields: the user ids who alone may change a record, when it names any (DW06). */
|
|
163
165
|
editors: editorsSchema.optional(),
|
|
164
166
|
});
|
|
165
|
-
const screenSchema = z
|
|
167
|
+
const screenSchema = z
|
|
168
|
+
.object({
|
|
166
169
|
/**
|
|
167
170
|
* Relative to the bundle's root: `screens/board.js` or `screens/board.mjs`.
|
|
168
171
|
* The server's schema said `.js` only while its store and the mount took
|
|
169
|
-
* `.mjs` too; the schema gives (E1 and Hodler, 16 Sep 14:04 and 14:12).
|
|
172
|
+
* `.mjs` too; the schema gives (E1 and Hodler, 16 Sep 14:04 and 14:12). A
|
|
173
|
+
* frame screen's entry is its page, `screens/settings.html` (PB27).
|
|
170
174
|
*/
|
|
171
175
|
entry: z
|
|
172
176
|
.string()
|
|
173
177
|
.min(1)
|
|
174
178
|
.max(200)
|
|
175
|
-
.regex(/^(?!\/)(?!.*\.\.)[A-Za-z0-9_\-./]+\.m?js$/, 'An entry is a .js or .mjs path inside the bundle.'),
|
|
179
|
+
.regex(/^(?!\/)(?!.*\.\.)[A-Za-z0-9_\-./]+\.(?:m?js|html)$/, 'An entry is a .js or .mjs path inside the bundle, or an .html page for a frame screen.'),
|
|
180
|
+
/** `tree` (the default): drawn by Brydio from the app's elements. `frame`: the app's own HTML and CSS (PB27). */
|
|
181
|
+
kind: z.enum(SCREEN_KINDS).optional(),
|
|
182
|
+
})
|
|
183
|
+
.superRefine((screen, ctx) => {
|
|
184
|
+
const page = screen.entry.endsWith('.html');
|
|
185
|
+
if ((screen.kind === 'frame') !== page) {
|
|
186
|
+
ctx.addIssue({
|
|
187
|
+
code: 'custom',
|
|
188
|
+
path: ['entry'],
|
|
189
|
+
message: screen.kind === 'frame'
|
|
190
|
+
? 'A frame screen’s entry is an .html page inside the bundle.'
|
|
191
|
+
: 'An .html entry is a frame screen: give the screen "kind": "frame".',
|
|
192
|
+
params: { code: 'screen_kind_entry' },
|
|
193
|
+
});
|
|
194
|
+
}
|
|
176
195
|
});
|
|
177
196
|
/** Most custom tools one app may declare (A3-F08). */
|
|
178
197
|
export const MAX_CUSTOM_TOOLS = 100;
|
|
@@ -270,6 +289,13 @@ const extensionShape = {
|
|
|
270
289
|
* still loads; `POST /apps/publish` requires it and checks it (A5-F04-S03).
|
|
271
290
|
*/
|
|
272
291
|
sdk: z.string().max(MANIFEST_LIMITS.versionChars).regex(SEMVER_FORMAT).optional(),
|
|
292
|
+
/**
|
|
293
|
+
* The app's own colours and shape (PB21): an accent, named colours each
|
|
294
|
+
* with a light and a dark value, a rounding and a density. No font: every
|
|
295
|
+
* app uses Brydio's. Checked by `themeProblems` (`look.ts`), Brydio's one
|
|
296
|
+
* rule set, copied.
|
|
297
|
+
*/
|
|
298
|
+
theme: z.unknown().optional(),
|
|
273
299
|
};
|
|
274
300
|
export function dataProblems(additions, options = {}) {
|
|
275
301
|
const problems = [];
|
|
@@ -706,6 +732,9 @@ function secretProblems(additions, options) {
|
|
|
706
732
|
return problems;
|
|
707
733
|
}
|
|
708
734
|
const refuse = (additions, ctx, options = {}) => {
|
|
735
|
+
for (const problem of themeProblems(additions.theme)) {
|
|
736
|
+
ctx.addIssue({ code: 'custom', message: problem.message, path: problem.path.split('.'), params: { code: problem.code } });
|
|
737
|
+
}
|
|
709
738
|
for (const problem of dataProblems(additions, options)) {
|
|
710
739
|
ctx.addIssue({
|
|
711
740
|
code: 'custom',
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two kinds of screen (`tasks/app-publishing` PB27). A copy of Brydio's
|
|
3
|
+
* `apps/api/src/apps/manifest/screen-kinds.ts`.
|
|
4
|
+
*
|
|
5
|
+
* A **tree screen** is the app's elements, drawn by Brydio (PB21 to PB24). A
|
|
6
|
+
* **frame screen** is the app's own HTML and CSS, drawn in a sandboxed frame
|
|
7
|
+
* on an origin that holds only app code. The manifest says which, per screen:
|
|
8
|
+
* `{ "kind": "frame", "entry": "screens/settings.html" }`. Left out, a screen
|
|
9
|
+
* is a tree screen, so every manifest from before keeps its meaning.
|
|
10
|
+
*/
|
|
11
|
+
export declare const SCREEN_KINDS: readonly ["tree", "frame"];
|
|
12
|
+
export type ScreenKind = (typeof SCREEN_KINDS)[number];
|
|
13
|
+
/** Which kind one of the manifest's screens is; `tree` when it says nothing. */
|
|
14
|
+
export declare function screenKindOf(manifest: unknown, screen: string): ScreenKind;
|
|
15
|
+
/** The manifest's screens of one kind, by name. */
|
|
16
|
+
export declare function screensOfKind(manifest: unknown, kind: ScreenKind): string[];
|
|
17
|
+
/** Every frame screen's page, by its path inside the bundle. */
|
|
18
|
+
export declare function framePagesOf(manifest: unknown): Set<string>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two kinds of screen (`tasks/app-publishing` PB27). A copy of Brydio's
|
|
3
|
+
* `apps/api/src/apps/manifest/screen-kinds.ts`.
|
|
4
|
+
*
|
|
5
|
+
* A **tree screen** is the app's elements, drawn by Brydio (PB21 to PB24). A
|
|
6
|
+
* **frame screen** is the app's own HTML and CSS, drawn in a sandboxed frame
|
|
7
|
+
* on an origin that holds only app code. The manifest says which, per screen:
|
|
8
|
+
* `{ "kind": "frame", "entry": "screens/settings.html" }`. Left out, a screen
|
|
9
|
+
* is a tree screen, so every manifest from before keeps its meaning.
|
|
10
|
+
*/
|
|
11
|
+
export const SCREEN_KINDS = ['tree', 'frame'];
|
|
12
|
+
const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
13
|
+
/** Which kind one of the manifest's screens is; `tree` when it says nothing. */
|
|
14
|
+
export function screenKindOf(manifest, screen) {
|
|
15
|
+
const screens = isRecord(manifest) && isRecord(manifest.screens) ? manifest.screens : {};
|
|
16
|
+
const declared = Object.prototype.hasOwnProperty.call(screens, screen) ? screens[screen] : undefined;
|
|
17
|
+
return isRecord(declared) && declared.kind === 'frame' ? 'frame' : 'tree';
|
|
18
|
+
}
|
|
19
|
+
/** The manifest's screens of one kind, by name. */
|
|
20
|
+
export function screensOfKind(manifest, kind) {
|
|
21
|
+
const screens = isRecord(manifest) && isRecord(manifest.screens) ? manifest.screens : {};
|
|
22
|
+
return Object.keys(screens).filter(screen => screenKindOf(manifest, screen) === kind);
|
|
23
|
+
}
|
|
24
|
+
/** Every frame screen's page, by its path inside the bundle. */
|
|
25
|
+
export function framePagesOf(manifest) {
|
|
26
|
+
const screens = isRecord(manifest) && isRecord(manifest.screens) ? manifest.screens : {};
|
|
27
|
+
return new Set(screensOfKind(manifest, 'frame')
|
|
28
|
+
.map(screen => screens[screen].entry)
|
|
29
|
+
.filter((entry) => typeof entry === 'string'));
|
|
30
|
+
}
|
package/src/validate.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { LookProblemCode } from './look.js';
|
|
1
2
|
import { type AppManifestWithData, type DataProblemCode } from './schema.js';
|
|
2
3
|
/**
|
|
3
4
|
* Reading a manifest and saying what is wrong with it, the way Brydio would.
|
|
@@ -9,7 +10,9 @@ import { type AppManifestWithData, type DataProblemCode } from './schema.js';
|
|
|
9
10
|
* `manifest_invalid` with the path to it, so an app's builder can find the
|
|
10
11
|
* line.
|
|
11
12
|
*/
|
|
12
|
-
export type ManifestProblemCode = DataProblemCode |
|
|
13
|
+
export type ManifestProblemCode = DataProblemCode | LookProblemCode
|
|
14
|
+
/** A frame screen without an .html page, or an .html entry that isn't a frame screen (PB27). */
|
|
15
|
+
| 'screen_kind_entry' | 'manifest_not_json' | 'manifest_invalid';
|
|
13
16
|
export interface ManifestProblem {
|
|
14
17
|
code: ManifestProblemCode;
|
|
15
18
|
message: string;
|