@tnid/core 0.0.6 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -52,6 +52,19 @@ const parsed: UserId = UserId.parse("user.Br2flcNDfF6LYICnT");
52
52
  // Convert to/from UUID format
53
53
  const uuid: string = UserId.toUuidString(id); // "d6157329-4640-8e30-..."
54
54
  const fromUuid: UserId = UserId.parseUuidString(uuid);
55
+
56
+ // Works great with Zod
57
+ import { z } from "zod";
58
+ const UserSchema = z.object({
59
+ id: z.string().transform(UserId.parse),
60
+ name: z.string(),
61
+ });
62
+ interface User extends z.infer<typeof UserSchema> {} // { id: UserId; name: string }
63
+
64
+ const user: User = UserSchema.parse({
65
+ id: "user.Br2flcNDfF6LYICnT",
66
+ name: "Alice",
67
+ });
55
68
  ```
56
69
 
57
70
  ## Features
@@ -87,8 +100,8 @@ id === otherUserId; // true/false
87
100
  import {
88
101
  Case, // "lower" | "upper"
89
102
  DynamicTnid, // Runtime TNID operations (type + namespace)
90
- Tnid, // NamedTnid creator function
91
103
  NamedTnid, // NamedTnid interface
104
+ Tnid, // NamedTnid creator function
92
105
  TnidType, // Type helper to extract ID type
93
106
  // Types only:
94
107
  TnidValue, // Branded string type
@@ -100,8 +113,8 @@ import {
100
113
 
101
114
  ### `Tnid(name)`
102
115
 
103
- Creates a `NamedTnid` for a specific name. The name is validated at
104
- **compile time**.
116
+ Creates a `NamedTnid` for a specific name. The name is validated at **compile
117
+ time**.
105
118
 
106
119
  ```typescript
107
120
  const UserId = Tnid("user");
@@ -138,27 +151,27 @@ Tnid(""); // empty not allowed
138
151
  const UserId = Tnid("user");
139
152
  type UserId = TnidType<typeof UserId>;
140
153
 
141
- UserId.new_v0(); // time-ordered ID
142
- UserId.new_v1(); // high-entropy random ID
143
- UserId.v0_from_parts(1234567890n, 0n); // V0 with explicit timestamp/random
144
- UserId.v1_from_parts(0n); // V1 with explicit random bits
154
+ UserId.new_v0(); // time-ordered ID
155
+ UserId.new_v1(); // high-entropy random ID
156
+ UserId.v0_from_parts(1234567890n, 0n); // V0 with explicit timestamp/random
157
+ UserId.v1_from_parts(0n); // V1 with explicit random bits
145
158
  ```
146
159
 
147
160
  #### Parsing
148
161
 
149
162
  ```typescript
150
- UserId.parse("user.Br2flcNDfF6LYICnT"); // parse TNID string
151
- UserId.parseUuidString("d6157329-4640-8e30-..."); // parse UUID hex string
163
+ UserId.parse("user.Br2flcNDfF6LYICnT"); // parse TNID string
164
+ UserId.parseUuidString("d6157329-4640-8e30-..."); // parse UUID hex string
152
165
  ```
153
166
 
154
167
  #### Inspection and Conversion
155
168
 
156
169
  ```typescript
157
- UserId.name; // "user" - the TNID name
158
- UserId.variant(id); // "v0" or "v1" - get the variant
159
- UserId.toUuidString(id); // "d6157329-4640-8e30-..." - convert to UUID
170
+ UserId.name; // "user" - the TNID name
171
+ UserId.variant(id); // "v0" or "v1" - get the variant
172
+ UserId.toUuidString(id); // "d6157329-4640-8e30-..." - convert to UUID
160
173
  UserId.toUuidString(id, "upper"); // "D6157329-4640-8E30-..." - uppercase UUID
161
- UserId.nameHex(); // "d6157" - name as 5-char hex
174
+ UserId.nameHex(); // "d6157" - name as 5-char hex
162
175
  ```
163
176
 
164
177
  ### `TnidType<T>`
@@ -188,23 +201,27 @@ function logAnyId(id: DynamicTnid) {
188
201
  }
189
202
 
190
203
  // Generation with runtime names
191
- DynamicTnid.new_v0("user"); // time-ordered (alias: new_time_ordered)
192
- DynamicTnid.new_v1("user"); // high-entropy (alias: new_high_entropy)
204
+ DynamicTnid.newV0("user"); // time-ordered (alias: newTimeOrdered)
205
+ DynamicTnid.newV1("user"); // high-entropy (alias: newHighEntropy)
193
206
 
194
207
  // Generation with explicit values (useful for testing/migrations)
195
- DynamicTnid.new_v0_with_time("user", new Date("2024-01-15"));
196
- DynamicTnid.new_v0_with_parts("user", 1705312800000n, 123n);
197
- DynamicTnid.new_v1_with_random("user", 0x123456789abcdef0123456789n);
208
+ DynamicTnid.newV0WithTime("user", new Date("2024-01-15"));
209
+ DynamicTnid.newV0WithParts("user", 1705312800000n, 123n);
210
+ DynamicTnid.newV1WithRandom("user", 0x123456789abcdef0123456789n);
211
+
212
+ // Parsing (auto-detects format)
213
+ DynamicTnid.parse("post.EUBcUw4T9x3KNOll-"); // TNID string
214
+ DynamicTnid.parse("d6157329-4640-..."); // UUID string
198
215
 
199
- // Parsing any TNID
200
- DynamicTnid.parse("post.EUBcUw4T9x3KNOll-");
201
- DynamicTnid.parse_uuid_string("d6157329-4640-...");
216
+ // Or use explicit parse methods
217
+ DynamicTnid.parseTnidString("post.EUBcUw4T9x3KNOll-");
218
+ DynamicTnid.parseUuidString("d6157329-4640-...");
202
219
 
203
220
  // Inspection
204
- DynamicTnid.getName(id); // "user"
205
- DynamicTnid.getNameHex(id); // "d6157"
206
- DynamicTnid.getVariant(id); // "v0" or "v1"
207
- DynamicTnid.toUuidString(id); // UUID hex string
221
+ DynamicTnid.getName(id); // "user"
222
+ DynamicTnid.getNameHex(id); // "d6157"
223
+ DynamicTnid.getVariant(id); // "v0" or "v1"
224
+ DynamicTnid.toUuidString(id); // UUID hex string
208
225
  ```
209
226
 
210
227
  ### `UuidLike`
@@ -212,10 +229,10 @@ DynamicTnid.toUuidString(id); // UUID hex string
212
229
  For working with UUID hex strings that may or may not be valid TNIDs.
213
230
 
214
231
  ```typescript
215
- UuidLike.fromTnid(id); // convert TNID to UUID string
216
- UuidLike.parse(s); // parse any UUID (validates format only)
217
- UuidLike.toTnid(uuid); // convert UUID to TNID (throws if invalid)
218
- UuidLike.toUpperCase(uuid); // convert to uppercase
232
+ UuidLike.fromTnid(id); // convert TNID to UUID string
233
+ UuidLike.parse(s); // parse any UUID (validates format only)
234
+ UuidLike.toTnid(uuid); // convert UUID to TNID (throws if invalid)
235
+ UuidLike.toUpperCase(uuid); // convert to uppercase
219
236
  ```
220
237
 
221
238
  ## Variants
package/esm/dynamic.d.ts CHANGED
@@ -6,23 +6,25 @@ declare function toUuidStringImpl(id: DynamicTnid, upperCase?: boolean): string;
6
6
  /** Interface for DynamicTnid static methods. */
7
7
  export interface DynamicTnidNamespace {
8
8
  /** Generate a new time-sortable TNID (variant 0) with runtime name validation. */
9
- new_v0(name: string): DynamicTnid;
10
- /** Alias for new_v0. */
11
- new_time_ordered(name: string): DynamicTnid;
9
+ newV0(name: string): DynamicTnid;
10
+ /** Alias for newV0. */
11
+ newTimeOrdered(name: string): DynamicTnid;
12
12
  /** Generate a new time-sortable TNID with a specific timestamp. */
13
- new_v0_with_time(name: string, time: Date): DynamicTnid;
13
+ newV0WithTime(name: string, time: Date): DynamicTnid;
14
14
  /** Generate a new time-sortable TNID with explicit timestamp and random components. */
15
- new_v0_with_parts(name: string, epochMillis: bigint, random: bigint): DynamicTnid;
15
+ newV0WithParts(name: string, epochMillis: bigint, random: bigint): DynamicTnid;
16
16
  /** Generate a new high-entropy TNID (variant 1) with runtime name validation. */
17
- new_v1(name: string): DynamicTnid;
18
- /** Alias for new_v1. */
19
- new_high_entropy(name: string): DynamicTnid;
17
+ newV1(name: string): DynamicTnid;
18
+ /** Alias for newV1. */
19
+ newHighEntropy(name: string): DynamicTnid;
20
20
  /** Generate a new high-entropy TNID with explicit random bits. */
21
- new_v1_with_random(name: string, randomBits: bigint): DynamicTnid;
22
- /** Parse any valid TNID string. */
21
+ newV1WithRandom(name: string, randomBits: bigint): DynamicTnid;
22
+ /** Parse a TNID from either TNID string format or UUID hex format (auto-detected). */
23
23
  parse(s: string): DynamicTnid;
24
+ /** Parse a TNID string (e.g., "user.Br2flcNDfF6LYICnT"). */
25
+ parseTnidString(s: string): DynamicTnid;
24
26
  /** Parse a UUID hex string into a DynamicTnid (validates TNID structure). */
25
- parse_uuid_string(uuid: string): DynamicTnid;
27
+ parseUuidString(uuid: string): DynamicTnid;
26
28
  /** Get the name from a TNID. */
27
29
  getName(id: DynamicTnid): string;
28
30
  /** Get the name encoded as a 5-character hex string. */
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic.d.ts","sourceRoot":"","sources":["../src/dynamic.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE/D,gEAAgE;AAChE,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAgB5C,iBAAS,kBAAkB,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CASxD;AAiBD,iBAAS,gBAAgB,CAAC,EAAE,EAAE,WAAW,EAAE,SAAS,GAAE,OAAe,GAAG,MAAM,CAmB7E;AAmDD,gDAAgD;AAChD,MAAM,WAAW,oBAAoB;IACnC,kFAAkF;IAClF,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAClC,wBAAwB;IACxB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5C,mEAAmE;IACnE,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,WAAW,CAAC;IACxD,uFAAuF;IACvF,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC;IAClF,iFAAiF;IACjF,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAClC,wBAAwB;IACxB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5C,kEAAkE;IAClE,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC;IAClE,mCAAmC;IACnC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC9B,6EAA6E;IAC7E,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC7C,gCAAgC;IAChC,OAAO,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAAC;IACjC,wDAAwD;IACxD,UAAU,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAAC;IACpC,iCAAiC;IACjC,UAAU,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CAAC;IACzC,yCAAyC;IACzC,YAAY,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;CAC1D;AAED,mEAAmE;AACnE,eAAO,MAAM,WAAW,EAAE,oBA8GzB,CAAC;AAGF,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GACjB,CAAC"}
1
+ {"version":3,"file":"dynamic.d.ts","sourceRoot":"","sources":["../src/dynamic.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE/D,gEAAgE;AAChE,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAgB5C,iBAAS,kBAAkB,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CASxD;AAiBD,iBAAS,gBAAgB,CAAC,EAAE,EAAE,WAAW,EAAE,SAAS,GAAE,OAAe,GAAG,MAAM,CAmB7E;AAmDD,gDAAgD;AAChD,MAAM,WAAW,oBAAoB;IACnC,kFAAkF;IAClF,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IACjC,uBAAuB;IACvB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC1C,mEAAmE;IACnE,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,WAAW,CAAC;IACrD,uFAAuF;IACvF,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC;IAC/E,iFAAiF;IACjF,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IACjC,uBAAuB;IACvB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC1C,kEAAkE;IAClE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC;IAC/D,sFAAsF;IACtF,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC9B,4DAA4D;IAC5D,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IACxC,6EAA6E;IAC7E,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3C,gCAAgC;IAChC,OAAO,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAAC;IACjC,wDAAwD;IACxD,UAAU,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAAC;IACpC,iCAAiC;IACjC,UAAU,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CAAC;IACzC,yCAAyC;IACzC,YAAY,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;CAC1D;AAED,mEAAmE;AACnE,eAAO,MAAM,WAAW,EAAE,oBA4HzB,CAAC;AAGF,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GACjB,CAAC"}
package/esm/dynamic.js CHANGED
@@ -83,7 +83,7 @@ function parseDynamicUuidStringImpl(uuid) {
83
83
  /** Static methods for working with any TNID regardless of name. */
84
84
  export const DynamicTnid = {
85
85
  /** Generate a new time-sortable TNID (variant 0) with runtime name validation. */
86
- new_v0(name) {
86
+ newV0(name) {
87
87
  if (!isValidNameRuntime(name)) {
88
88
  throw new Error(`Invalid TNID name: "${name}". Must be 1-4 characters of: 0-4, a-z`);
89
89
  }
@@ -92,12 +92,12 @@ export const DynamicTnid = {
92
92
  const dataEncoded = encodeData(bytes);
93
93
  return `${name}.${dataEncoded}`;
94
94
  },
95
- /** Alias for new_v0. */
96
- new_time_ordered(name) {
97
- return DynamicTnid.new_v0(name);
95
+ /** Alias for newV0. */
96
+ newTimeOrdered(name) {
97
+ return DynamicTnid.newV0(name);
98
98
  },
99
99
  /** Generate a new time-sortable TNID with a specific timestamp. */
100
- new_v0_with_time(name, time) {
100
+ newV0WithTime(name, time) {
101
101
  if (!isValidNameRuntime(name)) {
102
102
  throw new Error(`Invalid TNID name: "${name}". Must be 1-4 characters of: 0-4, a-z`);
103
103
  }
@@ -108,7 +108,7 @@ export const DynamicTnid = {
108
108
  return `${name}.${dataEncoded}`;
109
109
  },
110
110
  /** Generate a new time-sortable TNID with explicit timestamp and random components. */
111
- new_v0_with_parts(name, epochMillis, random) {
111
+ newV0WithParts(name, epochMillis, random) {
112
112
  if (!isValidNameRuntime(name)) {
113
113
  throw new Error(`Invalid TNID name: "${name}". Must be 1-4 characters of: 0-4, a-z`);
114
114
  }
@@ -118,7 +118,7 @@ export const DynamicTnid = {
118
118
  return `${name}.${dataEncoded}`;
119
119
  },
120
120
  /** Generate a new high-entropy TNID (variant 1) with runtime name validation. */
121
- new_v1(name) {
121
+ newV1(name) {
122
122
  if (!isValidNameRuntime(name)) {
123
123
  throw new Error(`Invalid TNID name: "${name}". Must be 1-4 characters of: 0-4, a-z`);
124
124
  }
@@ -127,12 +127,12 @@ export const DynamicTnid = {
127
127
  const dataEncoded = encodeData(bytes);
128
128
  return `${name}.${dataEncoded}`;
129
129
  },
130
- /** Alias for new_v1. */
131
- new_high_entropy(name) {
132
- return DynamicTnid.new_v1(name);
130
+ /** Alias for newV1. */
131
+ newHighEntropy(name) {
132
+ return DynamicTnid.newV1(name);
133
133
  },
134
134
  /** Generate a new high-entropy TNID with explicit random bits. */
135
- new_v1_with_random(name, randomBits) {
135
+ newV1WithRandom(name, randomBits) {
136
136
  if (!isValidNameRuntime(name)) {
137
137
  throw new Error(`Invalid TNID name: "${name}". Must be 1-4 characters of: 0-4, a-z`);
138
138
  }
@@ -141,12 +141,25 @@ export const DynamicTnid = {
141
141
  const dataEncoded = encodeData(bytes);
142
142
  return `${name}.${dataEncoded}`;
143
143
  },
144
- /** Parse any valid TNID string. */
144
+ /** Parse a TNID from either TNID string format or UUID hex format (auto-detected). */
145
145
  parse(s) {
146
+ // Detect format by length: TNID strings are 19-22 chars with '.', UUIDs are 36 chars
147
+ if (s.length >= 19 && s.length <= 22 && s.includes(".")) {
148
+ return parseDynamicTnidImpl(s);
149
+ }
150
+ else if (s.length === 36) {
151
+ return parseDynamicUuidStringImpl(s);
152
+ }
153
+ else {
154
+ throw new Error(`Invalid TNID: expected TNID string (19-22 chars) or UUID (36 chars), got ${s.length} chars`);
155
+ }
156
+ },
157
+ /** Parse a TNID string (e.g., "user.Br2flcNDfF6LYICnT"). */
158
+ parseTnidString(s) {
146
159
  return parseDynamicTnidImpl(s);
147
160
  },
148
161
  /** Parse a UUID hex string into a DynamicTnid (validates TNID structure). */
149
- parse_uuid_string(uuid) {
162
+ parseUuidString(uuid) {
150
163
  return parseDynamicUuidStringImpl(uuid);
151
164
  },
152
165
  /** Get the name from a TNID. */
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,SAAS,EAGT,YAAY,EACb,MAAM,YAAY,CAAC;AAapB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,IAAI,CAAC,KAAK,CAAC,IAAI,SAAS,MAAM,EAC5C,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,GACvB,SAAS,CAAC,IAAI,CAAC,CAsGjB"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,SAAS,EAGT,YAAY,EACb,MAAM,YAAY,CAAC;AAapB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,IAAI,CAAC,KAAK,CAAC,IAAI,SAAS,MAAM,EAC5C,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,GACvB,SAAS,CAAC,IAAI,CAAC,CAmHjB"}
package/esm/factory.js CHANGED
@@ -1,10 +1,10 @@
1
1
  // =============================================================================
2
2
  // Tnid Function
3
3
  // =============================================================================
4
- import { encodeName, decodeName, isValidNameRuntime } from "./name_encoding.js";
5
- import { encodeData, decodeData, dataBitsToBytes } from "./data_encoding.js";
4
+ import { decodeName, encodeName, isValidNameRuntime } from "./name_encoding.js";
5
+ import { dataBitsToBytes, decodeData, encodeData } from "./data_encoding.js";
6
6
  import { generateV0, generateV1 } from "./bits.js";
7
- import { parseUuidStringToValue, validateUuidBits, extractNameBitsFromValue, valueToTnidString, } from "./uuid.js";
7
+ import { extractNameBitsFromValue, parseUuidStringToValue, validateUuidBits, valueToTnidString, } from "./uuid.js";
8
8
  import { getTnidVariantImpl, toUuidStringImpl } from "./dynamic.js";
9
9
  /**
10
10
  * Create a NamedTnid for the given name.
@@ -59,6 +59,18 @@ export function Tnid(name) {
59
59
  return `${name}.${dataEncoded}`;
60
60
  },
61
61
  parse(s) {
62
+ // Detect format by length: TNID strings are 19-22 chars with '.', UUIDs are 36 chars
63
+ if (s.length >= 19 && s.length <= 22 && s.includes(".")) {
64
+ return tnid.parseTnidString(s);
65
+ }
66
+ else if (s.length === 36) {
67
+ return tnid.parseUuidString(s);
68
+ }
69
+ else {
70
+ throw new Error(`Invalid TNID: expected TNID string (19-22 chars) or UUID (36 chars), got ${s.length} chars`);
71
+ }
72
+ },
73
+ parseTnidString(s) {
62
74
  const dotIndex = s.indexOf(".");
63
75
  if (dotIndex === -1) {
64
76
  throw new Error(`Invalid TNID string: missing '.' separator`);
package/esm/types.d.ts CHANGED
@@ -23,14 +23,18 @@ export type ValidateName<S extends string> = ValidateNameChars<S> extends true ?
23
23
  * const id: UserId = UserId.new_v0(); // time-sortable
24
24
  * const id2: UserId = UserId.new_v1(); // high-entropy random
25
25
  *
26
- * // Parse from strings
27
- * const parsed = UserId.parse("user.abc..."); // validates name matches
28
- * const fromUuid = UserId.parseUuidString("d6157329-4640-8e30-...");
26
+ * // Parse from strings (auto-detects format)
27
+ * const parsed = UserId.parse("user.abc..."); // TNID string format
28
+ * const fromUuid = UserId.parse("d6157329-4640-8e30-..."); // UUID format
29
+ *
30
+ * // Or use explicit parse methods
31
+ * UserId.parseTnidString("user.abc..."); // TNID string only
32
+ * UserId.parseUuidString("d6157329-..."); // UUID string only
29
33
  *
30
34
  * // DynamicTnid - runtime name validation
31
- * DynamicTnid.new_v0("item"); // create with runtime name
32
- * DynamicTnid.new_v1("item"); // create with runtime name
33
- * DynamicTnid.parse("post.xyz..."); // parse any TNID
35
+ * DynamicTnid.newV0("item"); // create with runtime name
36
+ * DynamicTnid.newV1("item"); // create with runtime name
37
+ * DynamicTnid.parse("post.xyz..."); // parse any TNID (auto-detects)
34
38
  * DynamicTnid.getName(id); // "user"
35
39
  * DynamicTnid.getVariant(id); // "v0" | "v1" | "v2" | "v3"
36
40
  *
@@ -70,10 +74,15 @@ export interface NamedTnid<Name extends string> {
70
74
  /** Construct a V1 TNID from specific parts (for deterministic testing) */
71
75
  v1_from_parts(randomBits: bigint): TnidValue<Name>;
72
76
  /**
73
- * Parse and validate a TNID string.
77
+ * Parse a TNID from either TNID string format or UUID hex format (auto-detected).
74
78
  * @throws Error if the string is invalid or the name doesn't match
75
79
  */
76
80
  parse(s: string): TnidValue<Name>;
81
+ /**
82
+ * Parse and validate a TNID string (e.g., "user.Br2flcNDfF6LYICnT").
83
+ * @throws Error if the string is invalid or the name doesn't match
84
+ */
85
+ parseTnidString(s: string): TnidValue<Name>;
77
86
  /**
78
87
  * Parse a UUID hex string into a TNID.
79
88
  * Validates that it's a valid UUIDv8 TNID and the name matches.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tnid/core",
3
- "version": "0.0.6",
3
+ "version": "0.0.9",
4
4
  "description": "Type-safe, named, unique identifiers (TNIDs) - UUID-compatible IDs with embedded type names",
5
5
  "keywords": [
6
6
  "uuid",
@@ -12,11 +12,11 @@
12
12
  ],
13
13
  "repository": {
14
14
  "type": "git",
15
- "url": "git+https://github.com/tnid/tnid-typescript.git"
15
+ "url": "git+https://github.com/mkeedlinger/tnid-typescript.git"
16
16
  },
17
17
  "license": "MIT",
18
18
  "bugs": {
19
- "url": "https://github.com/tnid/tnid-typescript/issues"
19
+ "url": "https://github.com/mkeedlinger/tnid-typescript/issues"
20
20
  },
21
21
  "main": "./script/index.js",
22
22
  "module": "./esm/index.js",
@@ -6,23 +6,25 @@ declare function toUuidStringImpl(id: DynamicTnid, upperCase?: boolean): string;
6
6
  /** Interface for DynamicTnid static methods. */
7
7
  export interface DynamicTnidNamespace {
8
8
  /** Generate a new time-sortable TNID (variant 0) with runtime name validation. */
9
- new_v0(name: string): DynamicTnid;
10
- /** Alias for new_v0. */
11
- new_time_ordered(name: string): DynamicTnid;
9
+ newV0(name: string): DynamicTnid;
10
+ /** Alias for newV0. */
11
+ newTimeOrdered(name: string): DynamicTnid;
12
12
  /** Generate a new time-sortable TNID with a specific timestamp. */
13
- new_v0_with_time(name: string, time: Date): DynamicTnid;
13
+ newV0WithTime(name: string, time: Date): DynamicTnid;
14
14
  /** Generate a new time-sortable TNID with explicit timestamp and random components. */
15
- new_v0_with_parts(name: string, epochMillis: bigint, random: bigint): DynamicTnid;
15
+ newV0WithParts(name: string, epochMillis: bigint, random: bigint): DynamicTnid;
16
16
  /** Generate a new high-entropy TNID (variant 1) with runtime name validation. */
17
- new_v1(name: string): DynamicTnid;
18
- /** Alias for new_v1. */
19
- new_high_entropy(name: string): DynamicTnid;
17
+ newV1(name: string): DynamicTnid;
18
+ /** Alias for newV1. */
19
+ newHighEntropy(name: string): DynamicTnid;
20
20
  /** Generate a new high-entropy TNID with explicit random bits. */
21
- new_v1_with_random(name: string, randomBits: bigint): DynamicTnid;
22
- /** Parse any valid TNID string. */
21
+ newV1WithRandom(name: string, randomBits: bigint): DynamicTnid;
22
+ /** Parse a TNID from either TNID string format or UUID hex format (auto-detected). */
23
23
  parse(s: string): DynamicTnid;
24
+ /** Parse a TNID string (e.g., "user.Br2flcNDfF6LYICnT"). */
25
+ parseTnidString(s: string): DynamicTnid;
24
26
  /** Parse a UUID hex string into a DynamicTnid (validates TNID structure). */
25
- parse_uuid_string(uuid: string): DynamicTnid;
27
+ parseUuidString(uuid: string): DynamicTnid;
26
28
  /** Get the name from a TNID. */
27
29
  getName(id: DynamicTnid): string;
28
30
  /** Get the name encoded as a 5-character hex string. */
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic.d.ts","sourceRoot":"","sources":["../src/dynamic.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE/D,gEAAgE;AAChE,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAgB5C,iBAAS,kBAAkB,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CASxD;AAiBD,iBAAS,gBAAgB,CAAC,EAAE,EAAE,WAAW,EAAE,SAAS,GAAE,OAAe,GAAG,MAAM,CAmB7E;AAmDD,gDAAgD;AAChD,MAAM,WAAW,oBAAoB;IACnC,kFAAkF;IAClF,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAClC,wBAAwB;IACxB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5C,mEAAmE;IACnE,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,WAAW,CAAC;IACxD,uFAAuF;IACvF,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC;IAClF,iFAAiF;IACjF,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAClC,wBAAwB;IACxB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5C,kEAAkE;IAClE,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC;IAClE,mCAAmC;IACnC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC9B,6EAA6E;IAC7E,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC7C,gCAAgC;IAChC,OAAO,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAAC;IACjC,wDAAwD;IACxD,UAAU,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAAC;IACpC,iCAAiC;IACjC,UAAU,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CAAC;IACzC,yCAAyC;IACzC,YAAY,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;CAC1D;AAED,mEAAmE;AACnE,eAAO,MAAM,WAAW,EAAE,oBA8GzB,CAAC;AAGF,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GACjB,CAAC"}
1
+ {"version":3,"file":"dynamic.d.ts","sourceRoot":"","sources":["../src/dynamic.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE/D,gEAAgE;AAChE,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAgB5C,iBAAS,kBAAkB,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CASxD;AAiBD,iBAAS,gBAAgB,CAAC,EAAE,EAAE,WAAW,EAAE,SAAS,GAAE,OAAe,GAAG,MAAM,CAmB7E;AAmDD,gDAAgD;AAChD,MAAM,WAAW,oBAAoB;IACnC,kFAAkF;IAClF,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IACjC,uBAAuB;IACvB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC1C,mEAAmE;IACnE,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,WAAW,CAAC;IACrD,uFAAuF;IACvF,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC;IAC/E,iFAAiF;IACjF,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IACjC,uBAAuB;IACvB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC1C,kEAAkE;IAClE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAAC;IAC/D,sFAAsF;IACtF,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC9B,4DAA4D;IAC5D,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IACxC,6EAA6E;IAC7E,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3C,gCAAgC;IAChC,OAAO,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAAC;IACjC,wDAAwD;IACxD,UAAU,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAAC;IACpC,iCAAiC;IACjC,UAAU,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CAAC;IACzC,yCAAyC;IACzC,YAAY,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;CAC1D;AAED,mEAAmE;AACnE,eAAO,MAAM,WAAW,EAAE,oBA4HzB,CAAC;AAGF,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GACjB,CAAC"}
package/script/dynamic.js CHANGED
@@ -88,7 +88,7 @@ function parseDynamicUuidStringImpl(uuid) {
88
88
  /** Static methods for working with any TNID regardless of name. */
89
89
  exports.DynamicTnid = {
90
90
  /** Generate a new time-sortable TNID (variant 0) with runtime name validation. */
91
- new_v0(name) {
91
+ newV0(name) {
92
92
  if (!(0, name_encoding_js_1.isValidNameRuntime)(name)) {
93
93
  throw new Error(`Invalid TNID name: "${name}". Must be 1-4 characters of: 0-4, a-z`);
94
94
  }
@@ -97,12 +97,12 @@ exports.DynamicTnid = {
97
97
  const dataEncoded = (0, data_encoding_js_1.encodeData)(bytes);
98
98
  return `${name}.${dataEncoded}`;
99
99
  },
100
- /** Alias for new_v0. */
101
- new_time_ordered(name) {
102
- return exports.DynamicTnid.new_v0(name);
100
+ /** Alias for newV0. */
101
+ newTimeOrdered(name) {
102
+ return exports.DynamicTnid.newV0(name);
103
103
  },
104
104
  /** Generate a new time-sortable TNID with a specific timestamp. */
105
- new_v0_with_time(name, time) {
105
+ newV0WithTime(name, time) {
106
106
  if (!(0, name_encoding_js_1.isValidNameRuntime)(name)) {
107
107
  throw new Error(`Invalid TNID name: "${name}". Must be 1-4 characters of: 0-4, a-z`);
108
108
  }
@@ -113,7 +113,7 @@ exports.DynamicTnid = {
113
113
  return `${name}.${dataEncoded}`;
114
114
  },
115
115
  /** Generate a new time-sortable TNID with explicit timestamp and random components. */
116
- new_v0_with_parts(name, epochMillis, random) {
116
+ newV0WithParts(name, epochMillis, random) {
117
117
  if (!(0, name_encoding_js_1.isValidNameRuntime)(name)) {
118
118
  throw new Error(`Invalid TNID name: "${name}". Must be 1-4 characters of: 0-4, a-z`);
119
119
  }
@@ -123,7 +123,7 @@ exports.DynamicTnid = {
123
123
  return `${name}.${dataEncoded}`;
124
124
  },
125
125
  /** Generate a new high-entropy TNID (variant 1) with runtime name validation. */
126
- new_v1(name) {
126
+ newV1(name) {
127
127
  if (!(0, name_encoding_js_1.isValidNameRuntime)(name)) {
128
128
  throw new Error(`Invalid TNID name: "${name}". Must be 1-4 characters of: 0-4, a-z`);
129
129
  }
@@ -132,12 +132,12 @@ exports.DynamicTnid = {
132
132
  const dataEncoded = (0, data_encoding_js_1.encodeData)(bytes);
133
133
  return `${name}.${dataEncoded}`;
134
134
  },
135
- /** Alias for new_v1. */
136
- new_high_entropy(name) {
137
- return exports.DynamicTnid.new_v1(name);
135
+ /** Alias for newV1. */
136
+ newHighEntropy(name) {
137
+ return exports.DynamicTnid.newV1(name);
138
138
  },
139
139
  /** Generate a new high-entropy TNID with explicit random bits. */
140
- new_v1_with_random(name, randomBits) {
140
+ newV1WithRandom(name, randomBits) {
141
141
  if (!(0, name_encoding_js_1.isValidNameRuntime)(name)) {
142
142
  throw new Error(`Invalid TNID name: "${name}". Must be 1-4 characters of: 0-4, a-z`);
143
143
  }
@@ -146,12 +146,25 @@ exports.DynamicTnid = {
146
146
  const dataEncoded = (0, data_encoding_js_1.encodeData)(bytes);
147
147
  return `${name}.${dataEncoded}`;
148
148
  },
149
- /** Parse any valid TNID string. */
149
+ /** Parse a TNID from either TNID string format or UUID hex format (auto-detected). */
150
150
  parse(s) {
151
+ // Detect format by length: TNID strings are 19-22 chars with '.', UUIDs are 36 chars
152
+ if (s.length >= 19 && s.length <= 22 && s.includes(".")) {
153
+ return parseDynamicTnidImpl(s);
154
+ }
155
+ else if (s.length === 36) {
156
+ return parseDynamicUuidStringImpl(s);
157
+ }
158
+ else {
159
+ throw new Error(`Invalid TNID: expected TNID string (19-22 chars) or UUID (36 chars), got ${s.length} chars`);
160
+ }
161
+ },
162
+ /** Parse a TNID string (e.g., "user.Br2flcNDfF6LYICnT"). */
163
+ parseTnidString(s) {
151
164
  return parseDynamicTnidImpl(s);
152
165
  },
153
166
  /** Parse a UUID hex string into a DynamicTnid (validates TNID structure). */
154
- parse_uuid_string(uuid) {
167
+ parseUuidString(uuid) {
155
168
  return parseDynamicUuidStringImpl(uuid);
156
169
  },
157
170
  /** Get the name from a TNID. */
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,SAAS,EAGT,YAAY,EACb,MAAM,YAAY,CAAC;AAapB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,IAAI,CAAC,KAAK,CAAC,IAAI,SAAS,MAAM,EAC5C,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,GACvB,SAAS,CAAC,IAAI,CAAC,CAsGjB"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,SAAS,EAGT,YAAY,EACb,MAAM,YAAY,CAAC;AAapB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,IAAI,CAAC,KAAK,CAAC,IAAI,SAAS,MAAM,EAC5C,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,GACvB,SAAS,CAAC,IAAI,CAAC,CAmHjB"}
package/script/factory.js CHANGED
@@ -62,6 +62,18 @@ function Tnid(name) {
62
62
  return `${name}.${dataEncoded}`;
63
63
  },
64
64
  parse(s) {
65
+ // Detect format by length: TNID strings are 19-22 chars with '.', UUIDs are 36 chars
66
+ if (s.length >= 19 && s.length <= 22 && s.includes(".")) {
67
+ return tnid.parseTnidString(s);
68
+ }
69
+ else if (s.length === 36) {
70
+ return tnid.parseUuidString(s);
71
+ }
72
+ else {
73
+ throw new Error(`Invalid TNID: expected TNID string (19-22 chars) or UUID (36 chars), got ${s.length} chars`);
74
+ }
75
+ },
76
+ parseTnidString(s) {
65
77
  const dotIndex = s.indexOf(".");
66
78
  if (dotIndex === -1) {
67
79
  throw new Error(`Invalid TNID string: missing '.' separator`);
package/script/types.d.ts CHANGED
@@ -23,14 +23,18 @@ export type ValidateName<S extends string> = ValidateNameChars<S> extends true ?
23
23
  * const id: UserId = UserId.new_v0(); // time-sortable
24
24
  * const id2: UserId = UserId.new_v1(); // high-entropy random
25
25
  *
26
- * // Parse from strings
27
- * const parsed = UserId.parse("user.abc..."); // validates name matches
28
- * const fromUuid = UserId.parseUuidString("d6157329-4640-8e30-...");
26
+ * // Parse from strings (auto-detects format)
27
+ * const parsed = UserId.parse("user.abc..."); // TNID string format
28
+ * const fromUuid = UserId.parse("d6157329-4640-8e30-..."); // UUID format
29
+ *
30
+ * // Or use explicit parse methods
31
+ * UserId.parseTnidString("user.abc..."); // TNID string only
32
+ * UserId.parseUuidString("d6157329-..."); // UUID string only
29
33
  *
30
34
  * // DynamicTnid - runtime name validation
31
- * DynamicTnid.new_v0("item"); // create with runtime name
32
- * DynamicTnid.new_v1("item"); // create with runtime name
33
- * DynamicTnid.parse("post.xyz..."); // parse any TNID
35
+ * DynamicTnid.newV0("item"); // create with runtime name
36
+ * DynamicTnid.newV1("item"); // create with runtime name
37
+ * DynamicTnid.parse("post.xyz..."); // parse any TNID (auto-detects)
34
38
  * DynamicTnid.getName(id); // "user"
35
39
  * DynamicTnid.getVariant(id); // "v0" | "v1" | "v2" | "v3"
36
40
  *
@@ -70,10 +74,15 @@ export interface NamedTnid<Name extends string> {
70
74
  /** Construct a V1 TNID from specific parts (for deterministic testing) */
71
75
  v1_from_parts(randomBits: bigint): TnidValue<Name>;
72
76
  /**
73
- * Parse and validate a TNID string.
77
+ * Parse a TNID from either TNID string format or UUID hex format (auto-detected).
74
78
  * @throws Error if the string is invalid or the name doesn't match
75
79
  */
76
80
  parse(s: string): TnidValue<Name>;
81
+ /**
82
+ * Parse and validate a TNID string (e.g., "user.Br2flcNDfF6LYICnT").
83
+ * @throws Error if the string is invalid or the name doesn't match
84
+ */
85
+ parseTnidString(s: string): TnidValue<Name>;
77
86
  /**
78
87
  * Parse a UUID hex string into a TNID.
79
88
  * Validates that it's a valid UUIDv8 TNID and the name matches.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}