@atproto/lex-json 0.0.8 → 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/CHANGELOG.md +9 -0
- package/LICENSE.txt +1 -1
- package/dist/lex-json.js +2 -2
- package/dist/lex-json.js.map +1 -1
- package/package.json +2 -2
- package/src/lex-json.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @atproto/lex-json
|
|
2
2
|
|
|
3
|
+
## 0.0.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#4532](https://github.com/bluesky-social/atproto/pull/4532) [`aaedafc`](https://github.com/bluesky-social/atproto/commit/aaedafc6baef106b85e0954d8474cec21c00c1c2) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Minor change to validation of integers in lex data
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`7310b97`](https://github.com/bluesky-social/atproto/commit/7310b9704de678a3b389a741784d58bb7f79b10b), [`99963d0`](https://github.com/bluesky-social/atproto/commit/99963d002a9e030e79aed5fba700e0a68f31e101), [`99963d0`](https://github.com/bluesky-social/atproto/commit/99963d002a9e030e79aed5fba700e0a68f31e101)]:
|
|
10
|
+
- @atproto/lex-data@0.0.9
|
|
11
|
+
|
|
3
12
|
## 0.0.8
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
package/LICENSE.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Dual MIT/Apache-2.0 License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2022-
|
|
3
|
+
Copyright (c) 2022-2026 Bluesky Social PBC, and Contributors
|
|
4
4
|
|
|
5
5
|
Except as otherwise noted in individual files, this software is licensed under the MIT license (<http://opensource.org/licenses/MIT>), or the Apache License, Version 2.0 (<http://www.apache.org/licenses/LICENSE-2.0>).
|
|
6
6
|
|
package/dist/lex-json.js
CHANGED
|
@@ -24,7 +24,7 @@ function lexParse(input, options = { strict: false }) {
|
|
|
24
24
|
return value;
|
|
25
25
|
return parseSpecialJsonObject(value, options) ?? value;
|
|
26
26
|
case 'number':
|
|
27
|
-
if (Number.
|
|
27
|
+
if (Number.isSafeInteger(value))
|
|
28
28
|
return value;
|
|
29
29
|
if (options.strict) {
|
|
30
30
|
throw new TypeError(`Invalid non-integer number: ${value}`);
|
|
@@ -46,7 +46,7 @@ function jsonToLex(value, options = { strict: false }) {
|
|
|
46
46
|
jsonObjectToLexMap(value, options));
|
|
47
47
|
}
|
|
48
48
|
case 'number':
|
|
49
|
-
if (Number.
|
|
49
|
+
if (Number.isSafeInteger(value))
|
|
50
50
|
return value;
|
|
51
51
|
if (options.strict) {
|
|
52
52
|
throw new TypeError(`Invalid non-integer number: ${value}`);
|
package/dist/lex-json.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lex-json.js","sourceRoot":"","sources":["../src/lex-json.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BlobRef,\n Cid,\n LexArray,\n LexMap,\n LexValue,\n isCid,\n} from '@atproto/lex-data'\nimport { parseBlobRef } from './blob.js'\nimport { encodeLexBytes, parseLexBytes } from './bytes.js'\nimport { JsonObject, JsonValue } from './json.js'\nimport { encodeLexLink, parseLexLink } from './link.js'\n\nexport function lexStringify(input: LexValue): string {\n // @NOTE Because of the way the \"replacer\" works in JSON.stringify, it's\n // simpler to convert Lex to JSON first rather than trying to do it\n // on-the-fly.\n return JSON.stringify(lexToJson(input))\n}\n\nexport type LexParseOptions = {\n /**\n * Forbids the presence of invalid Lex values (e.g. non-integer numbers,\n * malformed $link, $bytes, blob objects, etc.)\n */\n strict?: boolean\n}\n\nexport function lexParse<T extends LexValue = LexValue>(\n input: string,\n options: LexParseOptions = { strict: false },\n): T {\n return JSON.parse(input, function (key: string, value: JsonValue): LexValue {\n switch (typeof value) {\n case 'object':\n if (value === null) return null\n if (Array.isArray(value)) return value\n return parseSpecialJsonObject(value, options) ?? value\n case 'number':\n if (Number.isInteger(value) && Number.isSafeInteger(value)) return value\n if (options.strict) {\n throw new TypeError(`Invalid non-integer number: ${value}`)\n }\n // fallthrough\n default:\n return value\n }\n })\n}\n\nexport function jsonToLex(\n value: JsonValue,\n options: LexParseOptions = { strict: false },\n): LexValue {\n switch (typeof value) {\n case 'object': {\n if (value === null) return null\n if (Array.isArray(value)) return jsonArrayToLex(value, options)\n return (\n parseSpecialJsonObject(value, options) ??\n jsonObjectToLexMap(value, options)\n )\n }\n case 'number':\n if (Number.isInteger(value) && Number.isSafeInteger(value)) return value\n if (options.strict) {\n throw new TypeError(`Invalid non-integer number: ${value}`)\n }\n // fallthrough\n case 'boolean':\n case 'string':\n return value\n default:\n throw new TypeError(`Invalid JSON value: ${typeof value}`)\n }\n}\n\nfunction jsonArrayToLex(\n input: JsonValue[],\n options: LexParseOptions,\n): LexValue[] {\n // Lazily copy value\n let copy: LexValue[] | undefined\n for (let i = 0; i < input.length; i++) {\n const inputItem = input[i]\n const item = jsonToLex(inputItem, options)\n if (item !== inputItem) {\n copy ??= Array.from(input)\n copy[i] = item\n }\n }\n return copy ?? input\n}\n\nfunction jsonObjectToLexMap(\n input: JsonObject,\n options: LexParseOptions,\n): LexMap {\n // Lazily copy value\n let copy: LexMap | undefined = undefined\n for (const [key, jsonValue] of Object.entries(input)) {\n // Prevent prototype pollution\n if (key === '__proto__') {\n throw new TypeError('Invalid key: __proto__')\n }\n\n // Ignore (strip) undefined values\n if (jsonValue === undefined) {\n copy ??= { ...input }\n delete copy[key]\n continue\n }\n\n const value = jsonToLex(jsonValue!, options)\n if (value !== jsonValue) {\n copy ??= { ...input }\n copy[key] = value\n }\n }\n return copy ?? input\n}\n\nexport function lexToJson(value: LexValue): JsonValue {\n switch (typeof value) {\n case 'object':\n if (value === null) {\n return value\n } else if (Array.isArray(value)) {\n return lexArrayToJson(value)\n } else if (isCid(value)) {\n return encodeLexLink(value)\n } else if (ArrayBuffer.isView(value)) {\n return encodeLexBytes(value)\n } else {\n return encodeLexMap(value)\n }\n case 'boolean':\n case 'string':\n case 'number':\n return value\n default:\n throw new TypeError(`Invalid Lex value: ${typeof value}`)\n }\n}\n\nfunction lexArrayToJson(input: LexArray): JsonValue[] {\n // Lazily copy value\n let copy: JsonValue[] | undefined\n for (let i = 0; i < input.length; i++) {\n const inputItem = input[i]\n const item = lexToJson(inputItem)\n if (item !== inputItem) {\n copy ??= Array.from(input) as JsonValue[]\n copy[i] = item\n }\n }\n return copy ?? (input as JsonValue[])\n}\n\nfunction encodeLexMap(input: LexMap): JsonObject {\n // Lazily copy value\n let copy: JsonObject | undefined = undefined\n for (const [key, lexValue] of Object.entries(input)) {\n // Prevent prototype pollution\n if (key === '__proto__') {\n throw new TypeError('Invalid key: __proto__')\n }\n\n // Ignore (strip) undefined values\n if (lexValue === undefined) {\n copy ??= { ...input } as JsonObject\n delete copy[key]\n continue\n }\n\n const jsonValue = lexToJson(lexValue!)\n if (jsonValue !== lexValue) {\n copy ??= { ...input } as JsonObject\n copy[key] = jsonValue\n }\n }\n return copy ?? (input as JsonObject)\n}\n\nfunction parseSpecialJsonObject(\n input: LexMap,\n options: LexParseOptions,\n): Cid | Uint8Array | BlobRef | undefined {\n // Hot path: use hints to avoid parsing when possible\n\n if (input.$link !== undefined) {\n const cid = parseLexLink(input)\n if (cid) return cid\n if (options.strict) throw new TypeError(`Invalid $link object`)\n } else if (input.$bytes !== undefined) {\n const bytes = parseLexBytes(input)\n if (bytes) return bytes\n if (options.strict) throw new TypeError(`Invalid $bytes object`)\n } else if (input.$type !== undefined) {\n // @NOTE Since blobs are \"just\" regular lex objects with a special shape,\n // and because an object that does not conform to the blob shape would still\n // result in undefined being returned, we only attempt to parse blobs when\n // the strict option is enabled.\n if (options.strict) {\n if (input.$type === 'blob') {\n const blob = parseBlobRef(input, options)\n if (blob) return blob\n throw new TypeError(`Invalid blob object`)\n } else if (typeof input.$type !== 'string') {\n throw new TypeError(`Invalid $type property (${typeof input.$type})`)\n } else if (input.$type.length === 0) {\n throw new TypeError(`Empty $type property`)\n }\n }\n }\n\n // @NOTE We ignore legacy blob representation here. They can be handled at the\n // application level if needed.\n\n return undefined\n}\n"]}
|
|
1
|
+
{"version":3,"file":"lex-json.js","sourceRoot":"","sources":["../src/lex-json.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BlobRef,\n Cid,\n LexArray,\n LexMap,\n LexValue,\n isCid,\n} from '@atproto/lex-data'\nimport { parseBlobRef } from './blob.js'\nimport { encodeLexBytes, parseLexBytes } from './bytes.js'\nimport { JsonObject, JsonValue } from './json.js'\nimport { encodeLexLink, parseLexLink } from './link.js'\n\nexport function lexStringify(input: LexValue): string {\n // @NOTE Because of the way the \"replacer\" works in JSON.stringify, it's\n // simpler to convert Lex to JSON first rather than trying to do it\n // on-the-fly.\n return JSON.stringify(lexToJson(input))\n}\n\nexport type LexParseOptions = {\n /**\n * Forbids the presence of invalid Lex values (e.g. non-integer numbers,\n * malformed $link, $bytes, blob objects, etc.)\n */\n strict?: boolean\n}\n\nexport function lexParse<T extends LexValue = LexValue>(\n input: string,\n options: LexParseOptions = { strict: false },\n): T {\n return JSON.parse(input, function (key: string, value: JsonValue): LexValue {\n switch (typeof value) {\n case 'object':\n if (value === null) return null\n if (Array.isArray(value)) return value\n return parseSpecialJsonObject(value, options) ?? value\n case 'number':\n if (Number.isSafeInteger(value)) return value\n if (options.strict) {\n throw new TypeError(`Invalid non-integer number: ${value}`)\n }\n // fallthrough\n default:\n return value\n }\n })\n}\n\nexport function jsonToLex(\n value: JsonValue,\n options: LexParseOptions = { strict: false },\n): LexValue {\n switch (typeof value) {\n case 'object': {\n if (value === null) return null\n if (Array.isArray(value)) return jsonArrayToLex(value, options)\n return (\n parseSpecialJsonObject(value, options) ??\n jsonObjectToLexMap(value, options)\n )\n }\n case 'number':\n if (Number.isSafeInteger(value)) return value\n if (options.strict) {\n throw new TypeError(`Invalid non-integer number: ${value}`)\n }\n // fallthrough\n case 'boolean':\n case 'string':\n return value\n default:\n throw new TypeError(`Invalid JSON value: ${typeof value}`)\n }\n}\n\nfunction jsonArrayToLex(\n input: JsonValue[],\n options: LexParseOptions,\n): LexValue[] {\n // Lazily copy value\n let copy: LexValue[] | undefined\n for (let i = 0; i < input.length; i++) {\n const inputItem = input[i]\n const item = jsonToLex(inputItem, options)\n if (item !== inputItem) {\n copy ??= Array.from(input)\n copy[i] = item\n }\n }\n return copy ?? input\n}\n\nfunction jsonObjectToLexMap(\n input: JsonObject,\n options: LexParseOptions,\n): LexMap {\n // Lazily copy value\n let copy: LexMap | undefined = undefined\n for (const [key, jsonValue] of Object.entries(input)) {\n // Prevent prototype pollution\n if (key === '__proto__') {\n throw new TypeError('Invalid key: __proto__')\n }\n\n // Ignore (strip) undefined values\n if (jsonValue === undefined) {\n copy ??= { ...input }\n delete copy[key]\n continue\n }\n\n const value = jsonToLex(jsonValue!, options)\n if (value !== jsonValue) {\n copy ??= { ...input }\n copy[key] = value\n }\n }\n return copy ?? input\n}\n\nexport function lexToJson(value: LexValue): JsonValue {\n switch (typeof value) {\n case 'object':\n if (value === null) {\n return value\n } else if (Array.isArray(value)) {\n return lexArrayToJson(value)\n } else if (isCid(value)) {\n return encodeLexLink(value)\n } else if (ArrayBuffer.isView(value)) {\n return encodeLexBytes(value)\n } else {\n return encodeLexMap(value)\n }\n case 'boolean':\n case 'string':\n case 'number':\n return value\n default:\n throw new TypeError(`Invalid Lex value: ${typeof value}`)\n }\n}\n\nfunction lexArrayToJson(input: LexArray): JsonValue[] {\n // Lazily copy value\n let copy: JsonValue[] | undefined\n for (let i = 0; i < input.length; i++) {\n const inputItem = input[i]\n const item = lexToJson(inputItem)\n if (item !== inputItem) {\n copy ??= Array.from(input) as JsonValue[]\n copy[i] = item\n }\n }\n return copy ?? (input as JsonValue[])\n}\n\nfunction encodeLexMap(input: LexMap): JsonObject {\n // Lazily copy value\n let copy: JsonObject | undefined = undefined\n for (const [key, lexValue] of Object.entries(input)) {\n // Prevent prototype pollution\n if (key === '__proto__') {\n throw new TypeError('Invalid key: __proto__')\n }\n\n // Ignore (strip) undefined values\n if (lexValue === undefined) {\n copy ??= { ...input } as JsonObject\n delete copy[key]\n continue\n }\n\n const jsonValue = lexToJson(lexValue!)\n if (jsonValue !== lexValue) {\n copy ??= { ...input } as JsonObject\n copy[key] = jsonValue\n }\n }\n return copy ?? (input as JsonObject)\n}\n\nfunction parseSpecialJsonObject(\n input: LexMap,\n options: LexParseOptions,\n): Cid | Uint8Array | BlobRef | undefined {\n // Hot path: use hints to avoid parsing when possible\n\n if (input.$link !== undefined) {\n const cid = parseLexLink(input)\n if (cid) return cid\n if (options.strict) throw new TypeError(`Invalid $link object`)\n } else if (input.$bytes !== undefined) {\n const bytes = parseLexBytes(input)\n if (bytes) return bytes\n if (options.strict) throw new TypeError(`Invalid $bytes object`)\n } else if (input.$type !== undefined) {\n // @NOTE Since blobs are \"just\" regular lex objects with a special shape,\n // and because an object that does not conform to the blob shape would still\n // result in undefined being returned, we only attempt to parse blobs when\n // the strict option is enabled.\n if (options.strict) {\n if (input.$type === 'blob') {\n const blob = parseBlobRef(input, options)\n if (blob) return blob\n throw new TypeError(`Invalid blob object`)\n } else if (typeof input.$type !== 'string') {\n throw new TypeError(`Invalid $type property (${typeof input.$type})`)\n } else if (input.$type.length === 0) {\n throw new TypeError(`Empty $type property`)\n }\n }\n }\n\n // @NOTE We ignore legacy blob representation here. They can be handled at the\n // application level if needed.\n\n return undefined\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/lex-json",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Lexicon encoding utilities for AT Lexicon data in JSON format",
|
|
6
6
|
"keywords": [
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"tslib": "^2.8.1",
|
|
42
|
-
"@atproto/lex-data": "0.0.
|
|
42
|
+
"@atproto/lex-data": "0.0.9"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"vitest": "^4.0.16"
|
package/src/lex-json.ts
CHANGED
|
@@ -37,7 +37,7 @@ export function lexParse<T extends LexValue = LexValue>(
|
|
|
37
37
|
if (Array.isArray(value)) return value
|
|
38
38
|
return parseSpecialJsonObject(value, options) ?? value
|
|
39
39
|
case 'number':
|
|
40
|
-
if (Number.
|
|
40
|
+
if (Number.isSafeInteger(value)) return value
|
|
41
41
|
if (options.strict) {
|
|
42
42
|
throw new TypeError(`Invalid non-integer number: ${value}`)
|
|
43
43
|
}
|
|
@@ -62,7 +62,7 @@ export function jsonToLex(
|
|
|
62
62
|
)
|
|
63
63
|
}
|
|
64
64
|
case 'number':
|
|
65
|
-
if (Number.
|
|
65
|
+
if (Number.isSafeInteger(value)) return value
|
|
66
66
|
if (options.strict) {
|
|
67
67
|
throw new TypeError(`Invalid non-integer number: ${value}`)
|
|
68
68
|
}
|