@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,178 @@
1
+ /**
2
+ * WOLS Error Types
3
+ *
4
+ * This module defines all error classes and error codes
5
+ * used by the WOLS TypeScript library.
6
+ *
7
+ * @module errors
8
+ */
9
+ // =============================================================================
10
+ // ERROR CODES
11
+ // =============================================================================
12
+ /**
13
+ * WOLS error codes (stable, for programmatic handling).
14
+ */
15
+ export var WolsErrorCode;
16
+ (function (WolsErrorCode) {
17
+ /** General parse error */
18
+ WolsErrorCode["PARSE_ERROR"] = "WOLS_PARSE_ERROR";
19
+ /** Invalid JSON syntax */
20
+ WolsErrorCode["INVALID_JSON"] = "WOLS_INVALID_JSON";
21
+ /** Not a valid WOLS format */
22
+ WolsErrorCode["INVALID_FORMAT"] = "WOLS_INVALID_FORMAT";
23
+ /** Missing or invalid @context field */
24
+ WolsErrorCode["INVALID_CONTEXT"] = "WOLS_INVALID_CONTEXT";
25
+ /** Missing or invalid @type field */
26
+ WolsErrorCode["INVALID_TYPE"] = "WOLS_INVALID_TYPE";
27
+ /** ID doesn't match wemush:[a-z0-9]+ pattern */
28
+ WolsErrorCode["INVALID_ID_FORMAT"] = "WOLS_INVALID_ID_FORMAT";
29
+ /** Version not valid semver */
30
+ WolsErrorCode["INVALID_VERSION"] = "WOLS_INVALID_VERSION";
31
+ /** Type not in SpecimenType enum */
32
+ WolsErrorCode["INVALID_SPECIMEN_TYPE"] = "WOLS_INVALID_SPECIMEN_TYPE";
33
+ /** Required field is missing */
34
+ WolsErrorCode["REQUIRED_FIELD"] = "WOLS_REQUIRED_FIELD";
35
+ /** Date not in ISO 8601 format */
36
+ WolsErrorCode["INVALID_DATE_FORMAT"] = "WOLS_INVALID_DATE_FORMAT";
37
+ /** Strain generation format is invalid */
38
+ WolsErrorCode["INVALID_GENERATION"] = "WOLS_INVALID_GENERATION";
39
+ /** Invalid compact URL format */
40
+ WolsErrorCode["INVALID_URL"] = "WOLS_INVALID_URL";
41
+ /** Encryption operation failed */
42
+ WolsErrorCode["ENCRYPTION_ERROR"] = "WOLS_ENCRYPTION_ERROR";
43
+ /** Decryption operation failed */
44
+ WolsErrorCode["DECRYPTION_ERROR"] = "WOLS_DECRYPTION_ERROR";
45
+ /** Invalid encryption key */
46
+ WolsErrorCode["INVALID_KEY"] = "WOLS_INVALID_KEY";
47
+ /** Payload exceeds QR code capacity */
48
+ WolsErrorCode["SIZE_EXCEEDED"] = "WOLS_SIZE_EXCEEDED";
49
+ /** Unknown or unspecified error */
50
+ WolsErrorCode["UNKNOWN_ERROR"] = "WOLS_UNKNOWN_ERROR";
51
+ })(WolsErrorCode || (WolsErrorCode = {}));
52
+ // =============================================================================
53
+ // ERROR CLASSES
54
+ // =============================================================================
55
+ /**
56
+ * Base WOLS error class.
57
+ * All WOLS-specific errors extend this class.
58
+ */
59
+ export class WolsError extends Error {
60
+ /** Error code for programmatic handling */
61
+ code;
62
+ /** Additional error details */
63
+ details;
64
+ constructor(code, message, details) {
65
+ super(message);
66
+ this.name = 'WolsError';
67
+ this.code = code;
68
+ this.details = details ?? undefined;
69
+ // Maintains proper stack trace for where error was thrown (V8 engines)
70
+ if (Error.captureStackTrace) {
71
+ Error.captureStackTrace(this, WolsError);
72
+ }
73
+ }
74
+ /**
75
+ * Convert error to JSON for serialization.
76
+ */
77
+ toJSON() {
78
+ return {
79
+ name: this.name,
80
+ code: this.code,
81
+ message: this.message,
82
+ details: this.details,
83
+ };
84
+ }
85
+ }
86
+ /**
87
+ * Parse error (JSON/format issues).
88
+ * Thrown when parsing JSON or WOLS data fails.
89
+ */
90
+ export class WolsParseError extends WolsError {
91
+ /** Character position in the input where error occurred */
92
+ position;
93
+ constructor(code, message, details) {
94
+ super(code, message, details);
95
+ this.name = 'WolsParseError';
96
+ this.position = details?.position ?? undefined;
97
+ if (Error.captureStackTrace) {
98
+ Error.captureStackTrace(this, WolsParseError);
99
+ }
100
+ }
101
+ }
102
+ /**
103
+ * Validation error (schema violations).
104
+ * Thrown when specimen data fails validation.
105
+ */
106
+ export class WolsValidationError extends WolsError {
107
+ /** Array of validation errors */
108
+ errors;
109
+ constructor(message, errors) {
110
+ super(WolsErrorCode.INVALID_FORMAT, message, { errors });
111
+ this.name = 'WolsValidationError';
112
+ this.errors = errors;
113
+ if (Error.captureStackTrace) {
114
+ Error.captureStackTrace(this, WolsValidationError);
115
+ }
116
+ }
117
+ }
118
+ /**
119
+ * Encryption/decryption error.
120
+ * Thrown when crypto operations fail.
121
+ */
122
+ export class WolsEncryptionError extends WolsError {
123
+ constructor(code, message, details) {
124
+ super(code, message, details);
125
+ this.name = 'WolsEncryptionError';
126
+ if (Error.captureStackTrace) {
127
+ Error.captureStackTrace(this, WolsEncryptionError);
128
+ }
129
+ }
130
+ }
131
+ // =============================================================================
132
+ // ERROR FACTORY FUNCTIONS
133
+ // =============================================================================
134
+ /**
135
+ * Create a required field error.
136
+ */
137
+ export function requiredFieldError(field, path = field) {
138
+ return new WolsValidationError(`Required field '${field}' is missing`, [
139
+ {
140
+ path,
141
+ code: WolsErrorCode.REQUIRED_FIELD,
142
+ message: `Field '${field}' is required`,
143
+ },
144
+ ]);
145
+ }
146
+ /**
147
+ * Create an invalid format error.
148
+ */
149
+ export function invalidFormatError(field, expected, path = field) {
150
+ return new WolsValidationError(`Invalid format for '${field}': expected ${expected}`, [
151
+ {
152
+ path,
153
+ code: WolsErrorCode.INVALID_FORMAT,
154
+ message: `Expected ${expected}`,
155
+ },
156
+ ]);
157
+ }
158
+ /**
159
+ * Create a parse error from a caught exception.
160
+ */
161
+ export function parseErrorFromException(error, _input) {
162
+ if (error instanceof SyntaxError) {
163
+ // Extract position from JSON.parse error message
164
+ const match = /position (\d+)/i.exec(error.message);
165
+ const position = match?.[1] ? parseInt(match[1], 10) : undefined;
166
+ const details = { originalError: error.message };
167
+ if (position !== undefined) {
168
+ details['position'] = position;
169
+ }
170
+ return new WolsParseError(WolsErrorCode.INVALID_JSON, error.message, details);
171
+ }
172
+ if (error instanceof WolsParseError) {
173
+ return error;
174
+ }
175
+ const message = error instanceof Error ? error.message : String(error);
176
+ return new WolsParseError(WolsErrorCode.PARSE_ERROR, message);
177
+ }
178
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @wemush/wols - Official WOLS TypeScript Library
3
+ *
4
+ * WeMush Open Labeling Standard (WOLS) v1.1.0 implementation
5
+ * for biological specimen labeling and traceability.
6
+ *
7
+ * @packageDocumentation
8
+ * @module @wemush/wols
9
+ * @version 1.1.0
10
+ */
11
+ // =============================================================================
12
+ // Constants
13
+ // =============================================================================
14
+ export { WOLS_VERSION, WOLS_CONTEXT } from './types.js';
15
+ // =============================================================================
16
+ // Type utilities
17
+ // =============================================================================
18
+ export { asSpecimenId, isSpecimenType, isGrowthStage, isStrain, SPECIMEN_TYPES, GROWTH_STAGES, } from './types.js';
19
+ // =============================================================================
20
+ // Errors
21
+ // =============================================================================
22
+ export { WolsErrorCode, WolsError, WolsParseError, WolsValidationError, WolsEncryptionError, } from './errors.js';
23
+ // =============================================================================
24
+ // Core Functions - Specimen
25
+ // =============================================================================
26
+ export { createSpecimen, serializeSpecimen } from './specimen.js';
27
+ // =============================================================================
28
+ // Core Functions - Validation
29
+ // =============================================================================
30
+ export { validateSpecimen } from './validator.js';
31
+ // =============================================================================
32
+ // Core Functions - Parser
33
+ // =============================================================================
34
+ export { parseSpecimen } from './parser.js';
35
+ // =============================================================================
36
+ // Core Functions - Compact URL
37
+ // =============================================================================
38
+ export { toCompactUrl, parseCompactUrl, SPECIES_CODES, getSpeciesFromCode, getCodeFromSpecies, registerSpeciesCode, } from './compact-url.js';
39
+ // =============================================================================
40
+ // Core Functions - Encryption
41
+ // =============================================================================
42
+ export { encryptSpecimen, isEncrypted, decryptSpecimen } from './crypto/index.js';
43
+ // =============================================================================
44
+ // Core Functions - QR Code Generation
45
+ // =============================================================================
46
+ export { toQRCode, toQRCodeDataURL, toQRCodeSVG, isQRAvailable, isQRAvailableSync, } from './qr/index.js';
47
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAChF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAoCxD,gFAAgF;AAChF,iBAAiB;AACjB,gFAAgF;AAChF,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,QAAQ,EACR,cAAc,EACd,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,gFAAgF;AAChF,SAAS;AACT,gFAAgF;AAChF,OAAO,EACL,aAAa,EACb,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,gFAAgF;AAChF,4BAA4B;AAC5B,gFAAgF;AAChF,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElE,gFAAgF;AAChF,8BAA8B;AAC9B,gFAAgF;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,gFAAgF;AAChF,0BAA0B;AAC1B,gFAAgF;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,gFAAgF;AAChF,+BAA+B;AAC/B,gFAAgF;AAChF,OAAO,EACL,YAAY,EACZ,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAE1B,gFAAgF;AAChF,8BAA8B;AAC9B,gFAAgF;AAChF,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAElF,gFAAgF;AAChF,sCAAsC;AACtC,gFAAgF;AAChF,OAAO,EACL,QAAQ,EACR,eAAe,EACf,WAAW,EACX,aAAa,EACb,iBAAiB,GAClB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * WOLS Specimen Parser
3
+ *
4
+ * This module provides parsing functionality for WOLS specimen JSON.
5
+ *
6
+ * @module parser
7
+ */
8
+ import { parseErrorFromException, WolsErrorCode, WolsParseError, WolsValidationError, } from './errors.js';
9
+ import { WOLS_CONTEXT, asSpecimenId, } from './types.js';
10
+ import { validateSpecimen } from './validator.js';
11
+ // =============================================================================
12
+ // HELPER FUNCTIONS
13
+ // =============================================================================
14
+ /**
15
+ * Check if a value is a plain object.
16
+ */
17
+ function isPlainObject(value) {
18
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
19
+ }
20
+ /**
21
+ * Get the first validation error code from a ValidationResult.
22
+ */
23
+ function getFirstErrorCode(errors) {
24
+ if (errors.length === 0) {
25
+ return WolsErrorCode.INVALID_FORMAT;
26
+ }
27
+ const firstError = errors[0];
28
+ if (!firstError) {
29
+ return WolsErrorCode.INVALID_FORMAT;
30
+ }
31
+ const code = firstError.code;
32
+ // Map string codes to WolsErrorCode enum
33
+ if (Object.values(WolsErrorCode).includes(code)) {
34
+ return code;
35
+ }
36
+ return WolsErrorCode.INVALID_FORMAT;
37
+ }
38
+ // =============================================================================
39
+ // MAIN PARSE FUNCTION
40
+ // =============================================================================
41
+ /**
42
+ * Parse a JSON string into a validated Specimen object.
43
+ *
44
+ * This function performs both JSON parsing and WOLS validation.
45
+ * If the JSON is invalid or the parsed object doesn't conform to WOLS,
46
+ * it returns a failure result with a detailed error.
47
+ *
48
+ * @param json - The JSON string to parse
49
+ * @returns ParseResult with either the parsed Specimen or an error
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * const result = parseSpecimen('{"@context": "https://wemush.com/wols/v1", ...}');
54
+ * if (result.success) {
55
+ * console.log('Specimen ID:', result.data.id);
56
+ * } else {
57
+ * console.error('Parse error:', result.error.message);
58
+ * }
59
+ * ```
60
+ */
61
+ export function parseSpecimen(json) {
62
+ // Step 1: Parse JSON
63
+ let parsed;
64
+ try {
65
+ parsed = JSON.parse(json);
66
+ }
67
+ catch (err) {
68
+ return {
69
+ success: false,
70
+ error: parseErrorFromException(err, json),
71
+ };
72
+ }
73
+ // Step 2: Verify it's an object
74
+ if (!isPlainObject(parsed)) {
75
+ return {
76
+ success: false,
77
+ error: new WolsParseError(WolsErrorCode.INVALID_FORMAT, 'Specimen must be a JSON object', {
78
+ receivedType: parsed === null ? 'null' : typeof parsed,
79
+ }),
80
+ };
81
+ }
82
+ // Step 3: Validate against WOLS schema
83
+ const validation = validateSpecimen(parsed);
84
+ if (!validation.valid) {
85
+ // Get the most specific error code
86
+ const errorCode = getFirstErrorCode(validation.errors);
87
+ const firstError = validation.errors[0];
88
+ // Create appropriate error
89
+ const errorMessage = validation.errors.map(e => `${e.path}: ${e.message}`).join('; ');
90
+ if (validation.errors.length === 1 && firstError) {
91
+ return {
92
+ success: false,
93
+ error: new WolsParseError(errorCode, firstError.message, {
94
+ path: firstError.path,
95
+ }),
96
+ };
97
+ }
98
+ return {
99
+ success: false,
100
+ error: new WolsValidationError(`Validation failed: ${errorMessage}`, validation.errors),
101
+ };
102
+ }
103
+ // Step 4: Cast to Specimen type (validation guarantees the shape)
104
+ const data = parsed;
105
+ const specimen = {
106
+ '@context': WOLS_CONTEXT,
107
+ '@type': 'Specimen',
108
+ id: asSpecimenId(data['id']),
109
+ version: data['version'],
110
+ type: data['type'],
111
+ species: data['species'],
112
+ };
113
+ // Copy optional fields if present
114
+ const strainValue = data['strain'];
115
+ if (strainValue !== undefined && strainValue !== null) {
116
+ specimen.strain = strainValue;
117
+ }
118
+ const stageValue = data['stage'];
119
+ if (stageValue !== undefined && stageValue !== null) {
120
+ specimen.stage = stageValue;
121
+ }
122
+ if (data['created'] !== undefined) {
123
+ specimen.created = data['created'];
124
+ }
125
+ if (data['batch'] !== undefined) {
126
+ specimen.batch = data['batch'];
127
+ }
128
+ if (data['organization'] !== undefined) {
129
+ specimen.organization = data['organization'];
130
+ }
131
+ if (data['creator'] !== undefined) {
132
+ specimen.creator = data['creator'];
133
+ }
134
+ if (data['custom'] !== undefined) {
135
+ specimen.custom = data['custom'];
136
+ }
137
+ if (data['signature'] !== undefined) {
138
+ specimen.signature = data['signature'];
139
+ }
140
+ return {
141
+ success: true,
142
+ data: specimen,
143
+ };
144
+ }
145
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/parser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,uBAAuB,EACvB,aAAa,EACb,cAAc,EACd,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EAKL,YAAY,EACZ,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF;;GAEG;AACH,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,MAA0B;IACnD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,aAAa,CAAC,cAAc,CAAC;IACtC,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,aAAa,CAAC,cAAc,CAAC;IACtC,CAAC;IAED,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC;IAE7B,yCAAyC;IACzC,IAAI,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,IAAqB,CAAC,EAAE,CAAC;QACjE,OAAO,IAAqB,CAAC;IAC/B,CAAC;IAED,OAAO,aAAa,CAAC,cAAc,CAAC;AACtC,CAAC;AAED,gFAAgF;AAChF,sBAAsB;AACtB,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,qBAAqB;IACrB,IAAI,MAAe,CAAC;IAEpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,uBAAuB,CAAC,GAAG,EAAE,IAAI,CAAC;SAC1C,CAAC;IACJ,CAAC;IAED,gCAAgC;IAChC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,IAAI,cAAc,CAAC,aAAa,CAAC,cAAc,EAAE,gCAAgC,EAAE;gBACxF,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,MAAM;aACvD,CAAC;SACH,CAAC;IACJ,CAAC;IAED,uCAAuC;IACvC,MAAM,UAAU,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAE5C,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,mCAAmC;QACnC,MAAM,SAAS,GAAG,iBAAiB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACvD,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAExC,2BAA2B;QAC3B,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEtF,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,UAAU,EAAE,CAAC;YACjD,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAI,cAAc,CAAC,SAAS,EAAE,UAAU,CAAC,OAAO,EAAE;oBACvD,IAAI,EAAE,UAAU,CAAC,IAAI;iBACtB,CAAC;aACH,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,IAAI,mBAAmB,CAAC,sBAAsB,YAAY,EAAE,EAAE,UAAU,CAAC,MAAM,CAAC;SACxF,CAAC;IACJ,CAAC;IAED,kEAAkE;IAClE,MAAM,IAAI,GAAG,MAAiC,CAAC;IAE/C,MAAM,QAAQ,GAAa;QACzB,UAAU,EAAE,YAAY;QACxB,OAAO,EAAE,UAAU;QACnB,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAW,CAAC;QACtC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAW;QAClC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAqB;QACtC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAW;KACnC,CAAC;IAEF,kCAAkC;IAClC,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACtD,QAAQ,CAAC,MAAM,GAAG,WAAqB,CAAC;IAC1C,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACpD,QAAQ,CAAC,KAAK,GAAG,UAAyB,CAAC;IAC7C,CAAC;IAED,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,SAAS,EAAE,CAAC;QAClC,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAW,CAAC;IAC/C,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;QAChC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAW,CAAC;IAC3C,CAAC;IAED,IAAI,IAAI,CAAC,cAAc,CAAC,KAAK,SAAS,EAAE,CAAC;QACvC,QAAQ,CAAC,YAAY,GAAG,IAAI,CAAC,cAAc,CAAW,CAAC;IACzD,CAAC;IAED,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,SAAS,EAAE,CAAC;QAClC,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAW,CAAC;IAC/C,CAAC;IAED,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,SAAS,EAAE,CAAC;QACjC,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAA4B,CAAC;IAC9D,CAAC;IAED,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,SAAS,EAAE,CAAC;QACpC,QAAQ,CAAC,SAAS,GAAG,IAAI,CAAC,WAAW,CAAW,CAAC;IACnD,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,QAAQ;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,235 @@
1
+ /**
2
+ * QR Code Generation Module
3
+ *
4
+ * This module provides QR code generation functionality for WOLS specimens.
5
+ * Requires the 'qrcode' package as an optional peer dependency.
6
+ *
7
+ * @module qr/generate
8
+ */
9
+ import { WolsError, WolsErrorCode } from '../errors.js';
10
+ import { serializeSpecimen } from '../specimen.js';
11
+ // Cached reference to the qrcode library
12
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
+ let qrLib = null;
14
+ let qrLibLoadAttempted = false;
15
+ /**
16
+ * Dynamically load the qrcode library.
17
+ * Returns null if the library is not installed.
18
+ */
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ async function loadQRLib() {
21
+ if (qrLibLoadAttempted) {
22
+ return qrLib;
23
+ }
24
+ qrLibLoadAttempted = true;
25
+ try {
26
+ // Dynamic import of optional peer dependency
27
+ const module = await import('qrcode');
28
+ qrLib = module.default ?? module;
29
+ return qrLib;
30
+ }
31
+ catch {
32
+ // qrcode package not installed
33
+ qrLib = null;
34
+ return null;
35
+ }
36
+ }
37
+ /**
38
+ * Ensure qrcode library is available.
39
+ * Throws an error if not installed.
40
+ */
41
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
+ async function requireQRLib() {
43
+ const lib = await loadQRLib();
44
+ if (!lib) {
45
+ throw new WolsError(WolsErrorCode.UNKNOWN_ERROR, 'QR code generation requires the "qrcode" package. Install it with: npm install qrcode', { missingDependency: 'qrcode' });
46
+ }
47
+ return lib;
48
+ }
49
+ // =============================================================================
50
+ // COMPACT URL FORMAT
51
+ // =============================================================================
52
+ /**
53
+ * Species code mapping for compact URLs.
54
+ */
55
+ const SPECIES_CODES = {
56
+ 'Pleurotus ostreatus': 'POSTR',
57
+ 'Pleurotus citrinopileatus': 'PCITRI',
58
+ 'Pleurotus djamor': 'PDJAR',
59
+ 'Pleurotus eryngii': 'PERYN',
60
+ 'Hericium erinaceus': 'HERIN',
61
+ 'Ganoderma lucidum': 'GLUCI',
62
+ 'Laetiporus pudens': 'LPUDE',
63
+ 'Lentinula edodes': 'LLENC',
64
+ 'Agrocybe polyphylla': 'APOLY',
65
+ 'Stropharia rugosoannulata': 'STRUG',
66
+ };
67
+ /**
68
+ * Growth stage to short code mapping.
69
+ */
70
+ const STAGE_CODES = {
71
+ INOCULATION: 'IN',
72
+ COLONIZATION: 'CO',
73
+ FRUITING: 'FR',
74
+ HARVEST: 'HA',
75
+ };
76
+ /**
77
+ * Convert specimen to compact URL format.
78
+ * Format: wemush://v1/{id}?s={species}&st={stage}&t={timestamp}
79
+ */
80
+ function toCompactUrl(specimen) {
81
+ // Extract the CUID part from the full ID
82
+ const cuidPart = specimen.id.replace('wemush:', '');
83
+ // Build query params
84
+ const params = new URLSearchParams();
85
+ // Add species code
86
+ const speciesCode = SPECIES_CODES[specimen.species];
87
+ if (speciesCode) {
88
+ params.set('s', speciesCode);
89
+ }
90
+ // Add stage if present
91
+ if (specimen.stage) {
92
+ const stageCode = STAGE_CODES[specimen.stage];
93
+ if (stageCode) {
94
+ params.set('st', stageCode);
95
+ }
96
+ }
97
+ // Add timestamp if created is present
98
+ if (specimen.created) {
99
+ const timestamp = Math.floor(new Date(specimen.created).getTime() / 1000);
100
+ params.set('t', String(timestamp));
101
+ }
102
+ const queryString = params.toString();
103
+ return `wemush://v1/${cuidPart}${queryString ? '?' + queryString : ''}`;
104
+ }
105
+ // =============================================================================
106
+ // QR CODE GENERATION
107
+ // =============================================================================
108
+ /**
109
+ * Generate QR code content based on format option.
110
+ */
111
+ function getQRContent(specimen, format) {
112
+ if (format === 'compact') {
113
+ return toCompactUrl(specimen);
114
+ }
115
+ return serializeSpecimen(specimen);
116
+ }
117
+ /**
118
+ * Map QRCodeOptions to library options.
119
+ */
120
+ function mapOptions(options = {}) {
121
+ const result = {
122
+ errorCorrectionLevel: options.errorCorrection ?? 'M',
123
+ width: options.size ?? 300,
124
+ margin: options.margin ?? 1,
125
+ };
126
+ if (options.color) {
127
+ result.color = options.color;
128
+ }
129
+ return result;
130
+ }
131
+ // =============================================================================
132
+ // PUBLIC API
133
+ // =============================================================================
134
+ /**
135
+ * Check if QR code generation is available.
136
+ * Returns true if the qrcode library is installed.
137
+ */
138
+ export async function isQRAvailable() {
139
+ const lib = await loadQRLib();
140
+ return lib !== null;
141
+ }
142
+ /**
143
+ * Synchronous check if QR code generation is available.
144
+ * Note: Only accurate after first async call to any QR function.
145
+ */
146
+ export function isQRAvailableSync() {
147
+ return qrLib !== null;
148
+ }
149
+ /**
150
+ * Generate QR code as PNG buffer.
151
+ *
152
+ * @param specimen - The specimen to encode
153
+ * @param options - QR code generation options
154
+ * @returns PNG buffer containing the QR code
155
+ *
156
+ * @example
157
+ * ```typescript
158
+ * const buffer = await toQRCode(specimen, { size: 400 });
159
+ * fs.writeFileSync('specimen-qr.png', buffer);
160
+ * ```
161
+ */
162
+ export async function toQRCode(specimen, options = {}) {
163
+ const lib = await requireQRLib();
164
+ const content = getQRContent(specimen, options.format ?? 'embedded');
165
+ const qrOptions = mapOptions(options);
166
+ try {
167
+ return await lib.toBuffer(content, { ...qrOptions, type: 'png' });
168
+ }
169
+ catch (err) {
170
+ const message = err instanceof Error ? err.message : String(err);
171
+ throw new WolsError(WolsErrorCode.SIZE_EXCEEDED, `Failed to generate QR code: ${message}`, {
172
+ originalError: message,
173
+ });
174
+ }
175
+ }
176
+ /**
177
+ * Generate QR code as data URL (base64 encoded PNG).
178
+ *
179
+ * @param specimen - The specimen to encode
180
+ * @param options - QR code generation options
181
+ * @returns Data URL string (data:image/png;base64,...)
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * const dataUrl = await toQRCodeDataURL(specimen);
186
+ * // Use in HTML: <img src={dataUrl} />
187
+ * ```
188
+ */
189
+ export async function toQRCodeDataURL(specimen, options = {}) {
190
+ const lib = await requireQRLib();
191
+ const content = getQRContent(specimen, options.format ?? 'embedded');
192
+ const qrOptions = mapOptions(options);
193
+ try {
194
+ return await lib.toDataURL(content, qrOptions);
195
+ }
196
+ catch (err) {
197
+ const message = err instanceof Error ? err.message : String(err);
198
+ throw new WolsError(WolsErrorCode.SIZE_EXCEEDED, `Failed to generate QR code: ${message}`, {
199
+ originalError: message,
200
+ });
201
+ }
202
+ }
203
+ /**
204
+ * Generate QR code as SVG string.
205
+ *
206
+ * @param specimen - The specimen to encode
207
+ * @param options - QR code generation options
208
+ * @returns SVG string
209
+ *
210
+ * @example
211
+ * ```typescript
212
+ * const svg = await toQRCodeSVG(specimen, { color: { dark: '#000', light: '#fff' } });
213
+ * fs.writeFileSync('specimen-qr.svg', svg);
214
+ * ```
215
+ */
216
+ export async function toQRCodeSVG(specimen, options = {}) {
217
+ const lib = await requireQRLib();
218
+ const content = getQRContent(specimen, options.format ?? 'embedded');
219
+ const qrOptions = mapOptions(options);
220
+ try {
221
+ const svg = await lib.toString(content, { ...qrOptions, type: 'svg' });
222
+ // Ensure the SVG has proper dimensions based on size option
223
+ const size = options.size ?? 300;
224
+ return svg
225
+ .replace(/width="[^"]*"/, `width="${size}"`)
226
+ .replace(/height="[^"]*"/, `height="${size}"`);
227
+ }
228
+ catch (err) {
229
+ const message = err instanceof Error ? err.message : String(err);
230
+ throw new WolsError(WolsErrorCode.SIZE_EXCEEDED, `Failed to generate QR code: ${message}`, {
231
+ originalError: message,
232
+ });
233
+ }
234
+ }
235
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/qr/generate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * QR Code Submodule
3
+ *
4
+ * This module provides QR code generation functionality for WOLS specimens.
5
+ *
6
+ * @packageDocumentation
7
+ * @module @wemush/wols/qr
8
+ */
9
+ export { toQRCode, toQRCodeDataURL, toQRCodeSVG, isQRAvailable, isQRAvailableSync, } from './generate.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/qr/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,QAAQ,EACR,eAAe,EACf,WAAW,EACX,aAAa,EACb,iBAAiB,GAClB,MAAM,eAAe,CAAC"}