@wemush/wols 0.1.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 (121) 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/compact-url.js +64 -0
  6. package/dist/cjs/compact-url.js.map +1 -1
  7. package/dist/cjs/crypto/decrypt.d.ts +110 -0
  8. package/dist/cjs/crypto/decrypt.d.ts.map +1 -0
  9. package/dist/cjs/crypto/decrypt.js +521 -90
  10. package/dist/cjs/crypto/decrypt.js.map +1 -1
  11. package/dist/cjs/crypto/encrypt.d.ts +132 -0
  12. package/dist/cjs/crypto/encrypt.d.ts.map +1 -0
  13. package/dist/cjs/crypto/encrypt.js +288 -105
  14. package/dist/cjs/crypto/encrypt.js.map +1 -1
  15. package/dist/cjs/crypto/index.d.ts +12 -0
  16. package/dist/cjs/crypto/index.d.ts.map +1 -0
  17. package/dist/cjs/crypto/index.js +15 -2
  18. package/dist/cjs/crypto/index.js.map +1 -1
  19. package/dist/cjs/crypto/shared.d.ts +116 -0
  20. package/dist/cjs/crypto/shared.d.ts.map +1 -0
  21. package/dist/cjs/crypto/shared.js +238 -0
  22. package/dist/cjs/crypto/shared.js.map +1 -0
  23. package/dist/cjs/errors.d.ts +133 -0
  24. package/dist/cjs/errors.d.ts.map +1 -0
  25. package/dist/cjs/errors.js +39 -1
  26. package/dist/cjs/errors.js.map +1 -1
  27. package/dist/cjs/index.d.ts +29 -0
  28. package/dist/cjs/index.d.ts.map +1 -0
  29. package/dist/cjs/index.js +70 -3
  30. package/dist/cjs/index.js.map +1 -1
  31. package/dist/cjs/package.json +3 -0
  32. package/dist/cjs/parser.d.ts +30 -0
  33. package/dist/cjs/parser.d.ts.map +1 -0
  34. package/dist/cjs/parser.js +3 -0
  35. package/dist/cjs/parser.js.map +1 -1
  36. package/dist/cjs/qr/generate.d.ts +62 -0
  37. package/dist/cjs/qr/generate.d.ts.map +1 -0
  38. package/dist/cjs/qr/index.d.ts +10 -0
  39. package/dist/cjs/qr/index.d.ts.map +1 -0
  40. package/dist/cjs/specimen.d.ts +96 -0
  41. package/dist/cjs/specimen.d.ts.map +1 -0
  42. package/dist/cjs/specimen.js +95 -9
  43. package/dist/cjs/specimen.js.map +1 -1
  44. package/dist/cjs/types.d.ts +735 -0
  45. package/dist/cjs/types.d.ts.map +1 -0
  46. package/dist/cjs/types.js +327 -3
  47. package/dist/cjs/types.js.map +1 -1
  48. package/dist/cjs/utils/cuid.d.ts +46 -0
  49. package/dist/cjs/utils/cuid.d.ts.map +1 -0
  50. package/dist/cjs/utils/cuid.js +6 -4
  51. package/dist/cjs/utils/cuid.js.map +1 -1
  52. package/dist/cjs/utils/environment.d.ts +137 -0
  53. package/dist/cjs/utils/environment.d.ts.map +1 -0
  54. package/dist/cjs/utils/environment.js +206 -0
  55. package/dist/cjs/utils/environment.js.map +1 -0
  56. package/dist/cjs/utils/iso8601.d.ts +79 -0
  57. package/dist/cjs/utils/iso8601.d.ts.map +1 -0
  58. package/dist/cjs/utils/migration.d.ts +162 -0
  59. package/dist/cjs/utils/migration.d.ts.map +1 -0
  60. package/dist/cjs/utils/migration.js +248 -0
  61. package/dist/cjs/utils/migration.js.map +1 -0
  62. package/dist/cjs/validator.d.ts +25 -0
  63. package/dist/cjs/validator.d.ts.map +1 -0
  64. package/dist/cjs/validator.js +85 -21
  65. package/dist/cjs/validator.js.map +1 -1
  66. package/dist/esm/compact-url.js +62 -0
  67. package/dist/esm/compact-url.js.map +1 -1
  68. package/dist/esm/crypto/decrypt.js +517 -90
  69. package/dist/esm/crypto/decrypt.js.map +1 -1
  70. package/dist/esm/crypto/encrypt.js +284 -105
  71. package/dist/esm/crypto/encrypt.js.map +1 -1
  72. package/dist/esm/crypto/index.js +5 -3
  73. package/dist/esm/crypto/index.js.map +1 -1
  74. package/dist/esm/crypto/shared.js +222 -0
  75. package/dist/esm/crypto/shared.js.map +1 -0
  76. package/dist/esm/errors.js +37 -0
  77. package/dist/esm/errors.js.map +1 -1
  78. package/dist/esm/index.js +26 -6
  79. package/dist/esm/index.js.map +1 -1
  80. package/dist/esm/parser.js +3 -0
  81. package/dist/esm/parser.js.map +1 -1
  82. package/dist/esm/specimen.js +95 -10
  83. package/dist/esm/specimen.js.map +1 -1
  84. package/dist/esm/types.js +317 -2
  85. package/dist/esm/types.js.map +1 -1
  86. package/dist/esm/utils/cuid.js +6 -4
  87. package/dist/esm/utils/cuid.js.map +1 -1
  88. package/dist/esm/utils/environment.js +193 -0
  89. package/dist/esm/utils/environment.js.map +1 -0
  90. package/dist/esm/utils/migration.js +237 -0
  91. package/dist/esm/utils/migration.js.map +1 -0
  92. package/dist/esm/validator.js +86 -22
  93. package/dist/esm/validator.js.map +1 -1
  94. package/dist/types/compact-url.d.ts +46 -0
  95. package/dist/types/compact-url.d.ts.map +1 -1
  96. package/dist/types/crypto/decrypt.d.ts +95 -18
  97. package/dist/types/crypto/decrypt.d.ts.map +1 -1
  98. package/dist/types/crypto/encrypt.d.ts +114 -14
  99. package/dist/types/crypto/encrypt.d.ts.map +1 -1
  100. package/dist/types/crypto/index.d.ts +5 -3
  101. package/dist/types/crypto/index.d.ts.map +1 -1
  102. package/dist/types/crypto/shared.d.ts +116 -0
  103. package/dist/types/crypto/shared.d.ts.map +1 -0
  104. package/dist/types/errors.d.ts +31 -1
  105. package/dist/types/errors.d.ts.map +1 -1
  106. package/dist/types/index.d.ts +15 -7
  107. package/dist/types/index.d.ts.map +1 -1
  108. package/dist/types/parser.d.ts.map +1 -1
  109. package/dist/types/specimen.d.ts +29 -4
  110. package/dist/types/specimen.d.ts.map +1 -1
  111. package/dist/types/types.d.ts +483 -17
  112. package/dist/types/types.d.ts.map +1 -1
  113. package/dist/types/utils/cuid.d.ts +5 -3
  114. package/dist/types/utils/cuid.d.ts.map +1 -1
  115. package/dist/types/utils/environment.d.ts +137 -0
  116. package/dist/types/utils/environment.d.ts.map +1 -0
  117. package/dist/types/utils/migration.d.ts +162 -0
  118. package/dist/types/utils/migration.d.ts.map +1 -0
  119. package/dist/types/validator.d.ts +1 -1
  120. package/dist/types/validator.d.ts.map +1 -1
  121. package/package.json +32 -14
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ /**
3
+ * Environment Detection Utilities
4
+ *
5
+ * This module provides runtime environment detection for selecting
6
+ * appropriate crypto implementations and other environment-specific behavior.
7
+ *
8
+ * @module utils/environment
9
+ * @since 1.2.0
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.isServer = isServer;
13
+ exports.isBrowser = isBrowser;
14
+ exports.isWebWorker = isWebWorker;
15
+ exports.isDeno = isDeno;
16
+ exports.isBun = isBun;
17
+ exports.getRuntimeEnvironment = getRuntimeEnvironment;
18
+ exports.supportsWebCrypto = supportsWebCrypto;
19
+ exports.supportsNodeCrypto = supportsNodeCrypto;
20
+ exports.isCryptoSupported = isCryptoSupported;
21
+ exports.supportsTextEncoding = supportsTextEncoding;
22
+ exports.supportsURLAPIs = supportsURLAPIs;
23
+ // =============================================================================
24
+ // ENVIRONMENT DETECTION
25
+ // =============================================================================
26
+ /**
27
+ * Check if running in a server-side Node.js environment.
28
+ *
29
+ * @returns True if running in Node.js, false otherwise
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * if (isServer()) {
34
+ * // Use Node.js crypto module
35
+ * }
36
+ * ```
37
+ *
38
+ * @since 1.2.0
39
+ */
40
+ function isServer() {
41
+ return (typeof globalThis !== 'undefined' &&
42
+ typeof globalThis.process
43
+ ?.versions?.node === 'string');
44
+ }
45
+ /**
46
+ * Check if running in a browser environment.
47
+ *
48
+ * @returns True if running in a browser, false otherwise
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * if (isBrowser()) {
53
+ * // Use Web Crypto API
54
+ * }
55
+ * ```
56
+ *
57
+ * @since 1.2.0
58
+ */
59
+ function isBrowser() {
60
+ return (typeof globalThis !== 'undefined' &&
61
+ typeof globalThis.window !== 'undefined' &&
62
+ typeof globalThis.document !== 'undefined');
63
+ }
64
+ /**
65
+ * Check if running in a Web Worker environment.
66
+ *
67
+ * @returns True if running in a Web Worker, false otherwise
68
+ *
69
+ * @since 1.2.0
70
+ */
71
+ function isWebWorker() {
72
+ // Check if WorkerGlobalScope exists and if self is an instance of it
73
+ // In a Web Worker, self instanceof WorkerGlobalScope is true
74
+ // In the main thread, WorkerGlobalScope doesn't exist or self is not an instance
75
+ if (typeof globalThis === 'undefined') {
76
+ return false;
77
+ }
78
+ const global = globalThis;
79
+ return (typeof global.WorkerGlobalScope !== 'undefined' &&
80
+ typeof global.self !== 'undefined' &&
81
+ global.self instanceof global.WorkerGlobalScope);
82
+ }
83
+ /**
84
+ * Check if running in Deno environment.
85
+ *
86
+ * @returns True if running in Deno, false otherwise
87
+ *
88
+ * @since 1.2.0
89
+ */
90
+ function isDeno() {
91
+ return (typeof globalThis !== 'undefined' &&
92
+ typeof globalThis.Deno !== 'undefined');
93
+ }
94
+ /**
95
+ * Check if running in Bun environment.
96
+ *
97
+ * @returns True if running in Bun, false otherwise
98
+ *
99
+ * @since 1.2.0
100
+ */
101
+ function isBun() {
102
+ return (typeof globalThis !== 'undefined' &&
103
+ typeof globalThis.Bun !== 'undefined');
104
+ }
105
+ /**
106
+ * Get the current runtime environment.
107
+ *
108
+ * @returns The detected runtime environment
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * const env = getRuntimeEnvironment();
113
+ * console.log(`Running in: ${env}`);
114
+ * ```
115
+ *
116
+ * @since 1.2.0
117
+ */
118
+ function getRuntimeEnvironment() {
119
+ if (isBun())
120
+ return 'bun';
121
+ if (isDeno())
122
+ return 'deno';
123
+ if (isServer())
124
+ return 'node';
125
+ if (isWebWorker())
126
+ return 'webworker';
127
+ if (isBrowser())
128
+ return 'browser';
129
+ return 'unknown';
130
+ }
131
+ // =============================================================================
132
+ // CRYPTO SUPPORT DETECTION
133
+ // =============================================================================
134
+ /**
135
+ * Check if Web Crypto API is available.
136
+ *
137
+ * @returns True if Web Crypto API is available, false otherwise
138
+ *
139
+ * @since 1.2.0
140
+ */
141
+ function supportsWebCrypto() {
142
+ return (typeof globalThis !== 'undefined' &&
143
+ typeof globalThis.crypto?.subtle !==
144
+ 'undefined');
145
+ }
146
+ /**
147
+ * Check if Node.js crypto module is available.
148
+ *
149
+ * Note: This performs a synchronous check and does not actually import the module.
150
+ *
151
+ * @returns True if likely running in Node.js with crypto support, false otherwise
152
+ *
153
+ * @since 1.2.0
154
+ */
155
+ function supportsNodeCrypto() {
156
+ return isServer() || isBun();
157
+ }
158
+ /**
159
+ * Check if any cryptographic support is available.
160
+ *
161
+ * This is useful for determining if encryption/decryption features can be used.
162
+ *
163
+ * @returns True if crypto is supported, false otherwise
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * if (isCryptoSupported()) {
168
+ * const encrypted = await encryptSpecimen(specimen, { key: password });
169
+ * } else {
170
+ * console.warn('Crypto not supported in this environment');
171
+ * }
172
+ * ```
173
+ *
174
+ * @since 1.2.0
175
+ */
176
+ function isCryptoSupported() {
177
+ return supportsWebCrypto() || supportsNodeCrypto();
178
+ }
179
+ // =============================================================================
180
+ // FEATURE DETECTION
181
+ // =============================================================================
182
+ /**
183
+ * Check if TextEncoder/TextDecoder are available.
184
+ *
185
+ * @returns True if text encoding is supported, false otherwise
186
+ *
187
+ * @since 1.2.0
188
+ */
189
+ function supportsTextEncoding() {
190
+ return (typeof globalThis !== 'undefined' &&
191
+ typeof globalThis.TextEncoder !== 'undefined' &&
192
+ typeof globalThis.TextDecoder !== 'undefined');
193
+ }
194
+ /**
195
+ * Check if URL and URLSearchParams are available.
196
+ *
197
+ * @returns True if URL APIs are supported, false otherwise
198
+ *
199
+ * @since 1.2.0
200
+ */
201
+ function supportsURLAPIs() {
202
+ return (typeof globalThis !== 'undefined' &&
203
+ typeof globalThis.URL !== 'undefined' &&
204
+ typeof globalThis.URLSearchParams !== 'undefined');
205
+ }
206
+ //# sourceMappingURL=environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../../../src/utils/environment.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AA+BH,4BAMC;AAgBD,8BAMC;AASD,kCAkBC;AASD,wBAKC;AASD,sBAKC;AAeD,sDAOC;AAaD,8CAMC;AAWD,gDAEC;AAoBD,8CAEC;AAaD,oDAMC;AASD,0CAMC;AAnND,gFAAgF;AAChF,wBAAwB;AACxB,gFAAgF;AAEhF;;;;;;;;;;;;;GAaG;AACH,SAAgB,QAAQ;IACtB,OAAO,CACL,OAAO,UAAU,KAAK,WAAW;QACjC,OAAQ,UAAwE,CAAC,OAAO;YACtF,EAAE,QAAQ,EAAE,IAAI,KAAK,QAAQ,CAChC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAgB,SAAS;IACvB,OAAO,CACL,OAAO,UAAU,KAAK,WAAW;QACjC,OAAQ,UAA8C,CAAC,MAAM,KAAK,WAAW;QAC7E,OAAQ,UAAgD,CAAC,QAAQ,KAAK,WAAW,CAClF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,WAAW;IACzB,qEAAqE;IACrE,6DAA6D;IAC7D,iFAAiF;IACjF,IAAI,OAAO,UAAU,KAAK,WAAW,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,UAGd,CAAC;IAEF,OAAO,CACL,OAAO,MAAM,CAAC,iBAAiB,KAAK,WAAW;QAC/C,OAAO,MAAM,CAAC,IAAI,KAAK,WAAW;QAClC,MAAM,CAAC,IAAI,YAAY,MAAM,CAAC,iBAAiB,CAChD,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,MAAM;IACpB,OAAO,CACL,OAAO,UAAU,KAAK,WAAW;QACjC,OAAQ,UAA4C,CAAC,IAAI,KAAK,WAAW,CAC1E,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,KAAK;IACnB,OAAO,CACL,OAAO,UAAU,KAAK,WAAW;QACjC,OAAQ,UAA2C,CAAC,GAAG,KAAK,WAAW,CACxE,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,qBAAqB;IACnC,IAAI,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IAC1B,IAAI,MAAM,EAAE;QAAE,OAAO,MAAM,CAAC;IAC5B,IAAI,QAAQ,EAAE;QAAE,OAAO,MAAM,CAAC;IAC9B,IAAI,WAAW,EAAE;QAAE,OAAO,WAAW,CAAC;IACtC,IAAI,SAAS,EAAE;QAAE,OAAO,SAAS,CAAC;IAClC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,gFAAgF;AAChF,2BAA2B;AAC3B,gFAAgF;AAEhF;;;;;;GAMG;AACH,SAAgB,iBAAiB;IAC/B,OAAO,CACL,OAAO,UAAU,KAAK,WAAW;QACjC,OAAQ,UAA2D,CAAC,MAAM,EAAE,MAAM;YAChF,WAAW,CACd,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,kBAAkB;IAChC,OAAO,QAAQ,EAAE,IAAI,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,iBAAiB;IAC/B,OAAO,iBAAiB,EAAE,IAAI,kBAAkB,EAAE,CAAC;AACrD,CAAC;AAED,gFAAgF;AAChF,oBAAoB;AACpB,gFAAgF;AAEhF;;;;;;GAMG;AACH,SAAgB,oBAAoB;IAClC,OAAO,CACL,OAAO,UAAU,KAAK,WAAW;QACjC,OAAQ,UAAmD,CAAC,WAAW,KAAK,WAAW;QACvF,OAAQ,UAAmD,CAAC,WAAW,KAAK,WAAW,CACxF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,eAAe;IAC7B,OAAO,CACL,OAAO,UAAU,KAAK,WAAW;QACjC,OAAQ,UAA2C,CAAC,GAAG,KAAK,WAAW;QACvE,OAAQ,UAAuD,CAAC,eAAe,KAAK,WAAW,CAChG,CAAC;AACJ,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * ISO 8601 Date Utilities
3
+ *
4
+ * Provides parsing and formatting for ISO 8601 date strings
5
+ * as used in WOLS specimens.
6
+ *
7
+ * @module utils/iso8601
8
+ */
9
+ /**
10
+ * Check if a string is a valid ISO 8601 date.
11
+ *
12
+ * @param value - The string to validate
13
+ * @returns true if valid ISO 8601 format
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * isValidISO8601('2025-12-16T10:30:00Z'); // true
18
+ * isValidISO8601('2025-12-16'); // false (date-only)
19
+ * isValidISO8601('invalid'); // false
20
+ * ```
21
+ */
22
+ export declare function isValidISO8601(value: string): boolean;
23
+ /**
24
+ * Check if a string is a valid date-only format (YYYY-MM-DD).
25
+ *
26
+ * @param value - The string to validate
27
+ * @returns true if valid date-only format
28
+ */
29
+ export declare function isValidDateOnly(value: string): boolean;
30
+ /**
31
+ * Get the current timestamp in ISO 8601 format.
32
+ *
33
+ * @returns Current time as ISO 8601 string
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * const now = getCurrentISO8601();
38
+ * // Returns: "2025-12-16T10:30:00.000Z"
39
+ * ```
40
+ */
41
+ export declare function getCurrentISO8601(): string;
42
+ /**
43
+ * Parse an ISO 8601 date string to a Date object.
44
+ *
45
+ * @param value - The ISO 8601 string to parse
46
+ * @returns The parsed Date, or null if invalid
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const date = parseISO8601('2025-12-16T10:30:00Z');
51
+ * // Returns: Date object
52
+ *
53
+ * const invalid = parseISO8601('invalid');
54
+ * // Returns: null
55
+ * ```
56
+ */
57
+ export declare function parseISO8601(value: string): Date | null;
58
+ /**
59
+ * Format a Date object to ISO 8601 string.
60
+ *
61
+ * @param date - The Date to format
62
+ * @returns ISO 8601 string
63
+ */
64
+ export declare function formatISO8601(date: Date): string;
65
+ /**
66
+ * Get Unix timestamp (seconds since epoch) from ISO 8601 string.
67
+ *
68
+ * @param value - The ISO 8601 string
69
+ * @returns Unix timestamp in seconds, or null if invalid
70
+ */
71
+ export declare function toUnixTimestamp(value: string): number | null;
72
+ /**
73
+ * Convert Unix timestamp to ISO 8601 string.
74
+ *
75
+ * @param timestamp - Unix timestamp in seconds
76
+ * @returns ISO 8601 string
77
+ */
78
+ export declare function fromUnixTimestamp(timestamp: number): string;
79
+ //# sourceMappingURL=iso8601.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iso8601.d.ts","sourceRoot":"","sources":["../../../src/utils/iso8601.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAiBH;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAQrD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAOtD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAKvD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAEhD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM5D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE3D"}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Version Migration Utilities
3
+ *
4
+ * This module provides utilities for comparing WOLS versions and
5
+ * migrating specimens between versions.
6
+ *
7
+ * @module utils/migration
8
+ * @since 1.2.0
9
+ */
10
+ import type { Specimen } from '../types.js';
11
+ /**
12
+ * Version comparison result.
13
+ *
14
+ * - `-1`: First version is older than second
15
+ * - `0`: Versions are equal
16
+ * - `1`: First version is newer than second
17
+ *
18
+ * @since 1.2.0
19
+ */
20
+ export type VersionComparison = -1 | 0 | 1;
21
+ /**
22
+ * Migration handler function signature.
23
+ *
24
+ * @since 1.2.0
25
+ */
26
+ export type MigrationHandler = (specimen: Specimen) => Specimen;
27
+ /**
28
+ * Migration definition.
29
+ *
30
+ * @since 1.2.0
31
+ */
32
+ interface MigrationDefinition {
33
+ from: string;
34
+ to: string;
35
+ handler: MigrationHandler;
36
+ }
37
+ /**
38
+ * Compare two semantic versions.
39
+ *
40
+ * @param a - First version string
41
+ * @param b - Second version string
42
+ * @returns -1 if a < b, 0 if a === b, 1 if a > b
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * compareVersions('1.0.0', '1.1.0') // Returns -1
47
+ * compareVersions('1.1.0', '1.1.0') // Returns 0
48
+ * compareVersions('2.0.0', '1.9.0') // Returns 1
49
+ * ```
50
+ *
51
+ * @since 1.2.0
52
+ */
53
+ export declare function compareVersions(a: string, b: string): VersionComparison;
54
+ /**
55
+ * Check if a specimen is using an outdated WOLS version.
56
+ *
57
+ * @param specimen - Specimen object or version string
58
+ * @returns True if the specimen version is older than current library version
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * isOutdated(specimen) // True if specimen.version < WOLS_VERSION
63
+ * isOutdated('1.0.0') // True (older than current)
64
+ * ```
65
+ *
66
+ * @since 1.2.0
67
+ */
68
+ export declare function isOutdated(specimen: Specimen | string): boolean;
69
+ /**
70
+ * Check if a specimen is using a newer WOLS version than this library.
71
+ *
72
+ * This can happen when specimens are created by a newer library version.
73
+ *
74
+ * @param specimen - Specimen object or version string
75
+ * @returns True if the specimen version is newer than current library version
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * isNewer(specimen) // True if specimen.version > WOLS_VERSION
80
+ * isNewer('2.0.0') // True if library is 1.x
81
+ * ```
82
+ *
83
+ * @since 1.2.0
84
+ */
85
+ export declare function isNewer(specimen: Specimen | string): boolean;
86
+ /**
87
+ * Get the current library WOLS version.
88
+ *
89
+ * @returns The WOLS version this library implements
90
+ *
91
+ * @since 1.2.0
92
+ */
93
+ export declare function getCurrentVersion(): string;
94
+ /**
95
+ * Register a migration handler for upgrading specimens between versions.
96
+ *
97
+ * Migrations are applied in order from oldest to newest when calling `migrate()`.
98
+ *
99
+ * @param from - Source version (e.g., "1.0.0")
100
+ * @param to - Target version (e.g., "1.1.0")
101
+ * @param handler - Function to transform the specimen
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * registerMigration('1.0.0', '1.1.0', (specimen) => {
106
+ * // Add new required field with default value
107
+ * return { ...specimen, newField: 'default' };
108
+ * });
109
+ * ```
110
+ *
111
+ * @since 1.2.0
112
+ */
113
+ export declare function registerMigration(from: string, to: string, handler: MigrationHandler): void;
114
+ /**
115
+ * Check if a specimen can be migrated to the current version.
116
+ *
117
+ * @param specimen - Specimen to check
118
+ * @returns True if migration path exists, false otherwise
119
+ *
120
+ * @since 1.2.0
121
+ */
122
+ export declare function canMigrate(specimen: Specimen): boolean;
123
+ /**
124
+ * Migrate a specimen to the current WOLS version.
125
+ *
126
+ * Applies all registered migrations in order from the specimen's version
127
+ * to the current library version.
128
+ *
129
+ * @param specimen - Specimen to migrate
130
+ * @returns Migrated specimen with updated version
131
+ * @throws Error if no migration path exists
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * const oldSpecimen = parseSpecimen(oldJson);
136
+ * if (isOutdated(oldSpecimen)) {
137
+ * const updated = migrate(oldSpecimen);
138
+ * console.log('Migrated to:', updated.version);
139
+ * }
140
+ * ```
141
+ *
142
+ * @since 1.2.0
143
+ */
144
+ export declare function migrate(specimen: Specimen): Specimen;
145
+ /**
146
+ * Get all registered migrations.
147
+ *
148
+ * @returns Array of migration definitions
149
+ *
150
+ * @since 1.2.0
151
+ */
152
+ export declare function getMigrations(): readonly MigrationDefinition[];
153
+ /**
154
+ * Clear all registered migrations.
155
+ *
156
+ * Primarily useful for testing.
157
+ *
158
+ * @since 1.2.0
159
+ */
160
+ export declare function clearMigrations(): void;
161
+ export {};
162
+ //# sourceMappingURL=migration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../../../src/utils/migration.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAO5C;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAE3C;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,QAAQ,KAAK,QAAQ,CAAC;AAEhE;;;;GAIG;AACH,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAgCD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAmBvE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAG/D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAG5D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAK3F;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAiBtD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAiCpD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,IAAI,SAAS,mBAAmB,EAAE,CAE9D;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
@@ -0,0 +1,248 @@
1
+ "use strict";
2
+ /**
3
+ * Version Migration Utilities
4
+ *
5
+ * This module provides utilities for comparing WOLS versions and
6
+ * migrating specimens between versions.
7
+ *
8
+ * @module utils/migration
9
+ * @since 1.2.0
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.compareVersions = compareVersions;
13
+ exports.isOutdated = isOutdated;
14
+ exports.isNewer = isNewer;
15
+ exports.getCurrentVersion = getCurrentVersion;
16
+ exports.registerMigration = registerMigration;
17
+ exports.canMigrate = canMigrate;
18
+ exports.migrate = migrate;
19
+ exports.getMigrations = getMigrations;
20
+ exports.clearMigrations = clearMigrations;
21
+ const types_js_1 = require("../types.js");
22
+ // =============================================================================
23
+ // INTERNAL STATE
24
+ // =============================================================================
25
+ /**
26
+ * Registered migration handlers.
27
+ */
28
+ const MIGRATION_REGISTRY = [];
29
+ // =============================================================================
30
+ // VERSION UTILITIES
31
+ // =============================================================================
32
+ /**
33
+ * Parse a semantic version string into components.
34
+ *
35
+ * @param version - Semantic version string (e.g., "1.2.0")
36
+ * @returns Array of [major, minor, patch] or null if invalid
37
+ */
38
+ function parseVersion(version) {
39
+ const match = /^(\d+)\.(\d+)\.(\d+)/.exec(version);
40
+ if (!match)
41
+ return null;
42
+ const major = parseInt(match[1], 10);
43
+ const minor = parseInt(match[2], 10);
44
+ const patch = parseInt(match[3], 10);
45
+ return [major, minor, patch];
46
+ }
47
+ /**
48
+ * Compare two semantic versions.
49
+ *
50
+ * @param a - First version string
51
+ * @param b - Second version string
52
+ * @returns -1 if a < b, 0 if a === b, 1 if a > b
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * compareVersions('1.0.0', '1.1.0') // Returns -1
57
+ * compareVersions('1.1.0', '1.1.0') // Returns 0
58
+ * compareVersions('2.0.0', '1.9.0') // Returns 1
59
+ * ```
60
+ *
61
+ * @since 1.2.0
62
+ */
63
+ function compareVersions(a, b) {
64
+ const parsedA = parseVersion(a);
65
+ const parsedB = parseVersion(b);
66
+ if (!parsedA || !parsedB) {
67
+ // Fallback to string comparison for invalid versions
68
+ if (a < b)
69
+ return -1;
70
+ if (a > b)
71
+ return 1;
72
+ return 0;
73
+ }
74
+ const [majorA, minorA, patchA] = parsedA;
75
+ const [majorB, minorB, patchB] = parsedB;
76
+ if (majorA !== majorB)
77
+ return majorA < majorB ? -1 : 1;
78
+ if (minorA !== minorB)
79
+ return minorA < minorB ? -1 : 1;
80
+ if (patchA !== patchB)
81
+ return patchA < patchB ? -1 : 1;
82
+ return 0;
83
+ }
84
+ /**
85
+ * Check if a specimen is using an outdated WOLS version.
86
+ *
87
+ * @param specimen - Specimen object or version string
88
+ * @returns True if the specimen version is older than current library version
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * isOutdated(specimen) // True if specimen.version < WOLS_VERSION
93
+ * isOutdated('1.0.0') // True (older than current)
94
+ * ```
95
+ *
96
+ * @since 1.2.0
97
+ */
98
+ function isOutdated(specimen) {
99
+ const version = typeof specimen === 'string' ? specimen : specimen.version;
100
+ return compareVersions(version, types_js_1.WOLS_VERSION) < 0;
101
+ }
102
+ /**
103
+ * Check if a specimen is using a newer WOLS version than this library.
104
+ *
105
+ * This can happen when specimens are created by a newer library version.
106
+ *
107
+ * @param specimen - Specimen object or version string
108
+ * @returns True if the specimen version is newer than current library version
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * isNewer(specimen) // True if specimen.version > WOLS_VERSION
113
+ * isNewer('2.0.0') // True if library is 1.x
114
+ * ```
115
+ *
116
+ * @since 1.2.0
117
+ */
118
+ function isNewer(specimen) {
119
+ const version = typeof specimen === 'string' ? specimen : specimen.version;
120
+ return compareVersions(version, types_js_1.WOLS_VERSION) > 0;
121
+ }
122
+ /**
123
+ * Get the current library WOLS version.
124
+ *
125
+ * @returns The WOLS version this library implements
126
+ *
127
+ * @since 1.2.0
128
+ */
129
+ function getCurrentVersion() {
130
+ return types_js_1.WOLS_VERSION;
131
+ }
132
+ // =============================================================================
133
+ // MIGRATION REGISTRATION
134
+ // =============================================================================
135
+ /**
136
+ * Register a migration handler for upgrading specimens between versions.
137
+ *
138
+ * Migrations are applied in order from oldest to newest when calling `migrate()`.
139
+ *
140
+ * @param from - Source version (e.g., "1.0.0")
141
+ * @param to - Target version (e.g., "1.1.0")
142
+ * @param handler - Function to transform the specimen
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * registerMigration('1.0.0', '1.1.0', (specimen) => {
147
+ * // Add new required field with default value
148
+ * return { ...specimen, newField: 'default' };
149
+ * });
150
+ * ```
151
+ *
152
+ * @since 1.2.0
153
+ */
154
+ function registerMigration(from, to, handler) {
155
+ MIGRATION_REGISTRY.push({ from, to, handler });
156
+ // Keep migrations sorted by source version
157
+ MIGRATION_REGISTRY.sort((a, b) => compareVersions(a.from, b.from));
158
+ }
159
+ /**
160
+ * Check if a specimen can be migrated to the current version.
161
+ *
162
+ * @param specimen - Specimen to check
163
+ * @returns True if migration path exists, false otherwise
164
+ *
165
+ * @since 1.2.0
166
+ */
167
+ function canMigrate(specimen) {
168
+ if (!isOutdated(specimen)) {
169
+ return false; // Already current or newer
170
+ }
171
+ // Check if we have a migration path
172
+ let currentVersion = specimen.version;
173
+ while (compareVersions(currentVersion, types_js_1.WOLS_VERSION) < 0) {
174
+ const migration = MIGRATION_REGISTRY.find(m => m.from === currentVersion);
175
+ if (!migration) {
176
+ return false; // No migration from this version
177
+ }
178
+ currentVersion = migration.to;
179
+ }
180
+ return true;
181
+ }
182
+ /**
183
+ * Migrate a specimen to the current WOLS version.
184
+ *
185
+ * Applies all registered migrations in order from the specimen's version
186
+ * to the current library version.
187
+ *
188
+ * @param specimen - Specimen to migrate
189
+ * @returns Migrated specimen with updated version
190
+ * @throws Error if no migration path exists
191
+ *
192
+ * @example
193
+ * ```typescript
194
+ * const oldSpecimen = parseSpecimen(oldJson);
195
+ * if (isOutdated(oldSpecimen)) {
196
+ * const updated = migrate(oldSpecimen);
197
+ * console.log('Migrated to:', updated.version);
198
+ * }
199
+ * ```
200
+ *
201
+ * @since 1.2.0
202
+ */
203
+ function migrate(specimen) {
204
+ if (!isOutdated(specimen)) {
205
+ return specimen; // Already current or newer
206
+ }
207
+ let current = specimen;
208
+ let currentVersion = specimen.version;
209
+ while (compareVersions(currentVersion, types_js_1.WOLS_VERSION) < 0) {
210
+ const migration = MIGRATION_REGISTRY.find(m => m.from === currentVersion);
211
+ if (!migration) {
212
+ throw new Error(`No migration path from version ${currentVersion} to ${types_js_1.WOLS_VERSION}. ` +
213
+ `Register a migration using registerMigration().`);
214
+ }
215
+ current = migration.handler(current);
216
+ currentVersion = migration.to;
217
+ }
218
+ // Ensure version is updated and consistent with the migration chain
219
+ if (currentVersion !== types_js_1.WOLS_VERSION) {
220
+ throw new Error(`Migration ended at version ${currentVersion}, but expected ${types_js_1.WOLS_VERSION}. ` +
221
+ `Check the registered migrations for incorrect target versions.`);
222
+ }
223
+ return {
224
+ ...current,
225
+ version: currentVersion,
226
+ };
227
+ }
228
+ /**
229
+ * Get all registered migrations.
230
+ *
231
+ * @returns Array of migration definitions
232
+ *
233
+ * @since 1.2.0
234
+ */
235
+ function getMigrations() {
236
+ return MIGRATION_REGISTRY;
237
+ }
238
+ /**
239
+ * Clear all registered migrations.
240
+ *
241
+ * Primarily useful for testing.
242
+ *
243
+ * @since 1.2.0
244
+ */
245
+ function clearMigrations() {
246
+ MIGRATION_REGISTRY.length = 0;
247
+ }
248
+ //# sourceMappingURL=migration.js.map