@brydio/manifest 0.1.0-alpha.31 → 0.1.0-alpha.33

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brydio/manifest",
3
- "version": "0.1.0-alpha.31",
3
+ "version": "0.1.0-alpha.33",
4
4
  "description": "The shape of a Brydio app's manifest, its collections' schemas, and the checks that say what is wrong with one.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -10,7 +10,7 @@
10
10
  "url": "https://github.com/nakel-ola/brydio-sdk",
11
11
  "directory": "packages/manifest"
12
12
  },
13
- "gitHead": "5b6cf4e4fdacc5c60684fbf25b6b3cc3c78bb4f8",
13
+ "gitHead": "664471f08e89483e25fb1bd49dfd69709b575bfa",
14
14
  "exports": {
15
15
  ".": {
16
16
  "types": "./src/index.d.ts",
package/src/grants.d.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  * `apps/api/src/apps/publishing/app-publish.service.ts`.
8
8
  */
9
9
  /** The host grants with a name of their own. A connection's is `connection:<name>`. */
10
- export declare const HOST_CAPABILITIES: readonly ["navigate", "message", "members", "projects", "files", "chats", "model", "secrets", "notify"];
10
+ export declare const HOST_CAPABILITIES: readonly ["navigate", "message", "members", "projects", "files", "chats", "model", "secrets", "notify", "approvals"];
11
11
  /** The older name for `HOST_CAPABILITIES`, kept for what already imports it. */
12
12
  export declare const KNOWN_HOST_GRANTS: readonly string[];
13
13
  /** True for a host grant Brydio knows how to honour: a named capability, or one connection. */
package/src/grants.js CHANGED
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { BUNDLE_MANIFEST } from "./bundle.js";
10
10
  /** The host grants with a name of their own. A connection's is `connection:<name>`. */
11
- export const HOST_CAPABILITIES = ['navigate', 'message', 'members', 'projects', 'files', 'chats', 'model', 'secrets', 'notify'];
11
+ export const HOST_CAPABILITIES = ['navigate', 'message', 'members', 'projects', 'files', 'chats', 'model', 'secrets', 'notify', 'approvals'];
12
12
  /** The older name for `HOST_CAPABILITIES`, kept for what already imports it. */
13
13
  export const KNOWN_HOST_GRANTS = HOST_CAPABILITIES;
14
14
  const CONNECTION = /^connection:[a-z0-9][a-z0-9_-]{0,59}$/;
package/src/schema.d.ts CHANGED
@@ -60,6 +60,7 @@ declare const customToolSchema: z.ZodObject<{
60
60
  input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
61
61
  write: z.ZodOptional<z.ZodBoolean>;
62
62
  collection: z.ZodOptional<z.ZodString>;
63
+ public: z.ZodOptional<z.ZodBoolean>;
63
64
  }, z.core.$strip>;
64
65
  export type CustomToolSpec = z.infer<typeof customToolSchema>;
65
66
  /** Most secrets one app may declare (ADR-A24). */
@@ -97,6 +98,7 @@ declare const extensionShape: {
97
98
  "project-tab": "project-tab";
98
99
  "project-sidebar": "project-sidebar";
99
100
  "workspace-sidebar": "workspace-sidebar";
101
+ "public-page": "public-page";
100
102
  }>;
101
103
  screen: z.ZodString;
102
104
  sizes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
@@ -141,6 +143,8 @@ declare const extensionShape: {
141
143
  schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
142
144
  search: z.ZodOptional<z.ZodArray<z.ZodString>>;
143
145
  label: z.ZodOptional<z.ZodString>;
146
+ publicRead: z.ZodOptional<z.ZodBoolean>;
147
+ publicSubmit: z.ZodOptional<z.ZodBoolean>;
144
148
  }, z.core.$strip>>>;
145
149
  tools: z.ZodOptional<z.ZodObject<{
146
150
  generated: z.ZodOptional<z.ZodBoolean>;
@@ -151,6 +155,7 @@ declare const extensionShape: {
151
155
  input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
152
156
  write: z.ZodOptional<z.ZodBoolean>;
153
157
  collection: z.ZodOptional<z.ZodString>;
158
+ public: z.ZodOptional<z.ZodBoolean>;
154
159
  }, z.core.$strip>>>;
155
160
  }, z.core.$strip>>;
156
161
  screens: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -218,7 +223,7 @@ export interface DataProblem {
218
223
  field?: string;
219
224
  message: string;
220
225
  }
221
- export type DataProblemCode = FieldTypeInvalid['code'] | 'data_too_many_collections' | 'data_too_many_fields' | 'data_collection_name_format' | 'data_field_name_format' | 'data_field_reserved' | 'data_label_format' | 'data_label_taken' | 'data_project_field_twice' | 'data_search_unknown_field' | 'data_search_not_text' | 'grant_collection_missing' | 'grant_tool_missing' | 'custom_name_taken' | 'custom_collection_unknown' | 'custom_input_invalid' | 'placement_key_taken' | 'placement_screen_unknown' | 'placement_home_sizes' | 'placement_sizes_not_home' | 'placement_widget_sizes' | 'placement_tab_retired' | 'placement_children_too_deep' | 'placement_create_tool_unknown' | 'placement_create_not_write' | 'secret_name_taken' | 'grant_secrets_missing';
226
+ export type DataProblemCode = FieldTypeInvalid['code'] | 'data_too_many_collections' | 'data_too_many_fields' | 'data_collection_name_format' | 'data_field_name_format' | 'data_field_reserved' | 'data_label_format' | 'data_label_taken' | 'data_project_field_twice' | 'data_search_unknown_field' | 'data_search_not_text' | 'grant_collection_missing' | 'grant_tool_missing' | 'custom_name_taken' | 'custom_collection_unknown' | 'custom_input_invalid' | 'placement_key_taken' | 'placement_screen_unknown' | 'placement_home_sizes' | 'placement_sizes_not_home' | 'placement_widget_sizes' | 'placement_tab_retired' | 'placement_public_shape' | 'placement_public_nothing' | 'placement_children_too_deep' | 'placement_create_tool_unknown' | 'placement_create_not_write' | 'secret_name_taken' | 'grant_secrets_missing';
222
227
  type Additions = z.infer<z.ZodObject<typeof extensionShape>>;
223
228
  /**
224
229
  * Everything wrong with an app's additions that a type cannot say.
@@ -244,6 +249,7 @@ export declare const manifestExtensionsSchema: z.ZodObject<{
244
249
  "project-tab": "project-tab";
245
250
  "project-sidebar": "project-sidebar";
246
251
  "workspace-sidebar": "workspace-sidebar";
252
+ "public-page": "public-page";
247
253
  }>;
248
254
  screen: z.ZodString;
249
255
  sizes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
@@ -288,6 +294,8 @@ export declare const manifestExtensionsSchema: z.ZodObject<{
288
294
  schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
289
295
  search: z.ZodOptional<z.ZodArray<z.ZodString>>;
290
296
  label: z.ZodOptional<z.ZodString>;
297
+ publicRead: z.ZodOptional<z.ZodBoolean>;
298
+ publicSubmit: z.ZodOptional<z.ZodBoolean>;
291
299
  }, z.core.$strip>>>;
292
300
  tools: z.ZodOptional<z.ZodObject<{
293
301
  generated: z.ZodOptional<z.ZodBoolean>;
@@ -298,6 +306,7 @@ export declare const manifestExtensionsSchema: z.ZodObject<{
298
306
  input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
299
307
  write: z.ZodOptional<z.ZodBoolean>;
300
308
  collection: z.ZodOptional<z.ZodString>;
309
+ public: z.ZodOptional<z.ZodBoolean>;
301
310
  }, z.core.$strip>>>;
302
311
  }, z.core.$strip>>;
303
312
  screens: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -361,6 +370,7 @@ export declare const storedExtensionsSchema: z.ZodObject<{
361
370
  "project-tab": "project-tab";
362
371
  "project-sidebar": "project-sidebar";
363
372
  "workspace-sidebar": "workspace-sidebar";
373
+ "public-page": "public-page";
364
374
  }>;
365
375
  screen: z.ZodString;
366
376
  sizes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
@@ -405,6 +415,8 @@ export declare const storedExtensionsSchema: z.ZodObject<{
405
415
  schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
406
416
  search: z.ZodOptional<z.ZodArray<z.ZodString>>;
407
417
  label: z.ZodOptional<z.ZodString>;
418
+ publicRead: z.ZodOptional<z.ZodBoolean>;
419
+ publicSubmit: z.ZodOptional<z.ZodBoolean>;
408
420
  }, z.core.$strip>>>;
409
421
  tools: z.ZodOptional<z.ZodObject<{
410
422
  generated: z.ZodOptional<z.ZodBoolean>;
@@ -415,6 +427,7 @@ export declare const storedExtensionsSchema: z.ZodObject<{
415
427
  input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
416
428
  write: z.ZodOptional<z.ZodBoolean>;
417
429
  collection: z.ZodOptional<z.ZodString>;
430
+ public: z.ZodOptional<z.ZodBoolean>;
418
431
  }, z.core.$strip>>>;
419
432
  }, z.core.$strip>>;
420
433
  screens: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -513,6 +526,7 @@ export declare const appManifestSchema: z.ZodObject<{
513
526
  "project-tab": "project-tab";
514
527
  "project-sidebar": "project-sidebar";
515
528
  "workspace-sidebar": "workspace-sidebar";
529
+ "public-page": "public-page";
516
530
  }>;
517
531
  screen: z.ZodString;
518
532
  sizes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
@@ -557,6 +571,8 @@ export declare const appManifestSchema: z.ZodObject<{
557
571
  schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
558
572
  search: z.ZodOptional<z.ZodArray<z.ZodString>>;
559
573
  label: z.ZodOptional<z.ZodString>;
574
+ publicRead: z.ZodOptional<z.ZodBoolean>;
575
+ publicSubmit: z.ZodOptional<z.ZodBoolean>;
560
576
  }, z.core.$strip>>>;
561
577
  tools: z.ZodOptional<z.ZodObject<{
562
578
  generated: z.ZodOptional<z.ZodBoolean>;
@@ -567,6 +583,7 @@ export declare const appManifestSchema: z.ZodObject<{
567
583
  input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
568
584
  write: z.ZodOptional<z.ZodBoolean>;
569
585
  collection: z.ZodOptional<z.ZodString>;
586
+ public: z.ZodOptional<z.ZodBoolean>;
570
587
  }, z.core.$strip>>>;
571
588
  }, z.core.$strip>>;
572
589
  screens: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -669,6 +686,7 @@ export declare const newAppManifestSchema: z.ZodObject<{
669
686
  "project-tab": "project-tab";
670
687
  "project-sidebar": "project-sidebar";
671
688
  "workspace-sidebar": "workspace-sidebar";
689
+ "public-page": "public-page";
672
690
  }>;
673
691
  screen: z.ZodString;
674
692
  sizes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
@@ -713,6 +731,8 @@ export declare const newAppManifestSchema: z.ZodObject<{
713
731
  schema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
714
732
  search: z.ZodOptional<z.ZodArray<z.ZodString>>;
715
733
  label: z.ZodOptional<z.ZodString>;
734
+ publicRead: z.ZodOptional<z.ZodBoolean>;
735
+ publicSubmit: z.ZodOptional<z.ZodBoolean>;
716
736
  }, z.core.$strip>>>;
717
737
  tools: z.ZodOptional<z.ZodObject<{
718
738
  generated: z.ZodOptional<z.ZodBoolean>;
@@ -723,6 +743,7 @@ export declare const newAppManifestSchema: z.ZodObject<{
723
743
  input: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
724
744
  write: z.ZodOptional<z.ZodBoolean>;
725
745
  collection: z.ZodOptional<z.ZodString>;
746
+ public: z.ZodOptional<z.ZodBoolean>;
726
747
  }, z.core.$strip>>>;
727
748
  }, z.core.$strip>>;
728
749
  screens: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
package/src/schema.js CHANGED
@@ -64,8 +64,13 @@ const placementSchema = z.object({
64
64
  * `project-widget`: a card on a project's page, drawn at one of `sizes`.
65
65
  * `project-tab` is retired (30 Sep 2026): still read from a published
66
66
  * manifest, refused in a new one (`placement_tab_retired`).
67
+ * `public-page`: a screen people without a Brydio account open at the
68
+ * page's own address, once an admin turns it on (P3). It has no `sizes`,
69
+ * `children` or `settings` (`placement_public_shape`), and it reaches only
70
+ * collections marked `publicRead` or `publicSubmit` and tools marked
71
+ * `public`.
67
72
  */
68
- kind: z.enum(['project-tab', 'project-widget', 'project-sidebar', 'workspace-sidebar', 'home']),
73
+ kind: z.enum(['project-tab', 'project-widget', 'project-sidebar', 'workspace-sidebar', 'home', 'public-page']),
69
74
  screen: z.string().min(1).max(FIELD_LIMITS.nameChars),
70
75
  /** For `home` and `project-widget` only, and required there: the sizes the screen draws well at. */
71
76
  sizes: z.array(z.enum(HOME_CARD_SIZES)).max(3).optional(),
@@ -101,6 +106,17 @@ const collectionSchema = z.object({
101
106
  search: z.array(z.string()).optional(),
102
107
  /** The singular noun the tools are named with: `issue` gives `create_issue`. */
103
108
  label: z.string().optional(),
109
+ /**
110
+ * A visitor on one of the app's public pages may `get` and `list` every
111
+ * record of this collection in that instance (P3).
112
+ */
113
+ publicRead: z.boolean().optional(),
114
+ /**
115
+ * A visitor on one of the app's public pages may create records here, and
116
+ * nothing else: no update, remove or batch, and no get or list unless
117
+ * `publicRead` is set too (P3).
118
+ */
119
+ publicSubmit: z.boolean().optional(),
104
120
  });
105
121
  const screenSchema = z.object({
106
122
  /**
@@ -137,6 +153,12 @@ const customToolSchema = z.object({
137
153
  write: z.boolean().optional(),
138
154
  /** The collection it works on, when it works on one: its grant then needs that collection too. */
139
155
  collection: z.string().optional(),
156
+ /**
157
+ * Callable from a public page (P3). Its handler then runs for a visitor,
158
+ * whose `data` is held to `publicRead` and `publicSubmit` and who can use
159
+ * nothing else of the workspace's.
160
+ */
161
+ public: z.boolean().optional(),
140
162
  });
141
163
  const toolsSchema = z.object({
142
164
  /** Off only when the app supplies every tool itself (A3-F08). */
@@ -366,6 +388,25 @@ export function dataProblems(additions, options = {}) {
366
388
  message: 'Project tabs are retired; declare a project-widget with sizes instead.',
367
389
  });
368
390
  }
391
+ // A public page is one screen at its own address: nothing to list in a
392
+ // sidebar, and nothing for an admin to fill in when it is placed.
393
+ if (placement.kind === 'public-page' && (placement.children || placement.settings)) {
394
+ problems.push({
395
+ code: 'placement_public_shape',
396
+ message: `The public page "${placement.screen}" can have no children or settings: it is one screen at its own address.`,
397
+ });
398
+ }
399
+ }
400
+ // A public page with nothing public could show a visitor nothing at all.
401
+ if ((additions.placements ?? []).some(placement => placement.kind === 'public-page')) {
402
+ const publicData = Object.values(additions.data ?? {}).some(declared => declared.publicRead || declared.publicSubmit);
403
+ const publicTool = (additions.tools?.custom ?? []).some(tool => tool.public);
404
+ if (!publicData && !publicTool) {
405
+ problems.push({
406
+ code: 'placement_public_nothing',
407
+ message: 'A public page needs something a visitor may use: mark a collection publicRead or publicSubmit, or a custom tool public.',
408
+ });
409
+ }
369
410
  }
370
411
  problems.push(...folderProblems(additions));
371
412
  return problems;