@atproto/syntax 0.2.1 → 0.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.
- package/CHANGELOG.md +6 -0
- package/dist/aturi.d.ts +1 -0
- package/dist/aturi.d.ts.map +1 -0
- package/dist/aturi.js +160 -0
- package/dist/aturi.js.map +1 -0
- package/dist/aturi_validation.d.ts +1 -0
- package/dist/aturi_validation.d.ts.map +1 -0
- package/dist/aturi_validation.js +120 -0
- package/dist/aturi_validation.js.map +1 -0
- package/dist/datetime.d.ts +1 -0
- package/dist/datetime.d.ts.map +1 -0
- package/dist/datetime.js +108 -0
- package/dist/datetime.js.map +1 -0
- package/dist/did.d.ts +1 -0
- package/dist/did.d.ts.map +1 -0
- package/dist/did.js +54 -0
- package/dist/did.js.map +1 -0
- package/dist/handle.d.ts +1 -0
- package/dist/handle.d.ts.map +1 -0
- package/dist/handle.js +119 -0
- package/dist/handle.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -603
- package/dist/index.js.map +1 -7
- package/dist/nsid.d.ts +1 -0
- package/dist/nsid.d.ts.map +1 -0
- package/dist/nsid.js +107 -0
- package/dist/nsid.js.map +1 -0
- package/dist/recordkey.d.ts +1 -0
- package/dist/recordkey.d.ts.map +1 -0
- package/dist/recordkey.js +32 -0
- package/dist/recordkey.js.map +1 -0
- package/dist/tid.d.ts +1 -0
- package/dist/tid.d.ts.map +1 -0
- package/dist/tid.js +30 -0
- package/dist/tid.js.map +1 -0
- package/jest.config.js +3 -3
- package/package.json +7 -8
- package/tsconfig.build.json +6 -2
- package/tsconfig.json +5 -8
- package/tsconfig.tests.json +7 -0
- package/babel.config.js +0 -1
- package/build.js +0 -22
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handle.js","sourceRoot":"","sources":["../src/handle.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,OAAO,CAAA;AACrB,cAAc,QAAQ,CAAA;AACtB,cAAc,SAAS,CAAA;AACvB,cAAc,OAAO,CAAA;AACrB,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,604 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
var
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
DISALLOWED_TLDS: () => DISALLOWED_TLDS,
|
|
26
|
-
DisallowedDomainError: () => DisallowedDomainError,
|
|
27
|
-
INVALID_HANDLE: () => INVALID_HANDLE,
|
|
28
|
-
InvalidDatetimeError: () => InvalidDatetimeError,
|
|
29
|
-
InvalidDidError: () => InvalidDidError,
|
|
30
|
-
InvalidHandleError: () => InvalidHandleError,
|
|
31
|
-
InvalidNsidError: () => InvalidNsidError,
|
|
32
|
-
InvalidRecordKeyError: () => InvalidRecordKeyError,
|
|
33
|
-
InvalidTidError: () => InvalidTidError,
|
|
34
|
-
NSID: () => NSID,
|
|
35
|
-
ReservedHandleError: () => ReservedHandleError,
|
|
36
|
-
UnsupportedDomainError: () => UnsupportedDomainError,
|
|
37
|
-
ensureValidAtUri: () => ensureValidAtUri,
|
|
38
|
-
ensureValidAtUriRegex: () => ensureValidAtUriRegex,
|
|
39
|
-
ensureValidDatetime: () => ensureValidDatetime,
|
|
40
|
-
ensureValidDid: () => ensureValidDid,
|
|
41
|
-
ensureValidDidRegex: () => ensureValidDidRegex,
|
|
42
|
-
ensureValidHandle: () => ensureValidHandle,
|
|
43
|
-
ensureValidHandleRegex: () => ensureValidHandleRegex,
|
|
44
|
-
ensureValidNsid: () => ensureValidNsid,
|
|
45
|
-
ensureValidNsidRegex: () => ensureValidNsidRegex,
|
|
46
|
-
ensureValidRecordKey: () => ensureValidRecordKey,
|
|
47
|
-
ensureValidTid: () => ensureValidTid,
|
|
48
|
-
isValidDatetime: () => isValidDatetime,
|
|
49
|
-
isValidHandle: () => isValidHandle,
|
|
50
|
-
isValidRecordKey: () => isValidRecordKey,
|
|
51
|
-
isValidTid: () => isValidTid,
|
|
52
|
-
isValidTld: () => isValidTld,
|
|
53
|
-
normalizeAndEnsureValidHandle: () => normalizeAndEnsureValidHandle,
|
|
54
|
-
normalizeDatetime: () => normalizeDatetime,
|
|
55
|
-
normalizeDatetimeAlways: () => normalizeDatetimeAlways,
|
|
56
|
-
normalizeHandle: () => normalizeHandle
|
|
57
|
-
});
|
|
58
|
-
module.exports = __toCommonJS(src_exports);
|
|
59
|
-
|
|
60
|
-
// src/handle.ts
|
|
61
|
-
var INVALID_HANDLE = "handle.invalid";
|
|
62
|
-
var DISALLOWED_TLDS = [
|
|
63
|
-
".local",
|
|
64
|
-
".arpa",
|
|
65
|
-
".invalid",
|
|
66
|
-
".localhost",
|
|
67
|
-
".internal",
|
|
68
|
-
".example",
|
|
69
|
-
".alt",
|
|
70
|
-
".onion"
|
|
71
|
-
];
|
|
72
|
-
var ensureValidHandle = (handle) => {
|
|
73
|
-
if (!/^[a-zA-Z0-9.-]*$/.test(handle)) {
|
|
74
|
-
throw new InvalidHandleError("Disallowed characters in handle (ASCII letters, digits, dashes, periods only)");
|
|
75
|
-
}
|
|
76
|
-
if (handle.length > 253) {
|
|
77
|
-
throw new InvalidHandleError("Handle is too long (253 chars max)");
|
|
78
|
-
}
|
|
79
|
-
const labels = handle.split(".");
|
|
80
|
-
if (labels.length < 2) {
|
|
81
|
-
throw new InvalidHandleError("Handle domain needs at least two parts");
|
|
82
|
-
}
|
|
83
|
-
for (let i = 0; i < labels.length; i++) {
|
|
84
|
-
const l = labels[i];
|
|
85
|
-
if (l.length < 1) {
|
|
86
|
-
throw new InvalidHandleError("Handle parts can not be empty");
|
|
87
|
-
}
|
|
88
|
-
if (l.length > 63) {
|
|
89
|
-
throw new InvalidHandleError("Handle part too long (max 63 chars)");
|
|
90
|
-
}
|
|
91
|
-
if (l.endsWith("-") || l.startsWith("-")) {
|
|
92
|
-
throw new InvalidHandleError("Handle parts can not start or end with hyphens");
|
|
93
|
-
}
|
|
94
|
-
if (i + 1 == labels.length && !/^[a-zA-Z]/.test(l)) {
|
|
95
|
-
throw new InvalidHandleError("Handle final component (TLD) must start with ASCII letter");
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
var ensureValidHandleRegex = (handle) => {
|
|
100
|
-
if (!/^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/.test(handle)) {
|
|
101
|
-
throw new InvalidHandleError("Handle didn't validate via regex");
|
|
102
|
-
}
|
|
103
|
-
if (handle.length > 253) {
|
|
104
|
-
throw new InvalidHandleError("Handle is too long (253 chars max)");
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
var normalizeHandle = (handle) => {
|
|
108
|
-
return handle.toLowerCase();
|
|
109
|
-
};
|
|
110
|
-
var normalizeAndEnsureValidHandle = (handle) => {
|
|
111
|
-
const normalized = normalizeHandle(handle);
|
|
112
|
-
ensureValidHandle(normalized);
|
|
113
|
-
return normalized;
|
|
114
|
-
};
|
|
115
|
-
var isValidHandle = (handle) => {
|
|
116
|
-
try {
|
|
117
|
-
ensureValidHandle(handle);
|
|
118
|
-
} catch (err) {
|
|
119
|
-
if (err instanceof InvalidHandleError) {
|
|
120
|
-
return false;
|
|
121
|
-
}
|
|
122
|
-
throw err;
|
|
123
|
-
}
|
|
124
|
-
return true;
|
|
125
|
-
};
|
|
126
|
-
var isValidTld = (handle) => {
|
|
127
|
-
return !DISALLOWED_TLDS.some((domain) => handle.endsWith(domain));
|
|
128
|
-
};
|
|
129
|
-
var InvalidHandleError = class extends Error {
|
|
130
|
-
};
|
|
131
|
-
var ReservedHandleError = class extends Error {
|
|
132
|
-
};
|
|
133
|
-
var UnsupportedDomainError = class extends Error {
|
|
134
|
-
};
|
|
135
|
-
var DisallowedDomainError = class extends Error {
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
// src/did.ts
|
|
139
|
-
var ensureValidDid = (did) => {
|
|
140
|
-
if (!/^[a-zA-Z0-9._:%-]*$/.test(did)) {
|
|
141
|
-
throw new InvalidDidError("Disallowed characters in DID (ASCII letters, digits, and a couple other characters only)");
|
|
142
|
-
}
|
|
143
|
-
const parts = did.split(":");
|
|
144
|
-
if (parts.length < 3) {
|
|
145
|
-
throw new InvalidDidError("DID requires prefix, method, and method-specific content");
|
|
146
|
-
}
|
|
147
|
-
if (parts[0] != "did") {
|
|
148
|
-
throw new InvalidDidError('DID requires "did:" prefix');
|
|
149
|
-
}
|
|
150
|
-
if (!/^[a-z]+$/.test(parts[1])) {
|
|
151
|
-
throw new InvalidDidError("DID method must be lower-case letters");
|
|
152
|
-
}
|
|
153
|
-
if (did.endsWith(":") || did.endsWith("%")) {
|
|
154
|
-
throw new InvalidDidError('DID can not end with ":" or "%"');
|
|
155
|
-
}
|
|
156
|
-
if (did.length > 2 * 1024) {
|
|
157
|
-
throw new InvalidDidError("DID is too long (2048 chars max)");
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
var ensureValidDidRegex = (did) => {
|
|
161
|
-
if (!/^did:[a-z]+:[a-zA-Z0-9._:%-]*[a-zA-Z0-9._-]$/.test(did)) {
|
|
162
|
-
throw new InvalidDidError("DID didn't validate via regex");
|
|
163
|
-
}
|
|
164
|
-
if (did.length > 2 * 1024) {
|
|
165
|
-
throw new InvalidDidError("DID is too long (2048 chars max)");
|
|
166
|
-
}
|
|
167
|
-
};
|
|
168
|
-
var InvalidDidError = class extends Error {
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
// src/nsid.ts
|
|
172
|
-
var NSID = class {
|
|
173
|
-
constructor(nsid) {
|
|
174
|
-
this.segments = [];
|
|
175
|
-
ensureValidNsid(nsid);
|
|
176
|
-
this.segments = nsid.split(".");
|
|
177
|
-
}
|
|
178
|
-
static parse(nsid) {
|
|
179
|
-
return new NSID(nsid);
|
|
180
|
-
}
|
|
181
|
-
static create(authority, name) {
|
|
182
|
-
const segments = [...authority.split(".").reverse(), name].join(".");
|
|
183
|
-
return new NSID(segments);
|
|
184
|
-
}
|
|
185
|
-
static isValid(nsid) {
|
|
186
|
-
try {
|
|
187
|
-
NSID.parse(nsid);
|
|
188
|
-
return true;
|
|
189
|
-
} catch (e) {
|
|
190
|
-
return false;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
get authority() {
|
|
194
|
-
return this.segments.slice(0, this.segments.length - 1).reverse().join(".");
|
|
195
|
-
}
|
|
196
|
-
get name() {
|
|
197
|
-
return this.segments.at(this.segments.length - 1);
|
|
198
|
-
}
|
|
199
|
-
toString() {
|
|
200
|
-
return this.segments.join(".");
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
var ensureValidNsid = (nsid) => {
|
|
204
|
-
const toCheck = nsid;
|
|
205
|
-
if (!/^[a-zA-Z0-9.-]*$/.test(toCheck)) {
|
|
206
|
-
throw new InvalidNsidError("Disallowed characters in NSID (ASCII letters, digits, dashes, periods only)");
|
|
207
|
-
}
|
|
208
|
-
if (toCheck.length > 253 + 1 + 63) {
|
|
209
|
-
throw new InvalidNsidError("NSID is too long (317 chars max)");
|
|
210
|
-
}
|
|
211
|
-
const labels = toCheck.split(".");
|
|
212
|
-
if (labels.length < 3) {
|
|
213
|
-
throw new InvalidNsidError("NSID needs at least three parts");
|
|
214
|
-
}
|
|
215
|
-
for (let i = 0; i < labels.length; i++) {
|
|
216
|
-
const l = labels[i];
|
|
217
|
-
if (l.length < 1) {
|
|
218
|
-
throw new InvalidNsidError("NSID parts can not be empty");
|
|
219
|
-
}
|
|
220
|
-
if (l.length > 63) {
|
|
221
|
-
throw new InvalidNsidError("NSID part too long (max 63 chars)");
|
|
222
|
-
}
|
|
223
|
-
if (l.endsWith("-") || l.startsWith("-")) {
|
|
224
|
-
throw new InvalidNsidError("NSID parts can not start or end with hyphen");
|
|
225
|
-
}
|
|
226
|
-
if (/^[0-9]/.test(l) && i == 0) {
|
|
227
|
-
throw new InvalidNsidError("NSID first part may not start with a digit");
|
|
228
|
-
}
|
|
229
|
-
if (!/^[a-zA-Z]+$/.test(l) && i + 1 == labels.length) {
|
|
230
|
-
throw new InvalidNsidError("NSID name part must be only letters");
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
var ensureValidNsidRegex = (nsid) => {
|
|
235
|
-
if (!/^[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(\.[a-zA-Z]([a-zA-Z]{0,61}[a-zA-Z])?)$/.test(nsid)) {
|
|
236
|
-
throw new InvalidNsidError("NSID didn't validate via regex");
|
|
237
|
-
}
|
|
238
|
-
if (nsid.length > 253 + 1 + 63) {
|
|
239
|
-
throw new InvalidNsidError("NSID is too long (317 chars max)");
|
|
240
|
-
}
|
|
241
|
-
};
|
|
242
|
-
var InvalidNsidError = class extends Error {
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
// src/aturi_validation.ts
|
|
246
|
-
var ensureValidAtUri = (uri) => {
|
|
247
|
-
const uriParts = uri.split("#");
|
|
248
|
-
if (uriParts.length > 2) {
|
|
249
|
-
throw new Error('ATURI can have at most one "#", separating fragment out');
|
|
250
|
-
}
|
|
251
|
-
const fragmentPart = uriParts[1] || null;
|
|
252
|
-
uri = uriParts[0];
|
|
253
|
-
if (!/^[a-zA-Z0-9._~:@!$&')(*+,;=%/-]*$/.test(uri)) {
|
|
254
|
-
throw new Error("Disallowed characters in ATURI (ASCII)");
|
|
255
|
-
}
|
|
256
|
-
const parts = uri.split("/");
|
|
257
|
-
if (parts.length >= 3 && (parts[0] != "at:" || parts[1].length != 0)) {
|
|
258
|
-
throw new Error('ATURI must start with "at://"');
|
|
259
|
-
}
|
|
260
|
-
if (parts.length < 3) {
|
|
261
|
-
throw new Error("ATURI requires at least method and authority sections");
|
|
262
|
-
}
|
|
263
|
-
try {
|
|
264
|
-
if (parts[2].startsWith("did:")) {
|
|
265
|
-
ensureValidDid(parts[2]);
|
|
266
|
-
} else {
|
|
267
|
-
ensureValidHandle(parts[2]);
|
|
268
|
-
}
|
|
269
|
-
} catch {
|
|
270
|
-
throw new Error("ATURI authority must be a valid handle or DID");
|
|
271
|
-
}
|
|
272
|
-
if (parts.length >= 4) {
|
|
273
|
-
if (parts[3].length == 0) {
|
|
274
|
-
throw new Error("ATURI can not have a slash after authority without a path segment");
|
|
275
|
-
}
|
|
276
|
-
try {
|
|
277
|
-
ensureValidNsid(parts[3]);
|
|
278
|
-
} catch {
|
|
279
|
-
throw new Error("ATURI requires first path segment (if supplied) to be valid NSID");
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
if (parts.length >= 5) {
|
|
283
|
-
if (parts[4].length == 0) {
|
|
284
|
-
throw new Error("ATURI can not have a slash after collection, unless record key is provided");
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
if (parts.length >= 6) {
|
|
288
|
-
throw new Error("ATURI path can have at most two parts, and no trailing slash");
|
|
289
|
-
}
|
|
290
|
-
if (uriParts.length >= 2 && fragmentPart == null) {
|
|
291
|
-
throw new Error("ATURI fragment must be non-empty and start with slash");
|
|
292
|
-
}
|
|
293
|
-
if (fragmentPart != null) {
|
|
294
|
-
if (fragmentPart.length == 0 || fragmentPart[0] != "/") {
|
|
295
|
-
throw new Error("ATURI fragment must be non-empty and start with slash");
|
|
296
|
-
}
|
|
297
|
-
if (!/^\/[a-zA-Z0-9._~:@!$&')(*+,;=%[\]/-]*$/.test(fragmentPart)) {
|
|
298
|
-
throw new Error("Disallowed characters in ATURI fragment (ASCII)");
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
if (uri.length > 8 * 1024) {
|
|
302
|
-
throw new Error("ATURI is far too long");
|
|
303
|
-
}
|
|
304
|
-
};
|
|
305
|
-
var ensureValidAtUriRegex = (uri) => {
|
|
306
|
-
const aturiRegex = /^at:\/\/(?<authority>[a-zA-Z0-9._:%-]+)(\/(?<collection>[a-zA-Z0-9-.]+)(\/(?<rkey>[a-zA-Z0-9._~:@!$&%')(*+,;=-]+))?)?(#(?<fragment>\/[a-zA-Z0-9._~:@!$&%')(*+,;=\-[\]/\\]*))?$/;
|
|
307
|
-
const rm = uri.match(aturiRegex);
|
|
308
|
-
if (!rm || !rm.groups) {
|
|
309
|
-
throw new Error("ATURI didn't validate via regex");
|
|
310
|
-
}
|
|
311
|
-
const groups = rm.groups;
|
|
312
|
-
try {
|
|
313
|
-
ensureValidHandleRegex(groups.authority);
|
|
314
|
-
} catch {
|
|
315
|
-
try {
|
|
316
|
-
ensureValidDidRegex(groups.authority);
|
|
317
|
-
} catch {
|
|
318
|
-
throw new Error("ATURI authority must be a valid handle or DID");
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
if (groups.collection) {
|
|
322
|
-
try {
|
|
323
|
-
ensureValidNsidRegex(groups.collection);
|
|
324
|
-
} catch {
|
|
325
|
-
throw new Error("ATURI collection path segment must be a valid NSID");
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
if (uri.length > 8 * 1024) {
|
|
329
|
-
throw new Error("ATURI is far too long");
|
|
330
|
-
}
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
// src/aturi.ts
|
|
334
|
-
var ATP_URI_REGEX = /^(at:\/\/)?((?:did:[a-z0-9:%-]+)|(?:[a-z0-9][a-z0-9.:-]*))(\/[^?#\s]*)?(\?[^#\s]+)?(#[^\s]+)?$/i;
|
|
335
|
-
var RELATIVE_REGEX = /^(\/[^?#\s]*)?(\?[^#\s]+)?(#[^\s]+)?$/i;
|
|
336
|
-
var AtUri = class {
|
|
337
|
-
constructor(uri, base) {
|
|
338
|
-
let parsed;
|
|
339
|
-
if (base) {
|
|
340
|
-
parsed = parse(base);
|
|
341
|
-
if (!parsed) {
|
|
342
|
-
throw new Error(`Invalid at uri: ${base}`);
|
|
343
|
-
}
|
|
344
|
-
const relativep = parseRelative(uri);
|
|
345
|
-
if (!relativep) {
|
|
346
|
-
throw new Error(`Invalid path: ${uri}`);
|
|
347
|
-
}
|
|
348
|
-
Object.assign(parsed, relativep);
|
|
349
|
-
} else {
|
|
350
|
-
parsed = parse(uri);
|
|
351
|
-
if (!parsed) {
|
|
352
|
-
throw new Error(`Invalid at uri: ${uri}`);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
this.hash = parsed.hash;
|
|
356
|
-
this.host = parsed.host;
|
|
357
|
-
this.pathname = parsed.pathname;
|
|
358
|
-
this.searchParams = parsed.searchParams;
|
|
359
|
-
}
|
|
360
|
-
static make(handleOrDid, collection, rkey) {
|
|
361
|
-
let str = handleOrDid;
|
|
362
|
-
if (collection)
|
|
363
|
-
str += "/" + collection;
|
|
364
|
-
if (rkey)
|
|
365
|
-
str += "/" + rkey;
|
|
366
|
-
return new AtUri(str);
|
|
367
|
-
}
|
|
368
|
-
get protocol() {
|
|
369
|
-
return "at:";
|
|
370
|
-
}
|
|
371
|
-
get origin() {
|
|
372
|
-
return `at://${this.host}`;
|
|
373
|
-
}
|
|
374
|
-
get hostname() {
|
|
375
|
-
return this.host;
|
|
376
|
-
}
|
|
377
|
-
set hostname(v) {
|
|
378
|
-
this.host = v;
|
|
379
|
-
}
|
|
380
|
-
get search() {
|
|
381
|
-
return this.searchParams.toString();
|
|
382
|
-
}
|
|
383
|
-
set search(v) {
|
|
384
|
-
this.searchParams = new URLSearchParams(v);
|
|
385
|
-
}
|
|
386
|
-
get collection() {
|
|
387
|
-
return this.pathname.split("/").filter(Boolean)[0] || "";
|
|
388
|
-
}
|
|
389
|
-
set collection(v) {
|
|
390
|
-
const parts = this.pathname.split("/").filter(Boolean);
|
|
391
|
-
parts[0] = v;
|
|
392
|
-
this.pathname = parts.join("/");
|
|
393
|
-
}
|
|
394
|
-
get rkey() {
|
|
395
|
-
return this.pathname.split("/").filter(Boolean)[1] || "";
|
|
396
|
-
}
|
|
397
|
-
set rkey(v) {
|
|
398
|
-
const parts = this.pathname.split("/").filter(Boolean);
|
|
399
|
-
if (!parts[0])
|
|
400
|
-
parts[0] = "undefined";
|
|
401
|
-
parts[1] = v;
|
|
402
|
-
this.pathname = parts.join("/");
|
|
403
|
-
}
|
|
404
|
-
get href() {
|
|
405
|
-
return this.toString();
|
|
406
|
-
}
|
|
407
|
-
toString() {
|
|
408
|
-
let path = this.pathname || "/";
|
|
409
|
-
if (!path.startsWith("/")) {
|
|
410
|
-
path = `/${path}`;
|
|
411
|
-
}
|
|
412
|
-
let qs = this.searchParams.toString();
|
|
413
|
-
if (qs && !qs.startsWith("?")) {
|
|
414
|
-
qs = `?${qs}`;
|
|
415
|
-
}
|
|
416
|
-
let hash = this.hash;
|
|
417
|
-
if (hash && !hash.startsWith("#")) {
|
|
418
|
-
hash = `#${hash}`;
|
|
419
|
-
}
|
|
420
|
-
return `at://${this.host}${path}${qs}${hash}`;
|
|
421
|
-
}
|
|
422
|
-
};
|
|
423
|
-
function parse(str) {
|
|
424
|
-
const match = ATP_URI_REGEX.exec(str);
|
|
425
|
-
if (match) {
|
|
426
|
-
return {
|
|
427
|
-
hash: match[5] || "",
|
|
428
|
-
host: match[2] || "",
|
|
429
|
-
pathname: match[3] || "",
|
|
430
|
-
searchParams: new URLSearchParams(match[4] || "")
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
return void 0;
|
|
434
|
-
}
|
|
435
|
-
function parseRelative(str) {
|
|
436
|
-
const match = RELATIVE_REGEX.exec(str);
|
|
437
|
-
if (match) {
|
|
438
|
-
return {
|
|
439
|
-
hash: match[3] || "",
|
|
440
|
-
pathname: match[1] || "",
|
|
441
|
-
searchParams: new URLSearchParams(match[2] || "")
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
return void 0;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// src/tid.ts
|
|
448
|
-
var ensureValidTid = (tid) => {
|
|
449
|
-
if (tid.length != 13) {
|
|
450
|
-
throw new InvalidTidError("TID must be 13 characters");
|
|
451
|
-
}
|
|
452
|
-
if (!/^[234567abcdefghij][234567abcdefghijklmnopqrstuvwxyz]{12}$/.test(tid)) {
|
|
453
|
-
throw new InvalidTidError("TID syntax not valid (regex)");
|
|
454
|
-
}
|
|
455
|
-
};
|
|
456
|
-
var isValidTid = (tid) => {
|
|
457
|
-
try {
|
|
458
|
-
ensureValidTid(tid);
|
|
459
|
-
} catch (err) {
|
|
460
|
-
if (err instanceof InvalidTidError) {
|
|
461
|
-
return false;
|
|
462
|
-
}
|
|
463
|
-
throw err;
|
|
464
|
-
}
|
|
465
|
-
return true;
|
|
466
|
-
};
|
|
467
|
-
var InvalidTidError = class extends Error {
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
// src/recordkey.ts
|
|
471
|
-
var ensureValidRecordKey = (rkey) => {
|
|
472
|
-
if (rkey.length > 512 || rkey.length < 1) {
|
|
473
|
-
throw new InvalidRecordKeyError("record key must be 1 to 512 characters");
|
|
474
|
-
}
|
|
475
|
-
if (!/^[a-zA-Z0-9_~.:-]{1,512}$/.test(rkey)) {
|
|
476
|
-
throw new InvalidRecordKeyError("record key syntax not valid (regex)");
|
|
477
|
-
}
|
|
478
|
-
if (rkey == "." || rkey == "..")
|
|
479
|
-
throw new InvalidRecordKeyError('record key can not be "." or ".."');
|
|
480
|
-
};
|
|
481
|
-
var isValidRecordKey = (rkey) => {
|
|
482
|
-
try {
|
|
483
|
-
ensureValidRecordKey(rkey);
|
|
484
|
-
} catch (err) {
|
|
485
|
-
if (err instanceof InvalidRecordKeyError) {
|
|
486
|
-
return false;
|
|
487
|
-
}
|
|
488
|
-
throw err;
|
|
489
|
-
}
|
|
490
|
-
return true;
|
|
491
|
-
};
|
|
492
|
-
var InvalidRecordKeyError = class extends Error {
|
|
493
|
-
};
|
|
494
|
-
|
|
495
|
-
// src/datetime.ts
|
|
496
|
-
var ensureValidDatetime = (dtStr) => {
|
|
497
|
-
const date = new Date(dtStr);
|
|
498
|
-
if (isNaN(date.getTime())) {
|
|
499
|
-
throw new InvalidDatetimeError("datetime did not parse as ISO 8601");
|
|
500
|
-
}
|
|
501
|
-
if (date.toISOString().startsWith("-")) {
|
|
502
|
-
throw new InvalidDatetimeError("datetime normalized to a negative time");
|
|
503
|
-
}
|
|
504
|
-
if (!/^[0-9]{4}-[01][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](.[0-9]{1,20})?(Z|([+-][0-2][0-9]:[0-5][0-9]))$/.test(dtStr)) {
|
|
505
|
-
throw new InvalidDatetimeError("datetime didn't validate via regex");
|
|
506
|
-
}
|
|
507
|
-
if (dtStr.length > 64) {
|
|
508
|
-
throw new InvalidDatetimeError("datetime is too long (64 chars max)");
|
|
509
|
-
}
|
|
510
|
-
if (dtStr.endsWith("-00:00")) {
|
|
511
|
-
throw new InvalidDatetimeError('datetime can not use "-00:00" for UTC timezone');
|
|
512
|
-
}
|
|
513
|
-
if (dtStr.startsWith("000")) {
|
|
514
|
-
throw new InvalidDatetimeError("datetime so close to year zero not allowed");
|
|
515
|
-
}
|
|
516
|
-
};
|
|
517
|
-
var isValidDatetime = (dtStr) => {
|
|
518
|
-
try {
|
|
519
|
-
ensureValidDatetime(dtStr);
|
|
520
|
-
} catch (err) {
|
|
521
|
-
if (err instanceof InvalidDatetimeError) {
|
|
522
|
-
return false;
|
|
523
|
-
}
|
|
524
|
-
throw err;
|
|
525
|
-
}
|
|
526
|
-
return true;
|
|
527
|
-
};
|
|
528
|
-
var normalizeDatetime = (dtStr) => {
|
|
529
|
-
if (isValidDatetime(dtStr)) {
|
|
530
|
-
const outStr = new Date(dtStr).toISOString();
|
|
531
|
-
if (isValidDatetime(outStr)) {
|
|
532
|
-
return outStr;
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
if (!/.*(([+-]\d\d:?\d\d)|[a-zA-Z])$/.test(dtStr)) {
|
|
536
|
-
const date2 = new Date(dtStr + "Z");
|
|
537
|
-
if (!isNaN(date2.getTime())) {
|
|
538
|
-
const tzStr = date2.toISOString();
|
|
539
|
-
if (isValidDatetime(tzStr)) {
|
|
540
|
-
return tzStr;
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
const date = new Date(dtStr);
|
|
545
|
-
if (isNaN(date.getTime())) {
|
|
546
|
-
throw new InvalidDatetimeError("datetime did not parse as any timestamp format");
|
|
547
|
-
}
|
|
548
|
-
const isoStr = date.toISOString();
|
|
549
|
-
if (isValidDatetime(isoStr)) {
|
|
550
|
-
return isoStr;
|
|
551
|
-
} else {
|
|
552
|
-
throw new InvalidDatetimeError("datetime normalized to invalid timestamp string");
|
|
553
|
-
}
|
|
554
|
-
};
|
|
555
|
-
var normalizeDatetimeAlways = (dtStr) => {
|
|
556
|
-
try {
|
|
557
|
-
return normalizeDatetime(dtStr);
|
|
558
|
-
} catch (err) {
|
|
559
|
-
if (err instanceof InvalidDatetimeError) {
|
|
560
|
-
return new Date(0).toISOString();
|
|
561
|
-
}
|
|
562
|
-
throw err;
|
|
563
|
-
}
|
|
564
|
-
};
|
|
565
|
-
var InvalidDatetimeError = class extends Error {
|
|
566
|
-
};
|
|
567
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
568
|
-
0 && (module.exports = {
|
|
569
|
-
ATP_URI_REGEX,
|
|
570
|
-
AtUri,
|
|
571
|
-
DISALLOWED_TLDS,
|
|
572
|
-
DisallowedDomainError,
|
|
573
|
-
INVALID_HANDLE,
|
|
574
|
-
InvalidDatetimeError,
|
|
575
|
-
InvalidDidError,
|
|
576
|
-
InvalidHandleError,
|
|
577
|
-
InvalidNsidError,
|
|
578
|
-
InvalidRecordKeyError,
|
|
579
|
-
InvalidTidError,
|
|
580
|
-
NSID,
|
|
581
|
-
ReservedHandleError,
|
|
582
|
-
UnsupportedDomainError,
|
|
583
|
-
ensureValidAtUri,
|
|
584
|
-
ensureValidAtUriRegex,
|
|
585
|
-
ensureValidDatetime,
|
|
586
|
-
ensureValidDid,
|
|
587
|
-
ensureValidDidRegex,
|
|
588
|
-
ensureValidHandle,
|
|
589
|
-
ensureValidHandleRegex,
|
|
590
|
-
ensureValidNsid,
|
|
591
|
-
ensureValidNsidRegex,
|
|
592
|
-
ensureValidRecordKey,
|
|
593
|
-
ensureValidTid,
|
|
594
|
-
isValidDatetime,
|
|
595
|
-
isValidHandle,
|
|
596
|
-
isValidRecordKey,
|
|
597
|
-
isValidTid,
|
|
598
|
-
isValidTld,
|
|
599
|
-
normalizeAndEnsureValidHandle,
|
|
600
|
-
normalizeDatetime,
|
|
601
|
-
normalizeDatetimeAlways,
|
|
602
|
-
normalizeHandle
|
|
603
|
-
});
|
|
604
|
-
//# sourceMappingURL=index.js.map
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./handle"), exports);
|
|
18
|
+
__exportStar(require("./did"), exports);
|
|
19
|
+
__exportStar(require("./nsid"), exports);
|
|
20
|
+
__exportStar(require("./aturi"), exports);
|
|
21
|
+
__exportStar(require("./tid"), exports);
|
|
22
|
+
__exportStar(require("./recordkey"), exports);
|
|
23
|
+
__exportStar(require("./datetime"), exports);
|
|
24
|
+
//# sourceMappingURL=index.js.map
|