@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/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.object({
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 | 'manifest_not_json' | 'manifest_invalid';
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;