@wemush/wols 0.1.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.
Files changed (87) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +294 -0
  3. package/dist/cjs/compact-url.js +272 -0
  4. package/dist/cjs/compact-url.js.map +1 -0
  5. package/dist/cjs/crypto/decrypt.js +125 -0
  6. package/dist/cjs/crypto/decrypt.js.map +1 -0
  7. package/dist/cjs/crypto/encrypt.js +151 -0
  8. package/dist/cjs/crypto/encrypt.js.map +1 -0
  9. package/dist/cjs/crypto/index.js +16 -0
  10. package/dist/cjs/crypto/index.js.map +1 -0
  11. package/dist/cjs/errors.js +188 -0
  12. package/dist/cjs/errors.js.map +1 -0
  13. package/dist/cjs/index.js +81 -0
  14. package/dist/cjs/index.js.map +1 -0
  15. package/dist/cjs/parser.js +148 -0
  16. package/dist/cjs/parser.js.map +1 -0
  17. package/dist/cjs/qr/generate.js +275 -0
  18. package/dist/cjs/qr/generate.js.map +1 -0
  19. package/dist/cjs/qr/index.js +18 -0
  20. package/dist/cjs/qr/index.js.map +1 -0
  21. package/dist/cjs/specimen.js +163 -0
  22. package/dist/cjs/specimen.js.map +1 -0
  23. package/dist/cjs/types.js +78 -0
  24. package/dist/cjs/types.js.map +1 -0
  25. package/dist/cjs/utils/cuid.js +150 -0
  26. package/dist/cjs/utils/cuid.js.map +1 -0
  27. package/dist/cjs/utils/iso8601.js +131 -0
  28. package/dist/cjs/utils/iso8601.js.map +1 -0
  29. package/dist/cjs/validator.js +307 -0
  30. package/dist/cjs/validator.js.map +1 -0
  31. package/dist/esm/compact-url.js +264 -0
  32. package/dist/esm/compact-url.js.map +1 -0
  33. package/dist/esm/crypto/decrypt.js +122 -0
  34. package/dist/esm/crypto/decrypt.js.map +1 -0
  35. package/dist/esm/crypto/encrypt.js +147 -0
  36. package/dist/esm/crypto/encrypt.js.map +1 -0
  37. package/dist/esm/crypto/index.js +10 -0
  38. package/dist/esm/crypto/index.js.map +1 -0
  39. package/dist/esm/errors.js +178 -0
  40. package/dist/esm/errors.js.map +1 -0
  41. package/dist/esm/index.js +47 -0
  42. package/dist/esm/index.js.map +1 -0
  43. package/dist/esm/parser.js +145 -0
  44. package/dist/esm/parser.js.map +1 -0
  45. package/dist/esm/qr/generate.js +235 -0
  46. package/dist/esm/qr/generate.js.map +1 -0
  47. package/dist/esm/qr/index.js +10 -0
  48. package/dist/esm/qr/index.js.map +1 -0
  49. package/dist/esm/specimen.js +159 -0
  50. package/dist/esm/specimen.js.map +1 -0
  51. package/dist/esm/types.js +71 -0
  52. package/dist/esm/types.js.map +1 -0
  53. package/dist/esm/utils/cuid.js +145 -0
  54. package/dist/esm/utils/cuid.js.map +1 -0
  55. package/dist/esm/utils/iso8601.js +122 -0
  56. package/dist/esm/utils/iso8601.js.map +1 -0
  57. package/dist/esm/validator.js +304 -0
  58. package/dist/esm/validator.js.map +1 -0
  59. package/dist/types/compact-url.d.ts +104 -0
  60. package/dist/types/compact-url.d.ts.map +1 -0
  61. package/dist/types/crypto/decrypt.d.ts +33 -0
  62. package/dist/types/crypto/decrypt.d.ts.map +1 -0
  63. package/dist/types/crypto/encrypt.d.ts +32 -0
  64. package/dist/types/crypto/encrypt.d.ts.map +1 -0
  65. package/dist/types/crypto/index.d.ts +10 -0
  66. package/dist/types/crypto/index.d.ts.map +1 -0
  67. package/dist/types/errors.d.ts +103 -0
  68. package/dist/types/errors.d.ts.map +1 -0
  69. package/dist/types/index.d.ts +21 -0
  70. package/dist/types/index.d.ts.map +1 -0
  71. package/dist/types/parser.d.ts +30 -0
  72. package/dist/types/parser.d.ts.map +1 -0
  73. package/dist/types/qr/generate.d.ts +62 -0
  74. package/dist/types/qr/generate.d.ts.map +1 -0
  75. package/dist/types/qr/index.d.ts +10 -0
  76. package/dist/types/qr/index.d.ts.map +1 -0
  77. package/dist/types/specimen.d.ts +71 -0
  78. package/dist/types/specimen.d.ts.map +1 -0
  79. package/dist/types/types.d.ts +269 -0
  80. package/dist/types/types.d.ts.map +1 -0
  81. package/dist/types/utils/cuid.d.ts +44 -0
  82. package/dist/types/utils/cuid.d.ts.map +1 -0
  83. package/dist/types/utils/iso8601.d.ts +79 -0
  84. package/dist/types/utils/iso8601.d.ts.map +1 -0
  85. package/dist/types/validator.d.ts +25 -0
  86. package/dist/types/validator.d.ts.map +1 -0
  87. package/package.json +95 -0
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+ /**
3
+ * Compact URL Format Functions
4
+ *
5
+ * This module provides functions to generate and parse compact URL format
6
+ * for WOLS specimens. The compact format is designed for small QR codes
7
+ * (petri dishes, culture tubes) where space is limited.
8
+ *
9
+ * Format: wemush://v1/{id}?s={species_code}&st={stage}&t={timestamp}
10
+ *
11
+ * @module compact-url
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.SPECIES_CODES = void 0;
15
+ exports.getSpeciesFromCode = getSpeciesFromCode;
16
+ exports.getCodeFromSpecies = getCodeFromSpecies;
17
+ exports.registerSpeciesCode = registerSpeciesCode;
18
+ exports.toCompactUrl = toCompactUrl;
19
+ exports.parseCompactUrl = parseCompactUrl;
20
+ const errors_js_1 = require("./errors.js");
21
+ /**
22
+ * Standard species codes from the WOLS specification
23
+ *
24
+ * @see https://github.com/wemush/open-standard for additional codes
25
+ */
26
+ exports.SPECIES_CODES = {
27
+ POSTR: 'Pleurotus ostreatus',
28
+ PCITRI: 'Pleurotus citrinopileatus',
29
+ PDJAR: 'Pleurotus djamor',
30
+ PERYN: 'Pleurotus eryngii',
31
+ HERIN: 'Hericium erinaceus',
32
+ GLUCI: 'Ganoderma lucidum',
33
+ LPUDE: 'Laetiporus pudens',
34
+ LLENC: 'Lentinula edodes',
35
+ APOLY: 'Agrocybe polyphylla',
36
+ STRUG: 'Stropharia rugosoannulata',
37
+ };
38
+ /**
39
+ * Reverse lookup map: species name → code
40
+ */
41
+ const SPECIES_TO_CODE = {};
42
+ // Initialize reverse lookup
43
+ for (const [code, species] of Object.entries(exports.SPECIES_CODES)) {
44
+ SPECIES_TO_CODE[species] = code;
45
+ }
46
+ /**
47
+ * Get the full species name from a species code
48
+ *
49
+ * @param code - Species code (e.g., "POSTR")
50
+ * @returns Species name or undefined if code is unknown
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * getSpeciesFromCode('POSTR') // Returns "Pleurotus ostreatus"
55
+ * getSpeciesFromCode('XXXXX') // Returns undefined
56
+ * ```
57
+ */
58
+ function getSpeciesFromCode(code) {
59
+ return exports.SPECIES_CODES[code];
60
+ }
61
+ /**
62
+ * Get the species code from a species name
63
+ *
64
+ * @param species - Full species name (e.g., "Pleurotus ostreatus")
65
+ * @returns Species code or undefined if species is not registered
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * getCodeFromSpecies('Pleurotus ostreatus') // Returns "POSTR"
70
+ * getCodeFromSpecies('Unknown species') // Returns undefined
71
+ * ```
72
+ */
73
+ function getCodeFromSpecies(species) {
74
+ return SPECIES_TO_CODE[species];
75
+ }
76
+ /**
77
+ * Register a custom species code
78
+ *
79
+ * Use this to add species codes that are not in the standard WOLS list.
80
+ *
81
+ * @param code - Species code (uppercase, 5 characters recommended)
82
+ * @param species - Full species name
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * registerSpeciesCode('CCOMA', 'Coprinus comatus');
87
+ * getSpeciesFromCode('CCOMA') // Returns "Coprinus comatus"
88
+ * ```
89
+ */
90
+ function registerSpeciesCode(code, species) {
91
+ // Remove old reverse lookup if code is being overwritten
92
+ const oldSpecies = exports.SPECIES_CODES[code];
93
+ if (oldSpecies !== undefined) {
94
+ delete SPECIES_TO_CODE[oldSpecies];
95
+ }
96
+ exports.SPECIES_CODES[code] = species;
97
+ SPECIES_TO_CODE[species] = code;
98
+ }
99
+ /**
100
+ * Generate a compact URL from a specimen
101
+ *
102
+ * The compact URL format is designed for small QR codes:
103
+ * ```
104
+ * wemush://v1/{id}?s={species_code}&st={stage}&t={timestamp}
105
+ * ```
106
+ *
107
+ * @param specimen - The specimen to encode
108
+ * @returns Compact URL string
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * const specimen = createSpecimen({
113
+ * type: 'CULTURE',
114
+ * species: 'Pleurotus ostreatus',
115
+ * stage: 'COLONIZATION'
116
+ * });
117
+ *
118
+ * const url = toCompactUrl(specimen);
119
+ * // wemush://v1/clx1a2b3c4?s=POSTR&st=COLONIZATION&ty=CULTURE&t=1734307200
120
+ * ```
121
+ */
122
+ function toCompactUrl(specimen) {
123
+ // Extract ID without prefix
124
+ const idWithoutPrefix = specimen.id.replace(/^wemush:/, '');
125
+ // Start building URL
126
+ let url = `wemush://v1/${idWithoutPrefix}`;
127
+ // Build query parameters
128
+ const params = new URLSearchParams();
129
+ // Species: use code if known, otherwise full name
130
+ const speciesCode = getCodeFromSpecies(specimen.species);
131
+ if (speciesCode !== undefined) {
132
+ params.set('s', speciesCode);
133
+ }
134
+ else {
135
+ params.set('s', specimen.species);
136
+ }
137
+ // Type
138
+ params.set('ty', specimen.type);
139
+ // Stage (if present)
140
+ if (specimen.stage !== undefined) {
141
+ params.set('st', specimen.stage);
142
+ }
143
+ // Timestamp: convert ISO date to Unix timestamp
144
+ if (specimen.created !== undefined) {
145
+ const timestamp = Math.floor(new Date(specimen.created).getTime() / 1000);
146
+ params.set('t', timestamp.toString());
147
+ }
148
+ // Optional: Batch
149
+ if (specimen.batch !== undefined) {
150
+ params.set('b', specimen.batch);
151
+ }
152
+ // Optional: Strain name
153
+ if (specimen.strain?.name !== undefined) {
154
+ params.set('sn', specimen.strain.name);
155
+ }
156
+ // Optional: Strain generation
157
+ if (specimen.strain?.generation !== undefined) {
158
+ params.set('sg', specimen.strain.generation);
159
+ }
160
+ // Append query string
161
+ const queryString = params.toString();
162
+ if (queryString) {
163
+ url += `?${queryString}`;
164
+ }
165
+ return url;
166
+ }
167
+ /**
168
+ * Parse a compact URL into a SpecimenRef
169
+ *
170
+ * Returns a reference object containing the minimal information
171
+ * encoded in the compact URL. Use the id to fetch full specimen
172
+ * data from the API if needed.
173
+ *
174
+ * @param url - Compact URL to parse (wemush://v1/...)
175
+ * @returns ParseResult with SpecimenRef on success, error on failure
176
+ *
177
+ * @example
178
+ * ```typescript
179
+ * const result = parseCompactUrl('wemush://v1/clx1a2b3c4?s=POSTR&st=COLONIZATION');
180
+ *
181
+ * if (result.success) {
182
+ * console.log(result.data.species); // "Pleurotus ostreatus"
183
+ * }
184
+ * ```
185
+ */
186
+ function parseCompactUrl(url) {
187
+ // Validate URL scheme
188
+ if (!url.startsWith('wemush://')) {
189
+ return {
190
+ success: false,
191
+ error: new errors_js_1.WolsParseError(errors_js_1.WolsErrorCode.INVALID_URL, 'URL must start with wemush://', {
192
+ url,
193
+ }),
194
+ };
195
+ }
196
+ // Parse URL parts
197
+ const withoutScheme = url.slice('wemush://'.length);
198
+ const [pathPart, queryPart] = withoutScheme.split('?');
199
+ if (!pathPart) {
200
+ return {
201
+ success: false,
202
+ error: new errors_js_1.WolsParseError(errors_js_1.WolsErrorCode.INVALID_URL, 'Invalid compact URL format: missing path', { url }),
203
+ };
204
+ }
205
+ // Parse path: v1/{id}
206
+ const pathSegments = pathPart.split('/');
207
+ if (pathSegments.length < 2 || !pathSegments[1]) {
208
+ return {
209
+ success: false,
210
+ error: new errors_js_1.WolsParseError(errors_js_1.WolsErrorCode.INVALID_URL, 'Invalid compact URL format: missing specimen ID', { url }),
211
+ };
212
+ }
213
+ const version = pathSegments[0] === 'v1' ? '1.1.0' : '1.0.0';
214
+ const idWithoutPrefix = pathSegments[1];
215
+ // Parse query parameters
216
+ const params = new URLSearchParams(queryPart ?? '');
217
+ // Extract species (resolve code if known)
218
+ const speciesParam = params.get('s');
219
+ let species;
220
+ if (speciesParam !== null) {
221
+ const resolvedSpecies = getSpeciesFromCode(speciesParam);
222
+ species = resolvedSpecies ?? speciesParam;
223
+ }
224
+ else {
225
+ return {
226
+ success: false,
227
+ error: new errors_js_1.WolsParseError(errors_js_1.WolsErrorCode.INVALID_URL, 'Invalid compact URL format: missing species parameter', { url }),
228
+ };
229
+ }
230
+ // Build result object
231
+ const result = {
232
+ id: `wemush:${idWithoutPrefix}`,
233
+ species,
234
+ version,
235
+ };
236
+ // Extract type
237
+ const typeParam = params.get('ty');
238
+ if (typeParam !== null) {
239
+ result.type = typeParam;
240
+ }
241
+ // Extract stage
242
+ const stageParam = params.get('st');
243
+ if (stageParam !== null) {
244
+ result.stage = stageParam;
245
+ }
246
+ // Extract timestamp
247
+ const timestampParam = params.get('t');
248
+ if (timestampParam !== null) {
249
+ result.timestamp = parseInt(timestampParam, 10);
250
+ }
251
+ // Extract batch
252
+ const batchParam = params.get('b');
253
+ if (batchParam !== null) {
254
+ result.batch = batchParam;
255
+ }
256
+ // Extract strain info
257
+ const strainNameParam = params.get('sn');
258
+ const strainGenParam = params.get('sg');
259
+ if (strainNameParam !== null) {
260
+ result.strain = {
261
+ name: strainNameParam,
262
+ };
263
+ if (strainGenParam !== null) {
264
+ result.strain.generation = strainGenParam;
265
+ }
266
+ }
267
+ return {
268
+ success: true,
269
+ data: result,
270
+ };
271
+ }
272
+ //# sourceMappingURL=compact-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compact-url.js","sourceRoot":"","sources":["../../src/compact-url.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ /**
3
+ * WOLS Decryption Module
4
+ *
5
+ * Provides AES-256-GCM decryption for encrypted specimens using Web Crypto API.
6
+ * Supports both password-based (PBKDF2) and raw CryptoKey decryption.
7
+ *
8
+ * @module crypto/decrypt
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.decryptSpecimen = decryptSpecimen;
12
+ const errors_js_1 = require("../errors.js");
13
+ const parser_js_1 = require("../parser.js");
14
+ // =============================================================================
15
+ // CONSTANTS
16
+ // =============================================================================
17
+ /** Salt for PBKDF2 key derivation (must match encrypt.ts) */
18
+ const PBKDF2_SALT = new TextEncoder().encode('@wemush/wols/crypto/v1');
19
+ /** Number of PBKDF2 iterations (must match encrypt.ts) */
20
+ const PBKDF2_ITERATIONS = 100_000;
21
+ // =============================================================================
22
+ // UTILITY FUNCTIONS
23
+ // =============================================================================
24
+ /**
25
+ * Convert base64url string to ArrayBuffer
26
+ */
27
+ function fromBase64Url(base64url) {
28
+ // Convert base64url to base64
29
+ const base64 = base64url
30
+ .replace(/-/g, '+')
31
+ .replace(/_/g, '/')
32
+ .padEnd(base64url.length + ((4 - (base64url.length % 4)) % 4), '=');
33
+ // Decode base64 to binary string
34
+ const binaryString = atob(base64);
35
+ // Convert to ArrayBuffer
36
+ const bytes = new Uint8Array(binaryString.length);
37
+ for (let i = 0; i < binaryString.length; i++) {
38
+ bytes[i] = binaryString.charCodeAt(i);
39
+ }
40
+ return bytes.buffer;
41
+ }
42
+ /**
43
+ * Derive a CryptoKey from a password using PBKDF2
44
+ */
45
+ async function deriveKey(password) {
46
+ const encoder = new TextEncoder();
47
+ const passwordBytes = encoder.encode(password);
48
+ // Import password as key material
49
+ const keyMaterial = await crypto.subtle.importKey('raw', passwordBytes, 'PBKDF2', false, [
50
+ 'deriveKey',
51
+ ]);
52
+ // Derive AES-256-GCM key
53
+ return crypto.subtle.deriveKey({
54
+ name: 'PBKDF2',
55
+ salt: PBKDF2_SALT,
56
+ iterations: PBKDF2_ITERATIONS,
57
+ hash: 'SHA-256',
58
+ }, keyMaterial, { name: 'AES-GCM', length: 256 }, false, ['decrypt']);
59
+ }
60
+ // =============================================================================
61
+ // DECRYPTION FUNCTIONS
62
+ // =============================================================================
63
+ /**
64
+ * Decrypt an encrypted specimen using AES-256-GCM
65
+ *
66
+ * @param encrypted - The encrypted specimen wrapper
67
+ * @param options - Decryption options (key required)
68
+ * @returns Promise resolving to ParseResult with decrypted specimen or error
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * import { decryptSpecimen } from '@wemush/wols/crypto';
73
+ *
74
+ * const result = await decryptSpecimen(encrypted, {
75
+ * key: 'my-secret-password',
76
+ * });
77
+ *
78
+ * if (result.success) {
79
+ * console.log(result.data);
80
+ * } else {
81
+ * console.error(result.error);
82
+ * }
83
+ * ```
84
+ */
85
+ async function decryptSpecimen(encrypted, options) {
86
+ const { key } = options;
87
+ // Validate encrypted specimen structure
88
+ if (!encrypted.payload) {
89
+ return {
90
+ success: false,
91
+ error: new errors_js_1.WolsEncryptionError(errors_js_1.WolsErrorCode.DECRYPTION_ERROR, 'Missing encrypted payload', {
92
+ path: ['payload'],
93
+ }),
94
+ };
95
+ }
96
+ if (!encrypted.iv) {
97
+ return {
98
+ success: false,
99
+ error: new errors_js_1.WolsEncryptionError(errors_js_1.WolsErrorCode.DECRYPTION_ERROR, 'Missing initialization vector (IV)', { path: ['iv'] }),
100
+ };
101
+ }
102
+ try {
103
+ // Get or derive the decryption key
104
+ const cryptoKey = typeof key === 'string' ? await deriveKey(key) : key;
105
+ // Decode payload and IV from base64url
106
+ const ciphertext = fromBase64Url(encrypted.payload);
107
+ const ivBuffer = fromBase64Url(encrypted.iv);
108
+ const iv = new Uint8Array(ivBuffer);
109
+ // Decrypt
110
+ const plaintext = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, cryptoKey, ciphertext);
111
+ // Decode plaintext to string
112
+ const json = new TextDecoder().decode(plaintext);
113
+ // Parse the decrypted JSON back into a specimen
114
+ return (0, parser_js_1.parseSpecimen)(json);
115
+ }
116
+ catch (error) {
117
+ // Handle decryption errors (wrong key, tampered data, etc.)
118
+ const errorMessage = error instanceof Error ? error.message : 'Unknown decryption error';
119
+ return {
120
+ success: false,
121
+ error: new errors_js_1.WolsEncryptionError(errors_js_1.WolsErrorCode.DECRYPTION_ERROR, `Decryption failed: ${errorMessage}`),
122
+ };
123
+ }
124
+ }
125
+ //# sourceMappingURL=decrypt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decrypt.js","sourceRoot":"","sources":["../../../src/crypto/decrypt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ /**
3
+ * WOLS Encryption Module
4
+ *
5
+ * Provides AES-256-GCM encryption for specimens using Web Crypto API.
6
+ * Supports both password-based (PBKDF2) and raw CryptoKey encryption.
7
+ *
8
+ * @module crypto/encrypt
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.encryptSpecimen = encryptSpecimen;
12
+ exports.isEncrypted = isEncrypted;
13
+ const specimen_js_1 = require("../specimen.js");
14
+ // =============================================================================
15
+ // CONSTANTS
16
+ // =============================================================================
17
+ /** Salt for PBKDF2 key derivation (fixed for deterministic key from same password) */
18
+ const PBKDF2_SALT = new TextEncoder().encode('@wemush/wols/crypto/v1');
19
+ /** Number of PBKDF2 iterations */
20
+ const PBKDF2_ITERATIONS = 100_000;
21
+ /** IV length in bytes (96 bits = 12 bytes recommended for GCM) */
22
+ const IV_LENGTH = 12;
23
+ // =============================================================================
24
+ // UTILITY FUNCTIONS
25
+ // =============================================================================
26
+ /**
27
+ * Convert ArrayBuffer to base64url string
28
+ */
29
+ function toBase64Url(buffer) {
30
+ const bytes = new Uint8Array(buffer);
31
+ let binary = '';
32
+ for (const byte of bytes) {
33
+ binary += String.fromCharCode(byte);
34
+ }
35
+ return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
36
+ }
37
+ /**
38
+ * Derive a CryptoKey from a password using PBKDF2
39
+ */
40
+ async function deriveKey(password) {
41
+ const encoder = new TextEncoder();
42
+ const passwordBytes = encoder.encode(password);
43
+ // Import password as key material
44
+ const keyMaterial = await crypto.subtle.importKey('raw', passwordBytes, 'PBKDF2', false, [
45
+ 'deriveKey',
46
+ ]);
47
+ // Derive AES-256-GCM key
48
+ return crypto.subtle.deriveKey({
49
+ name: 'PBKDF2',
50
+ salt: PBKDF2_SALT,
51
+ iterations: PBKDF2_ITERATIONS,
52
+ hash: 'SHA-256',
53
+ }, keyMaterial, { name: 'AES-GCM', length: 256 }, false, ['encrypt']);
54
+ }
55
+ /**
56
+ * Generate a random initialization vector
57
+ */
58
+ function generateIV() {
59
+ const buffer = new ArrayBuffer(IV_LENGTH);
60
+ const iv = new Uint8Array(buffer);
61
+ crypto.getRandomValues(iv);
62
+ return { iv, ivBuffer: buffer };
63
+ }
64
+ // =============================================================================
65
+ // ENCRYPTION FUNCTIONS
66
+ // =============================================================================
67
+ /**
68
+ * Encrypt a specimen using AES-256-GCM
69
+ *
70
+ * @param specimen - The specimen to encrypt
71
+ * @param options - Encryption options (key required)
72
+ * @returns Promise resolving to encrypted specimen wrapper
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * import { encryptSpecimen } from '@wemush/wols/crypto';
77
+ *
78
+ * const encrypted = await encryptSpecimen(specimen, {
79
+ * key: 'my-secret-password',
80
+ * });
81
+ * // Returns: { encrypted: true, payload: "...", iv: "...", algorithm: "AES-256-GCM" }
82
+ * ```
83
+ */
84
+ async function encryptSpecimen(specimen, options) {
85
+ const { key, fields } = options;
86
+ // If partial encryption requested, handle separately
87
+ if (fields !== undefined && fields.length > 0) {
88
+ return encryptPartial(specimen, options);
89
+ }
90
+ // Get or derive the encryption key
91
+ const cryptoKey = typeof key === 'string' ? await deriveKey(key) : key;
92
+ // Serialize the specimen to JSON
93
+ const plaintext = (0, specimen_js_1.serializeSpecimen)(specimen);
94
+ const plaintextBytes = new TextEncoder().encode(plaintext);
95
+ // Generate random IV
96
+ const { iv, ivBuffer } = generateIV();
97
+ // Encrypt
98
+ const ciphertext = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, cryptoKey, plaintextBytes);
99
+ // Return encrypted specimen
100
+ return {
101
+ encrypted: true,
102
+ payload: toBase64Url(ciphertext),
103
+ iv: toBase64Url(ivBuffer),
104
+ algorithm: 'AES-256-GCM',
105
+ };
106
+ }
107
+ /**
108
+ * Encrypt only specific fields of a specimen
109
+ *
110
+ * Returns a specimen-like object with specified fields encrypted.
111
+ */
112
+ async function encryptPartial(specimen, options) {
113
+ const { key, fields = [] } = options;
114
+ // Get or derive the encryption key
115
+ const cryptoKey = typeof key === 'string' ? await deriveKey(key) : key;
116
+ // Clone the specimen
117
+ const result = { ...specimen };
118
+ // Encrypt each specified field
119
+ for (const field of fields) {
120
+ const value = result[field];
121
+ if (value !== undefined) {
122
+ const plaintext = JSON.stringify(value);
123
+ const plaintextBytes = new TextEncoder().encode(plaintext);
124
+ const { iv, ivBuffer } = generateIV();
125
+ const ciphertext = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, cryptoKey, plaintextBytes);
126
+ result[field] = {
127
+ encrypted: true,
128
+ payload: toBase64Url(ciphertext),
129
+ iv: toBase64Url(ivBuffer),
130
+ algorithm: 'AES-256-GCM',
131
+ };
132
+ }
133
+ }
134
+ // Cast to EncryptedSpecimen for return type consistency
135
+ // In partial mode, this is actually a hybrid object
136
+ return result;
137
+ }
138
+ /**
139
+ * Type guard to check if an object is an encrypted specimen
140
+ */
141
+ function isEncrypted(value) {
142
+ if (value === null || value === undefined) {
143
+ return false;
144
+ }
145
+ if (typeof value !== 'object') {
146
+ return false;
147
+ }
148
+ const obj = value;
149
+ return obj['encrypted'] === true;
150
+ }
151
+ //# sourceMappingURL=encrypt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encrypt.js","sourceRoot":"","sources":["../../../src/crypto/encrypt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ /**
3
+ * WOLS Crypto Module
4
+ *
5
+ * Provides AES-256-GCM encryption and decryption for specimens.
6
+ *
7
+ * @module crypto
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.decryptSpecimen = exports.isEncrypted = exports.encryptSpecimen = void 0;
11
+ var encrypt_js_1 = require("./encrypt.js");
12
+ Object.defineProperty(exports, "encryptSpecimen", { enumerable: true, get: function () { return encrypt_js_1.encryptSpecimen; } });
13
+ Object.defineProperty(exports, "isEncrypted", { enumerable: true, get: function () { return encrypt_js_1.isEncrypted; } });
14
+ var decrypt_js_1 = require("./decrypt.js");
15
+ Object.defineProperty(exports, "decryptSpecimen", { enumerable: true, get: function () { return decrypt_js_1.decryptSpecimen; } });
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/crypto/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,2CAA4D;AAAnD,6GAAA,eAAe,OAAA;AAAE,yGAAA,WAAW,OAAA;AACrC,2CAA+C;AAAtC,6GAAA,eAAe,OAAA"}