@camstack/types 1.2.106 → 1.2.107

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.
@@ -25,6 +25,23 @@ declare const EngineInfoSchema: z.ZodObject<{
25
25
  * go through `settings-store`; they never see this cap, and an engine
26
26
  * never sees a caller.
27
27
  *
28
+ * ⚠ **`internal: true` DOES NOT gate the mount, and until 2026-08-26 this
29
+ * comment claimed otherwise.** `resolveCapMount` never reads the field, so this
30
+ * cap was live on the AppRouter with every method at the default
31
+ * `auth: 'protected'` — i.e. readable by ANY authenticated session, admin or
32
+ * not. Verified against the live hub: `dataStoreProvider.query` returned raw
33
+ * settings rows including a provider credential, bypassing the secret redaction
34
+ * that `deviceManager.listAll` and friends go through.
35
+ *
36
+ * Every method is now `auth: 'admin'` EXPLICITLY, including the five reads —
37
+ * they had no options object at all, which is exactly how they kept the
38
+ * permissive default while the mutations looked deliberate. The explicit
39
+ * annotation is the fix that works today; making `internal` mean something at
40
+ * mount time is the systemic one, and it is not free: 22 caps declare it, only
41
+ * 4 are `mount: 'skip'`, and forcing admin on all of them would change the auth
42
+ * of surfaces the viewer and admin-ui call as non-admin users. That decision is
43
+ * the operator's, not a side effect of this file.
44
+ *
28
45
  * Design notes:
29
46
  * - **Stateless dispatch.** Every method carries its own
30
47
  * `namespace` + `collection`, so an engine keeps no per-caller state
package/dist/index.js CHANGED
@@ -7374,6 +7374,23 @@ var EngineInfoSchema = zod.z.object({
7374
7374
  * go through `settings-store`; they never see this cap, and an engine
7375
7375
  * never sees a caller.
7376
7376
  *
7377
+ * ⚠ **`internal: true` DOES NOT gate the mount, and until 2026-08-26 this
7378
+ * comment claimed otherwise.** `resolveCapMount` never reads the field, so this
7379
+ * cap was live on the AppRouter with every method at the default
7380
+ * `auth: 'protected'` — i.e. readable by ANY authenticated session, admin or
7381
+ * not. Verified against the live hub: `dataStoreProvider.query` returned raw
7382
+ * settings rows including a provider credential, bypassing the secret redaction
7383
+ * that `deviceManager.listAll` and friends go through.
7384
+ *
7385
+ * Every method is now `auth: 'admin'` EXPLICITLY, including the five reads —
7386
+ * they had no options object at all, which is exactly how they kept the
7387
+ * permissive default while the mutations looked deliberate. The explicit
7388
+ * annotation is the fix that works today; making `internal` mean something at
7389
+ * mount time is the systemic one, and it is not free: 22 caps declare it, only
7390
+ * 4 are `mount: 'skip'`, and forcing admin on all of them would change the auth
7391
+ * of surfaces the viewer and admin-ui call as non-admin users. That decision is
7392
+ * the operator's, not a side effect of this file.
7393
+ *
7377
7394
  * Design notes:
7378
7395
  * - **Stateless dispatch.** Every method carries its own
7379
7396
  * `namespace` + `collection`, so an engine keeps no per-caller state
@@ -7395,20 +7412,23 @@ var dataStoreProviderCapability = {
7395
7412
  internal: true,
7396
7413
  methods: {
7397
7414
  /** Self-description — how the orchestrator picks a registrant. */
7398
- getEngineInfo: require_sleep.method(zod.z.void(), EngineInfoSchema),
7415
+ getEngineInfo: require_sleep.method(zod.z.void(), EngineInfoSchema, { auth: "admin" }),
7399
7416
  /** Get a single value by key from a collection. */
7400
7417
  get: require_sleep.method(zod.z.object({
7401
7418
  namespace: zod.z.string().optional(),
7402
7419
  collection: zod.z.string(),
7403
7420
  key: zod.z.string()
7404
- }), zod.z.unknown()),
7421
+ }), zod.z.unknown(), { auth: "admin" }),
7405
7422
  /** Set a value by key in a collection (upsert). */
7406
7423
  set: require_sleep.method(zod.z.object({
7407
7424
  namespace: zod.z.string().optional(),
7408
7425
  collection: zod.z.string(),
7409
7426
  key: zod.z.string(),
7410
7427
  value: zod.z.unknown()
7411
- }), zod.z.void(), { kind: "mutation" }),
7428
+ }), zod.z.void(), {
7429
+ kind: "mutation",
7430
+ auth: "admin"
7431
+ }),
7412
7432
  /** Get all entries matching an optional filter. */
7413
7433
  query: require_sleep.method(zod.z.object({
7414
7434
  namespace: zod.z.string().optional(),
@@ -7417,52 +7437,80 @@ var dataStoreProviderCapability = {
7417
7437
  /**
7418
7438
  * SQL-level column projection — MUST mirror `settings-store.query`.
7419
7439
  *
7420
- * This is the second schema the same call passes through, and Zod
7421
- * objects STRIP what they do not declare: a field present on the door
7422
- * and absent here does not error, it silently disappears one hop before
7423
- * the engine, and the caller concludes the projection does nothing.
7424
- * `data-door-schema-parity.spec.ts` is what keeps the two in step.
7440
+ * An earlier version of this comment blamed Zod stripping, and that
7441
+ * was wrong corrected 2026-08-26 after the hop map
7442
+ * (`docs/design/2026-08-26-mappa-hop-argomenti.md`) traced the path.
7443
+ * There is **no Zod parse at all** between the door and the engine: the
7444
+ * dispatcher forwards the payload verbatim and UDS carries it whole. A
7445
+ * field declared here reaches `SqliteSettingsBackend` either way.
7446
+ *
7447
+ * What actually lost `columns` was the THIRD declaration of this shape:
7448
+ * `SettingsQueryInput` in `interfaces/storage.ts`, a hand-written TS
7449
+ * interface the engine destructures from. The field existed on both
7450
+ * schemas and the engine still never read it, because nothing checks a
7451
+ * registered provider against `InferProvider<cap>` —
7452
+ * `ProviderRegistration.provider` is typed `object`.
7453
+ *
7454
+ * It is declared here anyway, and must stay in step with
7455
+ * `settings-store.query`: a caller reading only the cap definitions has
7456
+ * to be able to see that this call carries a projection.
7457
+ * `data-door-schema-parity.spec.ts` keeps the two aligned.
7425
7458
  */
7426
7459
  columns: zod.z.array(zod.z.string()).readonly().optional()
7427
- }), zod.z.array(SettingsRecordSchema).readonly()),
7460
+ }), zod.z.array(SettingsRecordSchema).readonly(), { auth: "admin" }),
7428
7461
  /** Insert a new record. */
7429
7462
  insert: require_sleep.method(zod.z.object({
7430
7463
  namespace: zod.z.string().optional(),
7431
7464
  collection: zod.z.string(),
7432
7465
  record: SettingsRecordSchema
7433
- }), zod.z.void(), { kind: "mutation" }),
7466
+ }), zod.z.void(), {
7467
+ kind: "mutation",
7468
+ auth: "admin"
7469
+ }),
7434
7470
  /** Update an existing record by ID. */
7435
7471
  update: require_sleep.method(zod.z.object({
7436
7472
  namespace: zod.z.string().optional(),
7437
7473
  collection: zod.z.string(),
7438
7474
  id: zod.z.string(),
7439
7475
  data: zod.z.record(zod.z.string(), zod.z.unknown())
7440
- }), zod.z.void(), { kind: "mutation" }),
7476
+ }), zod.z.void(), {
7477
+ kind: "mutation",
7478
+ auth: "admin"
7479
+ }),
7441
7480
  /** Delete a record by key/ID. */
7442
7481
  delete: require_sleep.method(zod.z.object({
7443
7482
  namespace: zod.z.string().optional(),
7444
7483
  collection: zod.z.string(),
7445
7484
  key: zod.z.string()
7446
- }), zod.z.void(), { kind: "mutation" }),
7485
+ }), zod.z.void(), {
7486
+ kind: "mutation",
7487
+ auth: "admin"
7488
+ }),
7447
7489
  /** Delete every record matching `filter`, in one statement. */
7448
7490
  deleteWhere: require_sleep.method(zod.z.object({
7449
7491
  namespace: zod.z.string().optional(),
7450
7492
  collection: zod.z.string(),
7451
7493
  filter: MutationFilterSchema
7452
- }), zod.z.object({ deleted: zod.z.number().int() }), { kind: "mutation" }),
7494
+ }), zod.z.object({ deleted: zod.z.number().int() }), {
7495
+ kind: "mutation",
7496
+ auth: "admin"
7497
+ }),
7453
7498
  /** Apply `data` to every record matching `filter`, in one statement. */
7454
7499
  updateWhere: require_sleep.method(zod.z.object({
7455
7500
  namespace: zod.z.string().optional(),
7456
7501
  collection: zod.z.string(),
7457
7502
  filter: MutationFilterSchema,
7458
7503
  data: zod.z.record(zod.z.string(), zod.z.unknown())
7459
- }), zod.z.object({ updated: zod.z.number().int() }), { kind: "mutation" }),
7504
+ }), zod.z.object({ updated: zod.z.number().int() }), {
7505
+ kind: "mutation",
7506
+ auth: "admin"
7507
+ }),
7460
7508
  /** Count entries in a collection, optionally filtered. */
7461
7509
  count: require_sleep.method(zod.z.object({
7462
7510
  namespace: zod.z.string().optional(),
7463
7511
  collection: zod.z.string(),
7464
7512
  filter: QueryFilterSchema.optional()
7465
- }), zod.z.number()),
7513
+ }), zod.z.number(), { auth: "admin" }),
7466
7514
  /** Grouped counts per ((field-origin)/bucketSize) bucket, filtered. */
7467
7515
  histogram: require_sleep.method(zod.z.object({
7468
7516
  namespace: zod.z.string().optional(),
@@ -7474,19 +7522,22 @@ var dataStoreProviderCapability = {
7474
7522
  }), zod.z.array(zod.z.object({
7475
7523
  bucket: zod.z.number().int(),
7476
7524
  count: zod.z.number().int()
7477
- })).readonly()),
7525
+ })).readonly(), { auth: "admin" }),
7478
7526
  /** Check if a collection is empty. */
7479
7527
  isEmpty: require_sleep.method(zod.z.object({
7480
7528
  namespace: zod.z.string().optional(),
7481
7529
  collection: zod.z.string()
7482
- }), zod.z.boolean()),
7530
+ }), zod.z.boolean(), { auth: "admin" }),
7483
7531
  /** Declare a typed (SQL-backed) collection with columns + indexes. */
7484
7532
  declareCollection: require_sleep.method(zod.z.object({
7485
7533
  namespace: zod.z.string().optional(),
7486
7534
  collection: zod.z.string(),
7487
7535
  columns: zod.z.array(CollectionColumnSchema).readonly(),
7488
7536
  indexes: zod.z.array(CollectionIndexSchema).readonly().optional()
7489
- }), zod.z.void(), { kind: "mutation" })
7537
+ }), zod.z.void(), {
7538
+ kind: "mutation",
7539
+ auth: "admin"
7540
+ })
7490
7541
  }
7491
7542
  };
7492
7543
  //#endregion
package/dist/index.mjs CHANGED
@@ -7373,6 +7373,23 @@ var EngineInfoSchema = z.object({
7373
7373
  * go through `settings-store`; they never see this cap, and an engine
7374
7374
  * never sees a caller.
7375
7375
  *
7376
+ * ⚠ **`internal: true` DOES NOT gate the mount, and until 2026-08-26 this
7377
+ * comment claimed otherwise.** `resolveCapMount` never reads the field, so this
7378
+ * cap was live on the AppRouter with every method at the default
7379
+ * `auth: 'protected'` — i.e. readable by ANY authenticated session, admin or
7380
+ * not. Verified against the live hub: `dataStoreProvider.query` returned raw
7381
+ * settings rows including a provider credential, bypassing the secret redaction
7382
+ * that `deviceManager.listAll` and friends go through.
7383
+ *
7384
+ * Every method is now `auth: 'admin'` EXPLICITLY, including the five reads —
7385
+ * they had no options object at all, which is exactly how they kept the
7386
+ * permissive default while the mutations looked deliberate. The explicit
7387
+ * annotation is the fix that works today; making `internal` mean something at
7388
+ * mount time is the systemic one, and it is not free: 22 caps declare it, only
7389
+ * 4 are `mount: 'skip'`, and forcing admin on all of them would change the auth
7390
+ * of surfaces the viewer and admin-ui call as non-admin users. That decision is
7391
+ * the operator's, not a side effect of this file.
7392
+ *
7376
7393
  * Design notes:
7377
7394
  * - **Stateless dispatch.** Every method carries its own
7378
7395
  * `namespace` + `collection`, so an engine keeps no per-caller state
@@ -7394,20 +7411,23 @@ var dataStoreProviderCapability = {
7394
7411
  internal: true,
7395
7412
  methods: {
7396
7413
  /** Self-description — how the orchestrator picks a registrant. */
7397
- getEngineInfo: method(z.void(), EngineInfoSchema),
7414
+ getEngineInfo: method(z.void(), EngineInfoSchema, { auth: "admin" }),
7398
7415
  /** Get a single value by key from a collection. */
7399
7416
  get: method(z.object({
7400
7417
  namespace: z.string().optional(),
7401
7418
  collection: z.string(),
7402
7419
  key: z.string()
7403
- }), z.unknown()),
7420
+ }), z.unknown(), { auth: "admin" }),
7404
7421
  /** Set a value by key in a collection (upsert). */
7405
7422
  set: method(z.object({
7406
7423
  namespace: z.string().optional(),
7407
7424
  collection: z.string(),
7408
7425
  key: z.string(),
7409
7426
  value: z.unknown()
7410
- }), z.void(), { kind: "mutation" }),
7427
+ }), z.void(), {
7428
+ kind: "mutation",
7429
+ auth: "admin"
7430
+ }),
7411
7431
  /** Get all entries matching an optional filter. */
7412
7432
  query: method(z.object({
7413
7433
  namespace: z.string().optional(),
@@ -7416,52 +7436,80 @@ var dataStoreProviderCapability = {
7416
7436
  /**
7417
7437
  * SQL-level column projection — MUST mirror `settings-store.query`.
7418
7438
  *
7419
- * This is the second schema the same call passes through, and Zod
7420
- * objects STRIP what they do not declare: a field present on the door
7421
- * and absent here does not error, it silently disappears one hop before
7422
- * the engine, and the caller concludes the projection does nothing.
7423
- * `data-door-schema-parity.spec.ts` is what keeps the two in step.
7439
+ * An earlier version of this comment blamed Zod stripping, and that
7440
+ * was wrong corrected 2026-08-26 after the hop map
7441
+ * (`docs/design/2026-08-26-mappa-hop-argomenti.md`) traced the path.
7442
+ * There is **no Zod parse at all** between the door and the engine: the
7443
+ * dispatcher forwards the payload verbatim and UDS carries it whole. A
7444
+ * field declared here reaches `SqliteSettingsBackend` either way.
7445
+ *
7446
+ * What actually lost `columns` was the THIRD declaration of this shape:
7447
+ * `SettingsQueryInput` in `interfaces/storage.ts`, a hand-written TS
7448
+ * interface the engine destructures from. The field existed on both
7449
+ * schemas and the engine still never read it, because nothing checks a
7450
+ * registered provider against `InferProvider<cap>` —
7451
+ * `ProviderRegistration.provider` is typed `object`.
7452
+ *
7453
+ * It is declared here anyway, and must stay in step with
7454
+ * `settings-store.query`: a caller reading only the cap definitions has
7455
+ * to be able to see that this call carries a projection.
7456
+ * `data-door-schema-parity.spec.ts` keeps the two aligned.
7424
7457
  */
7425
7458
  columns: z.array(z.string()).readonly().optional()
7426
- }), z.array(SettingsRecordSchema).readonly()),
7459
+ }), z.array(SettingsRecordSchema).readonly(), { auth: "admin" }),
7427
7460
  /** Insert a new record. */
7428
7461
  insert: method(z.object({
7429
7462
  namespace: z.string().optional(),
7430
7463
  collection: z.string(),
7431
7464
  record: SettingsRecordSchema
7432
- }), z.void(), { kind: "mutation" }),
7465
+ }), z.void(), {
7466
+ kind: "mutation",
7467
+ auth: "admin"
7468
+ }),
7433
7469
  /** Update an existing record by ID. */
7434
7470
  update: method(z.object({
7435
7471
  namespace: z.string().optional(),
7436
7472
  collection: z.string(),
7437
7473
  id: z.string(),
7438
7474
  data: z.record(z.string(), z.unknown())
7439
- }), z.void(), { kind: "mutation" }),
7475
+ }), z.void(), {
7476
+ kind: "mutation",
7477
+ auth: "admin"
7478
+ }),
7440
7479
  /** Delete a record by key/ID. */
7441
7480
  delete: method(z.object({
7442
7481
  namespace: z.string().optional(),
7443
7482
  collection: z.string(),
7444
7483
  key: z.string()
7445
- }), z.void(), { kind: "mutation" }),
7484
+ }), z.void(), {
7485
+ kind: "mutation",
7486
+ auth: "admin"
7487
+ }),
7446
7488
  /** Delete every record matching `filter`, in one statement. */
7447
7489
  deleteWhere: method(z.object({
7448
7490
  namespace: z.string().optional(),
7449
7491
  collection: z.string(),
7450
7492
  filter: MutationFilterSchema
7451
- }), z.object({ deleted: z.number().int() }), { kind: "mutation" }),
7493
+ }), z.object({ deleted: z.number().int() }), {
7494
+ kind: "mutation",
7495
+ auth: "admin"
7496
+ }),
7452
7497
  /** Apply `data` to every record matching `filter`, in one statement. */
7453
7498
  updateWhere: method(z.object({
7454
7499
  namespace: z.string().optional(),
7455
7500
  collection: z.string(),
7456
7501
  filter: MutationFilterSchema,
7457
7502
  data: z.record(z.string(), z.unknown())
7458
- }), z.object({ updated: z.number().int() }), { kind: "mutation" }),
7503
+ }), z.object({ updated: z.number().int() }), {
7504
+ kind: "mutation",
7505
+ auth: "admin"
7506
+ }),
7459
7507
  /** Count entries in a collection, optionally filtered. */
7460
7508
  count: method(z.object({
7461
7509
  namespace: z.string().optional(),
7462
7510
  collection: z.string(),
7463
7511
  filter: QueryFilterSchema.optional()
7464
- }), z.number()),
7512
+ }), z.number(), { auth: "admin" }),
7465
7513
  /** Grouped counts per ((field-origin)/bucketSize) bucket, filtered. */
7466
7514
  histogram: method(z.object({
7467
7515
  namespace: z.string().optional(),
@@ -7473,19 +7521,22 @@ var dataStoreProviderCapability = {
7473
7521
  }), z.array(z.object({
7474
7522
  bucket: z.number().int(),
7475
7523
  count: z.number().int()
7476
- })).readonly()),
7524
+ })).readonly(), { auth: "admin" }),
7477
7525
  /** Check if a collection is empty. */
7478
7526
  isEmpty: method(z.object({
7479
7527
  namespace: z.string().optional(),
7480
7528
  collection: z.string()
7481
- }), z.boolean()),
7529
+ }), z.boolean(), { auth: "admin" }),
7482
7530
  /** Declare a typed (SQL-backed) collection with columns + indexes. */
7483
7531
  declareCollection: method(z.object({
7484
7532
  namespace: z.string().optional(),
7485
7533
  collection: z.string(),
7486
7534
  columns: z.array(CollectionColumnSchema).readonly(),
7487
7535
  indexes: z.array(CollectionIndexSchema).readonly().optional()
7488
- }), z.void(), { kind: "mutation" })
7536
+ }), z.void(), {
7537
+ kind: "mutation",
7538
+ auth: "admin"
7539
+ })
7489
7540
  }
7490
7541
  };
7491
7542
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/types",
3
- "version": "1.2.106",
3
+ "version": "1.2.107",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",