@infinitetoken/lumber-kit 0.5.2 → 0.7.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/dist/index.js CHANGED
@@ -22,12 +22,15 @@ var index_exports = {};
22
22
  __export(index_exports, {
23
23
  APP_COLORS: () => APP_COLORS,
24
24
  DEFAULT_ACCENT: () => DEFAULT_ACCENT,
25
+ DEFAULT_API_ENDPOINT: () => DEFAULT_API_ENDPOINT,
25
26
  DEFAULT_PUSH_THRESHOLD: () => DEFAULT_PUSH_THRESHOLD,
27
+ LOG_KEY_VERSION: () => LOG_KEY_VERSION,
26
28
  LogLevel: () => LogLevel,
27
29
  PUSH_OFF: () => PUSH_OFF,
28
30
  SubscriptionLevel: () => SubscriptionLevel,
29
31
  apiErrorCodeOf: () => apiErrorCodeOf,
30
32
  apiErrorCodes: () => apiErrorCodes,
33
+ buildLogPayload: () => buildLogPayload,
31
34
  isApiErrorCode: () => isApiErrorCode,
32
35
  isValidAppearance: () => isValidAppearance,
33
36
  isValidColor: () => isValidColor,
@@ -37,10 +40,13 @@ __export(index_exports, {
37
40
  isValidSubscriptionLevel: () => isValidSubscriptionLevel,
38
41
  isValidTeamMemberRole: () => isValidTeamMemberRole,
39
42
  joinApiKey: () => joinApiKey,
43
+ logDelivery: () => logDelivery,
44
+ logDeliveryOutcome: () => logDeliveryOutcome,
40
45
  logLevelColors: () => logLevelColors,
41
46
  logLevelNameToLevel: () => logLevelNameToLevel,
42
47
  logLevelToName: () => logLevelToName,
43
48
  logLevels: () => logLevels,
49
+ logRetryDelayMs: () => logRetryDelayMs,
44
50
  nameColor: () => nameColor,
45
51
  normalizePushThreshold: () => normalizePushThreshold,
46
52
  parsePushData: () => parsePushData,
@@ -55,13 +61,13 @@ __export(index_exports, {
55
61
  module.exports = __toCommonJS(index_exports);
56
62
 
57
63
  // src/constants/logLevel.ts
58
- var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
59
- LogLevel2[LogLevel2["Debug"] = 0] = "Debug";
60
- LogLevel2[LogLevel2["Info"] = 1] = "Info";
61
- LogLevel2[LogLevel2["Warn"] = 2] = "Warn";
62
- LogLevel2[LogLevel2["Error"] = 3] = "Error";
63
- LogLevel2[LogLevel2["Fatal"] = 4] = "Fatal";
64
- return LogLevel2;
64
+ var LogLevel = /* @__PURE__ */ ((LogLevel3) => {
65
+ LogLevel3[LogLevel3["Debug"] = 0] = "Debug";
66
+ LogLevel3[LogLevel3["Info"] = 1] = "Info";
67
+ LogLevel3[LogLevel3["Warn"] = 2] = "Warn";
68
+ LogLevel3[LogLevel3["Error"] = 3] = "Error";
69
+ LogLevel3[LogLevel3["Fatal"] = 4] = "Fatal";
70
+ return LogLevel3;
65
71
  })(LogLevel || {});
66
72
  var logLevelToName = {
67
73
  [0 /* Debug */]: "debug",
@@ -108,6 +114,16 @@ var apiErrorCodes = [
108
114
  "HAS_ACCOUNT"
109
115
  ];
110
116
 
117
+ // src/constants/ingest.ts
118
+ var DEFAULT_API_ENDPOINT = "https://api.lumber.infinitetoken.com";
119
+ var LOG_KEY_VERSION = 1;
120
+ var logDelivery = {
121
+ maxAttempts: 5,
122
+ baseDelayMs: 1e3,
123
+ maxDelayMs: 3e4,
124
+ pauseMs: 60 * 60 * 1e3
125
+ };
126
+
111
127
  // src/constants/notifications.ts
112
128
  var PUSH_OFF = 5;
113
129
  var DEFAULT_PUSH_THRESHOLD = 2 /* Warn */;
@@ -140,6 +156,32 @@ var subscriptionPlans = {
140
156
  [3 /* Enterprise */]: { name: "Enterprise", monthlyPrice: null }
141
157
  };
142
158
 
159
+ // src/utils/ingest.ts
160
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
161
+ var buildLogPayload = (level, message, data, autoContext) => {
162
+ const { requestId, traceId, context: givenContext, metadata: givenMetadata, ...rest } = data ?? {};
163
+ const context = isRecord(givenContext) ? givenContext : void 0;
164
+ const metadata = isRecord(givenMetadata) ? givenMetadata : void 0;
165
+ if (givenContext != null && !context) rest.context = givenContext;
166
+ if (givenMetadata != null && !metadata) rest.metadata = givenMetadata;
167
+ const mergedMetadata = Object.keys(rest).length > 0 ? { ...rest, ...metadata ?? {} } : metadata;
168
+ const mergedContext = autoContext && Object.keys(autoContext).length > 0 ? { ...autoContext, ...context ?? {} } : context;
169
+ const payload = { level, message };
170
+ if (requestId !== void 0) payload.requestId = requestId;
171
+ if (traceId !== void 0) payload.traceId = traceId;
172
+ if (mergedContext !== void 0) payload.context = mergedContext;
173
+ if (mergedMetadata !== void 0) payload.metadata = mergedMetadata;
174
+ return payload;
175
+ };
176
+ var logDeliveryOutcome = (status) => {
177
+ if (status === null) return "retry";
178
+ if (status >= 200 && status < 300) return "sent";
179
+ if (status === 429) return "pause";
180
+ if (status >= 400 && status < 500) return "drop";
181
+ return "retry";
182
+ };
183
+ var logRetryDelayMs = (failedAttempts) => Math.min(logDelivery.baseDelayMs * 2 ** Math.max(0, failedAttempts - 1), logDelivery.maxDelayMs);
184
+
143
185
  // src/utils/index.ts
144
186
  var appearanceValues = ["system", "dark", "light"];
145
187
  var isValidAppearance = (value) => appearanceValues.includes(value);
@@ -157,7 +199,7 @@ var resolveAppColor = (name, color) => color && isValidColor(color) ? color : na
157
199
  var personColor = (userId) => nameColor(userId);
158
200
  var isValidLogLevel = (value) => logLevels.includes(value);
159
201
  var isValidSubscriptionLevel = (value) => subscriptionLevels.includes(value);
160
- var deviceLinkStatuses = ["pending", "approved", "denied"];
202
+ var deviceLinkStatuses = ["pending", "approved", "denied", "failed"];
161
203
  var isValidDeviceLinkStatus = (value) => deviceLinkStatuses.includes(value);
162
204
  var teamMemberRoles = ["owner", "admin", "member"];
163
205
  var isValidTeamMemberRole = (value) => teamMemberRoles.includes(value);
@@ -199,7 +241,8 @@ var parsePushData = (data) => {
199
241
  case "note":
200
242
  return isId(d.appId) && isId(d.noteId) ? { type: "note", appId: d.appId, noteId: d.noteId } : null;
201
243
  case "device_link":
202
- return isId(d.deviceLinkId) ? { type: "device_link", deviceLinkId: d.deviceLinkId, deviceName: typeof d.deviceName === "string" ? d.deviceName : "" } : null;
244
+ case "device_link_answered":
245
+ return isId(d.deviceLinkId) ? { type: d.type, deviceLinkId: d.deviceLinkId, deviceName: typeof d.deviceName === "string" ? d.deviceName : "" } : null;
203
246
  case "key_check":
204
247
  return isId(d.checkId) ? { type: "key_check", checkId: d.checkId } : null;
205
248
  case "key_waiting":
@@ -214,12 +257,15 @@ var parsePushData = (data) => {
214
257
  0 && (module.exports = {
215
258
  APP_COLORS,
216
259
  DEFAULT_ACCENT,
260
+ DEFAULT_API_ENDPOINT,
217
261
  DEFAULT_PUSH_THRESHOLD,
262
+ LOG_KEY_VERSION,
218
263
  LogLevel,
219
264
  PUSH_OFF,
220
265
  SubscriptionLevel,
221
266
  apiErrorCodeOf,
222
267
  apiErrorCodes,
268
+ buildLogPayload,
223
269
  isApiErrorCode,
224
270
  isValidAppearance,
225
271
  isValidColor,
@@ -229,10 +275,13 @@ var parsePushData = (data) => {
229
275
  isValidSubscriptionLevel,
230
276
  isValidTeamMemberRole,
231
277
  joinApiKey,
278
+ logDelivery,
279
+ logDeliveryOutcome,
232
280
  logLevelColors,
233
281
  logLevelNameToLevel,
234
282
  logLevelToName,
235
283
  logLevels,
284
+ logRetryDelayMs,
236
285
  nameColor,
237
286
  normalizePushThreshold,
238
287
  parsePushData,
package/dist/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  // src/constants/logLevel.ts
2
- var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
3
- LogLevel2[LogLevel2["Debug"] = 0] = "Debug";
4
- LogLevel2[LogLevel2["Info"] = 1] = "Info";
5
- LogLevel2[LogLevel2["Warn"] = 2] = "Warn";
6
- LogLevel2[LogLevel2["Error"] = 3] = "Error";
7
- LogLevel2[LogLevel2["Fatal"] = 4] = "Fatal";
8
- return LogLevel2;
2
+ var LogLevel = /* @__PURE__ */ ((LogLevel3) => {
3
+ LogLevel3[LogLevel3["Debug"] = 0] = "Debug";
4
+ LogLevel3[LogLevel3["Info"] = 1] = "Info";
5
+ LogLevel3[LogLevel3["Warn"] = 2] = "Warn";
6
+ LogLevel3[LogLevel3["Error"] = 3] = "Error";
7
+ LogLevel3[LogLevel3["Fatal"] = 4] = "Fatal";
8
+ return LogLevel3;
9
9
  })(LogLevel || {});
10
10
  var logLevelToName = {
11
11
  [0 /* Debug */]: "debug",
@@ -52,6 +52,16 @@ var apiErrorCodes = [
52
52
  "HAS_ACCOUNT"
53
53
  ];
54
54
 
55
+ // src/constants/ingest.ts
56
+ var DEFAULT_API_ENDPOINT = "https://api.lumber.infinitetoken.com";
57
+ var LOG_KEY_VERSION = 1;
58
+ var logDelivery = {
59
+ maxAttempts: 5,
60
+ baseDelayMs: 1e3,
61
+ maxDelayMs: 3e4,
62
+ pauseMs: 60 * 60 * 1e3
63
+ };
64
+
55
65
  // src/constants/notifications.ts
56
66
  var PUSH_OFF = 5;
57
67
  var DEFAULT_PUSH_THRESHOLD = 2 /* Warn */;
@@ -84,6 +94,32 @@ var subscriptionPlans = {
84
94
  [3 /* Enterprise */]: { name: "Enterprise", monthlyPrice: null }
85
95
  };
86
96
 
97
+ // src/utils/ingest.ts
98
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
99
+ var buildLogPayload = (level, message, data, autoContext) => {
100
+ const { requestId, traceId, context: givenContext, metadata: givenMetadata, ...rest } = data ?? {};
101
+ const context = isRecord(givenContext) ? givenContext : void 0;
102
+ const metadata = isRecord(givenMetadata) ? givenMetadata : void 0;
103
+ if (givenContext != null && !context) rest.context = givenContext;
104
+ if (givenMetadata != null && !metadata) rest.metadata = givenMetadata;
105
+ const mergedMetadata = Object.keys(rest).length > 0 ? { ...rest, ...metadata ?? {} } : metadata;
106
+ const mergedContext = autoContext && Object.keys(autoContext).length > 0 ? { ...autoContext, ...context ?? {} } : context;
107
+ const payload = { level, message };
108
+ if (requestId !== void 0) payload.requestId = requestId;
109
+ if (traceId !== void 0) payload.traceId = traceId;
110
+ if (mergedContext !== void 0) payload.context = mergedContext;
111
+ if (mergedMetadata !== void 0) payload.metadata = mergedMetadata;
112
+ return payload;
113
+ };
114
+ var logDeliveryOutcome = (status) => {
115
+ if (status === null) return "retry";
116
+ if (status >= 200 && status < 300) return "sent";
117
+ if (status === 429) return "pause";
118
+ if (status >= 400 && status < 500) return "drop";
119
+ return "retry";
120
+ };
121
+ var logRetryDelayMs = (failedAttempts) => Math.min(logDelivery.baseDelayMs * 2 ** Math.max(0, failedAttempts - 1), logDelivery.maxDelayMs);
122
+
87
123
  // src/utils/index.ts
88
124
  var appearanceValues = ["system", "dark", "light"];
89
125
  var isValidAppearance = (value) => appearanceValues.includes(value);
@@ -101,7 +137,7 @@ var resolveAppColor = (name, color) => color && isValidColor(color) ? color : na
101
137
  var personColor = (userId) => nameColor(userId);
102
138
  var isValidLogLevel = (value) => logLevels.includes(value);
103
139
  var isValidSubscriptionLevel = (value) => subscriptionLevels.includes(value);
104
- var deviceLinkStatuses = ["pending", "approved", "denied"];
140
+ var deviceLinkStatuses = ["pending", "approved", "denied", "failed"];
105
141
  var isValidDeviceLinkStatus = (value) => deviceLinkStatuses.includes(value);
106
142
  var teamMemberRoles = ["owner", "admin", "member"];
107
143
  var isValidTeamMemberRole = (value) => teamMemberRoles.includes(value);
@@ -143,7 +179,8 @@ var parsePushData = (data) => {
143
179
  case "note":
144
180
  return isId(d.appId) && isId(d.noteId) ? { type: "note", appId: d.appId, noteId: d.noteId } : null;
145
181
  case "device_link":
146
- return isId(d.deviceLinkId) ? { type: "device_link", deviceLinkId: d.deviceLinkId, deviceName: typeof d.deviceName === "string" ? d.deviceName : "" } : null;
182
+ case "device_link_answered":
183
+ return isId(d.deviceLinkId) ? { type: d.type, deviceLinkId: d.deviceLinkId, deviceName: typeof d.deviceName === "string" ? d.deviceName : "" } : null;
147
184
  case "key_check":
148
185
  return isId(d.checkId) ? { type: "key_check", checkId: d.checkId } : null;
149
186
  case "key_waiting":
@@ -157,12 +194,15 @@ var parsePushData = (data) => {
157
194
  export {
158
195
  APP_COLORS,
159
196
  DEFAULT_ACCENT,
197
+ DEFAULT_API_ENDPOINT,
160
198
  DEFAULT_PUSH_THRESHOLD,
199
+ LOG_KEY_VERSION,
161
200
  LogLevel,
162
201
  PUSH_OFF,
163
202
  SubscriptionLevel,
164
203
  apiErrorCodeOf,
165
204
  apiErrorCodes,
205
+ buildLogPayload,
166
206
  isApiErrorCode,
167
207
  isValidAppearance,
168
208
  isValidColor,
@@ -172,10 +212,13 @@ export {
172
212
  isValidSubscriptionLevel,
173
213
  isValidTeamMemberRole,
174
214
  joinApiKey,
215
+ logDelivery,
216
+ logDeliveryOutcome,
175
217
  logLevelColors,
176
218
  logLevelNameToLevel,
177
219
  logLevelToName,
178
220
  logLevels,
221
+ logRetryDelayMs,
179
222
  nameColor,
180
223
  normalizePushThreshold,
181
224
  parsePushData,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@infinitetoken/lumber-kit",
3
- "version": "0.5.2",
3
+ "version": "0.7.0",
4
4
  "description": "Shared TypeScript types and wire format contracts for the Lumber cloud logging suite",
5
5
  "keywords": [
6
6
  "lumber",
@@ -31,17 +31,20 @@
31
31
  "types": "./dist/index.d.ts",
32
32
  "default": "./dist/index.js"
33
33
  }
34
- }
34
+ },
35
+ "./contract/*": "./contract/*"
35
36
  },
36
37
  "main": "./dist/index.js",
37
38
  "module": "./dist/index.mjs",
38
39
  "types": "./dist/index.d.ts",
39
40
  "files": [
40
- "dist"
41
+ "dist",
42
+ "contract"
41
43
  ],
42
44
  "scripts": {
43
45
  "build": "tsup",
44
46
  "clean": "rm -rf dist coverage",
47
+ "contract": "node scripts/contract.cjs",
45
48
  "fix": "eslint . --fix",
46
49
  "lint": "eslint .",
47
50
  "prepublishOnly": "npm run build",
@@ -61,9 +64,11 @@
61
64
  "@infinitetoken/tsconfig": "^0.6.0",
62
65
  "@types/jest": "^30.0.0",
63
66
  "@types/node": "^25.0.0",
67
+ "ajv": "^8.20.0",
64
68
  "eslint": "^10.2.1",
65
69
  "jest": "^30.4.2",
66
70
  "prettier": "^3.8.3",
71
+ "ts-json-schema-generator": "^2.9.0",
67
72
  "tsup": "^8.5.1",
68
73
  "typescript": "^6.0.3"
69
74
  },