@infinitetoken/lumber-kit 0.5.1 → 0.6.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 +16 -1
- package/dist/index.d.mts +80 -4
- package/dist/index.d.ts +80 -4
- package/dist/index.js +55 -20
- package/dist/index.mjs +49 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,7 +50,7 @@ import { LogLevel, LogRecord, LogEncrypted, LogPayload, LogsQuery } from '@infin
|
|
|
50
50
|
| `PUSH_OFF` | constant | A push threshold one past Fatal (5): log pushes off |
|
|
51
51
|
| `PushThreshold` | type | A `LogLevel` or `PUSH_OFF`, stored as a preference's `minimumLevel` |
|
|
52
52
|
| `normalizePushThreshold` | function | A threshold from any stored or sent value: past Fatal is off, not a number is Warn |
|
|
53
|
-
| `PushData` | type | The `data` each push type carries (`log`, `note`, `device_link`, `key_check`, `key_waiting`, `keys_shared`) |
|
|
53
|
+
| `PushData` | type | The `data` each push type carries (`log`, `note`, `device_link`, `device_link_answered`, `key_check`, `key_waiting`, `keys_shared`) |
|
|
54
54
|
| `parsePushData` | function | A push's data as `PushData`, or `null` for data no Lumber push sends |
|
|
55
55
|
|
|
56
56
|
### Socket events
|
|
@@ -100,6 +100,21 @@ import { LogLevel, LogRecord, LogEncrypted, LogPayload, LogsQuery } from '@infin
|
|
|
100
100
|
| `AppKeyUpsertBody` | interface | Body of PUT /apps/:id/keys/:userId |
|
|
101
101
|
| `KeyPin` | interface | An account key a user accepted for someone, with its MAC |
|
|
102
102
|
| `HolderKeyCheck`, `ClaimantKeyCheck`, `KeyCheckResult` | interfaces | A key check as the holder and the person being confirmed read it |
|
|
103
|
+
| `DeviceLinkCreateBody`, `DeviceLinkCreatedRecord` | interfaces | POST /device-links: a new device asking for the account key, and its answer |
|
|
104
|
+
| `DeviceLinkRecord`, `DeviceLinkApproveBody` | interfaces | A link request as the new device polls it (the exchange's first message once a code is shown, then the account key and the tag proving a device that showed the code sent it), and the approval that carries them |
|
|
105
|
+
| `PendingDeviceLink` | interface | A link request as a device holding the account key reads it, to show its code and finish it |
|
|
106
|
+
| `DeviceLinkStatus`, `DeviceLinkPlatform` | types | `pending`, `approved`, `denied` or `failed` (a code that didn't match); what the request comes from |
|
|
107
|
+
|
|
108
|
+
### Colors
|
|
109
|
+
|
|
110
|
+
| Export | Kind | Purpose |
|
|
111
|
+
|--------|------|---------|
|
|
112
|
+
| `logLevelColors` | object | Each `LogLevel`'s color, as the apps and the CLI draw it |
|
|
113
|
+
| `DEFAULT_ACCENT` | constant | The accent until someone picks their own (their account's `color`): amber `#FBBF24` |
|
|
114
|
+
| `APP_COLORS` | array | The twelve colors `nameColor` picks from |
|
|
115
|
+
| `nameColor` | function | A stable color for a name, ignoring case and surrounding spaces, the same on every device |
|
|
116
|
+
| `resolveAppColor` | function | An app's own color, or its name's |
|
|
117
|
+
| `personColor` | function | Someone else's color, from their user id |
|
|
103
118
|
|
|
104
119
|
### API keys
|
|
105
120
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/** Each log level's color: its label in the apps' log list, a level's heat on the heatmap, the CLI's level column. */
|
|
2
|
+
declare const logLevelColors: Record<number, string>;
|
|
3
|
+
/** The accent until someone picks their own (their account's `color`): amber, the wordmark's and the icon's. */
|
|
4
|
+
declare const DEFAULT_ACCENT = "#FBBF24";
|
|
5
|
+
/**
|
|
6
|
+
* Colors for an app without one of its own, and for other people, picked by `nameColor`: Tailwind's 500s, roughly
|
|
7
|
+
* evenly spaced around the wheel, vivid and mid-light enough to read on dark and light surfaces.
|
|
8
|
+
*/
|
|
9
|
+
declare const APP_COLORS: readonly ["#EF4444", "#F97316", "#F59E0B", "#84CC16", "#22C55E", "#14B8A6", "#06B6D4", "#3B82F6", "#6366F1", "#8B5CF6", "#D946EF", "#EC4899"];
|
|
10
|
+
|
|
1
11
|
/**
|
|
2
12
|
* Machine-readable reasons the API refuses a request, sent as `code` beside `message` where one status means more than
|
|
3
13
|
* one thing. Messages are for people and may change; clients decide by the code.
|
|
@@ -212,7 +222,24 @@ interface AppsQuery {
|
|
|
212
222
|
cursor?: string;
|
|
213
223
|
}
|
|
214
224
|
|
|
215
|
-
|
|
225
|
+
/**
|
|
226
|
+
* A device link request: a new device asking for the account key from a device that has it. `failed` is a code that
|
|
227
|
+
* didn't match, which ends the request.
|
|
228
|
+
*/
|
|
229
|
+
type DeviceLinkStatus = 'pending' | 'approved' | 'denied' | 'failed';
|
|
230
|
+
/** What a request comes from, so the device answering it can say so and offer a QR code only to a phone's camera. */
|
|
231
|
+
type DeviceLinkPlatform = 'ios' | 'android' | 'web' | 'desktop' | 'cli';
|
|
232
|
+
/**
|
|
233
|
+
* Body of POST /device-links.
|
|
234
|
+
*/
|
|
235
|
+
interface DeviceLinkCreateBody {
|
|
236
|
+
deviceName: string;
|
|
237
|
+
platform: DeviceLinkPlatform;
|
|
238
|
+
/** The public half of the new device's one-off X25519 keypair, which the account key is wrapped to. */
|
|
239
|
+
publicKey: string;
|
|
240
|
+
/** The new device's push device id, so the push asking the account's devices to link it skips it. */
|
|
241
|
+
deviceId?: string;
|
|
242
|
+
}
|
|
216
243
|
/**
|
|
217
244
|
* Response from POST /device-links.
|
|
218
245
|
*/
|
|
@@ -221,14 +248,48 @@ interface DeviceLinkCreatedRecord {
|
|
|
221
248
|
expiresAt: string;
|
|
222
249
|
}
|
|
223
250
|
/**
|
|
224
|
-
*
|
|
225
|
-
*
|
|
251
|
+
* Body of POST /device-links/:id/approve: the account key wrapped to the new device, and a tag over it made from the
|
|
252
|
+
* code's secret, which the new device checks before storing the key, so the server can't hand it a key of its own.
|
|
253
|
+
*/
|
|
254
|
+
interface DeviceLinkApproveBody {
|
|
255
|
+
encryptedKey: string;
|
|
256
|
+
deliveryTag: string;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Response from GET /device-links/:id, as the new device reads it.
|
|
260
|
+
* encryptedKey and deliveryTag are present only when status is 'approved'. sid and holderMessage are set once a device
|
|
261
|
+
* holding the account key shows the request's code, and answeredAt once the new device has answered it.
|
|
226
262
|
*/
|
|
227
263
|
interface DeviceLinkRecord {
|
|
228
264
|
id: string;
|
|
229
265
|
status: DeviceLinkStatus;
|
|
230
266
|
encryptedKey?: string;
|
|
267
|
+
deliveryTag?: string;
|
|
268
|
+
expiresAt: string;
|
|
269
|
+
sid?: string | null;
|
|
270
|
+
holderMessage?: string | null;
|
|
271
|
+
answeredAt?: string | null;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* A request waiting on the caller's account key (GET /device-links/pending), as a device holding it reads it: enough
|
|
275
|
+
* to show its code, and to finish it once answered. The messages are the same password-authenticated exchange as a key
|
|
276
|
+
* check's, so the server can't read or test codes against them. holderState is the code's side of the exchange, sealed
|
|
277
|
+
* under the account key, so any of the account's devices can show the same code or finish the request.
|
|
278
|
+
*/
|
|
279
|
+
interface PendingDeviceLink {
|
|
280
|
+
id: string;
|
|
281
|
+
deviceName: string;
|
|
282
|
+
platform: DeviceLinkPlatform;
|
|
283
|
+
/** The new device's one-off public key, which an answer's tag has to cover before anything is wrapped to it. */
|
|
284
|
+
publicKey: string;
|
|
285
|
+
sid: string | null;
|
|
286
|
+
holderMessage: string | null;
|
|
287
|
+
holderState: string | null;
|
|
288
|
+
claimantMessage: string | null;
|
|
289
|
+
tag: string | null;
|
|
290
|
+
answeredAt: string | null;
|
|
231
291
|
expiresAt: string;
|
|
292
|
+
createdAt: string;
|
|
232
293
|
}
|
|
233
294
|
|
|
234
295
|
/**
|
|
@@ -461,6 +522,12 @@ type PushData =
|
|
|
461
522
|
deviceLinkId: string;
|
|
462
523
|
deviceName: string;
|
|
463
524
|
}
|
|
525
|
+
/** The new device entered its link code, which a device holding the account key now checks (Lumber-API). */
|
|
526
|
+
| {
|
|
527
|
+
type: 'device_link_answered';
|
|
528
|
+
deviceLinkId: string;
|
|
529
|
+
deviceName: string;
|
|
530
|
+
}
|
|
464
531
|
/** The person the reader gave a code entered it (Lumber-API). */
|
|
465
532
|
| {
|
|
466
533
|
type: 'key_check';
|
|
@@ -610,6 +677,15 @@ interface UserRecord {
|
|
|
610
677
|
declare const isValidAppearance: (value: unknown) => value is Appearance;
|
|
611
678
|
/** Accepts 3- and 6-digit hex color strings (#rgb, #rrggbb). */
|
|
612
679
|
declare const isValidColor: (value: string) => boolean;
|
|
680
|
+
/**
|
|
681
|
+
* One of APP_COLORS for a name, ignoring case and surrounding spaces. Nothing is stored: every device works out the
|
|
682
|
+
* same color.
|
|
683
|
+
*/
|
|
684
|
+
declare const nameColor: (name: string) => string;
|
|
685
|
+
/** An app's color: the one its owner picked, or its name's. */
|
|
686
|
+
declare const resolveAppColor: (name: string, color?: string | null) => string;
|
|
687
|
+
/** Someone else's color, from their user id, since their own accent lives on their account. */
|
|
688
|
+
declare const personColor: (userId: string) => string;
|
|
613
689
|
declare const isValidLogLevel: (value: unknown) => value is LogLevel;
|
|
614
690
|
declare const isValidSubscriptionLevel: (value: unknown) => value is SubscriptionLevel;
|
|
615
691
|
declare const isValidDeviceLinkStatus: (value: unknown) => value is DeviceLinkStatus;
|
|
@@ -638,4 +714,4 @@ declare const apiErrorCodeOf: (body: unknown) => ApiErrorCode | null;
|
|
|
638
714
|
/** A push notification's data as PushData, or null for data no Lumber push sends. */
|
|
639
715
|
declare const parsePushData: (data: unknown) => PushData | null;
|
|
640
716
|
|
|
641
|
-
export { 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_PUSH_THRESHOLD, type DeviceLinkCreatedRecord, 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 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, logLevelNameToLevel, logLevelToName, logLevels, normalizePushThreshold, parsePushData, splitApiKey, subscriptionLevelToName, subscriptionLevels, subscriptionLimits, subscriptionPlans };
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/** Each log level's color: its label in the apps' log list, a level's heat on the heatmap, the CLI's level column. */
|
|
2
|
+
declare const logLevelColors: Record<number, string>;
|
|
3
|
+
/** The accent until someone picks their own (their account's `color`): amber, the wordmark's and the icon's. */
|
|
4
|
+
declare const DEFAULT_ACCENT = "#FBBF24";
|
|
5
|
+
/**
|
|
6
|
+
* Colors for an app without one of its own, and for other people, picked by `nameColor`: Tailwind's 500s, roughly
|
|
7
|
+
* evenly spaced around the wheel, vivid and mid-light enough to read on dark and light surfaces.
|
|
8
|
+
*/
|
|
9
|
+
declare const APP_COLORS: readonly ["#EF4444", "#F97316", "#F59E0B", "#84CC16", "#22C55E", "#14B8A6", "#06B6D4", "#3B82F6", "#6366F1", "#8B5CF6", "#D946EF", "#EC4899"];
|
|
10
|
+
|
|
1
11
|
/**
|
|
2
12
|
* Machine-readable reasons the API refuses a request, sent as `code` beside `message` where one status means more than
|
|
3
13
|
* one thing. Messages are for people and may change; clients decide by the code.
|
|
@@ -212,7 +222,24 @@ interface AppsQuery {
|
|
|
212
222
|
cursor?: string;
|
|
213
223
|
}
|
|
214
224
|
|
|
215
|
-
|
|
225
|
+
/**
|
|
226
|
+
* A device link request: a new device asking for the account key from a device that has it. `failed` is a code that
|
|
227
|
+
* didn't match, which ends the request.
|
|
228
|
+
*/
|
|
229
|
+
type DeviceLinkStatus = 'pending' | 'approved' | 'denied' | 'failed';
|
|
230
|
+
/** What a request comes from, so the device answering it can say so and offer a QR code only to a phone's camera. */
|
|
231
|
+
type DeviceLinkPlatform = 'ios' | 'android' | 'web' | 'desktop' | 'cli';
|
|
232
|
+
/**
|
|
233
|
+
* Body of POST /device-links.
|
|
234
|
+
*/
|
|
235
|
+
interface DeviceLinkCreateBody {
|
|
236
|
+
deviceName: string;
|
|
237
|
+
platform: DeviceLinkPlatform;
|
|
238
|
+
/** The public half of the new device's one-off X25519 keypair, which the account key is wrapped to. */
|
|
239
|
+
publicKey: string;
|
|
240
|
+
/** The new device's push device id, so the push asking the account's devices to link it skips it. */
|
|
241
|
+
deviceId?: string;
|
|
242
|
+
}
|
|
216
243
|
/**
|
|
217
244
|
* Response from POST /device-links.
|
|
218
245
|
*/
|
|
@@ -221,14 +248,48 @@ interface DeviceLinkCreatedRecord {
|
|
|
221
248
|
expiresAt: string;
|
|
222
249
|
}
|
|
223
250
|
/**
|
|
224
|
-
*
|
|
225
|
-
*
|
|
251
|
+
* Body of POST /device-links/:id/approve: the account key wrapped to the new device, and a tag over it made from the
|
|
252
|
+
* code's secret, which the new device checks before storing the key, so the server can't hand it a key of its own.
|
|
253
|
+
*/
|
|
254
|
+
interface DeviceLinkApproveBody {
|
|
255
|
+
encryptedKey: string;
|
|
256
|
+
deliveryTag: string;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Response from GET /device-links/:id, as the new device reads it.
|
|
260
|
+
* encryptedKey and deliveryTag are present only when status is 'approved'. sid and holderMessage are set once a device
|
|
261
|
+
* holding the account key shows the request's code, and answeredAt once the new device has answered it.
|
|
226
262
|
*/
|
|
227
263
|
interface DeviceLinkRecord {
|
|
228
264
|
id: string;
|
|
229
265
|
status: DeviceLinkStatus;
|
|
230
266
|
encryptedKey?: string;
|
|
267
|
+
deliveryTag?: string;
|
|
268
|
+
expiresAt: string;
|
|
269
|
+
sid?: string | null;
|
|
270
|
+
holderMessage?: string | null;
|
|
271
|
+
answeredAt?: string | null;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* A request waiting on the caller's account key (GET /device-links/pending), as a device holding it reads it: enough
|
|
275
|
+
* to show its code, and to finish it once answered. The messages are the same password-authenticated exchange as a key
|
|
276
|
+
* check's, so the server can't read or test codes against them. holderState is the code's side of the exchange, sealed
|
|
277
|
+
* under the account key, so any of the account's devices can show the same code or finish the request.
|
|
278
|
+
*/
|
|
279
|
+
interface PendingDeviceLink {
|
|
280
|
+
id: string;
|
|
281
|
+
deviceName: string;
|
|
282
|
+
platform: DeviceLinkPlatform;
|
|
283
|
+
/** The new device's one-off public key, which an answer's tag has to cover before anything is wrapped to it. */
|
|
284
|
+
publicKey: string;
|
|
285
|
+
sid: string | null;
|
|
286
|
+
holderMessage: string | null;
|
|
287
|
+
holderState: string | null;
|
|
288
|
+
claimantMessage: string | null;
|
|
289
|
+
tag: string | null;
|
|
290
|
+
answeredAt: string | null;
|
|
231
291
|
expiresAt: string;
|
|
292
|
+
createdAt: string;
|
|
232
293
|
}
|
|
233
294
|
|
|
234
295
|
/**
|
|
@@ -461,6 +522,12 @@ type PushData =
|
|
|
461
522
|
deviceLinkId: string;
|
|
462
523
|
deviceName: string;
|
|
463
524
|
}
|
|
525
|
+
/** The new device entered its link code, which a device holding the account key now checks (Lumber-API). */
|
|
526
|
+
| {
|
|
527
|
+
type: 'device_link_answered';
|
|
528
|
+
deviceLinkId: string;
|
|
529
|
+
deviceName: string;
|
|
530
|
+
}
|
|
464
531
|
/** The person the reader gave a code entered it (Lumber-API). */
|
|
465
532
|
| {
|
|
466
533
|
type: 'key_check';
|
|
@@ -610,6 +677,15 @@ interface UserRecord {
|
|
|
610
677
|
declare const isValidAppearance: (value: unknown) => value is Appearance;
|
|
611
678
|
/** Accepts 3- and 6-digit hex color strings (#rgb, #rrggbb). */
|
|
612
679
|
declare const isValidColor: (value: string) => boolean;
|
|
680
|
+
/**
|
|
681
|
+
* One of APP_COLORS for a name, ignoring case and surrounding spaces. Nothing is stored: every device works out the
|
|
682
|
+
* same color.
|
|
683
|
+
*/
|
|
684
|
+
declare const nameColor: (name: string) => string;
|
|
685
|
+
/** An app's color: the one its owner picked, or its name's. */
|
|
686
|
+
declare const resolveAppColor: (name: string, color?: string | null) => string;
|
|
687
|
+
/** Someone else's color, from their user id, since their own accent lives on their account. */
|
|
688
|
+
declare const personColor: (userId: string) => string;
|
|
613
689
|
declare const isValidLogLevel: (value: unknown) => value is LogLevel;
|
|
614
690
|
declare const isValidSubscriptionLevel: (value: unknown) => value is SubscriptionLevel;
|
|
615
691
|
declare const isValidDeviceLinkStatus: (value: unknown) => value is DeviceLinkStatus;
|
|
@@ -638,4 +714,4 @@ declare const apiErrorCodeOf: (body: unknown) => ApiErrorCode | null;
|
|
|
638
714
|
/** A push notification's data as PushData, or null for data no Lumber push sends. */
|
|
639
715
|
declare const parsePushData: (data: unknown) => PushData | null;
|
|
640
716
|
|
|
641
|
-
export { 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_PUSH_THRESHOLD, type DeviceLinkCreatedRecord, 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 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, logLevelNameToLevel, logLevelToName, logLevels, normalizePushThreshold, parsePushData, splitApiKey, subscriptionLevelToName, subscriptionLevels, subscriptionLimits, subscriptionPlans };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
APP_COLORS: () => APP_COLORS,
|
|
24
|
+
DEFAULT_ACCENT: () => DEFAULT_ACCENT,
|
|
23
25
|
DEFAULT_PUSH_THRESHOLD: () => DEFAULT_PUSH_THRESHOLD,
|
|
24
26
|
LogLevel: () => LogLevel,
|
|
25
27
|
PUSH_OFF: () => PUSH_OFF,
|
|
@@ -35,11 +37,15 @@ __export(index_exports, {
|
|
|
35
37
|
isValidSubscriptionLevel: () => isValidSubscriptionLevel,
|
|
36
38
|
isValidTeamMemberRole: () => isValidTeamMemberRole,
|
|
37
39
|
joinApiKey: () => joinApiKey,
|
|
40
|
+
logLevelColors: () => logLevelColors,
|
|
38
41
|
logLevelNameToLevel: () => logLevelNameToLevel,
|
|
39
42
|
logLevelToName: () => logLevelToName,
|
|
40
43
|
logLevels: () => logLevels,
|
|
44
|
+
nameColor: () => nameColor,
|
|
41
45
|
normalizePushThreshold: () => normalizePushThreshold,
|
|
42
46
|
parsePushData: () => parsePushData,
|
|
47
|
+
personColor: () => personColor,
|
|
48
|
+
resolveAppColor: () => resolveAppColor,
|
|
43
49
|
splitApiKey: () => splitApiKey,
|
|
44
50
|
subscriptionLevelToName: () => subscriptionLevelToName,
|
|
45
51
|
subscriptionLevels: () => subscriptionLevels,
|
|
@@ -48,24 +54,6 @@ __export(index_exports, {
|
|
|
48
54
|
});
|
|
49
55
|
module.exports = __toCommonJS(index_exports);
|
|
50
56
|
|
|
51
|
-
// src/constants/errors.ts
|
|
52
|
-
var apiErrorCodes = [
|
|
53
|
-
/** 403: the team's plan has no room for another app. */
|
|
54
|
-
"APP_LIMIT",
|
|
55
|
-
/** 403: the team's plan has no room for another member (members and live invitations). */
|
|
56
|
-
"SEAT_LIMIT",
|
|
57
|
-
/** 403: the app's team's plan has no room for another guest on it (guests and live invitations). */
|
|
58
|
-
"GUEST_LIMIT",
|
|
59
|
-
/** 409: the person invited is already on the team. */
|
|
60
|
-
"ALREADY_MEMBER",
|
|
61
|
-
/** 409: the person invited can already read the app. */
|
|
62
|
-
"ALREADY_READS",
|
|
63
|
-
/** 409: the address invited already has an open invitation. */
|
|
64
|
-
"ALREADY_INVITED",
|
|
65
|
-
/** 409: the address invited already has an account, so invite the person instead. */
|
|
66
|
-
"HAS_ACCOUNT"
|
|
67
|
-
];
|
|
68
|
-
|
|
69
57
|
// src/constants/logLevel.ts
|
|
70
58
|
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
71
59
|
LogLevel2[LogLevel2["Debug"] = 0] = "Debug";
|
|
@@ -91,6 +79,35 @@ var logLevelNameToLevel = {
|
|
|
91
79
|
};
|
|
92
80
|
var logLevels = [0 /* Debug */, 1 /* Info */, 2 /* Warn */, 3 /* Error */, 4 /* Fatal */];
|
|
93
81
|
|
|
82
|
+
// src/constants/colors.ts
|
|
83
|
+
var logLevelColors = {
|
|
84
|
+
[0 /* Debug */]: "#737373",
|
|
85
|
+
[1 /* Info */]: "#60A5FA",
|
|
86
|
+
[2 /* Warn */]: "#FBBF24",
|
|
87
|
+
[3 /* Error */]: "#F87171",
|
|
88
|
+
[4 /* Fatal */]: "#E879F9"
|
|
89
|
+
};
|
|
90
|
+
var DEFAULT_ACCENT = "#FBBF24";
|
|
91
|
+
var APP_COLORS = ["#EF4444", "#F97316", "#F59E0B", "#84CC16", "#22C55E", "#14B8A6", "#06B6D4", "#3B82F6", "#6366F1", "#8B5CF6", "#D946EF", "#EC4899"];
|
|
92
|
+
|
|
93
|
+
// src/constants/errors.ts
|
|
94
|
+
var apiErrorCodes = [
|
|
95
|
+
/** 403: the team's plan has no room for another app. */
|
|
96
|
+
"APP_LIMIT",
|
|
97
|
+
/** 403: the team's plan has no room for another member (members and live invitations). */
|
|
98
|
+
"SEAT_LIMIT",
|
|
99
|
+
/** 403: the app's team's plan has no room for another guest on it (guests and live invitations). */
|
|
100
|
+
"GUEST_LIMIT",
|
|
101
|
+
/** 409: the person invited is already on the team. */
|
|
102
|
+
"ALREADY_MEMBER",
|
|
103
|
+
/** 409: the person invited can already read the app. */
|
|
104
|
+
"ALREADY_READS",
|
|
105
|
+
/** 409: the address invited already has an open invitation. */
|
|
106
|
+
"ALREADY_INVITED",
|
|
107
|
+
/** 409: the address invited already has an account, so invite the person instead. */
|
|
108
|
+
"HAS_ACCOUNT"
|
|
109
|
+
];
|
|
110
|
+
|
|
94
111
|
// src/constants/notifications.ts
|
|
95
112
|
var PUSH_OFF = 5;
|
|
96
113
|
var DEFAULT_PUSH_THRESHOLD = 2 /* Warn */;
|
|
@@ -127,9 +144,20 @@ var subscriptionPlans = {
|
|
|
127
144
|
var appearanceValues = ["system", "dark", "light"];
|
|
128
145
|
var isValidAppearance = (value) => appearanceValues.includes(value);
|
|
129
146
|
var isValidColor = (value) => /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value);
|
|
147
|
+
var hashName = (name) => {
|
|
148
|
+
let hash = 2166136261;
|
|
149
|
+
for (const char of name.trim().toLowerCase()) {
|
|
150
|
+
hash ^= char.codePointAt(0) ?? 0;
|
|
151
|
+
hash = Math.imul(hash, 16777619);
|
|
152
|
+
}
|
|
153
|
+
return hash >>> 0;
|
|
154
|
+
};
|
|
155
|
+
var nameColor = (name) => APP_COLORS[hashName(name) % APP_COLORS.length];
|
|
156
|
+
var resolveAppColor = (name, color) => color && isValidColor(color) ? color : nameColor(name);
|
|
157
|
+
var personColor = (userId) => nameColor(userId);
|
|
130
158
|
var isValidLogLevel = (value) => logLevels.includes(value);
|
|
131
159
|
var isValidSubscriptionLevel = (value) => subscriptionLevels.includes(value);
|
|
132
|
-
var deviceLinkStatuses = ["pending", "approved", "denied"];
|
|
160
|
+
var deviceLinkStatuses = ["pending", "approved", "denied", "failed"];
|
|
133
161
|
var isValidDeviceLinkStatus = (value) => deviceLinkStatuses.includes(value);
|
|
134
162
|
var teamMemberRoles = ["owner", "admin", "member"];
|
|
135
163
|
var isValidTeamMemberRole = (value) => teamMemberRoles.includes(value);
|
|
@@ -171,7 +199,8 @@ var parsePushData = (data) => {
|
|
|
171
199
|
case "note":
|
|
172
200
|
return isId(d.appId) && isId(d.noteId) ? { type: "note", appId: d.appId, noteId: d.noteId } : null;
|
|
173
201
|
case "device_link":
|
|
174
|
-
|
|
202
|
+
case "device_link_answered":
|
|
203
|
+
return isId(d.deviceLinkId) ? { type: d.type, deviceLinkId: d.deviceLinkId, deviceName: typeof d.deviceName === "string" ? d.deviceName : "" } : null;
|
|
175
204
|
case "key_check":
|
|
176
205
|
return isId(d.checkId) ? { type: "key_check", checkId: d.checkId } : null;
|
|
177
206
|
case "key_waiting":
|
|
@@ -184,6 +213,8 @@ var parsePushData = (data) => {
|
|
|
184
213
|
};
|
|
185
214
|
// Annotate the CommonJS export names for ESM import in node:
|
|
186
215
|
0 && (module.exports = {
|
|
216
|
+
APP_COLORS,
|
|
217
|
+
DEFAULT_ACCENT,
|
|
187
218
|
DEFAULT_PUSH_THRESHOLD,
|
|
188
219
|
LogLevel,
|
|
189
220
|
PUSH_OFF,
|
|
@@ -199,11 +230,15 @@ var parsePushData = (data) => {
|
|
|
199
230
|
isValidSubscriptionLevel,
|
|
200
231
|
isValidTeamMemberRole,
|
|
201
232
|
joinApiKey,
|
|
233
|
+
logLevelColors,
|
|
202
234
|
logLevelNameToLevel,
|
|
203
235
|
logLevelToName,
|
|
204
236
|
logLevels,
|
|
237
|
+
nameColor,
|
|
205
238
|
normalizePushThreshold,
|
|
206
239
|
parsePushData,
|
|
240
|
+
personColor,
|
|
241
|
+
resolveAppColor,
|
|
207
242
|
splitApiKey,
|
|
208
243
|
subscriptionLevelToName,
|
|
209
244
|
subscriptionLevels,
|
package/dist/index.mjs
CHANGED
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
// src/constants/errors.ts
|
|
2
|
-
var apiErrorCodes = [
|
|
3
|
-
/** 403: the team's plan has no room for another app. */
|
|
4
|
-
"APP_LIMIT",
|
|
5
|
-
/** 403: the team's plan has no room for another member (members and live invitations). */
|
|
6
|
-
"SEAT_LIMIT",
|
|
7
|
-
/** 403: the app's team's plan has no room for another guest on it (guests and live invitations). */
|
|
8
|
-
"GUEST_LIMIT",
|
|
9
|
-
/** 409: the person invited is already on the team. */
|
|
10
|
-
"ALREADY_MEMBER",
|
|
11
|
-
/** 409: the person invited can already read the app. */
|
|
12
|
-
"ALREADY_READS",
|
|
13
|
-
/** 409: the address invited already has an open invitation. */
|
|
14
|
-
"ALREADY_INVITED",
|
|
15
|
-
/** 409: the address invited already has an account, so invite the person instead. */
|
|
16
|
-
"HAS_ACCOUNT"
|
|
17
|
-
];
|
|
18
|
-
|
|
19
1
|
// src/constants/logLevel.ts
|
|
20
2
|
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
21
3
|
LogLevel2[LogLevel2["Debug"] = 0] = "Debug";
|
|
@@ -41,6 +23,35 @@ var logLevelNameToLevel = {
|
|
|
41
23
|
};
|
|
42
24
|
var logLevels = [0 /* Debug */, 1 /* Info */, 2 /* Warn */, 3 /* Error */, 4 /* Fatal */];
|
|
43
25
|
|
|
26
|
+
// src/constants/colors.ts
|
|
27
|
+
var logLevelColors = {
|
|
28
|
+
[0 /* Debug */]: "#737373",
|
|
29
|
+
[1 /* Info */]: "#60A5FA",
|
|
30
|
+
[2 /* Warn */]: "#FBBF24",
|
|
31
|
+
[3 /* Error */]: "#F87171",
|
|
32
|
+
[4 /* Fatal */]: "#E879F9"
|
|
33
|
+
};
|
|
34
|
+
var DEFAULT_ACCENT = "#FBBF24";
|
|
35
|
+
var APP_COLORS = ["#EF4444", "#F97316", "#F59E0B", "#84CC16", "#22C55E", "#14B8A6", "#06B6D4", "#3B82F6", "#6366F1", "#8B5CF6", "#D946EF", "#EC4899"];
|
|
36
|
+
|
|
37
|
+
// src/constants/errors.ts
|
|
38
|
+
var apiErrorCodes = [
|
|
39
|
+
/** 403: the team's plan has no room for another app. */
|
|
40
|
+
"APP_LIMIT",
|
|
41
|
+
/** 403: the team's plan has no room for another member (members and live invitations). */
|
|
42
|
+
"SEAT_LIMIT",
|
|
43
|
+
/** 403: the app's team's plan has no room for another guest on it (guests and live invitations). */
|
|
44
|
+
"GUEST_LIMIT",
|
|
45
|
+
/** 409: the person invited is already on the team. */
|
|
46
|
+
"ALREADY_MEMBER",
|
|
47
|
+
/** 409: the person invited can already read the app. */
|
|
48
|
+
"ALREADY_READS",
|
|
49
|
+
/** 409: the address invited already has an open invitation. */
|
|
50
|
+
"ALREADY_INVITED",
|
|
51
|
+
/** 409: the address invited already has an account, so invite the person instead. */
|
|
52
|
+
"HAS_ACCOUNT"
|
|
53
|
+
];
|
|
54
|
+
|
|
44
55
|
// src/constants/notifications.ts
|
|
45
56
|
var PUSH_OFF = 5;
|
|
46
57
|
var DEFAULT_PUSH_THRESHOLD = 2 /* Warn */;
|
|
@@ -77,9 +88,20 @@ var subscriptionPlans = {
|
|
|
77
88
|
var appearanceValues = ["system", "dark", "light"];
|
|
78
89
|
var isValidAppearance = (value) => appearanceValues.includes(value);
|
|
79
90
|
var isValidColor = (value) => /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value);
|
|
91
|
+
var hashName = (name) => {
|
|
92
|
+
let hash = 2166136261;
|
|
93
|
+
for (const char of name.trim().toLowerCase()) {
|
|
94
|
+
hash ^= char.codePointAt(0) ?? 0;
|
|
95
|
+
hash = Math.imul(hash, 16777619);
|
|
96
|
+
}
|
|
97
|
+
return hash >>> 0;
|
|
98
|
+
};
|
|
99
|
+
var nameColor = (name) => APP_COLORS[hashName(name) % APP_COLORS.length];
|
|
100
|
+
var resolveAppColor = (name, color) => color && isValidColor(color) ? color : nameColor(name);
|
|
101
|
+
var personColor = (userId) => nameColor(userId);
|
|
80
102
|
var isValidLogLevel = (value) => logLevels.includes(value);
|
|
81
103
|
var isValidSubscriptionLevel = (value) => subscriptionLevels.includes(value);
|
|
82
|
-
var deviceLinkStatuses = ["pending", "approved", "denied"];
|
|
104
|
+
var deviceLinkStatuses = ["pending", "approved", "denied", "failed"];
|
|
83
105
|
var isValidDeviceLinkStatus = (value) => deviceLinkStatuses.includes(value);
|
|
84
106
|
var teamMemberRoles = ["owner", "admin", "member"];
|
|
85
107
|
var isValidTeamMemberRole = (value) => teamMemberRoles.includes(value);
|
|
@@ -121,7 +143,8 @@ var parsePushData = (data) => {
|
|
|
121
143
|
case "note":
|
|
122
144
|
return isId(d.appId) && isId(d.noteId) ? { type: "note", appId: d.appId, noteId: d.noteId } : null;
|
|
123
145
|
case "device_link":
|
|
124
|
-
|
|
146
|
+
case "device_link_answered":
|
|
147
|
+
return isId(d.deviceLinkId) ? { type: d.type, deviceLinkId: d.deviceLinkId, deviceName: typeof d.deviceName === "string" ? d.deviceName : "" } : null;
|
|
125
148
|
case "key_check":
|
|
126
149
|
return isId(d.checkId) ? { type: "key_check", checkId: d.checkId } : null;
|
|
127
150
|
case "key_waiting":
|
|
@@ -133,6 +156,8 @@ var parsePushData = (data) => {
|
|
|
133
156
|
}
|
|
134
157
|
};
|
|
135
158
|
export {
|
|
159
|
+
APP_COLORS,
|
|
160
|
+
DEFAULT_ACCENT,
|
|
136
161
|
DEFAULT_PUSH_THRESHOLD,
|
|
137
162
|
LogLevel,
|
|
138
163
|
PUSH_OFF,
|
|
@@ -148,11 +173,15 @@ export {
|
|
|
148
173
|
isValidSubscriptionLevel,
|
|
149
174
|
isValidTeamMemberRole,
|
|
150
175
|
joinApiKey,
|
|
176
|
+
logLevelColors,
|
|
151
177
|
logLevelNameToLevel,
|
|
152
178
|
logLevelToName,
|
|
153
179
|
logLevels,
|
|
180
|
+
nameColor,
|
|
154
181
|
normalizePushThreshold,
|
|
155
182
|
parsePushData,
|
|
183
|
+
personColor,
|
|
184
|
+
resolveAppColor,
|
|
156
185
|
splitApiKey,
|
|
157
186
|
subscriptionLevelToName,
|
|
158
187
|
subscriptionLevels,
|