@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.
- package/dist/packlets/ai-assist/model.js.map +1 -1
- package/dist/packlets/ai-assist/registry.js +22 -18
- package/dist/packlets/ai-assist/registry.js.map +1 -1
- package/dist/packlets/crypto-utils/index.browser.js +1 -1
- package/dist/packlets/crypto-utils/index.browser.js.map +1 -1
- package/dist/packlets/crypto-utils/index.js +1 -1
- package/dist/packlets/crypto-utils/index.js.map +1 -1
- package/dist/packlets/crypto-utils/keystore/converters.js +8 -4
- package/dist/packlets/crypto-utils/keystore/converters.js.map +1 -1
- package/dist/packlets/crypto-utils/keystore/keyStore.js +101 -2
- package/dist/packlets/crypto-utils/keystore/keyStore.js.map +1 -1
- package/dist/packlets/crypto-utils/keystore/model.js +9 -4
- package/dist/packlets/crypto-utils/keystore/model.js.map +1 -1
- package/dist/packlets/crypto-utils/model.js.map +1 -1
- package/dist/packlets/crypto-utils/seedDerivedKeyPair.js +51 -38
- package/dist/packlets/crypto-utils/seedDerivedKeyPair.js.map +1 -1
- package/dist/packlets/crypto-utils/spkiHelpers.js +44 -0
- package/dist/packlets/crypto-utils/spkiHelpers.js.map +1 -1
- package/dist/ts-extras.d.ts +220 -38
- package/lib/packlets/ai-assist/model.d.ts +9 -8
- package/lib/packlets/ai-assist/model.d.ts.map +1 -1
- package/lib/packlets/ai-assist/model.js.map +1 -1
- package/lib/packlets/ai-assist/registry.d.ts.map +1 -1
- package/lib/packlets/ai-assist/registry.js +22 -18
- package/lib/packlets/ai-assist/registry.js.map +1 -1
- package/lib/packlets/crypto-utils/index.browser.d.ts +1 -1
- package/lib/packlets/crypto-utils/index.browser.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/index.browser.js +3 -1
- package/lib/packlets/crypto-utils/index.browser.js.map +1 -1
- package/lib/packlets/crypto-utils/index.d.ts +1 -1
- package/lib/packlets/crypto-utils/index.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/index.js +3 -1
- package/lib/packlets/crypto-utils/index.js.map +1 -1
- package/lib/packlets/crypto-utils/keystore/converters.d.ts +1 -1
- package/lib/packlets/crypto-utils/keystore/converters.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/keystore/converters.js +8 -4
- package/lib/packlets/crypto-utils/keystore/converters.js.map +1 -1
- package/lib/packlets/crypto-utils/keystore/keyStore.d.ts +45 -1
- package/lib/packlets/crypto-utils/keystore/keyStore.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/keystore/keyStore.js +101 -2
- package/lib/packlets/crypto-utils/keystore/keyStore.js.map +1 -1
- package/lib/packlets/crypto-utils/keystore/model.d.ts +57 -3
- package/lib/packlets/crypto-utils/keystore/model.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/keystore/model.js +9 -4
- package/lib/packlets/crypto-utils/keystore/model.js.map +1 -1
- package/lib/packlets/crypto-utils/model.d.ts +65 -20
- package/lib/packlets/crypto-utils/model.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/model.js.map +1 -1
- package/lib/packlets/crypto-utils/seedDerivedKeyPair.d.ts +11 -6
- package/lib/packlets/crypto-utils/seedDerivedKeyPair.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/seedDerivedKeyPair.js +51 -38
- package/lib/packlets/crypto-utils/seedDerivedKeyPair.js.map +1 -1
- package/lib/packlets/crypto-utils/spkiHelpers.d.ts +26 -0
- package/lib/packlets/crypto-utils/spkiHelpers.d.ts.map +1 -1
- package/lib/packlets/crypto-utils/spkiHelpers.js +46 -0
- package/lib/packlets/crypto-utils/spkiHelpers.js.map +1 -1
- 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
|
-
|
|
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
|
-
|
|
1399
|
+
metadata: jsonEntry.metadata,
|
|
1400
|
+
createdAt: jsonEntry.createdAt,
|
|
1401
|
+
updatedAt: jsonEntry.updatedAt
|
|
1303
1402
|
};
|
|
1304
1403
|
secrets.set(name, entry);
|
|
1305
1404
|
}
|