@atproto/syntax 0.4.2 → 0.4.3
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 +12 -0
- package/LICENSE.txt +1 -1
- package/dist/at-identifier.d.ts +1 -0
- package/dist/at-identifier.d.ts.map +1 -1
- package/dist/at-identifier.js +9 -0
- package/dist/at-identifier.js.map +1 -1
- package/dist/aturi.js +7 -40
- package/dist/aturi.js.map +1 -1
- package/dist/aturi_validation.d.ts +3 -2
- package/dist/aturi_validation.d.ts.map +1 -1
- package/dist/aturi_validation.js +13 -3
- package/dist/aturi_validation.js.map +1 -1
- package/dist/datetime.d.ts +2 -2
- package/dist/datetime.d.ts.map +1 -1
- package/dist/datetime.js +9 -12
- package/dist/datetime.js.map +1 -1
- package/dist/did.d.ts +3 -2
- package/dist/did.d.ts.map +1 -1
- package/dist/did.js +18 -13
- package/dist/did.js.map +1 -1
- package/dist/handle.d.ts +3 -3
- package/dist/handle.d.ts.map +1 -1
- package/dist/handle.js +9 -9
- package/dist/handle.js.map +1 -1
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -22
- package/dist/index.js.map +1 -1
- package/dist/language.d.ts +18 -0
- package/dist/language.d.ts.map +1 -0
- package/dist/language.js +30 -0
- package/dist/language.js.map +1 -0
- package/dist/nsid.d.ts +2 -2
- package/dist/nsid.d.ts.map +1 -1
- package/dist/nsid.js +5 -10
- package/dist/nsid.js.map +1 -1
- package/dist/recordkey.d.ts +2 -2
- package/dist/recordkey.d.ts.map +1 -1
- package/dist/recordkey.js +10 -10
- package/dist/recordkey.js.map +1 -1
- package/dist/tid.d.ts +2 -2
- package/dist/tid.d.ts.map +1 -1
- package/dist/tid.js +5 -5
- package/dist/tid.js.map +1 -1
- package/dist/uri.d.ts +3 -0
- package/dist/uri.d.ts.map +1 -0
- package/dist/uri.js +7 -0
- package/dist/uri.js.map +1 -0
- package/package.json +7 -4
- package/src/at-identifier.ts +12 -1
- package/src/aturi_validation.ts +20 -4
- package/src/datetime.ts +13 -14
- package/src/did.ts +25 -15
- package/src/handle.ts +15 -13
- package/src/index.ts +7 -5
- package/src/language.ts +39 -0
- package/src/nsid.ts +8 -4
- package/src/recordkey.ts +14 -12
- package/src/tid.ts +7 -5
- package/src/uri.ts +5 -0
- package/tests/aturi.test.ts +3 -2
- package/tests/datetime.test.ts +1 -0
- package/tests/did.test.ts +1 -0
- package/tests/handle.test.ts +1 -0
- package/tests/language.test.ts +88 -0
- package/tests/nsid.test.ts +1 -0
- package/tests/recordkey.test.ts +1 -0
- package/tests/tid.test.ts +1 -0
- package/tsconfig.build.json +5 -2
- package/tsconfig.build.tsbuildinfo +1 -1
- package/tsconfig.tests.json +6 -4
- package/vitest.config.ts +5 -0
- package/jest.config.js +0 -7
- package/tsconfig.tests.tsbuildinfo +0 -1
package/src/did.ts
CHANGED
|
@@ -14,19 +14,29 @@
|
|
|
14
14
|
|
|
15
15
|
export type DidString<M extends string = string> = `did:${M}:${string}`
|
|
16
16
|
|
|
17
|
-
export function ensureValidDid
|
|
18
|
-
|
|
17
|
+
export function ensureValidDid<I extends string>(
|
|
18
|
+
input: I,
|
|
19
|
+
): asserts input is I & DidString {
|
|
20
|
+
if (!input.startsWith('did:')) {
|
|
19
21
|
throw new InvalidDidError('DID requires "did:" prefix')
|
|
20
22
|
}
|
|
21
23
|
|
|
24
|
+
if (input.length > 2048) {
|
|
25
|
+
throw new InvalidDidError('DID is too long (2048 chars max)')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (input.endsWith(':') || input.endsWith('%')) {
|
|
29
|
+
throw new InvalidDidError('DID can not end with ":" or "%"')
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
// check that all chars are boring ASCII
|
|
23
|
-
if (!/^[a-zA-Z0-9._:%-]*$/.test(
|
|
33
|
+
if (!/^[a-zA-Z0-9._:%-]*$/.test(input)) {
|
|
24
34
|
throw new InvalidDidError(
|
|
25
35
|
'Disallowed characters in DID (ASCII letters, digits, and a couple other characters only)',
|
|
26
36
|
)
|
|
27
37
|
}
|
|
28
38
|
|
|
29
|
-
const { length, 1: method } =
|
|
39
|
+
const { length, 1: method } = input.split(':')
|
|
30
40
|
if (length < 3) {
|
|
31
41
|
throw new InvalidDidError(
|
|
32
42
|
'DID requires prefix, method, and method-specific content',
|
|
@@ -36,26 +46,26 @@ export function ensureValidDid(did: string): asserts did is DidString {
|
|
|
36
46
|
if (!/^[a-z]+$/.test(method)) {
|
|
37
47
|
throw new InvalidDidError('DID method must be lower-case letters')
|
|
38
48
|
}
|
|
39
|
-
|
|
40
|
-
if (did.endsWith(':') || did.endsWith('%')) {
|
|
41
|
-
throw new InvalidDidError('DID can not end with ":" or "%"')
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (did.length > 2 * 1024) {
|
|
45
|
-
throw new InvalidDidError('DID is too long (2048 chars max)')
|
|
46
|
-
}
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
const DID_REGEX = /^did:[a-z]+:[a-zA-Z0-9._:%-]*[a-zA-Z0-9._-]$/
|
|
52
|
+
|
|
53
|
+
export function ensureValidDidRegex<I extends string>(
|
|
54
|
+
input: I,
|
|
55
|
+
): asserts input is I & DidString {
|
|
50
56
|
// simple regex to enforce most constraints via just regex and length.
|
|
51
57
|
// hand wrote this regex based on above constraints
|
|
52
|
-
if (
|
|
58
|
+
if (!DID_REGEX.test(input)) {
|
|
53
59
|
throw new InvalidDidError("DID didn't validate via regex")
|
|
54
60
|
}
|
|
55
61
|
|
|
56
|
-
if (
|
|
62
|
+
if (input.length > 2048) {
|
|
57
63
|
throw new InvalidDidError('DID is too long (2048 chars max)')
|
|
58
64
|
}
|
|
59
65
|
}
|
|
60
66
|
|
|
67
|
+
export function isValidDid<I extends string>(input: I): input is I & DidString {
|
|
68
|
+
return input.length <= 2048 && DID_REGEX.test(input)
|
|
69
|
+
}
|
|
70
|
+
|
|
61
71
|
export class InvalidDidError extends Error {}
|
package/src/handle.ts
CHANGED
|
@@ -39,20 +39,20 @@ export const DISALLOWED_TLDS = [
|
|
|
39
39
|
// - does not validate whether domain or TLD exists, or is a reserved or
|
|
40
40
|
// special TLD (eg, .onion or .local)
|
|
41
41
|
// - does not validate punycode
|
|
42
|
-
export function ensureValidHandle(
|
|
43
|
-
|
|
44
|
-
): asserts
|
|
42
|
+
export function ensureValidHandle<I extends string>(
|
|
43
|
+
input: I,
|
|
44
|
+
): asserts input is I & HandleString {
|
|
45
45
|
// check that all chars are boring ASCII
|
|
46
|
-
if (!/^[a-zA-Z0-9.-]*$/.test(
|
|
46
|
+
if (!/^[a-zA-Z0-9.-]*$/.test(input)) {
|
|
47
47
|
throw new InvalidHandleError(
|
|
48
48
|
'Disallowed characters in handle (ASCII letters, digits, dashes, periods only)',
|
|
49
49
|
)
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
if (
|
|
52
|
+
if (input.length > 253) {
|
|
53
53
|
throw new InvalidHandleError('Handle is too long (253 chars max)')
|
|
54
54
|
}
|
|
55
|
-
const labels =
|
|
55
|
+
const labels = input.split('.')
|
|
56
56
|
if (labels.length < 2) {
|
|
57
57
|
throw new InvalidHandleError('Handle domain needs at least two parts')
|
|
58
58
|
}
|
|
@@ -81,13 +81,13 @@ export function ensureValidHandle(
|
|
|
81
81
|
const HANDLE_REGEX =
|
|
82
82
|
/^([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])?$/
|
|
83
83
|
|
|
84
|
-
export function ensureValidHandleRegex(
|
|
85
|
-
|
|
86
|
-
): asserts
|
|
87
|
-
if (
|
|
84
|
+
export function ensureValidHandleRegex<I extends string>(
|
|
85
|
+
input: I,
|
|
86
|
+
): asserts input is I & HandleString {
|
|
87
|
+
if (input.length > 253) {
|
|
88
88
|
throw new InvalidHandleError('Handle is too long (253 chars max)')
|
|
89
89
|
}
|
|
90
|
-
if (!HANDLE_REGEX.test(
|
|
90
|
+
if (!HANDLE_REGEX.test(input)) {
|
|
91
91
|
throw new InvalidHandleError("Handle didn't validate via regex")
|
|
92
92
|
}
|
|
93
93
|
}
|
|
@@ -102,8 +102,10 @@ export function normalizeAndEnsureValidHandle(handle: string): HandleString {
|
|
|
102
102
|
return normalized
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
export function isValidHandle
|
|
106
|
-
|
|
105
|
+
export function isValidHandle<I extends string>(
|
|
106
|
+
input: I,
|
|
107
|
+
): input is I & HandleString {
|
|
108
|
+
return input.length <= 253 && HANDLE_REGEX.test(input)
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
export function isValidTld(handle: string): boolean {
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './at-identifier.js'
|
|
2
|
+
export * from './aturi.js'
|
|
3
|
+
export * from './datetime.js'
|
|
2
4
|
export * from './did.js'
|
|
5
|
+
export * from './handle.js'
|
|
3
6
|
export * from './nsid.js'
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './at-identifier.js'
|
|
6
|
-
export * from './tid.js'
|
|
7
|
+
export * from './language.js'
|
|
7
8
|
export * from './recordkey.js'
|
|
8
|
-
export * from './
|
|
9
|
+
export * from './tid.js'
|
|
10
|
+
export * from './uri.js'
|
package/src/language.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const BCP47_REGEXP =
|
|
2
|
+
/^((?<grandfathered>(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))|((?<language>([A-Za-z]{2,3}(-(?<extlang>[A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-(?<script>[A-Za-z]{4}))?(-(?<region>[A-Za-z]{2}|[0-9]{3}))?(-(?<variant>[A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-(?<extension>[0-9A-WY-Za-wy-z](-[A-Za-z0-9]{2,8})+))*(-(?<privateUseA>x(-[A-Za-z0-9]{1,8})+))?)|(?<privateUseB>x(-[A-Za-z0-9]{1,8})+))$/
|
|
3
|
+
|
|
4
|
+
export type LanguageTag = {
|
|
5
|
+
grandfathered?: string
|
|
6
|
+
language?: string
|
|
7
|
+
extlang?: string
|
|
8
|
+
script?: string
|
|
9
|
+
region?: string
|
|
10
|
+
variant?: string
|
|
11
|
+
extension?: string
|
|
12
|
+
privateUse?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function parseLanguageString(input: string): LanguageTag | null {
|
|
16
|
+
const parsed = input.match(BCP47_REGEXP)
|
|
17
|
+
if (!parsed?.groups) return null
|
|
18
|
+
|
|
19
|
+
const { groups } = parsed
|
|
20
|
+
return {
|
|
21
|
+
grandfathered: groups.grandfathered,
|
|
22
|
+
language: groups.language,
|
|
23
|
+
extlang: groups.extlang,
|
|
24
|
+
script: groups.script,
|
|
25
|
+
region: groups.region,
|
|
26
|
+
variant: groups.variant,
|
|
27
|
+
extension: groups.extension,
|
|
28
|
+
privateUse: groups.privateUseA || groups.privateUseB,
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Validates well-formed BCP 47 syntax
|
|
34
|
+
*
|
|
35
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc5646.html#section-2.1}
|
|
36
|
+
*/
|
|
37
|
+
export function isValidLanguage(input: string): boolean {
|
|
38
|
+
return BCP47_REGEXP.test(input)
|
|
39
|
+
}
|
package/src/nsid.ts
CHANGED
|
@@ -60,8 +60,10 @@ export class NSID {
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
export function ensureValidNsid
|
|
64
|
-
|
|
63
|
+
export function ensureValidNsid<I extends string>(
|
|
64
|
+
input: I,
|
|
65
|
+
): asserts input is I & NsidString {
|
|
66
|
+
const result = validateNsid(input)
|
|
65
67
|
if (!result.success) throw new InvalidNsidError(result.message)
|
|
66
68
|
}
|
|
67
69
|
|
|
@@ -71,10 +73,12 @@ export function parseNsid(nsid: string): string[] {
|
|
|
71
73
|
return result.value
|
|
72
74
|
}
|
|
73
75
|
|
|
74
|
-
export function isValidNsid
|
|
76
|
+
export function isValidNsid<I extends string>(
|
|
77
|
+
input: I,
|
|
78
|
+
): input is I & NsidString {
|
|
75
79
|
// Since the regex version is more performant for valid NSIDs, we use it when
|
|
76
80
|
// we don't care about error details.
|
|
77
|
-
return validateNsidRegex(
|
|
81
|
+
return validateNsidRegex(input).success
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
type ValidateResult<T> =
|
package/src/recordkey.ts
CHANGED
|
@@ -17,32 +17,34 @@ const RECORD_KEY_REGEX = /^[a-zA-Z0-9_~.:-]{1,512}$/
|
|
|
17
17
|
// RFC-3986, section 3.3). The above constraints satisfy this condition, by
|
|
18
18
|
// matching the "unreserved" characters allowed in generic URI paths.
|
|
19
19
|
|
|
20
|
-
export function ensureValidRecordKey(
|
|
21
|
-
|
|
22
|
-
): asserts
|
|
20
|
+
export function ensureValidRecordKey<I extends string>(
|
|
21
|
+
input: I,
|
|
22
|
+
): asserts input is I & RecordKeyString {
|
|
23
23
|
if (
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
input.length > RECORD_KEY_MAX_LENGTH ||
|
|
25
|
+
input.length < RECORD_KEY_MIN_LENGTH
|
|
26
26
|
) {
|
|
27
27
|
throw new InvalidRecordKeyError(
|
|
28
28
|
`record key must be ${RECORD_KEY_MIN_LENGTH} to ${RECORD_KEY_MAX_LENGTH} characters`,
|
|
29
29
|
)
|
|
30
30
|
}
|
|
31
|
-
if (RECORD_KEY_INVALID_VALUES.has(
|
|
31
|
+
if (RECORD_KEY_INVALID_VALUES.has(input)) {
|
|
32
32
|
throw new InvalidRecordKeyError('record key can not be "." or ".."')
|
|
33
33
|
}
|
|
34
34
|
// simple regex to enforce most constraints via just regex and length.
|
|
35
|
-
if (!RECORD_KEY_REGEX.test(
|
|
35
|
+
if (!RECORD_KEY_REGEX.test(input)) {
|
|
36
36
|
throw new InvalidRecordKeyError('record key syntax not valid (regex)')
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
export function isValidRecordKey
|
|
40
|
+
export function isValidRecordKey<I extends string>(
|
|
41
|
+
input: I,
|
|
42
|
+
): input is I & RecordKeyString {
|
|
41
43
|
return (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
RECORD_KEY_REGEX.test(
|
|
45
|
-
!RECORD_KEY_INVALID_VALUES.has(
|
|
44
|
+
input.length >= RECORD_KEY_MIN_LENGTH &&
|
|
45
|
+
input.length <= RECORD_KEY_MAX_LENGTH &&
|
|
46
|
+
RECORD_KEY_REGEX.test(input) &&
|
|
47
|
+
!RECORD_KEY_INVALID_VALUES.has(input)
|
|
46
48
|
)
|
|
47
49
|
}
|
|
48
50
|
|
package/src/tid.ts
CHANGED
|
@@ -3,18 +3,20 @@ export type TidString = string
|
|
|
3
3
|
const TID_LENGTH = 13
|
|
4
4
|
const TID_REGEX = /^[234567abcdefghij][234567abcdefghijklmnopqrstuvwxyz]{12}$/
|
|
5
5
|
|
|
6
|
-
export function ensureValidTid
|
|
7
|
-
|
|
6
|
+
export function ensureValidTid<I extends string>(
|
|
7
|
+
input: I,
|
|
8
|
+
): asserts input is I & TidString {
|
|
9
|
+
if (input.length !== TID_LENGTH) {
|
|
8
10
|
throw new InvalidTidError(`TID must be ${TID_LENGTH} characters`)
|
|
9
11
|
}
|
|
10
12
|
// simple regex to enforce most constraints via just regex and length.
|
|
11
|
-
if (!TID_REGEX.test(
|
|
13
|
+
if (!TID_REGEX.test(input)) {
|
|
12
14
|
throw new InvalidTidError('TID syntax not valid (regex)')
|
|
13
15
|
}
|
|
14
16
|
}
|
|
15
17
|
|
|
16
|
-
export function isValidTid(
|
|
17
|
-
return
|
|
18
|
+
export function isValidTid<I extends string>(input: I): input is I & TidString {
|
|
19
|
+
return input.length === TID_LENGTH && TID_REGEX.test(input)
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
export class InvalidTidError extends Error {}
|
package/src/uri.ts
ADDED
package/tests/aturi.test.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as fs from 'node:fs'
|
|
2
2
|
import * as readline from 'node:readline'
|
|
3
|
-
import {
|
|
3
|
+
import { describe, expect, it } from 'vitest'
|
|
4
|
+
import { AtUri, ensureValidAtUri, ensureValidAtUriRegex } from '../src'
|
|
4
5
|
|
|
5
|
-
describe(
|
|
6
|
+
describe(AtUri, () => {
|
|
6
7
|
it('parses valid at uris', () => {
|
|
7
8
|
// input host path query hash
|
|
8
9
|
type AtUriTest = [string, string, string, string, string]
|
package/tests/datetime.test.ts
CHANGED
package/tests/did.test.ts
CHANGED
package/tests/handle.test.ts
CHANGED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { isValidLanguage, parseLanguageString } from '../src'
|
|
3
|
+
|
|
4
|
+
describe(isValidLanguage, () => {
|
|
5
|
+
it('validates BCP 47', () => {
|
|
6
|
+
// valid
|
|
7
|
+
expect(isValidLanguage('de')).toEqual(true)
|
|
8
|
+
expect(isValidLanguage('de-CH')).toEqual(true)
|
|
9
|
+
expect(isValidLanguage('de-DE-1901')).toEqual(true)
|
|
10
|
+
expect(isValidLanguage('es-419')).toEqual(true)
|
|
11
|
+
expect(isValidLanguage('sl-IT-nedis')).toEqual(true)
|
|
12
|
+
expect(isValidLanguage('mn-Cyrl-MN')).toEqual(true)
|
|
13
|
+
expect(isValidLanguage('x-fr-CH')).toEqual(true)
|
|
14
|
+
expect(
|
|
15
|
+
isValidLanguage('en-GB-boont-r-extended-sequence-x-private'),
|
|
16
|
+
).toEqual(true)
|
|
17
|
+
expect(isValidLanguage('sr-Cyrl')).toEqual(true)
|
|
18
|
+
expect(isValidLanguage('hy-Latn-IT-arevela')).toEqual(true)
|
|
19
|
+
expect(isValidLanguage('i-klingon')).toEqual(true)
|
|
20
|
+
// invalid
|
|
21
|
+
expect(isValidLanguage('')).toEqual(false)
|
|
22
|
+
expect(isValidLanguage('x')).toEqual(false)
|
|
23
|
+
expect(isValidLanguage('de-CH-')).toEqual(false)
|
|
24
|
+
expect(isValidLanguage('i-bad-grandfathered')).toEqual(false)
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
describe(parseLanguageString, () => {
|
|
29
|
+
it('parses BCP 47', () => {
|
|
30
|
+
// valid
|
|
31
|
+
expect(parseLanguageString('de')).toEqual({
|
|
32
|
+
language: 'de',
|
|
33
|
+
})
|
|
34
|
+
expect(parseLanguageString('de-CH')).toEqual({
|
|
35
|
+
language: 'de',
|
|
36
|
+
region: 'CH',
|
|
37
|
+
})
|
|
38
|
+
expect(parseLanguageString('de-DE-1901')).toEqual({
|
|
39
|
+
language: 'de',
|
|
40
|
+
region: 'DE',
|
|
41
|
+
variant: '1901',
|
|
42
|
+
})
|
|
43
|
+
expect(parseLanguageString('es-419')).toEqual({
|
|
44
|
+
language: 'es',
|
|
45
|
+
region: '419',
|
|
46
|
+
})
|
|
47
|
+
expect(parseLanguageString('sl-IT-nedis')).toEqual({
|
|
48
|
+
language: 'sl',
|
|
49
|
+
region: 'IT',
|
|
50
|
+
variant: 'nedis',
|
|
51
|
+
})
|
|
52
|
+
expect(parseLanguageString('mn-Cyrl-MN')).toEqual({
|
|
53
|
+
language: 'mn',
|
|
54
|
+
script: 'Cyrl',
|
|
55
|
+
region: 'MN',
|
|
56
|
+
})
|
|
57
|
+
expect(parseLanguageString('x-fr-CH')).toEqual({
|
|
58
|
+
privateUse: 'x-fr-CH',
|
|
59
|
+
})
|
|
60
|
+
expect(
|
|
61
|
+
parseLanguageString('en-GB-boont-r-extended-sequence-x-private'),
|
|
62
|
+
).toEqual({
|
|
63
|
+
language: 'en',
|
|
64
|
+
region: 'GB',
|
|
65
|
+
variant: 'boont',
|
|
66
|
+
extension: 'r-extended-sequence',
|
|
67
|
+
privateUse: 'x-private',
|
|
68
|
+
})
|
|
69
|
+
expect(parseLanguageString('sr-Cyrl')).toEqual({
|
|
70
|
+
language: 'sr',
|
|
71
|
+
script: 'Cyrl',
|
|
72
|
+
})
|
|
73
|
+
expect(parseLanguageString('hy-Latn-IT-arevela')).toEqual({
|
|
74
|
+
language: 'hy',
|
|
75
|
+
script: 'Latn',
|
|
76
|
+
region: 'IT',
|
|
77
|
+
variant: 'arevela',
|
|
78
|
+
})
|
|
79
|
+
expect(parseLanguageString('i-klingon')).toEqual({
|
|
80
|
+
grandfathered: 'i-klingon',
|
|
81
|
+
})
|
|
82
|
+
// invalid
|
|
83
|
+
expect(parseLanguageString('')).toEqual(null)
|
|
84
|
+
expect(parseLanguageString('x')).toEqual(null)
|
|
85
|
+
expect(parseLanguageString('de-CH-')).toEqual(null)
|
|
86
|
+
expect(parseLanguageString('i-bad-grandfathered')).toEqual(null)
|
|
87
|
+
})
|
|
88
|
+
})
|
package/tests/nsid.test.ts
CHANGED
package/tests/recordkey.test.ts
CHANGED
package/tests/tid.test.ts
CHANGED
package/tsconfig.build.json
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"extends": "../../tsconfig/isomorphic.json",
|
|
3
|
+
"include": ["./src"],
|
|
4
|
+
"exclude": ["**/*.test.ts"],
|
|
3
5
|
"compilerOptions": {
|
|
4
6
|
"noImplicitAny": true,
|
|
7
|
+
"importHelpers": true,
|
|
8
|
+
"target": "ES2023",
|
|
5
9
|
"rootDir": "./src",
|
|
6
10
|
"outDir": "./dist"
|
|
7
|
-
}
|
|
8
|
-
"include": ["./src"]
|
|
11
|
+
}
|
|
9
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./src/at-identifier.ts","./src/aturi.ts","./src/aturi_validation.ts","./src/datetime.ts","./src/did.ts","./src/handle.ts","./src/index.ts","./src/nsid.ts","./src/recordkey.ts","./src/tid.ts"],"version":"5.8.2"}
|
|
1
|
+
{"root":["./src/at-identifier.ts","./src/aturi.ts","./src/aturi_validation.ts","./src/datetime.ts","./src/did.ts","./src/handle.ts","./src/index.ts","./src/language.ts","./src/nsid.ts","./src/recordkey.ts","./src/tid.ts","./src/uri.ts"],"version":"5.8.2"}
|
package/tsconfig.tests.json
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"extends": "../../tsconfig/
|
|
2
|
+
"extends": "../../tsconfig/vitest.json",
|
|
3
|
+
"include": ["./tests", "./src/**/*.test.ts"],
|
|
3
4
|
"compilerOptions": {
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
"noImplicitAny": true,
|
|
6
|
+
"rootDir": "./",
|
|
7
|
+
"baseUrl": "./"
|
|
8
|
+
}
|
|
7
9
|
}
|
package/vitest.config.ts
ADDED
package/jest.config.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"root":["./tests/aturi.test.ts","./tests/datetime.test.ts","./tests/did.test.ts","./tests/handle.test.ts","./tests/nsid.test.ts","./tests/recordkey.test.ts","./tests/tid.test.ts"],"version":"5.8.3"}
|