@fgv/ts-extras 5.1.0-42 → 5.1.0-44

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 (57) hide show
  1. package/dist/packlets/ai-assist/model.js.map +1 -1
  2. package/dist/packlets/ai-assist/registry.js +22 -18
  3. package/dist/packlets/ai-assist/registry.js.map +1 -1
  4. package/dist/packlets/crypto-utils/index.browser.js +1 -1
  5. package/dist/packlets/crypto-utils/index.browser.js.map +1 -1
  6. package/dist/packlets/crypto-utils/index.js +1 -1
  7. package/dist/packlets/crypto-utils/index.js.map +1 -1
  8. package/dist/packlets/crypto-utils/keystore/converters.js +8 -4
  9. package/dist/packlets/crypto-utils/keystore/converters.js.map +1 -1
  10. package/dist/packlets/crypto-utils/keystore/keyStore.js +101 -2
  11. package/dist/packlets/crypto-utils/keystore/keyStore.js.map +1 -1
  12. package/dist/packlets/crypto-utils/keystore/model.js +9 -4
  13. package/dist/packlets/crypto-utils/keystore/model.js.map +1 -1
  14. package/dist/packlets/crypto-utils/model.js.map +1 -1
  15. package/dist/packlets/crypto-utils/seedDerivedKeyPair.js +51 -38
  16. package/dist/packlets/crypto-utils/seedDerivedKeyPair.js.map +1 -1
  17. package/dist/packlets/crypto-utils/spkiHelpers.js +44 -0
  18. package/dist/packlets/crypto-utils/spkiHelpers.js.map +1 -1
  19. package/dist/ts-extras.d.ts +220 -38
  20. package/lib/packlets/ai-assist/model.d.ts +9 -8
  21. package/lib/packlets/ai-assist/model.d.ts.map +1 -1
  22. package/lib/packlets/ai-assist/model.js.map +1 -1
  23. package/lib/packlets/ai-assist/registry.d.ts.map +1 -1
  24. package/lib/packlets/ai-assist/registry.js +22 -18
  25. package/lib/packlets/ai-assist/registry.js.map +1 -1
  26. package/lib/packlets/crypto-utils/index.browser.d.ts +1 -1
  27. package/lib/packlets/crypto-utils/index.browser.d.ts.map +1 -1
  28. package/lib/packlets/crypto-utils/index.browser.js +3 -1
  29. package/lib/packlets/crypto-utils/index.browser.js.map +1 -1
  30. package/lib/packlets/crypto-utils/index.d.ts +1 -1
  31. package/lib/packlets/crypto-utils/index.d.ts.map +1 -1
  32. package/lib/packlets/crypto-utils/index.js +3 -1
  33. package/lib/packlets/crypto-utils/index.js.map +1 -1
  34. package/lib/packlets/crypto-utils/keystore/converters.d.ts +1 -1
  35. package/lib/packlets/crypto-utils/keystore/converters.d.ts.map +1 -1
  36. package/lib/packlets/crypto-utils/keystore/converters.js +8 -4
  37. package/lib/packlets/crypto-utils/keystore/converters.js.map +1 -1
  38. package/lib/packlets/crypto-utils/keystore/keyStore.d.ts +45 -1
  39. package/lib/packlets/crypto-utils/keystore/keyStore.d.ts.map +1 -1
  40. package/lib/packlets/crypto-utils/keystore/keyStore.js +101 -2
  41. package/lib/packlets/crypto-utils/keystore/keyStore.js.map +1 -1
  42. package/lib/packlets/crypto-utils/keystore/model.d.ts +57 -3
  43. package/lib/packlets/crypto-utils/keystore/model.d.ts.map +1 -1
  44. package/lib/packlets/crypto-utils/keystore/model.js +9 -4
  45. package/lib/packlets/crypto-utils/keystore/model.js.map +1 -1
  46. package/lib/packlets/crypto-utils/model.d.ts +65 -20
  47. package/lib/packlets/crypto-utils/model.d.ts.map +1 -1
  48. package/lib/packlets/crypto-utils/model.js.map +1 -1
  49. package/lib/packlets/crypto-utils/seedDerivedKeyPair.d.ts +11 -6
  50. package/lib/packlets/crypto-utils/seedDerivedKeyPair.d.ts.map +1 -1
  51. package/lib/packlets/crypto-utils/seedDerivedKeyPair.js +51 -38
  52. package/lib/packlets/crypto-utils/seedDerivedKeyPair.js.map +1 -1
  53. package/lib/packlets/crypto-utils/spkiHelpers.d.ts +26 -0
  54. package/lib/packlets/crypto-utils/spkiHelpers.d.ts.map +1 -1
  55. package/lib/packlets/crypto-utils/spkiHelpers.js +46 -0
  56. package/lib/packlets/crypto-utils/spkiHelpers.js.map +1 -1
  57. package/package.json +7 -7
@@ -781,6 +781,101 @@ class KeyStore {
781
781
  const decoder = new TextDecoder();
782
782
  return (0, ts_utils_1.succeed)(decoder.decode(entry.key));
783
783
  }
784
+ /**
785
+ * Imports arbitrary raw bytes into the vault with type `'opaque'`.
786
+ *
787
+ * Unlike {@link KeyStore.importSecret} (which enforces a 32-byte AES-256 key)
788
+ * and {@link KeyStore.importApiKey} (which UTF-8 encodes a string), this
789
+ * accepts a byte buffer of any length and stores it verbatim — including
790
+ * embedded NUL bytes. Use it for byte blobs that are neither a fixed-size key
791
+ * nor a UTF-8 string (e.g. a serialized credential bundle), so they are not
792
+ * mistyped as `'api-key'`.
793
+ *
794
+ * @param name - Unique name for the secret
795
+ * @param bytes - The raw bytes to store
796
+ * @param options - Optional description, initial metadata, whether to replace existing
797
+ * @returns Success with entry, Failure if locked, empty, or exists and !replace
798
+ * @public
799
+ */
800
+ async importSecretBytes(name, bytes, options) {
801
+ if (!this._secrets) {
802
+ return (0, ts_utils_1.fail)('Key store is locked');
803
+ }
804
+ if (!name || name.length === 0) {
805
+ return (0, ts_utils_1.fail)('Secret name cannot be empty');
806
+ }
807
+ const existing = this._secrets.get(name);
808
+ if (existing && !(options === null || options === void 0 ? void 0 : options.replace)) {
809
+ return (0, ts_utils_1.fail)(`Secret '${name}' already exists - use replace=true to overwrite`);
810
+ }
811
+ const entry = {
812
+ name,
813
+ type: 'opaque',
814
+ key: new Uint8Array(bytes), // Copy to prevent external modification
815
+ description: options === null || options === void 0 ? void 0 : options.description,
816
+ metadata: options === null || options === void 0 ? void 0 : options.metadata,
817
+ createdAt: getCurrentTimestamp()
818
+ };
819
+ const warning = existing ? await this._releaseEntryResources(existing) : undefined;
820
+ this._secrets.set(name, entry);
821
+ this._dirty = true;
822
+ return (0, ts_utils_1.succeed)({ entry, replaced: existing !== undefined, warning });
823
+ }
824
+ /**
825
+ * Retrieves the raw stored bytes for a symmetric entry, returned verbatim
826
+ * (never UTF-8 decoded). Intended for `'opaque'` entries but works for any
827
+ * symmetric type; asymmetric-keypair entries carry no raw key material and
828
+ * are rejected.
829
+ *
830
+ * @param name - Name of the secret
831
+ * @returns Success with a copy of the stored bytes, Failure if not found,
832
+ * locked, or the entry is asymmetric
833
+ * @public
834
+ */
835
+ getSecretBytes(name) {
836
+ if (!this._secrets) {
837
+ return (0, ts_utils_1.fail)('Key store is locked');
838
+ }
839
+ const entry = this._secrets.get(name);
840
+ if (!entry) {
841
+ return (0, ts_utils_1.fail)(`Secret '${name}' not found`);
842
+ }
843
+ if (entry.type === 'asymmetric-keypair') {
844
+ return (0, ts_utils_1.fail)(`Secret '${name}' is an asymmetric keypair, not raw byte material (type: ${entry.type})`);
845
+ }
846
+ // Copy so callers cannot mutate the in-memory vault buffer.
847
+ return (0, ts_utils_1.succeed)(new Uint8Array(entry.key));
848
+ }
849
+ /**
850
+ * Replaces the mutable metadata on a symmetric entry and stamps `updatedAt`
851
+ * with the current timestamp. Does NOT touch the secret `key` bytes — the
852
+ * material reads back identically afterward.
853
+ *
854
+ * Metadata is non-secret by contract but physically lives inside the vault
855
+ * ciphertext (see {@link CryptoUtils.KeyStore.IKeyStoreSymmetricEntry.metadata}).
856
+ *
857
+ * @param name - Name of the secret to update
858
+ * @param value - New metadata value (replaces any prior metadata)
859
+ * @returns Success with the updated entry, Failure if not found, locked, or
860
+ * the entry is asymmetric
861
+ * @public
862
+ */
863
+ setSecretMetadata(name, value) {
864
+ if (!this._secrets) {
865
+ return (0, ts_utils_1.fail)('Key store is locked');
866
+ }
867
+ const entry = this._secrets.get(name);
868
+ if (!entry) {
869
+ return (0, ts_utils_1.fail)(`Secret '${name}' not found`);
870
+ }
871
+ if (entry.type === 'asymmetric-keypair') {
872
+ return (0, ts_utils_1.fail)(`Secret '${name}' is an asymmetric keypair; metadata is only supported on symmetric entries (type: ${entry.type})`);
873
+ }
874
+ const updated = Object.assign(Object.assign({}, entry), { metadata: value, updatedAt: getCurrentTimestamp() });
875
+ this._secrets.set(name, updated);
876
+ this._dirty = true;
877
+ return (0, ts_utils_1.succeed)(updated);
878
+ }
784
879
  // ============================================================================
785
880
  // Asymmetric Keypair Management
786
881
  // ============================================================================
@@ -1193,7 +1288,9 @@ class KeyStore {
1193
1288
  type: entry.type,
1194
1289
  key: this._cryptoProvider.toBase64(entry.key),
1195
1290
  description: entry.description,
1196
- createdAt: entry.createdAt
1291
+ metadata: entry.metadata,
1292
+ createdAt: entry.createdAt,
1293
+ updatedAt: entry.updatedAt
1197
1294
  };
1198
1295
  }
1199
1296
  }
@@ -1299,7 +1396,9 @@ class KeyStore {
1299
1396
  type: jsonEntry.type,
1300
1397
  key: keyBytesResult.value,
1301
1398
  description: jsonEntry.description,
1302
- createdAt: jsonEntry.createdAt
1399
+ metadata: jsonEntry.metadata,
1400
+ createdAt: jsonEntry.createdAt,
1401
+ updatedAt: jsonEntry.updatedAt
1303
1402
  };
1304
1403
  secrets.set(name, entry);
1305
1404
  }