@harperfast/harper 5.3.0-beta.1 → 5.3.0-beta.2

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.
Files changed (126) hide show
  1. package/components/DESIGN.md +421 -0
  2. package/components/mcp/DESIGN.md +109 -0
  3. package/components/mcp/audit.ts +21 -17
  4. package/config/DESIGN.md +306 -0
  5. package/dataLayer/DESIGN.md +179 -0
  6. package/dataLayer/restoreMarker.ts +92 -25
  7. package/dist/components/mcp/audit.d.ts +2 -1
  8. package/dist/components/mcp/audit.js +21 -17
  9. package/dist/components/mcp/audit.js.map +1 -1
  10. package/dist/dataLayer/restoreMarker.d.ts +21 -8
  11. package/dist/dataLayer/restoreMarker.js +94 -27
  12. package/dist/dataLayer/restoreMarker.js.map +1 -1
  13. package/dist/index.d.ts +1 -0
  14. package/dist/index.js +6 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/resources/RecordEncoder.js +25 -5
  17. package/dist/resources/RecordEncoder.js.map +1 -1
  18. package/dist/resources/Table.js +48 -2
  19. package/dist/resources/Table.js.map +1 -1
  20. package/dist/resources/analytics/write.d.ts +3 -0
  21. package/dist/resources/analytics/write.js +39 -13
  22. package/dist/resources/analytics/write.js.map +1 -1
  23. package/dist/resources/crdt.d.ts +10 -0
  24. package/dist/resources/crdt.js +22 -0
  25. package/dist/resources/crdt.js.map +1 -1
  26. package/dist/resources/databases.js +1 -1
  27. package/dist/resources/databases.js.map +1 -1
  28. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +2 -2
  29. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +43 -24
  30. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
  31. package/dist/resources/indexes/fullTextDerivedIndex.d.ts +81 -0
  32. package/dist/resources/indexes/fullTextDerivedIndex.js +1004 -0
  33. package/dist/resources/indexes/fullTextDerivedIndex.js.map +1 -0
  34. package/dist/resources/indexes/fullTextNativeBinding.d.ts +78 -0
  35. package/dist/resources/indexes/fullTextNativeBinding.js +85 -0
  36. package/dist/resources/indexes/fullTextNativeBinding.js.map +1 -0
  37. package/dist/resources/indexes/nativeFullTextDerivedIndexLifecycle.d.ts +24 -0
  38. package/dist/resources/indexes/nativeFullTextDerivedIndexLifecycle.js +149 -0
  39. package/dist/resources/indexes/nativeFullTextDerivedIndexLifecycle.js.map +1 -0
  40. package/dist/resources/recordLockCoordinator.d.ts +5 -5
  41. package/dist/resources/recordLockCoordinator.js +48 -16
  42. package/dist/resources/recordLockCoordinator.js.map +1 -1
  43. package/dist/resources/transactionBroadcast.js +4 -6
  44. package/dist/resources/transactionBroadcast.js.map +1 -1
  45. package/dist/security/auth.js +59 -23
  46. package/dist/security/auth.js.map +1 -1
  47. package/dist/security/deferredAuthentication.d.ts +11 -0
  48. package/dist/security/deferredAuthentication.js +25 -3
  49. package/dist/security/deferredAuthentication.js.map +1 -1
  50. package/dist/security/jsLoader.js +3 -0
  51. package/dist/security/jsLoader.js.map +1 -1
  52. package/dist/server/REST.js +6 -3
  53. package/dist/server/REST.js.map +1 -1
  54. package/dist/server/mqtt.js +5 -1
  55. package/dist/server/mqtt.js.map +1 -1
  56. package/dist/server/serverHelpers/serverUtilities.d.ts +3 -3
  57. package/dist/server/serverHelpers/serverUtilities.js +14 -3
  58. package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
  59. package/dist/server/serverHelpers/uwsServer.js +4 -1
  60. package/dist/server/serverHelpers/uwsServer.js.map +1 -1
  61. package/dist/server/serverHelpers/webSocketCloseReason.d.ts +2 -0
  62. package/dist/server/serverHelpers/webSocketCloseReason.js +29 -0
  63. package/dist/server/serverHelpers/webSocketCloseReason.js.map +1 -0
  64. package/dist/utility/logging/harper_logger.js +1 -0
  65. package/dist/utility/logging/harper_logger.js.map +1 -1
  66. package/index.ts +3 -0
  67. package/npm-shrinkwrap.json +104 -104
  68. package/package.json +6 -5
  69. package/resources/DESIGN.md +568 -3
  70. package/resources/RecordEncoder.ts +27 -5
  71. package/resources/Table.ts +49 -3
  72. package/resources/analytics/DESIGN.md +38 -0
  73. package/resources/analytics/write.ts +40 -14
  74. package/resources/crdt.ts +22 -0
  75. package/resources/databases.ts +1 -1
  76. package/resources/indexes/DESIGN.md +833 -0
  77. package/resources/indexes/HierarchicalNavigableSmallWorld.ts +44 -25
  78. package/resources/indexes/fullTextDerivedIndex.ts +1165 -0
  79. package/resources/indexes/fullTextNativeBinding.ts +146 -0
  80. package/resources/indexes/nativeFullTextDerivedIndexLifecycle.ts +181 -0
  81. package/resources/record-locks.md +1407 -0
  82. package/resources/recordLockCoordinator.ts +61 -22
  83. package/resources/scheduler/DESIGN.md +40 -0
  84. package/resources/transactionBroadcast.ts +4 -4
  85. package/security/DESIGN.md +175 -0
  86. package/security/auth.ts +53 -24
  87. package/security/deferredAuthentication.ts +24 -2
  88. package/security/jsLoader.ts +3 -0
  89. package/server/DESIGN.md +264 -0
  90. package/server/REST.ts +6 -3
  91. package/server/mqtt.ts +6 -4
  92. package/server/serverHelpers/serverUtilities.ts +14 -3
  93. package/server/serverHelpers/uwsServer.ts +4 -1
  94. package/server/serverHelpers/webSocketCloseReason.ts +25 -0
  95. package/studio/web/assets/{Chat-D3j-1yY1.js → Chat-DADFFGe_.js} +1 -1
  96. package/studio/web/assets/{FloatingChat-BxJGYcfB.js → FloatingChat-D_mI-rZ7.js} +3 -3
  97. package/studio/web/assets/{apiToken-CT55oWOe.js → apiToken-c2NiSDHa.js} +1 -1
  98. package/studio/web/assets/{applications-D9Ct9_vm.js → applications-DktUqh7G.js} +1 -1
  99. package/studio/web/assets/{cssMode-DV8H7VwA.js → cssMode-Cs_75Xhw.js} +1 -1
  100. package/studio/web/assets/{editor-uatc0unt.js → editor-19b-Y1IN.js} +1 -1
  101. package/studio/web/assets/{html-Bm6D6paN.js → html-DiYEQMpB.js} +1 -1
  102. package/studio/web/assets/{htmlMode-CEn7tpLG.js → htmlMode-CmR0y7P_.js} +1 -1
  103. package/studio/web/assets/{index-BIXW6Pu4.js → index-Dm0rfkJ7.js} +5 -5
  104. package/studio/web/assets/{index.lazy-UI7L-Vrk.js → index.lazy-7vqt2CC3.js} +1 -1
  105. package/studio/web/assets/{javascript-CJ0G3AFZ.js → javascript-BWtCFuOt.js} +1 -1
  106. package/studio/web/assets/{jsonMode-DQADAYEa.js → jsonMode-Buzzbv9y.js} +1 -1
  107. package/studio/web/assets/{languageServices-CAQJXWcI.js → languageServices-SqsFWfTM.js} +1 -1
  108. package/studio/web/assets/{lspLanguageFeatures-CCQ8P5sY.js → lspLanguageFeatures-EMV5cmjo.js} +1 -1
  109. package/studio/web/assets/{notifications-Cvb3P1lB.js → notifications-CAB-LZWT.js} +1 -1
  110. package/studio/web/assets/{notifications-BbxTU6Aw.js → notifications-DRzmSRxM.js} +1 -1
  111. package/studio/web/assets/{profile-Yyb7gsvL.js → profile-BNKAl79n.js} +1 -1
  112. package/studio/web/assets/{regions-OgjGHlU5.js → regions-CUow_Zw2.js} +1 -1
  113. package/studio/web/assets/{register-6qwNEOY3.js → register-Dkt3WUMp.js} +2 -2
  114. package/studio/web/assets/{setComponentFile-BilDMtgB.js → setComponentFile-BZRfMD0N.js} +1 -1
  115. package/studio/web/assets/{setup-J6qJ7OIU.js → setup-D_yiEPO2.js} +2 -2
  116. package/studio/web/assets/{status-0RWGcfyD.js → status-DhHh1Ge-.js} +1 -1
  117. package/studio/web/assets/{toggleHighContrast-BIn-vErT.js → toggleHighContrast-D7L1PDtV.js} +1 -1
  118. package/studio/web/assets/{tsMode-DgUXku4d.js → tsMode-CCwLk1YS.js} +1 -1
  119. package/studio/web/assets/{typescript-C9orXcsM.js → typescript-BP1j1mjn.js} +1 -1
  120. package/studio/web/assets/{useEntityRestURL-BEoXXbUB.js → useEntityRestURL-D7bnYxLw.js} +1 -1
  121. package/studio/web/assets/{workers-JVzSDmgx.js → workers-tOuCNT17.js} +1 -1
  122. package/studio/web/assets/{xml-Cq-S8S4X.js → xml-BSG_3mQT.js} +1 -1
  123. package/studio/web/assets/{yaml-sfoRdh1M.js → yaml-DxiLprBB.js} +1 -1
  124. package/studio/web/index.html +1 -1
  125. package/utility/DESIGN.md +55 -0
  126. package/utility/logging/harper_logger.ts +1 -0
@@ -8,6 +8,7 @@ import {
8
8
  openSync,
9
9
  readdirSync,
10
10
  readFileSync,
11
+ renameSync,
11
12
  unlinkSync,
12
13
  writeSync,
13
14
  } from 'node:fs';
@@ -39,11 +40,17 @@ import { tryFileLock, fileLockRelease } from '@harperfast/rocksdb-js';
39
40
  * duration of a restore, and briefly by `dropDatabase` so the two serialize on the same primitive.
40
41
  * Known limitation: the lock is owned by the process, so if the restore job's worker *thread*
41
42
  * dies without the process exiting, the lock stays held (restores 409) until Harper restarts.
42
- * - `<meta-dir>/<key>.restoring` — the completion marker. Written (and fsynced) after the lock is
43
- * acquired and before the destructive restore begins; deleted only after the restore completes
44
- * successfully, while still holding the lock. Its *existence* means "a restore started and has
45
- * not finished successfully". Its first line records the database directory name so the startup
46
- * scan can map a marker back to the database it blocks without decoding the hashed key.
43
+ * - `<meta-dir>/<key>.restoring` — the completion marker. Published (temp → fsync → rename → parent
44
+ * fsync) after the lock is acquired and before the destructive restore begins; deleted only after
45
+ * the restore completes successfully, while still holding the lock. Its *existence* means "a
46
+ * restore started and has not finished successfully". Its first line records the database
47
+ * directory name as a fallback so the startup scan can map a marker whose database directory is
48
+ * missing without decoding the hashed key.
49
+ *
50
+ * The rename is what makes the marker trustworthy: the marker path only ever holds the previous
51
+ * content or the complete new content, so a torn write can never replace a valid marker with one
52
+ * the scan reads as empty (and therefore honors as no block). An intact marker is also never
53
+ * rewritten at all — see `beginRestore`.
47
54
  */
48
55
 
49
56
  // The backtick makes this an illegal database name (schemaRegex rejects `/` and backtick only), so
@@ -51,6 +58,9 @@ import { tryFileLock, fileLockRelease } from '@harperfast/rocksdb-js';
51
58
  export const RESTORE_META_DIR = '`restore`';
52
59
  export const RESTORE_LOCK_SUFFIX = '.lock';
53
60
  export const RESTORING_MARKER_SUFFIX = '.restoring';
61
+ // Deliberately not a `.restoring` suffix: `scanBlockedRestores` selects markers by that suffix, and
62
+ // a half-written temp must never be mistaken for one.
63
+ const MARKER_TEMP_SUFFIX = '.tmp';
54
64
 
55
65
  /**
56
66
  * Directory holding the restore metadata for a database — the reserved `` `restore` `` sibling of
@@ -180,17 +190,29 @@ export function releaseRestoreLock(lock: RestoreLock): void {
180
190
  }
181
191
 
182
192
  /**
183
- * Acquire the per-database restore lock and write the restoring marker. Call before any
184
- * destructive step. Returns the lock (with `preexisting` set when a marker was already present, so
185
- * a failed recovery attempt knows not to clear it). Throws (statusCode 409) if another restore
186
- * already holds the lock.
193
+ * Whether a marker on disk still blocks the database it belongs to. `scanBlockedRestores` maps a
194
+ * marker to a database by its first line, so the line has to be the whole name: a torn write that
195
+ * left a prefix of it ("ord" for "orders") is non-empty and reads as valid, but blocks a database
196
+ * that does not exist while the real one loads.
187
197
  */
188
- export function beginRestore(dbPath: string): RestoreLock {
189
- const markerPath = restoringMarkerPath(dbPath);
190
- const preexisting = existsSync(markerPath);
191
- const lock = acquireRestoreLock(dbPath);
198
+ function markerIsIntact(markerPath: string, dbPath: string): boolean {
199
+ try {
200
+ return readFileSync(markerPath, 'utf8').split('\n', 1)[0] === basename(dbPath);
201
+ } catch {
202
+ return false;
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Publish the restoring marker atomically. The caller must already hold the restore lock, which is
208
+ * what makes the fixed temp name safe: only one writer per database can exist at a time, so a temp
209
+ * left by an earlier crash is this database's own debris and is simply overwritten.
210
+ */
211
+ function publishRestoringMarker(dbPath: string): void {
212
+ const metaDir = restoreMetaDir(dbPath);
213
+ const tempPath = join(metaDir, restoreMetaKey(dbPath) + MARKER_TEMP_SUFFIX);
192
214
  try {
193
- const fd = openSync(markerPath, 'w');
215
+ const fd = openSync(tempPath, 'w');
194
216
  try {
195
217
  // first line is the database directory name so the startup scan can map this marker back to
196
218
  // the database it blocks without reversing the hashed key
@@ -199,9 +221,44 @@ export function beginRestore(dbPath: string): RestoreLock {
199
221
  } finally {
200
222
  closeSync(fd);
201
223
  }
202
- // fsync the metadata directory so the marker's directory entry is durable — without this a
203
- // power loss can lose the entry, and a half-purged database would load as healthy
204
- fsyncDir(restoreMetaDir(dbPath));
224
+ renameSync(tempPath, restoringMarkerPath(dbPath));
225
+ } catch (error) {
226
+ try {
227
+ unlinkSync(tempPath);
228
+ } catch {
229
+ // debris either way; the write failure is the error worth reporting
230
+ }
231
+ throw error;
232
+ }
233
+ // fsync the metadata directory so the marker's directory entry is durable — without this a
234
+ // power loss can lose the entry, and a half-purged database would load as healthy
235
+ fsyncDir(metaDir);
236
+ }
237
+
238
+ /**
239
+ * Acquire the per-database restore lock and ensure the restoring marker is in place. Call before any
240
+ * destructive step. Returns the lock (with `preexisting` set when a marker was already present, so
241
+ * a failed recovery attempt knows not to clear it). Throws (statusCode 409) if another restore
242
+ * already holds the lock.
243
+ *
244
+ * An intact marker is left exactly as it is. A recovery attempt runs over a directory an earlier
245
+ * restore may have half-purged, so the marker it finds is the only thing keeping that directory
246
+ * from loading as healthy; rewriting it buys nothing (the content it would write is the content
247
+ * already there) and risks everything.
248
+ */
249
+ export function beginRestore(dbPath: string): RestoreLock {
250
+ const markerPath = restoringMarkerPath(dbPath);
251
+ const lock = acquireRestoreLock(dbPath);
252
+ // Sampled while holding the lock, not before it: a restore that waited out an earlier one would
253
+ // otherwise carry the earlier run's "no marker" reading, and on its own pre-destruction failure
254
+ // clear the marker protecting a directory that run had already half-purged.
255
+ const preexisting = existsSync(markerPath);
256
+ try {
257
+ if (!preexisting || !markerIsIntact(markerPath, dbPath)) publishRestoringMarker(dbPath);
258
+ // An intact marker is kept, but its durability is not assumed: the publisher that wrote it may
259
+ // have been interrupted between the rename and this flush, which would leave the directory
260
+ // entry — the thing the startup scan reads — still only in the page cache.
261
+ else fsyncDir(restoreMetaDir(dbPath));
205
262
  } catch (error) {
206
263
  fileLockRelease(lock.token);
207
264
  throw error;
@@ -251,24 +308,34 @@ export function clearRestoreMarker(lock: RestoreLock): void {
251
308
  }
252
309
 
253
310
  /**
254
- * Scan a databases root's reserved `` `restore` `` metadata directory and report every database currently blocked from
255
- * loading, mapping each surviving marker back to its database name via the marker's first line.
311
+ * Scan a databases root's reserved `` `restore` `` metadata directory and report every database
312
+ * currently blocked from loading. Existing database entries are mapped to markers by their hashed
313
+ * keys, so corrupt marker contents cannot unblock them; the first line remains the fallback for a
314
+ * marker whose database directory is missing.
256
315
  * Returns `[dbName, state]` pairs for markers whose state is `in-progress` or `incomplete`
257
316
  * (a `clear` result means the marker was removed concurrently and the database is loadable).
258
317
  */
259
318
  export function scanBlockedRestores(databasesRoot: string): Array<[string, RestoreState]> {
260
319
  const metaDir = join(databasesRoot, RESTORE_META_DIR);
261
320
  if (!existsSync(metaDir)) return [];
321
+ const databaseNamesByMarker = new Map(
322
+ readdirSync(databasesRoot, { withFileTypes: true })
323
+ .filter((entry) => entry.name !== RESTORE_META_DIR)
324
+ .map((entry) => [restoreMetaKey(join(databasesRoot, entry.name)) + RESTORING_MARKER_SUFFIX, entry.name])
325
+ );
262
326
  const blocked: Array<[string, RestoreState]> = [];
263
327
  for (const entry of readdirSync(metaDir, { withFileTypes: true })) {
264
328
  if (!entry.isFile() || !entry.name.endsWith(RESTORING_MARKER_SUFFIX)) continue;
265
- let dbName: string;
266
- try {
267
- dbName = readFileSync(join(metaDir, entry.name), 'utf8').split('\n', 1)[0];
268
- } catch {
269
- continue; // marker removed concurrently
329
+ const markerPath = join(metaDir, entry.name);
330
+ let dbName = databaseNamesByMarker.get(entry.name);
331
+ if (!dbName) {
332
+ try {
333
+ dbName = readFileSync(markerPath, 'utf8').split('\n', 1)[0];
334
+ } catch {
335
+ continue; // marker removed concurrently
336
+ }
337
+ if (!dbName || restoringMarkerPath(join(databasesRoot, dbName)) !== markerPath) continue;
270
338
  }
271
- if (!dbName) continue;
272
339
  const state = checkRestoreState(join(databasesRoot, dbName));
273
340
  if (state !== 'clear') blocked.push([dbName, state]);
274
341
  }
@@ -16,7 +16,8 @@ export interface AuditEntry {
16
16
  * a credential buried below the depth limit cannot leak. Returns a shallow
17
17
  * clone — the caller's payload is never mutated.
18
18
  */
19
- export declare function redactArgs(value: unknown, depth?: number, redactExactFields?: boolean): unknown;
19
+ export declare function redactArgs(value: unknown, depth?: number, redactionFields?: ReadonlySet<string>): unknown;
20
+ export declare function redactArgsForTool(value: unknown, tool: string): unknown;
20
21
  /** Mask a session id for logging — first 8 chars, suffix elided. */
21
22
  export declare function maskSessionId(id: string): string;
22
23
  /**
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.redactArgs = redactArgs;
7
+ exports.redactArgsForTool = redactArgsForTool;
7
8
  exports.maskSessionId = maskSessionId;
8
9
  exports.emitAuditEntry = emitAuditEntry;
9
10
  /**
@@ -14,23 +15,23 @@ exports.emitAuditEntry = emitAuditEntry;
14
15
  * (session id, profile, tool name).
15
16
  *
16
17
  * Argument summarization runs through a redaction step that drops anything
17
- * that looks like a credential (key/secret/password). Operators who need
18
+ * that looks like a credential (secret/password/token). Operators who need
18
19
  * stricter PII handling configure `mcp.audit.argumentRedactor` to a custom
19
20
  * function via a future component-author hook (v1.1).
20
21
  */
21
22
  const harper_logger_ts_1 = __importDefault(require("../../utility/logging/harper_logger.js"));
22
23
  const REDACTION_PATTERN = /(secret|password|token|api[-_]?key|credentials?|auth)/i;
23
- // Exact field names that carry secret material without a credential-looking name: `value`/`values`
24
- // (set_secret plaintext, set_env_value .env secrets) and `envelope` (set_secret ciphertext). These
25
- // mirror the fields processLocalTransaction strips from the REST operations log — the MCP audit
26
- // path must not become a bypass. Exact-match so e.g. `search_value` stays auditable.
27
- const REDACTION_EXACT_FIELDS = /^(value|values|envelope)$/i;
28
- // ...but only for the operations that actually put secrets in those generically-named fields.
29
- // `value`/`values` are common, non-secret params on many other operations (record data, config
30
- // values), so blanket-redacting them would gut the audit trail for unrelated tools. The global
31
- // REDACTION_PATTERN still applies to every tool; this just narrows the exact-field masking to the
32
- // secret-bearing ops. NOTE: extend this set if a new op ever carries a secret in a plain field.
33
- const EXACT_FIELD_TOOLS = new Set(['set_secret', 'set_env_value']);
24
+ // Both secret tools carry all three fields, not just the ones each declares: MCP forwards arguments
25
+ // as-is and audits them after the handler, so a field the tool rejects is still logged. Mirrors what
26
+ // the REST operations log strips unconditionally (UNLOGGABLE_OPERATION_FIELDS).
27
+ const SECRET_VALUE_FIELDS = new Set(['value', 'values', 'envelope']);
28
+ // Per tool, not global: `value`/`values` are ordinary params on many other operations.
29
+ const REDACTION_FIELDS_BY_TOOL = new Map([
30
+ ['set_secret', SECRET_VALUE_FIELDS],
31
+ ['set_env_value', SECRET_VALUE_FIELDS],
32
+ ['add_ssh_key', new Set(['key'])],
33
+ ['update_ssh_key', new Set(['key'])],
34
+ ]);
34
35
  const REDACTION_PLACEHOLDER = '[redacted]';
35
36
  const MAX_REDACTION_DEPTH = 10;
36
37
  /**
@@ -40,25 +41,28 @@ const MAX_REDACTION_DEPTH = 10;
40
41
  * a credential buried below the depth limit cannot leak. Returns a shallow
41
42
  * clone — the caller's payload is never mutated.
42
43
  */
43
- function redactArgs(value, depth = 0, redactExactFields = false) {
44
+ function redactArgs(value, depth = 0, redactionFields) {
44
45
  if (value === null || typeof value !== 'object')
45
46
  return value;
46
47
  if (depth > MAX_REDACTION_DEPTH)
47
48
  return REDACTION_PLACEHOLDER;
48
49
  if (Array.isArray(value)) {
49
- return value.map((v) => redactArgs(v, depth + 1, redactExactFields));
50
+ return value.map((v) => redactArgs(v, depth + 1, redactionFields));
50
51
  }
51
52
  const out = {};
52
53
  for (const [k, v] of Object.entries(value)) {
53
- if (REDACTION_PATTERN.test(k) || (redactExactFields && REDACTION_EXACT_FIELDS.test(k))) {
54
+ if (REDACTION_PATTERN.test(k) || redactionFields?.has(k.toLowerCase())) {
54
55
  out[k] = REDACTION_PLACEHOLDER;
55
56
  }
56
57
  else {
57
- out[k] = redactArgs(v, depth + 1, redactExactFields);
58
+ out[k] = redactArgs(v, depth + 1, redactionFields);
58
59
  }
59
60
  }
60
61
  return out;
61
62
  }
63
+ function redactArgsForTool(value, tool) {
64
+ return redactArgs(value, 0, REDACTION_FIELDS_BY_TOOL.get(tool));
65
+ }
62
66
  /** Mask a session id for logging — first 8 chars, suffix elided. */
63
67
  function maskSessionId(id) {
64
68
  if (typeof id !== 'string' || id.length <= 8)
@@ -75,7 +79,7 @@ function emitAuditEntry(entry) {
75
79
  const masked = {
76
80
  ...entry,
77
81
  sessionId: maskSessionId(entry.sessionId),
78
- args: redactArgs(entry.args, 0, EXACT_FIELD_TOOLS.has(entry.tool)),
82
+ args: redactArgsForTool(entry.args, entry.tool),
79
83
  };
80
84
  harper_logger_ts_1.default.info({ category: 'mcp.audit', ...masked });
81
85
  }
@@ -1 +1 @@
1
- {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../../components/mcp/audit.ts"],"names":[],"mappings":";;;;;AAgDA,gCAeC;AAGD,sCAGC;AAOD,wCAaC;AAzFD;;;;;;;;;;;GAWG;AACH,8FAAkE;AAclE,MAAM,iBAAiB,GAAG,wDAAwD,CAAC;AACnF,mGAAmG;AACnG,mGAAmG;AACnG,gGAAgG;AAChG,qFAAqF;AACrF,MAAM,sBAAsB,GAAG,4BAA4B,CAAC;AAC5D,8FAA8F;AAC9F,+FAA+F;AAC/F,+FAA+F;AAC/F,kGAAkG;AAClG,gGAAgG;AAChG,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;AACnE,MAAM,qBAAqB,GAAG,YAAY,CAAC;AAC3C,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B;;;;;;GAMG;AACH,SAAgB,UAAU,CAAC,KAAc,EAAE,KAAK,GAAG,CAAC,EAAE,iBAAiB,GAAG,KAAK;IAC9E,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC9D,IAAI,KAAK,GAAG,mBAAmB;QAAE,OAAO,qBAAqB,CAAC;IAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5C,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,IAAI,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACxF,GAAG,CAAC,CAAC,CAAC,GAAG,qBAAqB,CAAC;QAChC,CAAC;aAAM,CAAC;YACP,GAAG,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,iBAAiB,CAAC,CAAC;QACtD,CAAC;IACF,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,oEAAoE;AACpE,SAAgB,aAAa,CAAC,EAAU;IACvC,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACxD,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC;AAC7B,CAAC;AAED;;;;GAIG;AACH,SAAgB,cAAc,CAAC,KAAiB;IAC/C,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG;YACd,GAAG,KAAK;YACR,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC,SAAS,CAAC;YACzC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;SAClE,CAAC;QACF,0BAAY,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,uEAAuE;QACvE,0EAA0E;QAC1E,0BAAY,CAAC,KAAK,CAAC,0BAA2B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IACxE,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../../components/mcp/audit.ts"],"names":[],"mappings":"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"}
@@ -22,11 +22,17 @@
22
22
  * duration of a restore, and briefly by `dropDatabase` so the two serialize on the same primitive.
23
23
  * Known limitation: the lock is owned by the process, so if the restore job's worker *thread*
24
24
  * dies without the process exiting, the lock stays held (restores 409) until Harper restarts.
25
- * - `<meta-dir>/<key>.restoring` — the completion marker. Written (and fsynced) after the lock is
26
- * acquired and before the destructive restore begins; deleted only after the restore completes
27
- * successfully, while still holding the lock. Its *existence* means "a restore started and has
28
- * not finished successfully". Its first line records the database directory name so the startup
29
- * scan can map a marker back to the database it blocks without decoding the hashed key.
25
+ * - `<meta-dir>/<key>.restoring` — the completion marker. Published (temp → fsync → rename → parent
26
+ * fsync) after the lock is acquired and before the destructive restore begins; deleted only after
27
+ * the restore completes successfully, while still holding the lock. Its *existence* means "a
28
+ * restore started and has not finished successfully". Its first line records the database
29
+ * directory name as a fallback so the startup scan can map a marker whose database directory is
30
+ * missing without decoding the hashed key.
31
+ *
32
+ * The rename is what makes the marker trustworthy: the marker path only ever holds the previous
33
+ * content or the complete new content, so a torn write can never replace a valid marker with one
34
+ * the scan reads as empty (and therefore honors as no block). An intact marker is also never
35
+ * rewritten at all — see `beginRestore`.
30
36
  */
31
37
  export declare const RESTORE_META_DIR = "`restore`";
32
38
  export declare const RESTORE_LOCK_SUFFIX = ".lock";
@@ -91,10 +97,15 @@ export declare function acquireRestoreLock(dbPath: string): RestoreLock;
91
97
  */
92
98
  export declare function releaseRestoreLock(lock: RestoreLock): void;
93
99
  /**
94
- * Acquire the per-database restore lock and write the restoring marker. Call before any
100
+ * Acquire the per-database restore lock and ensure the restoring marker is in place. Call before any
95
101
  * destructive step. Returns the lock (with `preexisting` set when a marker was already present, so
96
102
  * a failed recovery attempt knows not to clear it). Throws (statusCode 409) if another restore
97
103
  * already holds the lock.
104
+ *
105
+ * An intact marker is left exactly as it is. A recovery attempt runs over a directory an earlier
106
+ * restore may have half-purged, so the marker it finds is the only thing keeping that directory
107
+ * from loading as healthy; rewriting it buys nothing (the content it would write is the content
108
+ * already there) and risks everything.
98
109
  */
99
110
  export declare function beginRestore(dbPath: string): RestoreLock;
100
111
  /**
@@ -114,8 +125,10 @@ export declare function abandonRestore(lock: RestoreLock): void;
114
125
  */
115
126
  export declare function clearRestoreMarker(lock: RestoreLock): void;
116
127
  /**
117
- * Scan a databases root's reserved `` `restore` `` metadata directory and report every database currently blocked from
118
- * loading, mapping each surviving marker back to its database name via the marker's first line.
128
+ * Scan a databases root's reserved `` `restore` `` metadata directory and report every database
129
+ * currently blocked from loading. Existing database entries are mapped to markers by their hashed
130
+ * keys, so corrupt marker contents cannot unblock them; the first line remains the fallback for a
131
+ * marker whose database directory is missing.
119
132
  * Returns `[dbName, state]` pairs for markers whose state is `in-progress` or `incomplete`
120
133
  * (a `clear` result means the marker was removed concurrently and the database is loadable).
121
134
  */
@@ -41,17 +41,26 @@ const rocksdb_js_1 = require("@harperfast/rocksdb-js");
41
41
  * duration of a restore, and briefly by `dropDatabase` so the two serialize on the same primitive.
42
42
  * Known limitation: the lock is owned by the process, so if the restore job's worker *thread*
43
43
  * dies without the process exiting, the lock stays held (restores 409) until Harper restarts.
44
- * - `<meta-dir>/<key>.restoring` — the completion marker. Written (and fsynced) after the lock is
45
- * acquired and before the destructive restore begins; deleted only after the restore completes
46
- * successfully, while still holding the lock. Its *existence* means "a restore started and has
47
- * not finished successfully". Its first line records the database directory name so the startup
48
- * scan can map a marker back to the database it blocks without decoding the hashed key.
44
+ * - `<meta-dir>/<key>.restoring` — the completion marker. Published (temp → fsync → rename → parent
45
+ * fsync) after the lock is acquired and before the destructive restore begins; deleted only after
46
+ * the restore completes successfully, while still holding the lock. Its *existence* means "a
47
+ * restore started and has not finished successfully". Its first line records the database
48
+ * directory name as a fallback so the startup scan can map a marker whose database directory is
49
+ * missing without decoding the hashed key.
50
+ *
51
+ * The rename is what makes the marker trustworthy: the marker path only ever holds the previous
52
+ * content or the complete new content, so a torn write can never replace a valid marker with one
53
+ * the scan reads as empty (and therefore honors as no block). An intact marker is also never
54
+ * rewritten at all — see `beginRestore`.
49
55
  */
50
56
  // The backtick makes this an illegal database name (schemaRegex rejects `/` and backtick only), so
51
57
  // it can never collide with a real database directory — see the module header.
52
58
  exports.RESTORE_META_DIR = '`restore`';
53
59
  exports.RESTORE_LOCK_SUFFIX = '.lock';
54
60
  exports.RESTORING_MARKER_SUFFIX = '.restoring';
61
+ // Deliberately not a `.restoring` suffix: `scanBlockedRestores` selects markers by that suffix, and
62
+ // a half-written temp must never be mistaken for one.
63
+ const MARKER_TEMP_SUFFIX = '.tmp';
55
64
  /**
56
65
  * Directory holding the restore metadata for a database — the reserved `` `restore` `` sibling of
57
66
  * the database directory (see the module header for why the name contains a backtick). Shared by
@@ -159,17 +168,29 @@ function releaseRestoreLock(lock) {
159
168
  (0, rocksdb_js_1.fileLockRelease)(lock.token);
160
169
  }
161
170
  /**
162
- * Acquire the per-database restore lock and write the restoring marker. Call before any
163
- * destructive step. Returns the lock (with `preexisting` set when a marker was already present, so
164
- * a failed recovery attempt knows not to clear it). Throws (statusCode 409) if another restore
165
- * already holds the lock.
171
+ * Whether a marker on disk still blocks the database it belongs to. `scanBlockedRestores` maps a
172
+ * marker to a database by its first line, so the line has to be the whole name: a torn write that
173
+ * left a prefix of it ("ord" for "orders") is non-empty and reads as valid, but blocks a database
174
+ * that does not exist while the real one loads.
166
175
  */
167
- function beginRestore(dbPath) {
168
- const markerPath = restoringMarkerPath(dbPath);
169
- const preexisting = (0, node_fs_1.existsSync)(markerPath);
170
- const lock = acquireRestoreLock(dbPath);
176
+ function markerIsIntact(markerPath, dbPath) {
171
177
  try {
172
- const fd = (0, node_fs_1.openSync)(markerPath, 'w');
178
+ return (0, node_fs_1.readFileSync)(markerPath, 'utf8').split('\n', 1)[0] === (0, node_path_1.basename)(dbPath);
179
+ }
180
+ catch {
181
+ return false;
182
+ }
183
+ }
184
+ /**
185
+ * Publish the restoring marker atomically. The caller must already hold the restore lock, which is
186
+ * what makes the fixed temp name safe: only one writer per database can exist at a time, so a temp
187
+ * left by an earlier crash is this database's own debris and is simply overwritten.
188
+ */
189
+ function publishRestoringMarker(dbPath) {
190
+ const metaDir = restoreMetaDir(dbPath);
191
+ const tempPath = (0, node_path_1.join)(metaDir, restoreMetaKey(dbPath) + MARKER_TEMP_SUFFIX);
192
+ try {
193
+ const fd = (0, node_fs_1.openSync)(tempPath, 'w');
173
194
  try {
174
195
  // first line is the database directory name so the startup scan can map this marker back to
175
196
  // the database it blocks without reversing the hashed key
@@ -179,9 +200,47 @@ function beginRestore(dbPath) {
179
200
  finally {
180
201
  (0, node_fs_1.closeSync)(fd);
181
202
  }
182
- // fsync the metadata directory so the marker's directory entry is durable — without this a
183
- // power loss can lose the entry, and a half-purged database would load as healthy
184
- fsyncDir(restoreMetaDir(dbPath));
203
+ (0, node_fs_1.renameSync)(tempPath, restoringMarkerPath(dbPath));
204
+ }
205
+ catch (error) {
206
+ try {
207
+ (0, node_fs_1.unlinkSync)(tempPath);
208
+ }
209
+ catch {
210
+ // debris either way; the write failure is the error worth reporting
211
+ }
212
+ throw error;
213
+ }
214
+ // fsync the metadata directory so the marker's directory entry is durable — without this a
215
+ // power loss can lose the entry, and a half-purged database would load as healthy
216
+ fsyncDir(metaDir);
217
+ }
218
+ /**
219
+ * Acquire the per-database restore lock and ensure the restoring marker is in place. Call before any
220
+ * destructive step. Returns the lock (with `preexisting` set when a marker was already present, so
221
+ * a failed recovery attempt knows not to clear it). Throws (statusCode 409) if another restore
222
+ * already holds the lock.
223
+ *
224
+ * An intact marker is left exactly as it is. A recovery attempt runs over a directory an earlier
225
+ * restore may have half-purged, so the marker it finds is the only thing keeping that directory
226
+ * from loading as healthy; rewriting it buys nothing (the content it would write is the content
227
+ * already there) and risks everything.
228
+ */
229
+ function beginRestore(dbPath) {
230
+ const markerPath = restoringMarkerPath(dbPath);
231
+ const lock = acquireRestoreLock(dbPath);
232
+ // Sampled while holding the lock, not before it: a restore that waited out an earlier one would
233
+ // otherwise carry the earlier run's "no marker" reading, and on its own pre-destruction failure
234
+ // clear the marker protecting a directory that run had already half-purged.
235
+ const preexisting = (0, node_fs_1.existsSync)(markerPath);
236
+ try {
237
+ if (!preexisting || !markerIsIntact(markerPath, dbPath))
238
+ publishRestoringMarker(dbPath);
239
+ // An intact marker is kept, but its durability is not assumed: the publisher that wrote it may
240
+ // have been interrupted between the rename and this flush, which would leave the directory
241
+ // entry — the thing the startup scan reads — still only in the page cache.
242
+ else
243
+ fsyncDir(restoreMetaDir(dbPath));
185
244
  }
186
245
  catch (error) {
187
246
  (0, rocksdb_js_1.fileLockRelease)(lock.token);
@@ -230,8 +289,10 @@ function clearRestoreMarker(lock) {
230
289
  }
231
290
  }
232
291
  /**
233
- * Scan a databases root's reserved `` `restore` `` metadata directory and report every database currently blocked from
234
- * loading, mapping each surviving marker back to its database name via the marker's first line.
292
+ * Scan a databases root's reserved `` `restore` `` metadata directory and report every database
293
+ * currently blocked from loading. Existing database entries are mapped to markers by their hashed
294
+ * keys, so corrupt marker contents cannot unblock them; the first line remains the fallback for a
295
+ * marker whose database directory is missing.
235
296
  * Returns `[dbName, state]` pairs for markers whose state is `in-progress` or `incomplete`
236
297
  * (a `clear` result means the marker was removed concurrently and the database is loadable).
237
298
  */
@@ -239,19 +300,25 @@ function scanBlockedRestores(databasesRoot) {
239
300
  const metaDir = (0, node_path_1.join)(databasesRoot, exports.RESTORE_META_DIR);
240
301
  if (!(0, node_fs_1.existsSync)(metaDir))
241
302
  return [];
303
+ const databaseNamesByMarker = new Map((0, node_fs_1.readdirSync)(databasesRoot, { withFileTypes: true })
304
+ .filter((entry) => entry.name !== exports.RESTORE_META_DIR)
305
+ .map((entry) => [restoreMetaKey((0, node_path_1.join)(databasesRoot, entry.name)) + exports.RESTORING_MARKER_SUFFIX, entry.name]));
242
306
  const blocked = [];
243
307
  for (const entry of (0, node_fs_1.readdirSync)(metaDir, { withFileTypes: true })) {
244
308
  if (!entry.isFile() || !entry.name.endsWith(exports.RESTORING_MARKER_SUFFIX))
245
309
  continue;
246
- let dbName;
247
- try {
248
- dbName = (0, node_fs_1.readFileSync)((0, node_path_1.join)(metaDir, entry.name), 'utf8').split('\n', 1)[0];
249
- }
250
- catch {
251
- continue; // marker removed concurrently
310
+ const markerPath = (0, node_path_1.join)(metaDir, entry.name);
311
+ let dbName = databaseNamesByMarker.get(entry.name);
312
+ if (!dbName) {
313
+ try {
314
+ dbName = (0, node_fs_1.readFileSync)(markerPath, 'utf8').split('\n', 1)[0];
315
+ }
316
+ catch {
317
+ continue; // marker removed concurrently
318
+ }
319
+ if (!dbName || restoringMarkerPath((0, node_path_1.join)(databasesRoot, dbName)) !== markerPath)
320
+ continue;
252
321
  }
253
- if (!dbName)
254
- continue;
255
322
  const state = checkRestoreState((0, node_path_1.join)(databasesRoot, dbName));
256
323
  if (state !== 'clear')
257
324
  blocked.push([dbName, state]);
@@ -1 +1 @@
1
- {"version":3,"file":"restoreMarker.js","sourceRoot":"","sources":["../../dataLayer/restoreMarker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"restoreMarker.js","sourceRoot":"","sources":["../../dataLayer/restoreMarker.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export { RequestTarget } from './resources/RequestTarget.ts';
2
2
  export { flushDatabases } from './resources/databases.ts';
3
3
  export { registerReplicatedApplyFailureListener, unregisterReplicatedApplyFailureListener, type ReplicatedApplyFailure, type ReplicatedApplyFailureListener, } from './resources/replicatedApplyFailure.ts';
4
4
  export { getContext, getResponse, getUser } from './security/jsLoader.ts';
5
+ export { markCredentialRejection, credentialRejectionError } from './security/credentialRejection.ts';
5
6
  export { defineTable, types } from './resources/defineTable.ts';
6
7
  export { defineResource, t, schemaOf, projectTableFragment } from './resources/defineResource.ts';
7
8
  export type { Query, Context, Session, SourceContext, SubscriptionRequest, RecordLockOptions, RequestTargetOrId, ResourceInterface, WritableRecord, } from './resources/ResourceInterface.ts';
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.projectTableFragment = exports.schemaOf = exports.t = exports.defineResource = exports.types = exports.defineTable = exports.getUser = exports.getResponse = exports.getContext = exports.unregisterReplicatedApplyFailureListener = exports.registerReplicatedApplyFailureListener = exports.flushDatabases = exports.RequestTarget = void 0;
6
+ exports.projectTableFragment = exports.schemaOf = exports.t = exports.defineResource = exports.types = exports.defineTable = exports.credentialRejectionError = exports.markCredentialRejection = exports.getUser = exports.getResponse = exports.getContext = exports.unregisterReplicatedApplyFailureListener = exports.registerReplicatedApplyFailureListener = exports.flushDatabases = exports.RequestTarget = void 0;
7
7
  // Prevents server from starting in worker threads if this was directly imported from a non-server user thread
8
8
  const node_worker_threads_1 = __importDefault(require("node:worker_threads"));
9
9
  if (!node_worker_threads_1.default.isMainThread) {
@@ -24,6 +24,11 @@ var jsLoader_ts_1 = require("./security/jsLoader.js");
24
24
  Object.defineProperty(exports, "getContext", { enumerable: true, get: function () { return jsLoader_ts_1.getContext; } });
25
25
  Object.defineProperty(exports, "getResponse", { enumerable: true, get: function () { return jsLoader_ts_1.getResponse; } });
26
26
  Object.defineProperty(exports, "getUser", { enumerable: true, get: function () { return jsLoader_ts_1.getUser; } });
27
+ // An untagged error from a `server.getUser` override is treated as an internal fault; these tag one
28
+ // as a rejected credential, which authentication defers to the route owner instead (#2703).
29
+ var credentialRejection_ts_1 = require("./security/credentialRejection.js");
30
+ Object.defineProperty(exports, "markCredentialRejection", { enumerable: true, get: function () { return credentialRejection_ts_1.markCredentialRejection; } });
31
+ Object.defineProperty(exports, "credentialRejectionError", { enumerable: true, get: function () { return credentialRejection_ts_1.credentialRejectionError; } });
27
32
  // Code-first schema authoring: declare a table as a TypeScript value; the returned
28
33
  // handle is the live, registered table class with per-verb shapes inferred from the definition.
29
34
  var defineTable_ts_1 = require("./resources/defineTable.js");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;AAAA,8GAA8G;AAC9G,8EAAgD;AAChD,IAAI,CAAC,6BAAa,CAAC,YAAY,EAAE,CAAC;IACjC,4GAA4G;IAC5G,IAAI,CAAC,6BAAa,CAAC,UAAU;QAAE,6BAAa,CAAC,UAAU,GAAG,EAAE,CAAC;IAC7D,6BAAa,CAAC,UAAU,CAAC,aAAa,GAAG,IAAI,CAAC;AAC/C,CAAC;AAED,oGAAoG;AACpG,iEAA6D;AAApD,iHAAA,aAAa,OAAA;AACtB,yDAA0D;AAAjD,8GAAA,cAAc,OAAA;AACvB,mFAK+C;AAJ9C,mJAAA,sCAAsC,OAAA;AACtC,qJAAA,wCAAwC,OAAA;AAIzC,sDAA0E;AAAjE,yGAAA,UAAU,OAAA;AAAE,0GAAA,WAAW,OAAA;AAAE,sGAAA,OAAO,OAAA;AACzC,mFAAmF;AACnF,gGAAgG;AAChG,6DAAgE;AAAvD,6GAAA,WAAW,OAAA;AAAE,uGAAA,KAAK,OAAA;AAE3B,+EAA+E;AAC/E,qGAAqG;AACrG,2FAA2F;AAC3F,mEAAkG;AAAzF,mHAAA,cAAc,OAAA;AAAE,sGAAA,CAAC,OAAA;AAAE,6GAAA,QAAQ,OAAA;AAAE,yHAAA,oBAAoB,OAAA;AAyJ1D,oEAAoE;AACpE,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;AAC5B,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;AAC/B,OAAO,CAAC,SAAS,GAAG,EAAE,CAAC;AACvB,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC;AACpB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;AAC3B,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;AAC9B,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;AAC7B,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;AAC5B,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC;AACpB,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC;AACpB,OAAO,CAAC,OAAO,GAAG,EAAE,CAAC;AACrB,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;AAEhC,yCAAyC;AACzC,gGAAgG;AAChG,oDAAoD;AACpD,sEAA2D;AAE3D,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,yBAAO,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;AAAA,8GAA8G;AAC9G,8EAAgD;AAChD,IAAI,CAAC,6BAAa,CAAC,YAAY,EAAE,CAAC;IACjC,4GAA4G;IAC5G,IAAI,CAAC,6BAAa,CAAC,UAAU;QAAE,6BAAa,CAAC,UAAU,GAAG,EAAE,CAAC;IAC7D,6BAAa,CAAC,UAAU,CAAC,aAAa,GAAG,IAAI,CAAC;AAC/C,CAAC;AAED,oGAAoG;AACpG,iEAA6D;AAApD,iHAAA,aAAa,OAAA;AACtB,yDAA0D;AAAjD,8GAAA,cAAc,OAAA;AACvB,mFAK+C;AAJ9C,mJAAA,sCAAsC,OAAA;AACtC,qJAAA,wCAAwC,OAAA;AAIzC,sDAA0E;AAAjE,yGAAA,UAAU,OAAA;AAAE,0GAAA,WAAW,OAAA;AAAE,sGAAA,OAAO,OAAA;AACzC,oGAAoG;AACpG,4FAA4F;AAC5F,4EAAsG;AAA7F,iIAAA,uBAAuB,OAAA;AAAE,kIAAA,wBAAwB,OAAA;AAC1D,mFAAmF;AACnF,gGAAgG;AAChG,6DAAgE;AAAvD,6GAAA,WAAW,OAAA;AAAE,uGAAA,KAAK,OAAA;AAE3B,+EAA+E;AAC/E,qGAAqG;AACrG,2FAA2F;AAC3F,mEAAkG;AAAzF,mHAAA,cAAc,OAAA;AAAE,sGAAA,CAAC,OAAA;AAAE,6GAAA,QAAQ,OAAA;AAAE,yHAAA,oBAAoB,OAAA;AAyJ1D,oEAAoE;AACpE,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;AAC5B,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;AAC/B,OAAO,CAAC,SAAS,GAAG,EAAE,CAAC;AACvB,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC;AACpB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;AAC3B,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;AAC9B,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;AAC7B,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;AAC5B,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC;AACpB,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC;AACpB,OAAO,CAAC,OAAO,GAAG,EAAE,CAAC;AACrB,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;AAEhC,yCAAyC;AACzC,gGAAgG;AAChG,oDAAoD;AACpD,sEAA2D;AAE3D,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,yBAAO,CAAC,CAAC"}