@secondlayer/shared 11.17.0 → 11.19.0

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.
@@ -237,7 +237,9 @@ interface ApiKeysTable {
237
237
  rate_limit: Generated<number>;
238
238
  ip_address: string;
239
239
  account_id: string;
240
- product: Generated<"account" | "streams" | "index">;
240
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
241
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
242
+ areas: unknown | null;
241
243
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
242
244
  last_used_at: Date | null;
243
245
  revoked_at: Date | null;
@@ -237,7 +237,9 @@ interface ApiKeysTable {
237
237
  rate_limit: Generated<number>;
238
238
  ip_address: string;
239
239
  account_id: string;
240
- product: Generated<"account" | "streams" | "index">;
240
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
241
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
242
+ areas: unknown | null;
241
243
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
242
244
  last_used_at: Date | null;
243
245
  revoked_at: Date | null;
@@ -554,7 +554,9 @@ interface ApiKeysTable {
554
554
  rate_limit: Generated<number>;
555
555
  ip_address: string;
556
556
  account_id: string;
557
- product: Generated<"account" | "streams" | "index">;
557
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
558
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
559
+ areas: unknown | null;
558
560
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
559
561
  last_used_at: Date | null;
560
562
  revoked_at: Date | null;
@@ -238,7 +238,9 @@ interface ApiKeysTable {
238
238
  rate_limit: Generated<number>;
239
239
  ip_address: string;
240
240
  account_id: string;
241
- product: Generated<"account" | "streams" | "index">;
241
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
242
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
243
+ areas: unknown | null;
242
244
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
243
245
  last_used_at: Date | null;
244
246
  revoked_at: Date | null;
@@ -237,7 +237,9 @@ interface ApiKeysTable {
237
237
  rate_limit: Generated<number>;
238
238
  ip_address: string;
239
239
  account_id: string;
240
- product: Generated<"account" | "streams" | "index">;
240
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
241
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
242
+ areas: unknown | null;
241
243
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
242
244
  last_used_at: Date | null;
243
245
  revoked_at: Date | null;
@@ -237,7 +237,9 @@ interface ApiKeysTable {
237
237
  rate_limit: Generated<number>;
238
238
  ip_address: string;
239
239
  account_id: string;
240
- product: Generated<"account" | "streams" | "index">;
240
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
241
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
242
+ areas: unknown | null;
241
243
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
242
244
  last_used_at: Date | null;
243
245
  revoked_at: Date | null;
@@ -237,7 +237,9 @@ interface ApiKeysTable {
237
237
  rate_limit: Generated<number>;
238
238
  ip_address: string;
239
239
  account_id: string;
240
- product: Generated<"account" | "streams" | "index">;
240
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
241
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
242
+ areas: unknown | null;
241
243
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
242
244
  last_used_at: Date | null;
243
245
  revoked_at: Date | null;
@@ -237,7 +237,9 @@ interface ApiKeysTable {
237
237
  rate_limit: Generated<number>;
238
238
  ip_address: string;
239
239
  account_id: string;
240
- product: Generated<"account" | "streams" | "index">;
240
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
241
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
242
+ areas: unknown | null;
241
243
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
242
244
  last_used_at: Date | null;
243
245
  revoked_at: Date | null;
@@ -237,7 +237,9 @@ interface ApiKeysTable {
237
237
  rate_limit: Generated<number>;
238
238
  ip_address: string;
239
239
  account_id: string;
240
- product: Generated<"account" | "streams" | "index">;
240
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
241
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
242
+ areas: unknown | null;
241
243
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
242
244
  last_used_at: Date | null;
243
245
  revoked_at: Date | null;
@@ -237,7 +237,9 @@ interface ApiKeysTable {
237
237
  rate_limit: Generated<number>;
238
238
  ip_address: string;
239
239
  account_id: string;
240
- product: Generated<"account" | "streams" | "index">;
240
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
241
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
242
+ areas: unknown | null;
241
243
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
242
244
  last_used_at: Date | null;
243
245
  revoked_at: Date | null;
@@ -237,7 +237,9 @@ interface ApiKeysTable {
237
237
  rate_limit: Generated<number>;
238
238
  ip_address: string;
239
239
  account_id: string;
240
- product: Generated<"account" | "streams" | "index">;
240
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
241
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
242
+ areas: unknown | null;
241
243
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
242
244
  last_used_at: Date | null;
243
245
  revoked_at: Date | null;
@@ -247,7 +247,9 @@ interface ApiKeysTable {
247
247
  rate_limit: Generated<number>;
248
248
  ip_address: string;
249
249
  account_id: string;
250
- product: Generated<"account" | "streams" | "index">;
250
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
251
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
252
+ areas: unknown | null;
251
253
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
252
254
  last_used_at: Date | null;
253
255
  revoked_at: Date | null;
@@ -237,7 +237,9 @@ interface ApiKeysTable {
237
237
  rate_limit: Generated<number>;
238
238
  ip_address: string;
239
239
  account_id: string;
240
- product: Generated<"account" | "streams" | "index">;
240
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
241
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
242
+ areas: unknown | null;
241
243
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
242
244
  last_used_at: Date | null;
243
245
  revoked_at: Date | null;
@@ -236,7 +236,9 @@ interface ApiKeysTable {
236
236
  rate_limit: Generated<number>;
237
237
  ip_address: string;
238
238
  account_id: string;
239
- product: Generated<"account" | "streams" | "index">;
239
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
240
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
241
+ areas: unknown | null;
240
242
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
241
243
  last_used_at: Date | null;
242
244
  revoked_at: Date | null;
@@ -56,6 +56,10 @@ type RuneStreamsEvent = {
56
56
  event_type: RuneEventType
57
57
  rune_id: string
58
58
  payload: RuneEventPayload
59
+ /** The event's block time, ISO 8601. Absent when the indexer has no header
60
+ * time for that block yet (rows written before block times were recorded,
61
+ * until backfilled). */
62
+ ts?: string
59
63
  /** True when this event's block is past the finality boundary (immutable).
60
64
  * Optional for back-compat with the same reasoning as `StreamsEventBase`. */
61
65
  finalized?: boolean
@@ -236,7 +236,9 @@ interface ApiKeysTable {
236
236
  rate_limit: Generated<number>;
237
237
  ip_address: string;
238
238
  account_id: string;
239
- product: Generated<"account" | "streams" | "index">;
239
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
240
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
241
+ areas: unknown | null;
240
242
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
241
243
  last_used_at: Date | null;
242
244
  revoked_at: Date | null;
@@ -237,7 +237,9 @@ interface ApiKeysTable {
237
237
  rate_limit: Generated<number>;
238
238
  ip_address: string;
239
239
  account_id: string;
240
- product: Generated<"account" | "streams" | "index">;
240
+ product: Generated<"account" | "streams" | "index" | "sentinel">;
241
+ /** Sentinel permission areas; set only on `product = 'sentinel'` keys. */
242
+ areas: unknown | null;
241
243
  tier: "free" | "build" | "scale" | "enterprise" | "internal" | null;
242
244
  last_used_at: Date | null;
243
245
  revoked_at: Date | null;
@@ -223,6 +223,10 @@ type RuneStreamsEvent = {
223
223
  event_type: RuneEventType
224
224
  rune_id: string
225
225
  payload: RuneEventPayload
226
+ /** The event's block time, ISO 8601. Absent when the indexer has no header
227
+ * time for that block yet (rows written before block times were recorded,
228
+ * until backfilled). */
229
+ ts?: string
226
230
  /** True when this event's block is past the finality boundary (immutable).
227
231
  * Optional for back-compat with the same reasoning as `StreamsEventBase`. */
228
232
  finalized?: boolean
@@ -0,0 +1,42 @@
1
+ import { type Kysely, sql } from "kysely";
2
+ import { onControlPlane } from "../src/db/migration-role.ts";
3
+
4
+ /**
5
+ * Sentinel agent keys: `api_keys.product = 'sentinel'` plus nullable `areas`
6
+ * jsonb holding Sentinel's permission areas (`{plans, monitoring, alerts}`,
7
+ * each none|read|write). Only `/internal/sentinel/keys` mints them; they
8
+ * authenticate nothing on secondlayer itself (hosted /v1 and `requireAuth`
9
+ * accept `account` keys only), Sentinel resolves them server-to-server.
10
+ */
11
+ export async function up(db: Kysely<unknown>): Promise<void> {
12
+ await onControlPlane(async () => {
13
+ await sql`SET lock_timeout = '30s'`.execute(db);
14
+ await sql`ALTER TABLE api_keys ADD COLUMN IF NOT EXISTS areas jsonb`.execute(
15
+ db,
16
+ );
17
+ await sql`
18
+ ALTER TABLE api_keys DROP CONSTRAINT IF EXISTS api_keys_product_check
19
+ `.execute(db);
20
+ await sql`
21
+ ALTER TABLE api_keys
22
+ ADD CONSTRAINT api_keys_product_check
23
+ CHECK (product IN ('account', 'streams', 'index', 'sentinel'))
24
+ `.execute(db);
25
+ });
26
+ }
27
+
28
+ export async function down(db: Kysely<unknown>): Promise<void> {
29
+ await onControlPlane(async () => {
30
+ await sql`SET lock_timeout = '30s'`.execute(db);
31
+ await sql`DELETE FROM api_keys WHERE product = 'sentinel'`.execute(db);
32
+ await sql`
33
+ ALTER TABLE api_keys DROP CONSTRAINT IF EXISTS api_keys_product_check
34
+ `.execute(db);
35
+ await sql`
36
+ ALTER TABLE api_keys
37
+ ADD CONSTRAINT api_keys_product_check
38
+ CHECK (product IN ('account', 'streams', 'index'))
39
+ `.execute(db);
40
+ await sql`ALTER TABLE api_keys DROP COLUMN IF EXISTS areas`.execute(db);
41
+ });
42
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@secondlayer/shared",
3
- "version": "11.17.0",
3
+ "version": "11.19.0",
4
4
  "description": "Internal building blocks shared across Secondlayer packages.",
5
5
  "license": "MIT",
6
6
  "repository": {