@infinitetoken/lumber-kit 0.6.0 → 0.8.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.
- package/README.md +40 -11
- package/contract/README.md +21 -0
- package/contract/schema.json +2317 -0
- package/contract/vectors.json +180 -0
- package/dist/index.d.mts +116 -44
- package/dist/index.d.ts +116 -44
- package/dist/index.js +73 -7
- package/dist/index.mjs +64 -7
- package/package.json +8 -3
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "Known answers every Lumber plugin is tested against, whatever its language. Lumber-Kit's own tests check each one against its TypeScript (buildLogPayload, splitApiKey, logDeliveryOutcome, logRetryDelayMs, the constants) and Node's crypto, so these can't drift from the kit. An absent key means absent: JSON has no undefined, and null data values are left out like missing ones.",
|
|
3
|
+
"constants": {
|
|
4
|
+
"defaultEndpoint": "https://api.lumber.infinitetoken.com",
|
|
5
|
+
"ingestPath": "/logs",
|
|
6
|
+
"keyVersion": 1,
|
|
7
|
+
"keyBytes": 32,
|
|
8
|
+
"nonceBytes": 12,
|
|
9
|
+
"tagBytes": 16,
|
|
10
|
+
"levels": { "debug": 0, "info": 1, "warn": 2, "error": 3, "fatal": 4 },
|
|
11
|
+
"delivery": { "maxAttempts": 5, "baseDelayMs": 1000, "maxDelayMs": 30000, "pauseMs": 3600000 }
|
|
12
|
+
},
|
|
13
|
+
"apiKeys": [
|
|
14
|
+
{
|
|
15
|
+
"name": "token and encryption key",
|
|
16
|
+
"apiKey": "3f9c0e7a1b2d4c6e8f0a1b2c3d4e5f60.AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
|
|
17
|
+
"token": "3f9c0e7a1b2d4c6e8f0a1b2c3d4e5f60",
|
|
18
|
+
"encryptionKey": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8="
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "surrounding whitespace, as pasted from a terminal",
|
|
22
|
+
"apiKey": " 3f9c0e7a1b2d4c6e8f0a1b2c3d4e5f60.AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=\n",
|
|
23
|
+
"token": "3f9c0e7a1b2d4c6e8f0a1b2c3d4e5f60",
|
|
24
|
+
"encryptionKey": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8="
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "a bare token carries no encryption key",
|
|
28
|
+
"apiKey": "3f9c0e7a1b2d4c6e8f0a1b2c3d4e5f60",
|
|
29
|
+
"token": "3f9c0e7a1b2d4c6e8f0a1b2c3d4e5f60",
|
|
30
|
+
"encryptionKey": null
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "empty",
|
|
34
|
+
"apiKey": "",
|
|
35
|
+
"token": "",
|
|
36
|
+
"encryptionKey": null
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"encryption": [
|
|
40
|
+
{
|
|
41
|
+
"name": "ascii",
|
|
42
|
+
"key": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
|
|
43
|
+
"nonce": "oKGio6Slpqeoqaqr",
|
|
44
|
+
"plaintext": "{\"level\":1,\"message\":\"Server started\",\"metadata\":{\"port\":3000}}",
|
|
45
|
+
"payload": "GJU0Lu4J1IGhob9mA32TqJ06EEgzrm6dWFSr8Wofs60RyzwyqJURCe54Q/Rf2AFgoAIim40OcVA66GWsaA7i231gZDgNom5ce207bpQN+A=="
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "non-ascii, encoded as utf-8",
|
|
49
|
+
"key": "QkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkI=",
|
|
50
|
+
"nonce": "BwcHBwcHBwcHBwcH",
|
|
51
|
+
"plaintext": "{\"level\":3,\"message\":\"Paiement échoué ☕ 🚨\",\"context\":{\"pid\":4242,\"hostname\":\"web-1\"},\"metadata\":{\"user\":\"Zoë\"}}",
|
|
52
|
+
"payload": "bG1l/6IGl9vfE0wA1rhuEAPAMcnDlB7ZGWfAErA+VQ+UPWofx/cYJAkRUjZ0WTi3hotyvwFw3G2lbtCoKgD6/aRDnUpDt4kk+HF3FGk6VaEEt5fqiu28C5u9EifuYjd4Qh8KcSMdO9eeVWLqsg2eIpbV9qQQOtD1fMXktGfQmxTjmMtMZuKm"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "empty message",
|
|
56
|
+
"key": "7qi7Ixae6epI48zxshkBw43xktBTaE/pwLxUoUhZ6e0=",
|
|
57
|
+
"nonce": "eDd7UldXtJRCf4kB",
|
|
58
|
+
"plaintext": "{\"level\":0,\"message\":\"\"}",
|
|
59
|
+
"payload": "M2E8vR0ITv6RfAwC3fDiMVIfWt3N9U6DEveRBpqxc/K49Py/HVQpMw=="
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"payloads": [
|
|
63
|
+
{
|
|
64
|
+
"name": "message alone",
|
|
65
|
+
"level": 1,
|
|
66
|
+
"message": "Server started",
|
|
67
|
+
"payload": { "level": 1, "message": "Server started" }
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"name": "request and trace ids",
|
|
71
|
+
"level": 3,
|
|
72
|
+
"message": "Payment failed",
|
|
73
|
+
"data": { "requestId": "req-123", "traceId": "trace-abc" },
|
|
74
|
+
"payload": { "level": 3, "message": "Payment failed", "requestId": "req-123", "traceId": "trace-abc" }
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name": "other keys become metadata",
|
|
78
|
+
"level": 1,
|
|
79
|
+
"message": "User action",
|
|
80
|
+
"data": { "userId": "123", "action": "login", "order": { "id": 7, "total": 12.5, "items": ["a", "b"] } },
|
|
81
|
+
"payload": { "level": 1, "message": "User action", "metadata": { "userId": "123", "action": "login", "order": { "id": 7, "total": 12.5, "items": ["a", "b"] } } }
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"name": "explicit metadata wins over other keys",
|
|
85
|
+
"level": 2,
|
|
86
|
+
"message": "Rate limit approaching",
|
|
87
|
+
"data": { "version": 1, "region": "us", "metadata": { "version": 2, "build": "b7" } },
|
|
88
|
+
"payload": { "level": 2, "message": "Rate limit approaching", "metadata": { "version": 2, "region": "us", "build": "b7" } }
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"name": "metadata alone",
|
|
92
|
+
"level": 1,
|
|
93
|
+
"message": "Cache warmed",
|
|
94
|
+
"data": { "metadata": { "entries": 512 } },
|
|
95
|
+
"payload": { "level": 1, "message": "Cache warmed", "metadata": { "entries": 512 } }
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"name": "automatic context alone",
|
|
99
|
+
"level": 0,
|
|
100
|
+
"message": "Cache miss",
|
|
101
|
+
"autoContext": { "pid": 4242, "hostname": "web-1" },
|
|
102
|
+
"payload": { "level": 0, "message": "Cache miss", "context": { "pid": 4242, "hostname": "web-1" } }
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "the call's context over the automatic context",
|
|
106
|
+
"level": 1,
|
|
107
|
+
"message": "Job done",
|
|
108
|
+
"autoContext": { "pid": 4242, "hostname": "web-1", "env": "production" },
|
|
109
|
+
"data": { "context": { "hostname": "worker-3", "code": "jobs/billing.py", "line": 42 } },
|
|
110
|
+
"payload": { "level": 1, "message": "Job done", "context": { "pid": 4242, "hostname": "worker-3", "env": "production", "code": "jobs/billing.py", "line": 42 } }
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"name": "context with no automatic context",
|
|
114
|
+
"level": 1,
|
|
115
|
+
"message": "Job done",
|
|
116
|
+
"autoContext": {},
|
|
117
|
+
"data": { "context": { "code": "app.ts" } },
|
|
118
|
+
"payload": { "level": 1, "message": "Job done", "context": { "code": "app.ts" } }
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"name": "a context that isn't an object is a metadata key",
|
|
122
|
+
"level": 1,
|
|
123
|
+
"message": "Invoice sent",
|
|
124
|
+
"data": { "context": "billing" },
|
|
125
|
+
"payload": { "level": 1, "message": "Invoice sent", "metadata": { "context": "billing" } }
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"name": "metadata that isn't an object is a metadata key",
|
|
129
|
+
"level": 1,
|
|
130
|
+
"message": "Batch",
|
|
131
|
+
"data": { "metadata": [1, 2, 3] },
|
|
132
|
+
"payload": { "level": 1, "message": "Batch", "metadata": { "metadata": [1, 2, 3] } }
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"name": "a null context and metadata are left out",
|
|
136
|
+
"level": 1,
|
|
137
|
+
"message": "Nothing extra",
|
|
138
|
+
"data": { "context": null, "metadata": null },
|
|
139
|
+
"payload": { "level": 1, "message": "Nothing extra" }
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"name": "a level key in the data is metadata, never the log's level",
|
|
143
|
+
"level": 3,
|
|
144
|
+
"message": "Disk nearly full",
|
|
145
|
+
"data": { "level": "high", "message": "ignored" },
|
|
146
|
+
"payload": { "level": 3, "message": "Disk nearly full", "metadata": { "level": "high", "message": "ignored" } }
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"name": "everything",
|
|
150
|
+
"level": 4,
|
|
151
|
+
"message": "DB connection lost ☠",
|
|
152
|
+
"autoContext": { "pid": 1, "hostname": "db-proxy" },
|
|
153
|
+
"data": { "requestId": "r1", "traceId": "t1", "context": { "method": "connect" }, "metadata": { "retries": 3 }, "host": "10.0.0.5" },
|
|
154
|
+
"payload": { "level": 4, "message": "DB connection lost ☠", "requestId": "r1", "traceId": "t1", "context": { "pid": 1, "hostname": "db-proxy", "method": "connect" }, "metadata": { "host": "10.0.0.5", "retries": 3 } }
|
|
155
|
+
}
|
|
156
|
+
],
|
|
157
|
+
"deliveryOutcomes": [
|
|
158
|
+
{ "status": 200, "outcome": "sent" },
|
|
159
|
+
{ "status": 201, "outcome": "sent" },
|
|
160
|
+
{ "status": 301, "outcome": "retry" },
|
|
161
|
+
{ "status": 400, "outcome": "drop" },
|
|
162
|
+
{ "status": 401, "outcome": "drop" },
|
|
163
|
+
{ "status": 403, "outcome": "drop" },
|
|
164
|
+
{ "status": 404, "outcome": "drop" },
|
|
165
|
+
{ "status": 413, "outcome": "drop" },
|
|
166
|
+
{ "status": 429, "outcome": "pause" },
|
|
167
|
+
{ "status": 500, "outcome": "retry" },
|
|
168
|
+
{ "status": 502, "outcome": "retry" },
|
|
169
|
+
{ "status": 503, "outcome": "retry" },
|
|
170
|
+
{ "status": null, "outcome": "retry" }
|
|
171
|
+
],
|
|
172
|
+
"retryDelaysMs": [
|
|
173
|
+
{ "failedAttempts": 1, "delayMs": 1000 },
|
|
174
|
+
{ "failedAttempts": 2, "delayMs": 2000 },
|
|
175
|
+
{ "failedAttempts": 3, "delayMs": 4000 },
|
|
176
|
+
{ "failedAttempts": 4, "delayMs": 8000 },
|
|
177
|
+
{ "failedAttempts": 5, "delayMs": 16000 },
|
|
178
|
+
{ "failedAttempts": 6, "delayMs": 30000 }
|
|
179
|
+
]
|
|
180
|
+
}
|
package/dist/index.d.mts
CHANGED
|
@@ -15,6 +15,23 @@ declare const APP_COLORS: readonly ["#EF4444", "#F97316", "#F59E0B", "#84CC16",
|
|
|
15
15
|
declare const apiErrorCodes: readonly ["APP_LIMIT", "SEAT_LIMIT", "GUEST_LIMIT", "ALREADY_MEMBER", "ALREADY_READS", "ALREADY_INVITED", "HAS_ACCOUNT"];
|
|
16
16
|
type ApiErrorCode = (typeof apiErrorCodes)[number];
|
|
17
17
|
|
|
18
|
+
/** The Lumber API a plugin sends logs to unless it's given another endpoint. */
|
|
19
|
+
declare const DEFAULT_API_ENDPOINT = "https://api.lumber.infinitetoken.com";
|
|
20
|
+
/** LogEncrypted's keyVersion. Every app has one encryption key, so it's 1 until keys can be rotated. */
|
|
21
|
+
declare const LOG_KEY_VERSION = 1;
|
|
22
|
+
/**
|
|
23
|
+
* How a plugin delivers logs: one POST /logs per log, in the order they were logged. A network error or a 5xx is a
|
|
24
|
+
* failed attempt, tried again after `baseDelayMs`, doubling up to `maxDelayMs`, and dropped after `maxAttempts`. Any
|
|
25
|
+
* other 4xx is dropped at once, since sending it again won't help. A 429 (the team's logs for the month are used up)
|
|
26
|
+
* drops what's queued and every new log until its Retry-After, or for `pauseMs` when it has none.
|
|
27
|
+
*/
|
|
28
|
+
declare const logDelivery: {
|
|
29
|
+
readonly maxAttempts: 5;
|
|
30
|
+
readonly baseDelayMs: 1000;
|
|
31
|
+
readonly maxDelayMs: 30000;
|
|
32
|
+
readonly pauseMs: number;
|
|
33
|
+
};
|
|
34
|
+
|
|
18
35
|
/** Log severity level. Numeric values match the existing Lumber-API level field. */
|
|
19
36
|
declare const enum LogLevel {
|
|
20
37
|
Debug = 0,
|
|
@@ -32,48 +49,6 @@ declare const logLevelNameToLevel: Record<LogLevelName, LogLevel>;
|
|
|
32
49
|
/** All valid log levels, ordered from least to most severe. */
|
|
33
50
|
declare const logLevels: readonly LogLevel[];
|
|
34
51
|
|
|
35
|
-
/** A push threshold one past Fatal, which no log reaches: log pushes are off (the account's, or one app's). */
|
|
36
|
-
declare const PUSH_OFF = 5;
|
|
37
|
-
/** The lowest log level that pushes, or PUSH_OFF. Stored as a notification preference's `minimumLevel`. */
|
|
38
|
-
type PushThreshold = LogLevel | typeof PUSH_OFF;
|
|
39
|
-
/** The threshold a user gets when none is set. */
|
|
40
|
-
declare const DEFAULT_PUSH_THRESHOLD: PushThreshold;
|
|
41
|
-
|
|
42
|
-
/** User subscription level. Mirrors User.subscriptionLevel in Lumber-API. */
|
|
43
|
-
declare const enum SubscriptionLevel {
|
|
44
|
-
Hobby = 0,
|
|
45
|
-
Dev = 1,
|
|
46
|
-
Pro = 2,
|
|
47
|
-
Enterprise = 3
|
|
48
|
-
}
|
|
49
|
-
/** String name for each subscription level, suitable for display and Redux state. */
|
|
50
|
-
type SubscriptionLevelName = 'hobby' | 'dev' | 'pro' | 'enterprise';
|
|
51
|
-
/** Maps numeric subscription level to its string level name. */
|
|
52
|
-
declare const subscriptionLevelToName: Record<SubscriptionLevel, SubscriptionLevelName>;
|
|
53
|
-
/** All valid subscription levels, ordered from least to most severe. */
|
|
54
|
-
declare const subscriptionLevels: readonly SubscriptionLevel[];
|
|
55
|
-
type SubscriptionLimits = {
|
|
56
|
-
apps: number;
|
|
57
|
-
seats: number;
|
|
58
|
-
apiKeys: number;
|
|
59
|
-
logRetentionDays: number;
|
|
60
|
-
monthlyLogs: number;
|
|
61
|
-
/** Whether real-time WebSocket log streaming is available. */
|
|
62
|
-
realtimeLogs: boolean;
|
|
63
|
-
/** Minimum log level that triggers a push notification. Infinity means push is disabled. */
|
|
64
|
-
minPushLevel: number;
|
|
65
|
-
};
|
|
66
|
-
/** Per-level resource limits. Use Infinity to mean unlimited or disabled. */
|
|
67
|
-
declare const subscriptionLimits: Record<SubscriptionLevel, SubscriptionLimits>;
|
|
68
|
-
type SubscriptionPlan = {
|
|
69
|
-
/** Display name, as every surface shows it. */
|
|
70
|
-
name: string;
|
|
71
|
-
/** Monthly price in US dollars: 0 for free, null when priced per customer. */
|
|
72
|
-
monthlyPrice: number | null;
|
|
73
|
-
};
|
|
74
|
-
/** Each level's name and price. Stripe holds the prices themselves; these must match what it charges. */
|
|
75
|
-
declare const subscriptionPlans: Record<SubscriptionLevel, SubscriptionPlan>;
|
|
76
|
-
|
|
77
52
|
/**
|
|
78
53
|
* An organization that owns apps and pays for member usage.
|
|
79
54
|
* Team subscriptionLevel takes precedence over individual member levels.
|
|
@@ -423,7 +398,7 @@ interface LogEncrypted {
|
|
|
423
398
|
keyVersion: number;
|
|
424
399
|
}
|
|
425
400
|
/**
|
|
426
|
-
* Plaintext shape of log content
|
|
401
|
+
* Plaintext shape of log content: a plugin encrypts it into LogEncrypted, and the server never sees it.
|
|
427
402
|
*/
|
|
428
403
|
interface LogPayload {
|
|
429
404
|
level: LogLevel;
|
|
@@ -433,6 +408,25 @@ interface LogPayload {
|
|
|
433
408
|
context?: LogContext;
|
|
434
409
|
metadata?: Record<string, unknown>;
|
|
435
410
|
}
|
|
411
|
+
/**
|
|
412
|
+
* What a plugin's log call takes beside its message (Lumber-Node's second argument). requestId and traceId become the
|
|
413
|
+
* payload's own fields, context is merged over the plugin's automatic context, and any other key goes into metadata,
|
|
414
|
+
* where an explicit metadata key wins. A context or metadata that isn't an object is kept as an ordinary metadata key.
|
|
415
|
+
*/
|
|
416
|
+
interface LogData {
|
|
417
|
+
requestId?: string;
|
|
418
|
+
traceId?: string;
|
|
419
|
+
context?: LogContext;
|
|
420
|
+
metadata?: Record<string, unknown>;
|
|
421
|
+
[key: string]: unknown;
|
|
422
|
+
}
|
|
423
|
+
/** POST /logs' body. The level stays plaintext for filtering and pushes; everything else is in `encrypted`. */
|
|
424
|
+
interface LogIngestBody {
|
|
425
|
+
level: LogLevel;
|
|
426
|
+
encrypted: LogEncrypted;
|
|
427
|
+
}
|
|
428
|
+
/** What a plugin does with a log after POST /logs answers (see logDelivery). */
|
|
429
|
+
type LogDeliveryOutcome = 'sent' | 'retry' | 'drop' | 'pause';
|
|
436
430
|
/**
|
|
437
431
|
* API response shape for a stored log.
|
|
438
432
|
* level is plaintext for server-side notification routing; all content is inside encrypted.
|
|
@@ -631,6 +625,18 @@ interface LogTimeseriesQuery {
|
|
|
631
625
|
}
|
|
632
626
|
|
|
633
627
|
type Appearance = 'system' | 'dark' | 'light';
|
|
628
|
+
/** A 24-hour clock (`19:15:44`) or a 12-hour one (`7:15:44 PM`). */
|
|
629
|
+
type TimeClock = '24h' | '12h';
|
|
630
|
+
/** The device's own time zone, or UTC. */
|
|
631
|
+
type TimeZoneChoice = 'local' | 'utc';
|
|
632
|
+
/**
|
|
633
|
+
* How a user reads times, on every device: the clock, and the zone that times, days and hours are in (the log list, the
|
|
634
|
+
* heatmap, pushes).
|
|
635
|
+
*/
|
|
636
|
+
interface TimeFormat {
|
|
637
|
+
clock: TimeClock;
|
|
638
|
+
zone: TimeZoneChoice;
|
|
639
|
+
}
|
|
634
640
|
interface PushToken {
|
|
635
641
|
token: string;
|
|
636
642
|
deviceId?: string;
|
|
@@ -665,6 +671,8 @@ interface UserRecord {
|
|
|
665
671
|
appearance?: Appearance;
|
|
666
672
|
color?: string;
|
|
667
673
|
imageUrl?: string;
|
|
674
|
+
/** Null until the user picks one (DEFAULT_TIME_FORMAT). Missing from an API before it was kept. */
|
|
675
|
+
timeFormat?: TimeFormat | null;
|
|
668
676
|
agreedToTermsVersion?: string;
|
|
669
677
|
notificationPreferences: NotificationPreferences;
|
|
670
678
|
pushTokens: PushToken[];
|
|
@@ -674,7 +682,71 @@ interface UserRecord {
|
|
|
674
682
|
notesReadAt?: Record<string, string>;
|
|
675
683
|
}
|
|
676
684
|
|
|
685
|
+
/** A push threshold one past Fatal, which no log reaches: log pushes are off (the account's, or one app's). */
|
|
686
|
+
declare const PUSH_OFF = 5;
|
|
687
|
+
/** The lowest log level that pushes, or PUSH_OFF. Stored as a notification preference's `minimumLevel`. */
|
|
688
|
+
type PushThreshold = LogLevel | typeof PUSH_OFF;
|
|
689
|
+
/** The threshold a user gets when none is set. */
|
|
690
|
+
declare const DEFAULT_PUSH_THRESHOLD: PushThreshold;
|
|
691
|
+
/** The time format a user gets until they pick one: 24-hour, in the device's own time zone. */
|
|
692
|
+
declare const DEFAULT_TIME_FORMAT: TimeFormat;
|
|
693
|
+
|
|
694
|
+
/** User subscription level. Mirrors User.subscriptionLevel in Lumber-API. */
|
|
695
|
+
declare const enum SubscriptionLevel {
|
|
696
|
+
Hobby = 0,
|
|
697
|
+
Dev = 1,
|
|
698
|
+
Pro = 2,
|
|
699
|
+
Enterprise = 3
|
|
700
|
+
}
|
|
701
|
+
/** String name for each subscription level, suitable for display and Redux state. */
|
|
702
|
+
type SubscriptionLevelName = 'hobby' | 'dev' | 'pro' | 'enterprise';
|
|
703
|
+
/** Maps numeric subscription level to its string level name. */
|
|
704
|
+
declare const subscriptionLevelToName: Record<SubscriptionLevel, SubscriptionLevelName>;
|
|
705
|
+
/** All valid subscription levels, ordered from least to most severe. */
|
|
706
|
+
declare const subscriptionLevels: readonly SubscriptionLevel[];
|
|
707
|
+
type SubscriptionLimits = {
|
|
708
|
+
apps: number;
|
|
709
|
+
seats: number;
|
|
710
|
+
apiKeys: number;
|
|
711
|
+
logRetentionDays: number;
|
|
712
|
+
monthlyLogs: number;
|
|
713
|
+
/** Whether real-time WebSocket log streaming is available. */
|
|
714
|
+
realtimeLogs: boolean;
|
|
715
|
+
/** Minimum log level that triggers a push notification. Infinity means push is disabled. */
|
|
716
|
+
minPushLevel: number;
|
|
717
|
+
};
|
|
718
|
+
/** Per-level resource limits. Use Infinity to mean unlimited or disabled. */
|
|
719
|
+
declare const subscriptionLimits: Record<SubscriptionLevel, SubscriptionLimits>;
|
|
720
|
+
type SubscriptionPlan = {
|
|
721
|
+
/** Display name, as every surface shows it. */
|
|
722
|
+
name: string;
|
|
723
|
+
/** Monthly price in US dollars: 0 for free, null when priced per customer. */
|
|
724
|
+
monthlyPrice: number | null;
|
|
725
|
+
};
|
|
726
|
+
/** Each level's name and price. Stripe holds the prices themselves; these must match what it charges. */
|
|
727
|
+
declare const subscriptionPlans: Record<SubscriptionLevel, SubscriptionPlan>;
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* The plaintext a plugin encrypts for one log call: its level and message, requestId and traceId when given, the
|
|
731
|
+
* plugin's automatic context (pid, hostname and the like) with the call's context over it, and the call's other keys
|
|
732
|
+
* as metadata with its explicit metadata over them. A context or metadata that isn't an object (a string, an array) is
|
|
733
|
+
* kept as an ordinary metadata key, since spreading it would turn `{ context: 'billing' }` into `{ 0: 'b', ... }`, and
|
|
734
|
+
* a null one is left out. Every plugin builds the same payload: contract/vectors.json pins it for the other languages.
|
|
735
|
+
*/
|
|
736
|
+
declare const buildLogPayload: (level: LogLevel, message: string, data?: LogData, autoContext?: Record<string, unknown>) => LogPayload;
|
|
737
|
+
/**
|
|
738
|
+
* What to do with a log once POST /logs answers with `status`, or null for no answer (a network error): sent on a 2xx,
|
|
739
|
+
* pause on a 429, drop on any other 4xx, and retry on anything else.
|
|
740
|
+
*/
|
|
741
|
+
declare const logDeliveryOutcome: (status: number | null) => LogDeliveryOutcome;
|
|
742
|
+
/** How long to wait before trying a log again after its `failedAttempts`th failure: 1s, 2s, 4s and so on, up to 30s. */
|
|
743
|
+
declare const logRetryDelayMs: (failedAttempts: number) => number;
|
|
744
|
+
|
|
677
745
|
declare const isValidAppearance: (value: unknown) => value is Appearance;
|
|
746
|
+
/** A time format as sent or stored: an object with a known clock and zone, and nothing else. */
|
|
747
|
+
declare const isValidTimeFormat: (value: unknown) => value is TimeFormat;
|
|
748
|
+
/** A stored or sent time format, each part the default (DEFAULT_TIME_FORMAT) when it's missing or unknown. */
|
|
749
|
+
declare const normalizeTimeFormat: (value: unknown) => TimeFormat;
|
|
678
750
|
/** Accepts 3- and 6-digit hex color strings (#rgb, #rrggbb). */
|
|
679
751
|
declare const isValidColor: (value: string) => boolean;
|
|
680
752
|
/**
|
|
@@ -714,4 +786,4 @@ declare const apiErrorCodeOf: (body: unknown) => ApiErrorCode | null;
|
|
|
714
786
|
/** A push notification's data as PushData, or null for data no Lumber push sends. */
|
|
715
787
|
declare const parsePushData: (data: unknown) => PushData | null;
|
|
716
788
|
|
|
717
|
-
export { APP_COLORS, type ApiErrorBody, type ApiErrorCode, type ApiKeyRecord, type ApiResponse, type AppCreatedRecord, type AppEncryptedKey, type AppKeyUpsertBody, type AppPermission, type AppPersonRecord, type AppRecord, type AppTeamAccess, type Appearance, type AppsQuery, type ClaimantKeyCheck, type ClientToServerEvents, DEFAULT_ACCENT, DEFAULT_PUSH_THRESHOLD, type DeviceLinkApproveBody, type DeviceLinkCreateBody, type DeviceLinkCreatedRecord, type DeviceLinkPlatform, type DeviceLinkRecord, type DeviceLinkStatus, type FlagRecord, type FlagsQuery, type GuestRecord, type HolderKeyCheck, type InvitationRecord, type KeyCheckResult, type KeyHolder, type KeyPin, type LogContext, type LogEncrypted, LogLevel, type LogLevelName, type LogPayload, type LogRecord, type LogTimeseriesQuery, type LogsQuery, type NoteEncrypted, type NoteRecord, type NotesQuery, type NotificationPreference, type NotificationPreferences, PUSH_OFF, type PendingAppKey, type PendingDeviceLink, type PushData, type PushThreshold, type PushToken, type PushType, type ResponseMetadata, type ServerToClientEvents, type SocketAppPayload, SubscriptionLevel, type SubscriptionLevelName, type SubscriptionLimits, type SubscriptionPlan, type SubscriptionPlanRecord, type TeamMemberRecord, type TeamRecord, type TeamsQuery, type TimeseriesBucket, type TimeseriesResponse, type UserRecord, apiErrorCodeOf, apiErrorCodes, isApiErrorCode, isValidAppearance, isValidColor, isValidDeviceLinkStatus, isValidImageUrl, isValidLogLevel, isValidSubscriptionLevel, isValidTeamMemberRole, joinApiKey, logLevelColors, logLevelNameToLevel, logLevelToName, logLevels, nameColor, normalizePushThreshold, parsePushData, personColor, resolveAppColor, splitApiKey, subscriptionLevelToName, subscriptionLevels, subscriptionLimits, subscriptionPlans };
|
|
789
|
+
export { APP_COLORS, type ApiErrorBody, type ApiErrorCode, type ApiKeyRecord, type ApiResponse, type AppCreatedRecord, type AppEncryptedKey, type AppKeyUpsertBody, type AppPermission, type AppPersonRecord, type AppRecord, type AppTeamAccess, type Appearance, type AppsQuery, type ClaimantKeyCheck, type ClientToServerEvents, DEFAULT_ACCENT, DEFAULT_API_ENDPOINT, DEFAULT_PUSH_THRESHOLD, DEFAULT_TIME_FORMAT, type DeviceLinkApproveBody, type DeviceLinkCreateBody, type DeviceLinkCreatedRecord, type DeviceLinkPlatform, type DeviceLinkRecord, type DeviceLinkStatus, type FlagRecord, type FlagsQuery, type GuestRecord, type HolderKeyCheck, type InvitationRecord, type KeyCheckResult, type KeyHolder, type KeyPin, LOG_KEY_VERSION, type LogContext, type LogData, type LogDeliveryOutcome, type LogEncrypted, type LogIngestBody, LogLevel, type LogLevelName, type LogPayload, type LogRecord, type LogTimeseriesQuery, type LogsQuery, type NoteEncrypted, type NoteRecord, type NotesQuery, type NotificationPreference, type NotificationPreferences, PUSH_OFF, type PendingAppKey, type PendingDeviceLink, type PushData, type PushThreshold, type PushToken, type PushType, type ResponseMetadata, type ServerToClientEvents, type SocketAppPayload, SubscriptionLevel, type SubscriptionLevelName, type SubscriptionLimits, type SubscriptionPlan, type SubscriptionPlanRecord, type TeamMemberRecord, type TeamRecord, type TeamsQuery, type TimeClock, type TimeFormat, type TimeZoneChoice, type TimeseriesBucket, type TimeseriesResponse, type UserRecord, apiErrorCodeOf, apiErrorCodes, buildLogPayload, isApiErrorCode, isValidAppearance, isValidColor, isValidDeviceLinkStatus, isValidImageUrl, isValidLogLevel, isValidSubscriptionLevel, isValidTeamMemberRole, isValidTimeFormat, joinApiKey, logDelivery, logDeliveryOutcome, logLevelColors, logLevelNameToLevel, logLevelToName, logLevels, logRetryDelayMs, nameColor, normalizePushThreshold, normalizeTimeFormat, parsePushData, personColor, resolveAppColor, splitApiKey, subscriptionLevelToName, subscriptionLevels, subscriptionLimits, subscriptionPlans };
|
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,23 @@ declare const APP_COLORS: readonly ["#EF4444", "#F97316", "#F59E0B", "#84CC16",
|
|
|
15
15
|
declare const apiErrorCodes: readonly ["APP_LIMIT", "SEAT_LIMIT", "GUEST_LIMIT", "ALREADY_MEMBER", "ALREADY_READS", "ALREADY_INVITED", "HAS_ACCOUNT"];
|
|
16
16
|
type ApiErrorCode = (typeof apiErrorCodes)[number];
|
|
17
17
|
|
|
18
|
+
/** The Lumber API a plugin sends logs to unless it's given another endpoint. */
|
|
19
|
+
declare const DEFAULT_API_ENDPOINT = "https://api.lumber.infinitetoken.com";
|
|
20
|
+
/** LogEncrypted's keyVersion. Every app has one encryption key, so it's 1 until keys can be rotated. */
|
|
21
|
+
declare const LOG_KEY_VERSION = 1;
|
|
22
|
+
/**
|
|
23
|
+
* How a plugin delivers logs: one POST /logs per log, in the order they were logged. A network error or a 5xx is a
|
|
24
|
+
* failed attempt, tried again after `baseDelayMs`, doubling up to `maxDelayMs`, and dropped after `maxAttempts`. Any
|
|
25
|
+
* other 4xx is dropped at once, since sending it again won't help. A 429 (the team's logs for the month are used up)
|
|
26
|
+
* drops what's queued and every new log until its Retry-After, or for `pauseMs` when it has none.
|
|
27
|
+
*/
|
|
28
|
+
declare const logDelivery: {
|
|
29
|
+
readonly maxAttempts: 5;
|
|
30
|
+
readonly baseDelayMs: 1000;
|
|
31
|
+
readonly maxDelayMs: 30000;
|
|
32
|
+
readonly pauseMs: number;
|
|
33
|
+
};
|
|
34
|
+
|
|
18
35
|
/** Log severity level. Numeric values match the existing Lumber-API level field. */
|
|
19
36
|
declare const enum LogLevel {
|
|
20
37
|
Debug = 0,
|
|
@@ -32,48 +49,6 @@ declare const logLevelNameToLevel: Record<LogLevelName, LogLevel>;
|
|
|
32
49
|
/** All valid log levels, ordered from least to most severe. */
|
|
33
50
|
declare const logLevels: readonly LogLevel[];
|
|
34
51
|
|
|
35
|
-
/** A push threshold one past Fatal, which no log reaches: log pushes are off (the account's, or one app's). */
|
|
36
|
-
declare const PUSH_OFF = 5;
|
|
37
|
-
/** The lowest log level that pushes, or PUSH_OFF. Stored as a notification preference's `minimumLevel`. */
|
|
38
|
-
type PushThreshold = LogLevel | typeof PUSH_OFF;
|
|
39
|
-
/** The threshold a user gets when none is set. */
|
|
40
|
-
declare const DEFAULT_PUSH_THRESHOLD: PushThreshold;
|
|
41
|
-
|
|
42
|
-
/** User subscription level. Mirrors User.subscriptionLevel in Lumber-API. */
|
|
43
|
-
declare const enum SubscriptionLevel {
|
|
44
|
-
Hobby = 0,
|
|
45
|
-
Dev = 1,
|
|
46
|
-
Pro = 2,
|
|
47
|
-
Enterprise = 3
|
|
48
|
-
}
|
|
49
|
-
/** String name for each subscription level, suitable for display and Redux state. */
|
|
50
|
-
type SubscriptionLevelName = 'hobby' | 'dev' | 'pro' | 'enterprise';
|
|
51
|
-
/** Maps numeric subscription level to its string level name. */
|
|
52
|
-
declare const subscriptionLevelToName: Record<SubscriptionLevel, SubscriptionLevelName>;
|
|
53
|
-
/** All valid subscription levels, ordered from least to most severe. */
|
|
54
|
-
declare const subscriptionLevels: readonly SubscriptionLevel[];
|
|
55
|
-
type SubscriptionLimits = {
|
|
56
|
-
apps: number;
|
|
57
|
-
seats: number;
|
|
58
|
-
apiKeys: number;
|
|
59
|
-
logRetentionDays: number;
|
|
60
|
-
monthlyLogs: number;
|
|
61
|
-
/** Whether real-time WebSocket log streaming is available. */
|
|
62
|
-
realtimeLogs: boolean;
|
|
63
|
-
/** Minimum log level that triggers a push notification. Infinity means push is disabled. */
|
|
64
|
-
minPushLevel: number;
|
|
65
|
-
};
|
|
66
|
-
/** Per-level resource limits. Use Infinity to mean unlimited or disabled. */
|
|
67
|
-
declare const subscriptionLimits: Record<SubscriptionLevel, SubscriptionLimits>;
|
|
68
|
-
type SubscriptionPlan = {
|
|
69
|
-
/** Display name, as every surface shows it. */
|
|
70
|
-
name: string;
|
|
71
|
-
/** Monthly price in US dollars: 0 for free, null when priced per customer. */
|
|
72
|
-
monthlyPrice: number | null;
|
|
73
|
-
};
|
|
74
|
-
/** Each level's name and price. Stripe holds the prices themselves; these must match what it charges. */
|
|
75
|
-
declare const subscriptionPlans: Record<SubscriptionLevel, SubscriptionPlan>;
|
|
76
|
-
|
|
77
52
|
/**
|
|
78
53
|
* An organization that owns apps and pays for member usage.
|
|
79
54
|
* Team subscriptionLevel takes precedence over individual member levels.
|
|
@@ -423,7 +398,7 @@ interface LogEncrypted {
|
|
|
423
398
|
keyVersion: number;
|
|
424
399
|
}
|
|
425
400
|
/**
|
|
426
|
-
* Plaintext shape of log content
|
|
401
|
+
* Plaintext shape of log content: a plugin encrypts it into LogEncrypted, and the server never sees it.
|
|
427
402
|
*/
|
|
428
403
|
interface LogPayload {
|
|
429
404
|
level: LogLevel;
|
|
@@ -433,6 +408,25 @@ interface LogPayload {
|
|
|
433
408
|
context?: LogContext;
|
|
434
409
|
metadata?: Record<string, unknown>;
|
|
435
410
|
}
|
|
411
|
+
/**
|
|
412
|
+
* What a plugin's log call takes beside its message (Lumber-Node's second argument). requestId and traceId become the
|
|
413
|
+
* payload's own fields, context is merged over the plugin's automatic context, and any other key goes into metadata,
|
|
414
|
+
* where an explicit metadata key wins. A context or metadata that isn't an object is kept as an ordinary metadata key.
|
|
415
|
+
*/
|
|
416
|
+
interface LogData {
|
|
417
|
+
requestId?: string;
|
|
418
|
+
traceId?: string;
|
|
419
|
+
context?: LogContext;
|
|
420
|
+
metadata?: Record<string, unknown>;
|
|
421
|
+
[key: string]: unknown;
|
|
422
|
+
}
|
|
423
|
+
/** POST /logs' body. The level stays plaintext for filtering and pushes; everything else is in `encrypted`. */
|
|
424
|
+
interface LogIngestBody {
|
|
425
|
+
level: LogLevel;
|
|
426
|
+
encrypted: LogEncrypted;
|
|
427
|
+
}
|
|
428
|
+
/** What a plugin does with a log after POST /logs answers (see logDelivery). */
|
|
429
|
+
type LogDeliveryOutcome = 'sent' | 'retry' | 'drop' | 'pause';
|
|
436
430
|
/**
|
|
437
431
|
* API response shape for a stored log.
|
|
438
432
|
* level is plaintext for server-side notification routing; all content is inside encrypted.
|
|
@@ -631,6 +625,18 @@ interface LogTimeseriesQuery {
|
|
|
631
625
|
}
|
|
632
626
|
|
|
633
627
|
type Appearance = 'system' | 'dark' | 'light';
|
|
628
|
+
/** A 24-hour clock (`19:15:44`) or a 12-hour one (`7:15:44 PM`). */
|
|
629
|
+
type TimeClock = '24h' | '12h';
|
|
630
|
+
/** The device's own time zone, or UTC. */
|
|
631
|
+
type TimeZoneChoice = 'local' | 'utc';
|
|
632
|
+
/**
|
|
633
|
+
* How a user reads times, on every device: the clock, and the zone that times, days and hours are in (the log list, the
|
|
634
|
+
* heatmap, pushes).
|
|
635
|
+
*/
|
|
636
|
+
interface TimeFormat {
|
|
637
|
+
clock: TimeClock;
|
|
638
|
+
zone: TimeZoneChoice;
|
|
639
|
+
}
|
|
634
640
|
interface PushToken {
|
|
635
641
|
token: string;
|
|
636
642
|
deviceId?: string;
|
|
@@ -665,6 +671,8 @@ interface UserRecord {
|
|
|
665
671
|
appearance?: Appearance;
|
|
666
672
|
color?: string;
|
|
667
673
|
imageUrl?: string;
|
|
674
|
+
/** Null until the user picks one (DEFAULT_TIME_FORMAT). Missing from an API before it was kept. */
|
|
675
|
+
timeFormat?: TimeFormat | null;
|
|
668
676
|
agreedToTermsVersion?: string;
|
|
669
677
|
notificationPreferences: NotificationPreferences;
|
|
670
678
|
pushTokens: PushToken[];
|
|
@@ -674,7 +682,71 @@ interface UserRecord {
|
|
|
674
682
|
notesReadAt?: Record<string, string>;
|
|
675
683
|
}
|
|
676
684
|
|
|
685
|
+
/** A push threshold one past Fatal, which no log reaches: log pushes are off (the account's, or one app's). */
|
|
686
|
+
declare const PUSH_OFF = 5;
|
|
687
|
+
/** The lowest log level that pushes, or PUSH_OFF. Stored as a notification preference's `minimumLevel`. */
|
|
688
|
+
type PushThreshold = LogLevel | typeof PUSH_OFF;
|
|
689
|
+
/** The threshold a user gets when none is set. */
|
|
690
|
+
declare const DEFAULT_PUSH_THRESHOLD: PushThreshold;
|
|
691
|
+
/** The time format a user gets until they pick one: 24-hour, in the device's own time zone. */
|
|
692
|
+
declare const DEFAULT_TIME_FORMAT: TimeFormat;
|
|
693
|
+
|
|
694
|
+
/** User subscription level. Mirrors User.subscriptionLevel in Lumber-API. */
|
|
695
|
+
declare const enum SubscriptionLevel {
|
|
696
|
+
Hobby = 0,
|
|
697
|
+
Dev = 1,
|
|
698
|
+
Pro = 2,
|
|
699
|
+
Enterprise = 3
|
|
700
|
+
}
|
|
701
|
+
/** String name for each subscription level, suitable for display and Redux state. */
|
|
702
|
+
type SubscriptionLevelName = 'hobby' | 'dev' | 'pro' | 'enterprise';
|
|
703
|
+
/** Maps numeric subscription level to its string level name. */
|
|
704
|
+
declare const subscriptionLevelToName: Record<SubscriptionLevel, SubscriptionLevelName>;
|
|
705
|
+
/** All valid subscription levels, ordered from least to most severe. */
|
|
706
|
+
declare const subscriptionLevels: readonly SubscriptionLevel[];
|
|
707
|
+
type SubscriptionLimits = {
|
|
708
|
+
apps: number;
|
|
709
|
+
seats: number;
|
|
710
|
+
apiKeys: number;
|
|
711
|
+
logRetentionDays: number;
|
|
712
|
+
monthlyLogs: number;
|
|
713
|
+
/** Whether real-time WebSocket log streaming is available. */
|
|
714
|
+
realtimeLogs: boolean;
|
|
715
|
+
/** Minimum log level that triggers a push notification. Infinity means push is disabled. */
|
|
716
|
+
minPushLevel: number;
|
|
717
|
+
};
|
|
718
|
+
/** Per-level resource limits. Use Infinity to mean unlimited or disabled. */
|
|
719
|
+
declare const subscriptionLimits: Record<SubscriptionLevel, SubscriptionLimits>;
|
|
720
|
+
type SubscriptionPlan = {
|
|
721
|
+
/** Display name, as every surface shows it. */
|
|
722
|
+
name: string;
|
|
723
|
+
/** Monthly price in US dollars: 0 for free, null when priced per customer. */
|
|
724
|
+
monthlyPrice: number | null;
|
|
725
|
+
};
|
|
726
|
+
/** Each level's name and price. Stripe holds the prices themselves; these must match what it charges. */
|
|
727
|
+
declare const subscriptionPlans: Record<SubscriptionLevel, SubscriptionPlan>;
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* The plaintext a plugin encrypts for one log call: its level and message, requestId and traceId when given, the
|
|
731
|
+
* plugin's automatic context (pid, hostname and the like) with the call's context over it, and the call's other keys
|
|
732
|
+
* as metadata with its explicit metadata over them. A context or metadata that isn't an object (a string, an array) is
|
|
733
|
+
* kept as an ordinary metadata key, since spreading it would turn `{ context: 'billing' }` into `{ 0: 'b', ... }`, and
|
|
734
|
+
* a null one is left out. Every plugin builds the same payload: contract/vectors.json pins it for the other languages.
|
|
735
|
+
*/
|
|
736
|
+
declare const buildLogPayload: (level: LogLevel, message: string, data?: LogData, autoContext?: Record<string, unknown>) => LogPayload;
|
|
737
|
+
/**
|
|
738
|
+
* What to do with a log once POST /logs answers with `status`, or null for no answer (a network error): sent on a 2xx,
|
|
739
|
+
* pause on a 429, drop on any other 4xx, and retry on anything else.
|
|
740
|
+
*/
|
|
741
|
+
declare const logDeliveryOutcome: (status: number | null) => LogDeliveryOutcome;
|
|
742
|
+
/** How long to wait before trying a log again after its `failedAttempts`th failure: 1s, 2s, 4s and so on, up to 30s. */
|
|
743
|
+
declare const logRetryDelayMs: (failedAttempts: number) => number;
|
|
744
|
+
|
|
677
745
|
declare const isValidAppearance: (value: unknown) => value is Appearance;
|
|
746
|
+
/** A time format as sent or stored: an object with a known clock and zone, and nothing else. */
|
|
747
|
+
declare const isValidTimeFormat: (value: unknown) => value is TimeFormat;
|
|
748
|
+
/** A stored or sent time format, each part the default (DEFAULT_TIME_FORMAT) when it's missing or unknown. */
|
|
749
|
+
declare const normalizeTimeFormat: (value: unknown) => TimeFormat;
|
|
678
750
|
/** Accepts 3- and 6-digit hex color strings (#rgb, #rrggbb). */
|
|
679
751
|
declare const isValidColor: (value: string) => boolean;
|
|
680
752
|
/**
|
|
@@ -714,4 +786,4 @@ declare const apiErrorCodeOf: (body: unknown) => ApiErrorCode | null;
|
|
|
714
786
|
/** A push notification's data as PushData, or null for data no Lumber push sends. */
|
|
715
787
|
declare const parsePushData: (data: unknown) => PushData | null;
|
|
716
788
|
|
|
717
|
-
export { APP_COLORS, type ApiErrorBody, type ApiErrorCode, type ApiKeyRecord, type ApiResponse, type AppCreatedRecord, type AppEncryptedKey, type AppKeyUpsertBody, type AppPermission, type AppPersonRecord, type AppRecord, type AppTeamAccess, type Appearance, type AppsQuery, type ClaimantKeyCheck, type ClientToServerEvents, DEFAULT_ACCENT, DEFAULT_PUSH_THRESHOLD, type DeviceLinkApproveBody, type DeviceLinkCreateBody, type DeviceLinkCreatedRecord, type DeviceLinkPlatform, type DeviceLinkRecord, type DeviceLinkStatus, type FlagRecord, type FlagsQuery, type GuestRecord, type HolderKeyCheck, type InvitationRecord, type KeyCheckResult, type KeyHolder, type KeyPin, type LogContext, type LogEncrypted, LogLevel, type LogLevelName, type LogPayload, type LogRecord, type LogTimeseriesQuery, type LogsQuery, type NoteEncrypted, type NoteRecord, type NotesQuery, type NotificationPreference, type NotificationPreferences, PUSH_OFF, type PendingAppKey, type PendingDeviceLink, type PushData, type PushThreshold, type PushToken, type PushType, type ResponseMetadata, type ServerToClientEvents, type SocketAppPayload, SubscriptionLevel, type SubscriptionLevelName, type SubscriptionLimits, type SubscriptionPlan, type SubscriptionPlanRecord, type TeamMemberRecord, type TeamRecord, type TeamsQuery, type TimeseriesBucket, type TimeseriesResponse, type UserRecord, apiErrorCodeOf, apiErrorCodes, isApiErrorCode, isValidAppearance, isValidColor, isValidDeviceLinkStatus, isValidImageUrl, isValidLogLevel, isValidSubscriptionLevel, isValidTeamMemberRole, joinApiKey, logLevelColors, logLevelNameToLevel, logLevelToName, logLevels, nameColor, normalizePushThreshold, parsePushData, personColor, resolveAppColor, splitApiKey, subscriptionLevelToName, subscriptionLevels, subscriptionLimits, subscriptionPlans };
|
|
789
|
+
export { APP_COLORS, type ApiErrorBody, type ApiErrorCode, type ApiKeyRecord, type ApiResponse, type AppCreatedRecord, type AppEncryptedKey, type AppKeyUpsertBody, type AppPermission, type AppPersonRecord, type AppRecord, type AppTeamAccess, type Appearance, type AppsQuery, type ClaimantKeyCheck, type ClientToServerEvents, DEFAULT_ACCENT, DEFAULT_API_ENDPOINT, DEFAULT_PUSH_THRESHOLD, DEFAULT_TIME_FORMAT, type DeviceLinkApproveBody, type DeviceLinkCreateBody, type DeviceLinkCreatedRecord, type DeviceLinkPlatform, type DeviceLinkRecord, type DeviceLinkStatus, type FlagRecord, type FlagsQuery, type GuestRecord, type HolderKeyCheck, type InvitationRecord, type KeyCheckResult, type KeyHolder, type KeyPin, LOG_KEY_VERSION, type LogContext, type LogData, type LogDeliveryOutcome, type LogEncrypted, type LogIngestBody, LogLevel, type LogLevelName, type LogPayload, type LogRecord, type LogTimeseriesQuery, type LogsQuery, type NoteEncrypted, type NoteRecord, type NotesQuery, type NotificationPreference, type NotificationPreferences, PUSH_OFF, type PendingAppKey, type PendingDeviceLink, type PushData, type PushThreshold, type PushToken, type PushType, type ResponseMetadata, type ServerToClientEvents, type SocketAppPayload, SubscriptionLevel, type SubscriptionLevelName, type SubscriptionLimits, type SubscriptionPlan, type SubscriptionPlanRecord, type TeamMemberRecord, type TeamRecord, type TeamsQuery, type TimeClock, type TimeFormat, type TimeZoneChoice, type TimeseriesBucket, type TimeseriesResponse, type UserRecord, apiErrorCodeOf, apiErrorCodes, buildLogPayload, isApiErrorCode, isValidAppearance, isValidColor, isValidDeviceLinkStatus, isValidImageUrl, isValidLogLevel, isValidSubscriptionLevel, isValidTeamMemberRole, isValidTimeFormat, joinApiKey, logDelivery, logDeliveryOutcome, logLevelColors, logLevelNameToLevel, logLevelToName, logLevels, logRetryDelayMs, nameColor, normalizePushThreshold, normalizeTimeFormat, parsePushData, personColor, resolveAppColor, splitApiKey, subscriptionLevelToName, subscriptionLevels, subscriptionLimits, subscriptionPlans };
|