@korajs/core 1.0.0-beta.0 → 1.0.0-beta.1

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.cjs CHANGED
@@ -38,6 +38,7 @@ __export(index_exports, {
38
38
  MergeConflictError: () => MergeConflictError,
39
39
  MigrationBuilder: () => MigrationBuilder,
40
40
  MigrationRollbackError: () => MigrationRollbackError,
41
+ MissingSecretKeyError: () => MissingSecretKeyError,
41
42
  OperationError: () => OperationError,
42
43
  RemoteClockDriftError: () => RemoteClockDriftError,
43
44
  RollbackBuilder: () => RollbackBuilder,
@@ -54,16 +55,19 @@ __export(index_exports, {
54
55
  collectSchemaScopeFields: () => collectSchemaScopeFields,
55
56
  collectSchemaScopeValueKeys: () => collectSchemaScopeValueKeys,
56
57
  computeDelta: () => computeDelta,
58
+ createBlobRef: () => createBlobRef,
57
59
  createOperation: () => createOperation,
58
60
  createReversibleMigration: () => createReversibleMigration,
59
61
  createVersionVector: () => createVersionVector,
60
62
  decodeBytesFromOpData: () => decodeBytesFromOpData,
63
+ decryptSecret: () => decryptSecret,
61
64
  defaultApplyFailureReason: () => defaultApplyFailureReason,
62
65
  defaultSequenceFormat: () => defaultSequenceFormat,
63
66
  defineSchema: () => defineSchema,
64
67
  deserializeVector: () => deserializeVector,
65
68
  dominates: () => dominates,
66
69
  encodeBytesForOpData: () => encodeBytesForOpData,
70
+ encryptSecret: () => encryptSecret,
67
71
  extractScopeValuesFromClaims: () => extractScopeValuesFromClaims,
68
72
  extractTimestamp: () => extractTimestamp,
69
73
  formatSequenceValue: () => formatSequenceValue,
@@ -76,8 +80,11 @@ __export(index_exports, {
76
80
  getKoraErrorFix: () => getKoraErrorFix,
77
81
  getTransitionMap: () => getTransitionMap,
78
82
  hasSchemaSyncRules: () => hasSchemaSyncRules,
83
+ hashBlob: () => hashBlob,
84
+ hashSecret: () => hashSecret,
79
85
  isApplyFailure: () => isApplyFailure,
80
86
  isAtomicOp: () => isAtomicOp,
87
+ isBlobRef: () => isBlobRef,
81
88
  isCollectionSyncScoped: () => isCollectionSyncScoped,
82
89
  isKoraBytesValue: () => isKoraBytesValue,
83
90
  isLegacyNumericByteObject: () => isLegacyNumericByteObject,
@@ -88,14 +95,18 @@ __export(index_exports, {
88
95
  migrationStepsToSQL: () => migrationStepsToSQL,
89
96
  op: () => op,
90
97
  resolveAtomicOp: () => resolveAtomicOp,
98
+ revealSecret: () => revealSecret,
91
99
  rollbackStepsToSQL: () => rollbackStepsToSQL,
92
100
  serializeVector: () => serializeVector,
93
101
  t: () => t,
94
102
  toAtomicOp: () => toAtomicOp,
103
+ transformSecretFieldsForWrite: () => transformSecretFieldsForWrite,
95
104
  validateRecord: () => validateRecord,
96
105
  validateTransition: () => validateTransition,
97
106
  vectorsEqual: () => vectorsEqual,
98
- verifyOperationIntegrity: () => verifyOperationIntegrity
107
+ verifyOperationIntegrity: () => verifyOperationIntegrity,
108
+ verifySecret: () => verifySecret,
109
+ verifySecretValue: () => verifySecretValue
99
110
  });
100
111
  module.exports = __toCommonJS(index_exports);
101
112
 
@@ -534,6 +545,226 @@ function formatUUID(bytes) {
534
545
  return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
535
546
  }
536
547
 
548
+ // src/blob/blob-ref.ts
549
+ async function hashBlob(bytes) {
550
+ const view = new Uint8Array(bytes.byteLength);
551
+ view.set(bytes);
552
+ const digest = await globalThis.crypto.subtle.digest("SHA-256", view);
553
+ const out = new Uint8Array(digest);
554
+ return Array.from(out, (b) => b.toString(16).padStart(2, "0")).join("");
555
+ }
556
+ async function createBlobRef(bytes, metadata = {}) {
557
+ const hash = await hashBlob(bytes);
558
+ const ref = { hash, size: bytes.byteLength };
559
+ if (metadata.mimeType !== void 0) {
560
+ ref.mimeType = metadata.mimeType;
561
+ }
562
+ if (metadata.filename !== void 0) {
563
+ ref.filename = metadata.filename;
564
+ }
565
+ return ref;
566
+ }
567
+ function isBlobRef(value) {
568
+ if (typeof value !== "object" || value === null) {
569
+ return false;
570
+ }
571
+ const ref = value;
572
+ if (typeof ref.hash !== "string" || !/^[0-9a-f]{64}$/.test(ref.hash)) {
573
+ return false;
574
+ }
575
+ if (typeof ref.size !== "number" || !Number.isInteger(ref.size) || ref.size < 0) {
576
+ return false;
577
+ }
578
+ if (ref.mimeType !== void 0 && typeof ref.mimeType !== "string") {
579
+ return false;
580
+ }
581
+ if (ref.filename !== void 0 && typeof ref.filename !== "string") {
582
+ return false;
583
+ }
584
+ if (ref.manifestHash !== void 0 && (typeof ref.manifestHash !== "string" || !/^[0-9a-f]{64}$/.test(ref.manifestHash))) {
585
+ return false;
586
+ }
587
+ return true;
588
+ }
589
+
590
+ // src/secret/secret-crypto.ts
591
+ var PBKDF2_ITERATIONS = 21e4;
592
+ var SALT_BYTES = 16;
593
+ var IV_BYTES = 12;
594
+ var HASH_BYTES = 32;
595
+ function toHex(bytes) {
596
+ return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
597
+ }
598
+ function fromHex(hex) {
599
+ if (hex.length % 2 !== 0 || /[^0-9a-f]/i.test(hex)) {
600
+ throw new Error("Invalid hex string");
601
+ }
602
+ const out = new Uint8Array(hex.length / 2);
603
+ for (let i = 0; i < out.length; i++) {
604
+ out[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
605
+ }
606
+ return out;
607
+ }
608
+ function randomBytes(n) {
609
+ const out = new Uint8Array(n);
610
+ globalThis.crypto.getRandomValues(out);
611
+ return out;
612
+ }
613
+ function timingSafeEqual(a, b) {
614
+ if (a.length !== b.length) {
615
+ return false;
616
+ }
617
+ let diff = 0;
618
+ for (let i = 0; i < a.length; i++) {
619
+ diff |= a[i] ^ b[i];
620
+ }
621
+ return diff === 0;
622
+ }
623
+ async function deriveAesKey(secretKey, salt) {
624
+ const baseKey = await globalThis.crypto.subtle.importKey(
625
+ "raw",
626
+ new TextEncoder().encode(secretKey),
627
+ "PBKDF2",
628
+ false,
629
+ ["deriveKey"]
630
+ );
631
+ return globalThis.crypto.subtle.deriveKey(
632
+ { name: "PBKDF2", salt, iterations: PBKDF2_ITERATIONS, hash: "SHA-256" },
633
+ baseKey,
634
+ { name: "AES-GCM", length: 256 },
635
+ false,
636
+ ["encrypt", "decrypt"]
637
+ );
638
+ }
639
+ async function encryptSecret(plaintext, secretKey) {
640
+ const salt = randomBytes(SALT_BYTES);
641
+ const iv = randomBytes(IV_BYTES);
642
+ const key = await deriveAesKey(secretKey, salt);
643
+ const ciphertext = await globalThis.crypto.subtle.encrypt(
644
+ { name: "AES-GCM", iv },
645
+ key,
646
+ new TextEncoder().encode(plaintext)
647
+ );
648
+ return `v1.${toHex(salt)}.${toHex(iv)}.${toHex(new Uint8Array(ciphertext))}`;
649
+ }
650
+ async function decryptSecret(encrypted, secretKey) {
651
+ const parts = encrypted.split(".");
652
+ if (parts.length !== 4 || parts[0] !== "v1") {
653
+ throw new Error("Invalid encrypted secret format");
654
+ }
655
+ const salt = fromHex(parts[1]);
656
+ const iv = fromHex(parts[2]);
657
+ const ciphertext = fromHex(parts[3]);
658
+ const key = await deriveAesKey(secretKey, salt);
659
+ const plaintext = await globalThis.crypto.subtle.decrypt(
660
+ { name: "AES-GCM", iv },
661
+ key,
662
+ ciphertext
663
+ );
664
+ return new TextDecoder().decode(plaintext);
665
+ }
666
+ async function hashSecret(plaintext) {
667
+ const salt = randomBytes(SALT_BYTES);
668
+ const hash = await pbkdf2(plaintext, salt);
669
+ return `v1.${toHex(salt)}.${toHex(hash)}`;
670
+ }
671
+ async function verifySecret(plaintext, stored) {
672
+ const parts = stored.split(".");
673
+ if (parts.length !== 3 || parts[0] !== "v1") {
674
+ return false;
675
+ }
676
+ let salt;
677
+ let expected;
678
+ try {
679
+ salt = fromHex(parts[1]);
680
+ expected = fromHex(parts[2]);
681
+ } catch {
682
+ return false;
683
+ }
684
+ const actual = await pbkdf2(plaintext, salt);
685
+ return timingSafeEqual(actual, expected);
686
+ }
687
+ async function pbkdf2(plaintext, salt) {
688
+ const baseKey = await globalThis.crypto.subtle.importKey(
689
+ "raw",
690
+ new TextEncoder().encode(plaintext),
691
+ "PBKDF2",
692
+ false,
693
+ ["deriveBits"]
694
+ );
695
+ const bits = await globalThis.crypto.subtle.deriveBits(
696
+ { name: "PBKDF2", salt, iterations: PBKDF2_ITERATIONS, hash: "SHA-256" },
697
+ baseKey,
698
+ HASH_BYTES * 8
699
+ );
700
+ return new Uint8Array(bits);
701
+ }
702
+
703
+ // src/secret/secret-transform.ts
704
+ var MissingSecretKeyError = class extends Error {
705
+ constructor(field) {
706
+ super(
707
+ `Secret field "${field}" is encrypted but no encryption key is configured. Provide sync.encryption.key (or a key provider) to createApp.`
708
+ );
709
+ this.field = field;
710
+ this.name = "MissingSecretKeyError";
711
+ }
712
+ field;
713
+ };
714
+ async function resolveKey(provider) {
715
+ if (!provider) {
716
+ return void 0;
717
+ }
718
+ return provider();
719
+ }
720
+ async function transformSecretFieldsForWrite(data, collectionDef, keyProvider) {
721
+ const hasSecret = Object.values(collectionDef.fields).some((f) => f.kind === "secret");
722
+ if (!hasSecret) {
723
+ return data;
724
+ }
725
+ const result = { ...data };
726
+ let key;
727
+ let keyResolved = false;
728
+ for (const [field, value] of Object.entries(data)) {
729
+ const descriptor = collectionDef.fields[field];
730
+ if (descriptor?.kind !== "secret") {
731
+ continue;
732
+ }
733
+ if (typeof value !== "string") {
734
+ continue;
735
+ }
736
+ const mode = descriptor.secretMode ?? "encrypted";
737
+ if (mode === "hashed") {
738
+ result[field] = await hashSecret(value);
739
+ continue;
740
+ }
741
+ if (!keyResolved) {
742
+ key = await resolveKey(keyProvider);
743
+ keyResolved = true;
744
+ }
745
+ if (key === void 0) {
746
+ throw new MissingSecretKeyError(field);
747
+ }
748
+ result[field] = await encryptSecret(value, key);
749
+ }
750
+ return result;
751
+ }
752
+ async function revealSecret(storedValue, mode, keyProvider, field = "secret") {
753
+ if (mode === "hashed") {
754
+ throw new Error(
755
+ `Secret field "${field}" is hashed (one-way) and cannot be revealed. Use verifySecretValue to check a candidate.`
756
+ );
757
+ }
758
+ const key = await resolveKey(keyProvider);
759
+ if (key === void 0) {
760
+ throw new MissingSecretKeyError(field);
761
+ }
762
+ return decryptSecret(storedValue, key);
763
+ }
764
+ async function verifySecretValue(candidate, storedValue) {
765
+ return verifySecret(candidate, storedValue);
766
+ }
767
+
537
768
  // src/operations/apply-result.ts
538
769
  var APPLY_RESULTS = ["applied", "duplicate", "skipped", "rejected", "deferred"];
539
770
  var APPLY_FAILURE_CODES = {
@@ -1465,6 +1696,17 @@ function mapFieldType(descriptor) {
1465
1696
  case "array":
1466
1697
  return "TEXT";
1467
1698
  // JSON-serialized
1699
+ case "object":
1700
+ return "TEXT";
1701
+ // JSON-serialized structured object
1702
+ case "json":
1703
+ return "TEXT";
1704
+ // JSON-serialized dynamic-key value
1705
+ case "blob":
1706
+ return "TEXT";
1707
+ // JSON-serialized content-addressed BlobRef (bytes stored out of band)
1708
+ case "secret":
1709
+ return "TEXT";
1468
1710
  case "richtext":
1469
1711
  return "BLOB";
1470
1712
  }
@@ -1698,6 +1940,160 @@ var ArrayFieldBuilder = class _ArrayFieldBuilder extends FieldBuilder {
1698
1940
  };
1699
1941
  }
1700
1942
  };
1943
+ var ObjectFieldBuilder = class _ObjectFieldBuilder extends FieldBuilder {
1944
+ _fields;
1945
+ constructor(fields, required = true, defaultValue = void 0, auto = false, mergeStrategy = null) {
1946
+ super("object", required, defaultValue, auto, mergeStrategy);
1947
+ this._fields = fields;
1948
+ }
1949
+ optional() {
1950
+ return new _ObjectFieldBuilder(
1951
+ this._fields,
1952
+ false,
1953
+ this._defaultValue,
1954
+ this._auto,
1955
+ this._mergeStrategy
1956
+ );
1957
+ }
1958
+ default(value) {
1959
+ return new _ObjectFieldBuilder(this._fields, false, value, this._auto, this._mergeStrategy);
1960
+ }
1961
+ auto() {
1962
+ return new _ObjectFieldBuilder(this._fields, false, void 0, true, this._mergeStrategy);
1963
+ }
1964
+ merge(strategy) {
1965
+ return new _ObjectFieldBuilder(
1966
+ this._fields,
1967
+ this._required,
1968
+ this._defaultValue,
1969
+ this._auto,
1970
+ strategy
1971
+ );
1972
+ }
1973
+ _build() {
1974
+ const nestedFields = {};
1975
+ for (const [key, builder] of Object.entries(this._fields)) {
1976
+ nestedFields[key] = builder._build();
1977
+ }
1978
+ return {
1979
+ kind: "object",
1980
+ required: this._required,
1981
+ defaultValue: this._defaultValue,
1982
+ auto: this._auto,
1983
+ enumValues: null,
1984
+ itemKind: null,
1985
+ mergeStrategy: this._mergeStrategy,
1986
+ transitions: null,
1987
+ nestedFields
1988
+ };
1989
+ }
1990
+ };
1991
+ var JsonFieldBuilder = class _JsonFieldBuilder extends FieldBuilder {
1992
+ optional() {
1993
+ return new _JsonFieldBuilder(
1994
+ "json",
1995
+ false,
1996
+ this._defaultValue,
1997
+ this._auto,
1998
+ this._mergeStrategy
1999
+ );
2000
+ }
2001
+ default(value) {
2002
+ return new _JsonFieldBuilder(
2003
+ "json",
2004
+ false,
2005
+ value,
2006
+ this._auto,
2007
+ this._mergeStrategy
2008
+ );
2009
+ }
2010
+ auto() {
2011
+ return new _JsonFieldBuilder("json", false, void 0, true, this._mergeStrategy);
2012
+ }
2013
+ merge(strategy) {
2014
+ return new _JsonFieldBuilder(
2015
+ "json",
2016
+ this._required,
2017
+ this._defaultValue,
2018
+ this._auto,
2019
+ strategy
2020
+ );
2021
+ }
2022
+ _build() {
2023
+ return {
2024
+ kind: "json",
2025
+ required: this._required,
2026
+ defaultValue: this._defaultValue,
2027
+ auto: this._auto,
2028
+ enumValues: null,
2029
+ itemKind: null,
2030
+ mergeStrategy: this._mergeStrategy,
2031
+ transitions: null,
2032
+ nestedFields: null
2033
+ };
2034
+ }
2035
+ };
2036
+ var SecretFieldBuilder = class _SecretFieldBuilder extends FieldBuilder {
2037
+ _secretMode;
2038
+ constructor(secretMode = "encrypted", required = true, defaultValue = void 0, auto = false, mergeStrategy = null) {
2039
+ super("secret", required, defaultValue, auto, mergeStrategy);
2040
+ this._secretMode = secretMode;
2041
+ }
2042
+ /** Store this secret as a one-way salted hash (passwords: verify, never read back). */
2043
+ hashed() {
2044
+ return new _SecretFieldBuilder(
2045
+ "hashed",
2046
+ this._required,
2047
+ this._defaultValue,
2048
+ this._auto,
2049
+ this._mergeStrategy
2050
+ );
2051
+ }
2052
+ /** Store this secret as reversible ciphertext (tokens/keys: decrypt to use). */
2053
+ encrypted() {
2054
+ return new _SecretFieldBuilder(
2055
+ "encrypted",
2056
+ this._required,
2057
+ this._defaultValue,
2058
+ this._auto,
2059
+ this._mergeStrategy
2060
+ );
2061
+ }
2062
+ optional() {
2063
+ return new _SecretFieldBuilder(
2064
+ this._secretMode,
2065
+ false,
2066
+ this._defaultValue,
2067
+ this._auto,
2068
+ this._mergeStrategy
2069
+ );
2070
+ }
2071
+ auto() {
2072
+ return new _SecretFieldBuilder(this._secretMode, false, void 0, true, this._mergeStrategy);
2073
+ }
2074
+ merge(strategy) {
2075
+ return new _SecretFieldBuilder(
2076
+ this._secretMode,
2077
+ this._required,
2078
+ this._defaultValue,
2079
+ this._auto,
2080
+ strategy
2081
+ );
2082
+ }
2083
+ _build() {
2084
+ return {
2085
+ kind: "secret",
2086
+ required: this._required,
2087
+ defaultValue: this._defaultValue,
2088
+ auto: this._auto,
2089
+ enumValues: null,
2090
+ itemKind: null,
2091
+ mergeStrategy: this._mergeStrategy,
2092
+ transitions: null,
2093
+ secretMode: this._secretMode
2094
+ };
2095
+ }
2096
+ };
1701
2097
  var t = {
1702
2098
  string() {
1703
2099
  return new FieldBuilder("string", true, void 0, false);
@@ -1719,6 +2115,18 @@ var t = {
1719
2115
  },
1720
2116
  array(itemBuilder) {
1721
2117
  return new ArrayFieldBuilder(itemBuilder, true, void 0, false);
2118
+ },
2119
+ object(fields) {
2120
+ return new ObjectFieldBuilder(fields, true, void 0, false);
2121
+ },
2122
+ json() {
2123
+ return new JsonFieldBuilder("json", true, void 0, false);
2124
+ },
2125
+ blob() {
2126
+ return new FieldBuilder("blob", true, void 0, false);
2127
+ },
2128
+ secret() {
2129
+ return new SecretFieldBuilder("encrypted", true, void 0, false);
1722
2130
  }
1723
2131
  };
1724
2132
 
@@ -1883,8 +2291,99 @@ function validateFieldValue(collection, fieldName, descriptor, value) {
1883
2291
  }
1884
2292
  break;
1885
2293
  }
2294
+ case "object": {
2295
+ if (!isPlainObject(value)) {
2296
+ throw new SchemaValidationError(
2297
+ `Field "${fieldName}" in collection "${collection}" must be a plain object, got ${describeType(value)}`,
2298
+ {
2299
+ collection,
2300
+ field: fieldName,
2301
+ expectedType: "object",
2302
+ receivedType: describeType(value)
2303
+ }
2304
+ );
2305
+ }
2306
+ if (descriptor.nestedFields) {
2307
+ for (const [nestedName, nestedDescriptor] of Object.entries(descriptor.nestedFields)) {
2308
+ const nestedValue = value[nestedName];
2309
+ if (nestedValue !== void 0 && nestedValue !== null) {
2310
+ validateFieldValue(
2311
+ collection,
2312
+ `${fieldName}.${nestedName}`,
2313
+ nestedDescriptor,
2314
+ nestedValue
2315
+ );
2316
+ }
2317
+ }
2318
+ }
2319
+ break;
2320
+ }
2321
+ case "json": {
2322
+ if (!isJsonSerializable(value)) {
2323
+ throw new SchemaValidationError(
2324
+ `Field "${fieldName}" in collection "${collection}" must be JSON-serializable, got ${describeType(value)}`,
2325
+ { collection, field: fieldName, expectedType: "json", receivedType: describeType(value) }
2326
+ );
2327
+ }
2328
+ break;
2329
+ }
2330
+ case "blob": {
2331
+ if (!isBlobRef(value)) {
2332
+ throw new SchemaValidationError(
2333
+ `Field "${fieldName}" in collection "${collection}" must be a BlobRef (from the blob store), got ${describeType(value)}`,
2334
+ { collection, field: fieldName, expectedType: "blob", receivedType: describeType(value) }
2335
+ );
2336
+ }
2337
+ break;
2338
+ }
2339
+ case "secret": {
2340
+ if (typeof value !== "string") {
2341
+ throw new SchemaValidationError(
2342
+ `Field "${fieldName}" in collection "${collection}" must be a string, got ${describeType(value)}`,
2343
+ {
2344
+ collection,
2345
+ field: fieldName,
2346
+ expectedType: "secret",
2347
+ receivedType: describeType(value)
2348
+ }
2349
+ );
2350
+ }
2351
+ break;
2352
+ }
1886
2353
  }
1887
2354
  }
2355
+ function isPlainObject(value) {
2356
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
2357
+ return false;
2358
+ }
2359
+ const proto = Object.getPrototypeOf(value);
2360
+ return proto === null || proto === Object.prototype;
2361
+ }
2362
+ function isJsonSerializable(value) {
2363
+ if (value === null) {
2364
+ return true;
2365
+ }
2366
+ const type = typeof value;
2367
+ if (type === "string" || type === "number" || type === "boolean") {
2368
+ return Number.isFinite(value) || type !== "number";
2369
+ }
2370
+ if (Array.isArray(value)) {
2371
+ return value.every(isJsonSerializable);
2372
+ }
2373
+ if (type === "object") {
2374
+ return Object.values(value).every(isJsonSerializable);
2375
+ }
2376
+ return false;
2377
+ }
2378
+ function describeType(value) {
2379
+ if (value === null) {
2380
+ return "null";
2381
+ }
2382
+ if (Array.isArray(value)) {
2383
+ return "array";
2384
+ }
2385
+ return typeof value;
2386
+ }
1888
2387
  function jsTypeForKind(kind) {
1889
2388
  switch (kind) {
1890
2389
  case "string":
@@ -2482,6 +2981,14 @@ function mapFieldType2(descriptor) {
2482
2981
  return "INTEGER";
2483
2982
  case "array":
2484
2983
  return "TEXT";
2984
+ case "object":
2985
+ return "TEXT";
2986
+ case "json":
2987
+ return "TEXT";
2988
+ case "blob":
2989
+ return "TEXT";
2990
+ case "secret":
2991
+ return "TEXT";
2485
2992
  case "richtext":
2486
2993
  return "BLOB";
2487
2994
  }
@@ -2500,7 +3007,14 @@ var SCALAR_TYPE_MAP = {
2500
3007
  number: "double",
2501
3008
  boolean: "bool",
2502
3009
  timestamp: "int64",
2503
- richtext: "bytes"
3010
+ richtext: "bytes",
3011
+ // object/json values travel as JSON-serialized strings on the proto wire.
3012
+ object: "string",
3013
+ json: "string",
3014
+ // A blob field carries a JSON-serialized content-addressed reference, not bytes.
3015
+ blob: "string",
3016
+ // A secret field's stored value is a JSON string (ciphertext or hash).
3017
+ secret: "string"
2504
3018
  };
2505
3019
  var ARRAY_ITEM_TYPE_MAP = {
2506
3020
  string: "string",
@@ -2744,6 +3258,7 @@ function generateProtoDefinitions(schema) {
2744
3258
  MergeConflictError,
2745
3259
  MigrationBuilder,
2746
3260
  MigrationRollbackError,
3261
+ MissingSecretKeyError,
2747
3262
  OperationError,
2748
3263
  RemoteClockDriftError,
2749
3264
  RollbackBuilder,
@@ -2760,16 +3275,19 @@ function generateProtoDefinitions(schema) {
2760
3275
  collectSchemaScopeFields,
2761
3276
  collectSchemaScopeValueKeys,
2762
3277
  computeDelta,
3278
+ createBlobRef,
2763
3279
  createOperation,
2764
3280
  createReversibleMigration,
2765
3281
  createVersionVector,
2766
3282
  decodeBytesFromOpData,
3283
+ decryptSecret,
2767
3284
  defaultApplyFailureReason,
2768
3285
  defaultSequenceFormat,
2769
3286
  defineSchema,
2770
3287
  deserializeVector,
2771
3288
  dominates,
2772
3289
  encodeBytesForOpData,
3290
+ encryptSecret,
2773
3291
  extractScopeValuesFromClaims,
2774
3292
  extractTimestamp,
2775
3293
  formatSequenceValue,
@@ -2782,8 +3300,11 @@ function generateProtoDefinitions(schema) {
2782
3300
  getKoraErrorFix,
2783
3301
  getTransitionMap,
2784
3302
  hasSchemaSyncRules,
3303
+ hashBlob,
3304
+ hashSecret,
2785
3305
  isApplyFailure,
2786
3306
  isAtomicOp,
3307
+ isBlobRef,
2787
3308
  isCollectionSyncScoped,
2788
3309
  isKoraBytesValue,
2789
3310
  isLegacyNumericByteObject,
@@ -2794,13 +3315,17 @@ function generateProtoDefinitions(schema) {
2794
3315
  migrationStepsToSQL,
2795
3316
  op,
2796
3317
  resolveAtomicOp,
3318
+ revealSecret,
2797
3319
  rollbackStepsToSQL,
2798
3320
  serializeVector,
2799
3321
  t,
2800
3322
  toAtomicOp,
3323
+ transformSecretFieldsForWrite,
2801
3324
  validateRecord,
2802
3325
  validateTransition,
2803
3326
  vectorsEqual,
2804
- verifyOperationIntegrity
3327
+ verifyOperationIntegrity,
3328
+ verifySecret,
3329
+ verifySecretValue
2805
3330
  });
2806
3331
  //# sourceMappingURL=index.cjs.map