@wemush/wols 1.2.0 → 1.3.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 (98) hide show
  1. package/CHANGELOG.md +170 -0
  2. package/README.md +204 -31
  3. package/dist/cjs/compact-url.d.ts +150 -0
  4. package/dist/cjs/compact-url.d.ts.map +1 -0
  5. package/dist/cjs/crypto/decrypt.d.ts +110 -0
  6. package/dist/cjs/crypto/decrypt.d.ts.map +1 -0
  7. package/dist/cjs/crypto/decrypt.js +519 -99
  8. package/dist/cjs/crypto/decrypt.js.map +1 -1
  9. package/dist/cjs/crypto/encrypt.d.ts +132 -0
  10. package/dist/cjs/crypto/encrypt.d.ts.map +1 -0
  11. package/dist/cjs/crypto/encrypt.js +281 -200
  12. package/dist/cjs/crypto/encrypt.js.map +1 -1
  13. package/dist/cjs/crypto/index.d.ts +12 -0
  14. package/dist/cjs/crypto/index.d.ts.map +1 -0
  15. package/dist/cjs/crypto/index.js +15 -2
  16. package/dist/cjs/crypto/index.js.map +1 -1
  17. package/dist/cjs/crypto/shared.d.ts +116 -0
  18. package/dist/cjs/crypto/shared.d.ts.map +1 -0
  19. package/dist/cjs/crypto/shared.js +238 -0
  20. package/dist/cjs/crypto/shared.js.map +1 -0
  21. package/dist/cjs/errors.d.ts +133 -0
  22. package/dist/cjs/errors.d.ts.map +1 -0
  23. package/dist/cjs/errors.js +39 -1
  24. package/dist/cjs/errors.js.map +1 -1
  25. package/dist/cjs/index.d.ts +29 -0
  26. package/dist/cjs/index.d.ts.map +1 -0
  27. package/dist/cjs/index.js +19 -4
  28. package/dist/cjs/index.js.map +1 -1
  29. package/dist/cjs/package.json +3 -0
  30. package/dist/cjs/parser.d.ts +30 -0
  31. package/dist/cjs/parser.d.ts.map +1 -0
  32. package/dist/cjs/qr/generate.d.ts +62 -0
  33. package/dist/cjs/qr/generate.d.ts.map +1 -0
  34. package/dist/cjs/qr/index.d.ts +10 -0
  35. package/dist/cjs/qr/index.d.ts.map +1 -0
  36. package/dist/cjs/specimen.d.ts +96 -0
  37. package/dist/cjs/specimen.d.ts.map +1 -0
  38. package/dist/cjs/specimen.js +84 -11
  39. package/dist/cjs/specimen.js.map +1 -1
  40. package/dist/cjs/types.d.ts +735 -0
  41. package/dist/cjs/types.d.ts.map +1 -0
  42. package/dist/cjs/types.js +65 -5
  43. package/dist/cjs/types.js.map +1 -1
  44. package/dist/cjs/utils/cuid.d.ts +46 -0
  45. package/dist/cjs/utils/cuid.d.ts.map +1 -0
  46. package/dist/cjs/utils/cuid.js +6 -4
  47. package/dist/cjs/utils/cuid.js.map +1 -1
  48. package/dist/cjs/utils/environment.d.ts +137 -0
  49. package/dist/cjs/utils/environment.d.ts.map +1 -0
  50. package/dist/cjs/utils/iso8601.d.ts +79 -0
  51. package/dist/cjs/utils/iso8601.d.ts.map +1 -0
  52. package/dist/cjs/utils/migration.d.ts +162 -0
  53. package/dist/cjs/utils/migration.d.ts.map +1 -0
  54. package/dist/cjs/validator.d.ts +25 -0
  55. package/dist/cjs/validator.d.ts.map +1 -0
  56. package/dist/cjs/validator.js +33 -22
  57. package/dist/cjs/validator.js.map +1 -1
  58. package/dist/esm/crypto/decrypt.js +515 -99
  59. package/dist/esm/crypto/decrypt.js.map +1 -1
  60. package/dist/esm/crypto/encrypt.js +277 -200
  61. package/dist/esm/crypto/encrypt.js.map +1 -1
  62. package/dist/esm/crypto/index.js +5 -3
  63. package/dist/esm/crypto/index.js.map +1 -1
  64. package/dist/esm/crypto/shared.js +222 -0
  65. package/dist/esm/crypto/shared.js.map +1 -0
  66. package/dist/esm/errors.js +37 -0
  67. package/dist/esm/errors.js.map +1 -1
  68. package/dist/esm/index.js +6 -6
  69. package/dist/esm/index.js.map +1 -1
  70. package/dist/esm/specimen.js +84 -12
  71. package/dist/esm/specimen.js.map +1 -1
  72. package/dist/esm/types.js +63 -4
  73. package/dist/esm/types.js.map +1 -1
  74. package/dist/esm/utils/cuid.js +6 -4
  75. package/dist/esm/utils/cuid.js.map +1 -1
  76. package/dist/esm/validator.js +34 -23
  77. package/dist/esm/validator.js.map +1 -1
  78. package/dist/types/crypto/decrypt.d.ts +93 -22
  79. package/dist/types/crypto/decrypt.d.ts.map +1 -1
  80. package/dist/types/crypto/encrypt.d.ts +106 -61
  81. package/dist/types/crypto/encrypt.d.ts.map +1 -1
  82. package/dist/types/crypto/index.d.ts +5 -3
  83. package/dist/types/crypto/index.d.ts.map +1 -1
  84. package/dist/types/crypto/shared.d.ts +116 -0
  85. package/dist/types/crypto/shared.d.ts.map +1 -0
  86. package/dist/types/errors.d.ts +31 -1
  87. package/dist/types/errors.d.ts.map +1 -1
  88. package/dist/types/index.d.ts +7 -7
  89. package/dist/types/index.d.ts.map +1 -1
  90. package/dist/types/specimen.d.ts +29 -4
  91. package/dist/types/specimen.d.ts.map +1 -1
  92. package/dist/types/types.d.ts +265 -40
  93. package/dist/types/types.d.ts.map +1 -1
  94. package/dist/types/utils/cuid.d.ts +5 -3
  95. package/dist/types/utils/cuid.d.ts.map +1 -1
  96. package/dist/types/validator.d.ts +1 -1
  97. package/dist/types/validator.d.ts.map +1 -1
  98. package/package.json +32 -14
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @wemush/wols - Official WOLS TypeScript Library
3
+ *
4
+ * WeMush Open Labeling Standard (WOLS) v1.3.0 implementation
5
+ * for biological specimen labeling and traceability.
6
+ *
7
+ * @packageDocumentation
8
+ * @module @wemush/wols
9
+ * @version 1.3.0
10
+ */
11
+ export { WOLS_VERSION, WOLS_CONTEXT } from './types.js';
12
+ export type { Brand, SpecimenId, SpecimenType, GrowthStage, Strain, Specimen, SpecimenInput, SpecimenMeta, CreateSpecimenOptions, ParseResult, ValidationResult, ValidationError, ValidationWarning, ValidationOptions, IdValidationMode, IdValidator, SpecimenRef, QRCodeOptions, EncryptionOptions, DecryptionOptions, EncryptedSpecimen, EncryptedField, EncryptionKdf, RawEncryptionKey, DecryptionFailureReason, DecryptResult, FieldEncryptedSpecimen, FieldEncryptionOptions, } from './types.js';
13
+ export { asSpecimenId, isSpecimenType, isGrowthStage, isStrain, SPECIMEN_TYPES, GROWTH_STAGES, } from './types.js';
14
+ export { registerTypeAlias, resolveTypeAlias, getTypeAliases, resolveTypeAndStage, PRIMORDIA_TYPE_ALIAS, } from './types.js';
15
+ export { WOLS_TO_PLATFORM_MAP, mapToWolsType, mapFromWolsType, registerPlatformType, } from './types.js';
16
+ export { normalizeGeneration, isValidGeneration } from './types.js';
17
+ export type { GenerationFormat } from './types.js';
18
+ export { WolsErrorCode, WolsError, WolsParseError, WolsValidationError, WolsEncryptionError, WolsDecryptionError, } from './errors.js';
19
+ export { createSpecimen, serializeSpecimen, PRIMORDIA_AS_TYPE_WARNING } from './specimen.js';
20
+ export { validateSpecimen } from './validator.js';
21
+ export { parseSpecimen } from './parser.js';
22
+ export { toCompactUrl, parseCompactUrl, parseCompactUrlOrThrow, parseCompactUrlOrNull, SPECIES_CODES, getSpeciesFromCode, getCodeFromSpecies, registerSpeciesCode, } from './compact-url.js';
23
+ export { encryptSpecimen, encryptFields, isEncrypted, isEncryptedSpecimen, isEncryptedField, toEncryptedUrl, decryptSpecimen, decryptPlaintext, decryptField, decryptFields, parseEncryptedUrl, type FieldBinding, base64UrlEncode, base64UrlDecode, derivePassphraseKey, } from './crypto/index.js';
24
+ export { toQRCode, toQRCodeDataURL, toQRCodeSVG, isQRAvailable, isQRAvailableSync, } from './qr/index.js';
25
+ export { isServer, isBrowser, isWebWorker, isDeno, isBun, getRuntimeEnvironment, supportsWebCrypto, supportsNodeCrypto, isCryptoSupported, supportsTextEncoding, supportsURLAPIs, } from './utils/environment.js';
26
+ export type { RuntimeEnvironment } from './utils/environment.js';
27
+ export { compareVersions, isOutdated, isNewer, getCurrentVersion, registerMigration, canMigrate, migrate, getMigrations, clearMigrations, } from './utils/migration.js';
28
+ export type { VersionComparison, MigrationHandler } from './utils/migration.js';
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAKxD,YAAY,EAEV,KAAK,EACL,UAAU,EAGV,YAAY,EACZ,WAAW,EACX,MAAM,EACN,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,qBAAqB,EAGrB,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EAGjB,gBAAgB,EAChB,WAAW,EAGX,WAAW,EAGX,aAAa,EAGb,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,uBAAuB,EACvB,aAAa,EACb,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAKpB,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,QAAQ,EACR,cAAc,EACd,aAAa,GACd,MAAM,YAAY,CAAC;AAKpB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAKpB,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAKpB,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAKnD,OAAO,EACL,aAAa,EACb,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAKrB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAK7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAKlD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAK5C,OAAO,EACL,YAAY,EACZ,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EACL,eAAe,EACf,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,KAAK,YAAY,EACjB,eAAe,EACf,eAAe,EACf,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EACL,QAAQ,EACR,eAAe,EACf,WAAW,EACX,aAAa,EACb,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAKvB,OAAO,EACL,QAAQ,EACR,SAAS,EACT,WAAW,EACX,MAAM,EACN,KAAK,EACL,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,GAChB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAKjE,OAAO,EACL,eAAe,EACf,UAAU,EACV,OAAO,EACP,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,OAAO,EACP,aAAa,EACb,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/cjs/index.js CHANGED
@@ -2,16 +2,16 @@
2
2
  /**
3
3
  * @wemush/wols - Official WOLS TypeScript Library
4
4
  *
5
- * WeMush Open Labeling Standard (WOLS) v1.1.0 implementation
5
+ * WeMush Open Labeling Standard (WOLS) v1.3.0 implementation
6
6
  * for biological specimen labeling and traceability.
7
7
  *
8
8
  * @packageDocumentation
9
9
  * @module @wemush/wols
10
- * @version 1.1.0
10
+ * @version 1.3.0
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.supportsNodeCrypto = exports.supportsWebCrypto = exports.getRuntimeEnvironment = exports.isBun = exports.isDeno = exports.isWebWorker = exports.isBrowser = exports.isServer = exports.isQRAvailableSync = exports.isQRAvailable = exports.toQRCodeSVG = exports.toQRCodeDataURL = exports.toQRCode = exports.decryptSpecimen = exports.isEncrypted = exports.encryptSpecimen = exports.registerSpeciesCode = exports.getCodeFromSpecies = exports.getSpeciesFromCode = exports.SPECIES_CODES = exports.parseCompactUrlOrNull = exports.parseCompactUrlOrThrow = exports.parseCompactUrl = exports.toCompactUrl = exports.parseSpecimen = exports.validateSpecimen = exports.serializeSpecimen = exports.createSpecimen = exports.WolsEncryptionError = exports.WolsValidationError = exports.WolsParseError = exports.WolsError = exports.WolsErrorCode = exports.isValidGeneration = exports.normalizeGeneration = exports.registerPlatformType = exports.mapFromWolsType = exports.mapToWolsType = exports.WOLS_TO_PLATFORM_MAP = exports.getTypeAliases = exports.resolveTypeAlias = exports.registerTypeAlias = exports.GROWTH_STAGES = exports.SPECIMEN_TYPES = exports.isStrain = exports.isGrowthStage = exports.isSpecimenType = exports.asSpecimenId = exports.WOLS_CONTEXT = exports.WOLS_VERSION = void 0;
14
- exports.clearMigrations = exports.getMigrations = exports.migrate = exports.canMigrate = exports.registerMigration = exports.getCurrentVersion = exports.isNewer = exports.isOutdated = exports.compareVersions = exports.supportsURLAPIs = exports.supportsTextEncoding = exports.isCryptoSupported = void 0;
13
+ exports.base64UrlEncode = exports.parseEncryptedUrl = exports.decryptFields = exports.decryptField = exports.decryptPlaintext = exports.decryptSpecimen = exports.toEncryptedUrl = exports.isEncryptedField = exports.isEncryptedSpecimen = exports.isEncrypted = exports.encryptFields = exports.encryptSpecimen = exports.registerSpeciesCode = exports.getCodeFromSpecies = exports.getSpeciesFromCode = exports.SPECIES_CODES = exports.parseCompactUrlOrNull = exports.parseCompactUrlOrThrow = exports.parseCompactUrl = exports.toCompactUrl = exports.parseSpecimen = exports.validateSpecimen = exports.PRIMORDIA_AS_TYPE_WARNING = exports.serializeSpecimen = exports.createSpecimen = exports.WolsDecryptionError = exports.WolsEncryptionError = exports.WolsValidationError = exports.WolsParseError = exports.WolsError = exports.WolsErrorCode = exports.isValidGeneration = exports.normalizeGeneration = exports.registerPlatformType = exports.mapFromWolsType = exports.mapToWolsType = exports.WOLS_TO_PLATFORM_MAP = exports.PRIMORDIA_TYPE_ALIAS = exports.resolveTypeAndStage = exports.getTypeAliases = exports.resolveTypeAlias = exports.registerTypeAlias = exports.GROWTH_STAGES = exports.SPECIMEN_TYPES = exports.isStrain = exports.isGrowthStage = exports.isSpecimenType = exports.asSpecimenId = exports.WOLS_CONTEXT = exports.WOLS_VERSION = void 0;
14
+ exports.clearMigrations = exports.getMigrations = exports.migrate = exports.canMigrate = exports.registerMigration = exports.getCurrentVersion = exports.isNewer = exports.isOutdated = exports.compareVersions = exports.supportsURLAPIs = exports.supportsTextEncoding = exports.isCryptoSupported = exports.supportsNodeCrypto = exports.supportsWebCrypto = exports.getRuntimeEnvironment = exports.isBun = exports.isDeno = exports.isWebWorker = exports.isBrowser = exports.isServer = exports.isQRAvailableSync = exports.isQRAvailable = exports.toQRCodeSVG = exports.toQRCodeDataURL = exports.toQRCode = exports.derivePassphraseKey = exports.base64UrlDecode = void 0;
15
15
  // =============================================================================
16
16
  // Constants
17
17
  // =============================================================================
@@ -35,6 +35,8 @@ var types_js_3 = require("./types.js");
35
35
  Object.defineProperty(exports, "registerTypeAlias", { enumerable: true, get: function () { return types_js_3.registerTypeAlias; } });
36
36
  Object.defineProperty(exports, "resolveTypeAlias", { enumerable: true, get: function () { return types_js_3.resolveTypeAlias; } });
37
37
  Object.defineProperty(exports, "getTypeAliases", { enumerable: true, get: function () { return types_js_3.getTypeAliases; } });
38
+ Object.defineProperty(exports, "resolveTypeAndStage", { enumerable: true, get: function () { return types_js_3.resolveTypeAndStage; } });
39
+ Object.defineProperty(exports, "PRIMORDIA_TYPE_ALIAS", { enumerable: true, get: function () { return types_js_3.PRIMORDIA_TYPE_ALIAS; } });
38
40
  // =============================================================================
39
41
  // Type Mapping System (v1.2.0)
40
42
  // =============================================================================
@@ -58,12 +60,14 @@ Object.defineProperty(exports, "WolsError", { enumerable: true, get: function ()
58
60
  Object.defineProperty(exports, "WolsParseError", { enumerable: true, get: function () { return errors_js_1.WolsParseError; } });
59
61
  Object.defineProperty(exports, "WolsValidationError", { enumerable: true, get: function () { return errors_js_1.WolsValidationError; } });
60
62
  Object.defineProperty(exports, "WolsEncryptionError", { enumerable: true, get: function () { return errors_js_1.WolsEncryptionError; } });
63
+ Object.defineProperty(exports, "WolsDecryptionError", { enumerable: true, get: function () { return errors_js_1.WolsDecryptionError; } });
61
64
  // =============================================================================
62
65
  // Core Functions - Specimen
63
66
  // =============================================================================
64
67
  var specimen_js_1 = require("./specimen.js");
65
68
  Object.defineProperty(exports, "createSpecimen", { enumerable: true, get: function () { return specimen_js_1.createSpecimen; } });
66
69
  Object.defineProperty(exports, "serializeSpecimen", { enumerable: true, get: function () { return specimen_js_1.serializeSpecimen; } });
70
+ Object.defineProperty(exports, "PRIMORDIA_AS_TYPE_WARNING", { enumerable: true, get: function () { return specimen_js_1.PRIMORDIA_AS_TYPE_WARNING; } });
67
71
  // =============================================================================
68
72
  // Core Functions - Validation
69
73
  // =============================================================================
@@ -91,8 +95,19 @@ Object.defineProperty(exports, "registerSpeciesCode", { enumerable: true, get: f
91
95
  // =============================================================================
92
96
  var index_js_1 = require("./crypto/index.js");
93
97
  Object.defineProperty(exports, "encryptSpecimen", { enumerable: true, get: function () { return index_js_1.encryptSpecimen; } });
98
+ Object.defineProperty(exports, "encryptFields", { enumerable: true, get: function () { return index_js_1.encryptFields; } });
94
99
  Object.defineProperty(exports, "isEncrypted", { enumerable: true, get: function () { return index_js_1.isEncrypted; } });
100
+ Object.defineProperty(exports, "isEncryptedSpecimen", { enumerable: true, get: function () { return index_js_1.isEncryptedSpecimen; } });
101
+ Object.defineProperty(exports, "isEncryptedField", { enumerable: true, get: function () { return index_js_1.isEncryptedField; } });
102
+ Object.defineProperty(exports, "toEncryptedUrl", { enumerable: true, get: function () { return index_js_1.toEncryptedUrl; } });
95
103
  Object.defineProperty(exports, "decryptSpecimen", { enumerable: true, get: function () { return index_js_1.decryptSpecimen; } });
104
+ Object.defineProperty(exports, "decryptPlaintext", { enumerable: true, get: function () { return index_js_1.decryptPlaintext; } });
105
+ Object.defineProperty(exports, "decryptField", { enumerable: true, get: function () { return index_js_1.decryptField; } });
106
+ Object.defineProperty(exports, "decryptFields", { enumerable: true, get: function () { return index_js_1.decryptFields; } });
107
+ Object.defineProperty(exports, "parseEncryptedUrl", { enumerable: true, get: function () { return index_js_1.parseEncryptedUrl; } });
108
+ Object.defineProperty(exports, "base64UrlEncode", { enumerable: true, get: function () { return index_js_1.base64UrlEncode; } });
109
+ Object.defineProperty(exports, "base64UrlDecode", { enumerable: true, get: function () { return index_js_1.base64UrlDecode; } });
110
+ Object.defineProperty(exports, "derivePassphraseKey", { enumerable: true, get: function () { return index_js_1.derivePassphraseKey; } });
96
111
  // =============================================================================
97
112
  // Core Functions - QR Code Generation
98
113
  // =============================================================================
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * WOLS Specimen Parser
3
+ *
4
+ * This module provides parsing functionality for WOLS specimen JSON.
5
+ *
6
+ * @module parser
7
+ */
8
+ import { type ParseResult, type Specimen } from './types.js';
9
+ /**
10
+ * Parse a JSON string into a validated Specimen object.
11
+ *
12
+ * This function performs both JSON parsing and WOLS validation.
13
+ * If the JSON is invalid or the parsed object doesn't conform to WOLS,
14
+ * it returns a failure result with a detailed error.
15
+ *
16
+ * @param json - The JSON string to parse
17
+ * @returns ParseResult with either the parsed Specimen or an error
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * const result = parseSpecimen('{"@context": "https://wemush.com/wols/v1", ...}');
22
+ * if (result.success) {
23
+ * console.log('Specimen ID:', result.data.id);
24
+ * } else {
25
+ * console.error('Parse error:', result.error.message);
26
+ * }
27
+ * ```
28
+ */
29
+ export declare function parseSpecimen(json: string): ParseResult<Specimen>;
30
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/parser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,QAAQ,EAKd,MAAM,YAAY,CAAC;AAyCpB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,CAwGjE"}
@@ -0,0 +1,62 @@
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 type { Specimen, QRCodeOptions } from '../types.js';
10
+ /**
11
+ * Check if QR code generation is available.
12
+ * Returns true if the qrcode library is installed.
13
+ */
14
+ export declare function isQRAvailable(): Promise<boolean>;
15
+ /**
16
+ * Synchronous check if QR code generation is available.
17
+ * Note: Only accurate after first async call to any QR function.
18
+ */
19
+ export declare function isQRAvailableSync(): boolean;
20
+ /**
21
+ * Generate QR code as PNG buffer.
22
+ *
23
+ * @param specimen - The specimen to encode
24
+ * @param options - QR code generation options
25
+ * @returns PNG buffer containing the QR code
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const buffer = await toQRCode(specimen, { size: 400 });
30
+ * fs.writeFileSync('specimen-qr.png', buffer);
31
+ * ```
32
+ */
33
+ export declare function toQRCode(specimen: Specimen, options?: QRCodeOptions): Promise<Buffer>;
34
+ /**
35
+ * Generate QR code as data URL (base64 encoded PNG).
36
+ *
37
+ * @param specimen - The specimen to encode
38
+ * @param options - QR code generation options
39
+ * @returns Data URL string (data:image/png;base64,...)
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const dataUrl = await toQRCodeDataURL(specimen);
44
+ * // Use in HTML: <img src={dataUrl} />
45
+ * ```
46
+ */
47
+ export declare function toQRCodeDataURL(specimen: Specimen, options?: QRCodeOptions): Promise<string>;
48
+ /**
49
+ * Generate QR code as SVG string.
50
+ *
51
+ * @param specimen - The specimen to encode
52
+ * @param options - QR code generation options
53
+ * @returns SVG string
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const svg = await toQRCodeSVG(specimen, { color: { dark: '#000', light: '#fff' } });
58
+ * fs.writeFileSync('specimen-qr.svg', svg);
59
+ * ```
60
+ */
61
+ export declare function toQRCodeSVG(specimen: Specimen, options?: QRCodeOptions): Promise<string>;
62
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/qr/generate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAwK3D;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAGtD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAa/F;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAajB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
@@ -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.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","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"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Specimen Creation and Serialization
3
+ *
4
+ * This module provides functions to create and serialize
5
+ * WOLS v1.3.0 compliant specimen objects.
6
+ *
7
+ * @module specimen
8
+ */
9
+ import type { CreateSpecimenOptions, Specimen, SpecimenInput } from './types.js';
10
+ /**
11
+ * Warning code emitted when `PRIMORDIA` is supplied as a specimen type.
12
+ *
13
+ * @since 1.3.0
14
+ */
15
+ export declare const PRIMORDIA_AS_TYPE_WARNING = "PRIMORDIA_AS_TYPE";
16
+ /**
17
+ * Create a new specimen with auto-generated ID and JSON-LD fields.
18
+ *
19
+ * This function creates a fully-formed WOLS v1.3.0 compliant Specimen
20
+ * with automatic ID generation, version assignment, and JSON-LD context.
21
+ *
22
+ * Type aliases resolve case-insensitively. `PRIMORDIA` supplied as a type
23
+ * resolves to `FRUITING`, sets `stage: 'PRIMORDIA'` when no stage was given
24
+ * (a supplied stage is never overridden), and emits a warning.
25
+ *
26
+ * @param input - Specimen creation parameters
27
+ * @param options - `onWarning` receives non-fatal warnings (default: console.warn)
28
+ * @returns Fully-formed Specimen with JSON-LD fields
29
+ * @throws Error if the type is unknown or `created` is not ISO 8601
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * // Minimal specimen
34
+ * const culture = createSpecimen({
35
+ * type: 'CULTURE',
36
+ * species: 'Pleurotus ostreatus',
37
+ * });
38
+ *
39
+ * // Full specimen with strain info
40
+ * const substrate = createSpecimen({
41
+ * type: 'SUBSTRATE',
42
+ * species: 'Hericium erinaceus',
43
+ * strain: {
44
+ * name: "Lion's Mane Premium",
45
+ * generation: 'F2',
46
+ * clonalGeneration: 3,
47
+ * },
48
+ * stage: 'COLONIZATION',
49
+ * batch: 'batch_2025_12_001',
50
+ * organization: 'org_mushoh',
51
+ * });
52
+ *
53
+ * // String strain shorthand
54
+ * const spawn = createSpecimen({
55
+ * type: 'SPAWN',
56
+ * species: 'Ganoderma lucidum',
57
+ * strain: 'Reishi Red', // Auto-expands to { name: 'Reishi Red' }
58
+ * });
59
+ *
60
+ * // PRIMORDIA as a type (v1.3.0) -> type FRUITING, stage PRIMORDIA, plus a warning
61
+ * const pinning = createSpecimen(
62
+ * { type: 'PRIMORDIA', species: 'Pleurotus ostreatus' },
63
+ * { onWarning: w => console.info(w.message) }
64
+ * );
65
+ *
66
+ * // Explicit creation timestamp (v1.3.0)
67
+ * const dated = createSpecimen({
68
+ * type: 'CULTURE',
69
+ * species: 'Pleurotus ostreatus',
70
+ * created: '2025-12-16T10:30:00Z',
71
+ * });
72
+ * ```
73
+ */
74
+ export declare function createSpecimen(input: SpecimenInput, options?: CreateSpecimenOptions): Specimen;
75
+ /**
76
+ * Serialize a specimen to JSON-LD string.
77
+ *
78
+ * The output is formatted with JSON-LD fields (@context, @type) first,
79
+ * followed by id, version, and remaining fields. Undefined fields are omitted.
80
+ *
81
+ * @param specimen - Specimen to serialize
82
+ * @returns JSON string suitable for QR encoding
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * const specimen = createSpecimen({
87
+ * type: 'CULTURE',
88
+ * species: 'Pleurotus ostreatus',
89
+ * });
90
+ *
91
+ * const json = serializeSpecimen(specimen);
92
+ * // Returns: '{"@context":"https://wemush.com/wols/v1","@type":"Specimen",...}'
93
+ * ```
94
+ */
95
+ export declare function serializeSpecimen(specimen: Specimen): string;
96
+ //# sourceMappingURL=specimen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"specimen.d.ts","sourceRoot":"","sources":["../../src/specimen.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,QAAQ,EACR,aAAa,EAGd,MAAM,YAAY,CAAC;AAWpB;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,sBAAsB,CAAC;AAkC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,aAAa,EACpB,OAAO,GAAE,qBAA0B,GAClC,QAAQ,CAmFV;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CA4D5D"}
@@ -3,15 +3,31 @@
3
3
  * Specimen Creation and Serialization
4
4
  *
5
5
  * This module provides functions to create and serialize
6
- * WOLS v1.1.0 compliant specimen objects.
6
+ * WOLS v1.3.0 compliant specimen objects.
7
7
  *
8
8
  * @module specimen
9
9
  */
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.PRIMORDIA_AS_TYPE_WARNING = void 0;
11
12
  exports.createSpecimen = createSpecimen;
12
13
  exports.serializeSpecimen = serializeSpecimen;
13
14
  const types_js_1 = require("./types.js");
14
15
  const cuid_js_1 = require("./utils/cuid.js");
16
+ const iso8601_js_1 = require("./utils/iso8601.js");
17
+ /**
18
+ * Warning code emitted when `PRIMORDIA` is supplied as a specimen type.
19
+ *
20
+ * @since 1.3.0
21
+ */
22
+ exports.PRIMORDIA_AS_TYPE_WARNING = 'PRIMORDIA_AS_TYPE';
23
+ function primordiaWarning() {
24
+ return {
25
+ path: 'type',
26
+ code: exports.PRIMORDIA_AS_TYPE_WARNING,
27
+ message: `'PRIMORDIA' is a growth stage, not a specimen type; resolved to type 'FRUITING'`,
28
+ suggestion: `Use type: 'FRUITING', stage: 'PRIMORDIA'`,
29
+ };
30
+ }
15
31
  /**
16
32
  * Expand a strain input to a full Strain object.
17
33
  * String inputs are expanded to { name: string }.
@@ -34,11 +50,17 @@ function expandStrain(strain) {
34
50
  /**
35
51
  * Create a new specimen with auto-generated ID and JSON-LD fields.
36
52
  *
37
- * This function creates a fully-formed WOLS v1.1.0 compliant Specimen
53
+ * This function creates a fully-formed WOLS v1.3.0 compliant Specimen
38
54
  * with automatic ID generation, version assignment, and JSON-LD context.
39
55
  *
56
+ * Type aliases resolve case-insensitively. `PRIMORDIA` supplied as a type
57
+ * resolves to `FRUITING`, sets `stage: 'PRIMORDIA'` when no stage was given
58
+ * (a supplied stage is never overridden), and emits a warning.
59
+ *
40
60
  * @param input - Specimen creation parameters
61
+ * @param options - `onWarning` receives non-fatal warnings (default: console.warn)
41
62
  * @returns Fully-formed Specimen with JSON-LD fields
63
+ * @throws Error if the type is unknown or `created` is not ISO 8601
42
64
  *
43
65
  * @example
44
66
  * ```typescript
@@ -68,33 +90,74 @@ function expandStrain(strain) {
68
90
  * species: 'Ganoderma lucidum',
69
91
  * strain: 'Reishi Red', // Auto-expands to { name: 'Reishi Red' }
70
92
  * });
93
+ *
94
+ * // PRIMORDIA as a type (v1.3.0) -> type FRUITING, stage PRIMORDIA, plus a warning
95
+ * const pinning = createSpecimen(
96
+ * { type: 'PRIMORDIA', species: 'Pleurotus ostreatus' },
97
+ * { onWarning: w => console.info(w.message) }
98
+ * );
99
+ *
100
+ * // Explicit creation timestamp (v1.3.0)
101
+ * const dated = createSpecimen({
102
+ * type: 'CULTURE',
103
+ * species: 'Pleurotus ostreatus',
104
+ * created: '2025-12-16T10:30:00Z',
105
+ * });
71
106
  * ```
72
107
  */
73
- function createSpecimen(input) {
108
+ function createSpecimen(input, options = {}) {
74
109
  const id = (0, types_js_1.asSpecimenId)((0, cuid_js_1.createSpecimenId)());
75
110
  const strain = expandStrain(input.strain);
76
111
  // Resolve type alias to canonical WOLS type (e.g., 'LIQUID_CULTURE' -> 'CULTURE')
77
- const resolvedType = (0, types_js_1.resolveTypeAlias)(input.type);
78
- if (!(0, types_js_1.isSpecimenType)(resolvedType)) {
112
+ const resolved = (0, types_js_1.resolveTypeAndStage)(input.type, input.stage);
113
+ if (resolved === null) {
79
114
  throw new Error(`Invalid specimen type: '${input.type}'. ` +
80
115
  `Must be one of: CULTURE, SPAWN, SUBSTRATE, FRUITING, HARVEST ` +
81
116
  `(or a registered alias).`);
82
117
  }
118
+ let created;
119
+ if (input.created !== undefined) {
120
+ if (input.created instanceof Date) {
121
+ if (Number.isNaN(input.created.getTime())) {
122
+ throw new Error('Invalid created timestamp: Date is invalid. Must be ISO 8601.');
123
+ }
124
+ created = input.created.toISOString();
125
+ }
126
+ else {
127
+ created = input.created;
128
+ }
129
+ if (typeof created !== 'string' || !(0, iso8601_js_1.isValidISO8601)(created)) {
130
+ throw new Error(`Invalid created timestamp: '${String(input.created)}'. Must be ISO 8601.`);
131
+ }
132
+ }
133
+ if (resolved.primordia) {
134
+ const warning = primordiaWarning();
135
+ if (options.onWarning) {
136
+ options.onWarning(warning);
137
+ }
138
+ else {
139
+ // eslint-disable-next-line no-console
140
+ console.warn(`[@wemush/wols] ${warning.message}. ${warning.suggestion ?? ''}`.trim());
141
+ }
142
+ }
83
143
  // Build specimen with required fields
84
144
  const specimen = {
85
145
  '@context': types_js_1.WOLS_CONTEXT,
86
146
  '@type': 'Specimen',
87
147
  id,
88
148
  version: types_js_1.WOLS_VERSION,
89
- type: resolvedType,
149
+ type: resolved.type,
90
150
  species: input.species,
91
151
  };
92
152
  // Add optional fields only if defined
93
153
  if (strain !== undefined) {
94
154
  specimen.strain = strain;
95
155
  }
96
- if (input.stage !== undefined) {
97
- specimen.stage = input.stage;
156
+ if (resolved.stage !== undefined) {
157
+ specimen.stage = resolved.stage;
158
+ }
159
+ if (created !== undefined) {
160
+ specimen.created = created;
98
161
  }
99
162
  if (input.batch !== undefined) {
100
163
  specimen.batch = input.batch;
@@ -134,21 +197,31 @@ function createSpecimen(input) {
134
197
  * ```
135
198
  */
136
199
  function serializeSpecimen(specimen) {
200
+ // WOLS v1.3.0: PRIMORDIA is never emitted as a type. A specimen object built
201
+ // by hand with type PRIMORDIA gets the same resolution as createSpecimen()
202
+ // (shared resolveTypeAndStage). Any other type is emitted as given.
203
+ let type = specimen.type;
204
+ let stage = specimen.stage;
205
+ const resolved = (0, types_js_1.resolveTypeAndStage)(type, stage);
206
+ if (resolved?.primordia) {
207
+ type = resolved.type;
208
+ stage = resolved.stage;
209
+ }
137
210
  // Build ordered object with JSON-LD fields first
138
211
  const ordered = {
139
212
  '@context': specimen['@context'],
140
213
  '@type': specimen['@type'],
141
214
  id: specimen.id,
142
215
  version: specimen.version,
143
- type: specimen.type,
216
+ type,
144
217
  species: specimen.species,
145
218
  };
146
219
  // Add optional fields in order, only if defined
147
220
  if (specimen.strain !== undefined) {
148
221
  ordered['strain'] = specimen.strain;
149
222
  }
150
- if (specimen.stage !== undefined) {
151
- ordered['stage'] = specimen.stage;
223
+ if (stage !== undefined) {
224
+ ordered['stage'] = stage;
152
225
  }
153
226
  if (specimen.created !== undefined) {
154
227
  ordered['created'] = specimen.created;
@@ -1 +1 @@
1
- {"version":3,"file":"specimen.js","sourceRoot":"","sources":["../../src/specimen.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"specimen.js","sourceRoot":"","sources":["../../src/specimen.ts"],"names":[],"mappings":"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"}