Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
grammar.js
package-lock.json
package-lock.json
.pnpm-debug.log
47 changes: 47 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
declare module "mojangson" {
type MojangsonNumericType = 'byte' | 'short' | 'long' | 'float' | 'double' | 'int';
type MojangsonArrayElementType = 'byte' | 'int' | 'long';
type MojangsonElementaryType = 'string' | 'boolean' | MojangsonNumericType;
type MojangsonArrayType = 'byteArray' | 'intArray' | 'longArray';
type MojangsonAnyType = 'compound' | MojangsonElementaryType | MojangsonArrayType;
type MojangsonAnyValue = MojangsonEntry | string | boolean | number;

interface MojangsonNumber {
value: number;
type: 'byte' | 'short' | 'long' | 'float' | 'double' | 'int';
};
interface MojangsonBoolean {
value: boolean;
type: 'boolean';
};
interface MojangsonArray {
value: {
value: number[];
type: 'byte' | 'int' | 'long';
};
type: 'byteArray' | 'intArray' | 'longArray';
};
interface MojangsonList {
value: {
type: MojangsonAnyType;
value: MojangsonAnyValue[];
};
type: 'list';
};
interface MojangsonString {
value: string;
type: 'string';
};
interface MojangsonCompound {
value: {
[key: string]: MojangsonEntry;
};
type: 'compound';
}
type MojangsonEntry = MojangsonArray | MojangsonList | MojangsonString | MojangsonNumber | MojangsonBoolean | MojangsonCompound;

function simplify(data: MojangsonEntry): any;
function stringify({ value, type }: MojangsonEntry, quotes?: boolean): string;
function parse(text: string): MojangsonEntry;
function normalize(str: string, quotes?: boolean): string;
}
25 changes: 13 additions & 12 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,45 +17,46 @@ function simplify (data) {
return transform(data.value, data.type)
}

function stringify ({ value, type }) {
function stringify ({ value, type }, quotes = false) {
if (type === 'compound') {
const str = []
const entries = Object.entries(value)
for (let i = 0; i < entries.length; i++) {
const _type = entries[i][0]
let _value = stringify(entries[i][1])
if (_type === 'string') _value = normalizeString(_value)
str.push(`${_type}:${_value}`)
let _value = stringify(entries[i][1], quotes)
if (_type === 'string') _value = normalizeString(_value, quotes)
if (quotes) { str.push(`"${_type}":${_value}`) } else { str.push(`${_type}:${_value}`) }
}
return `{${str.join(',')}}`
} else if (type === 'list') {
if (!Array.isArray(value.value)) return '[]'
const arrayElements = getArrayValues(value)
const arrayElements = getArrayValues(value, quotes)
return `[${arrayElements}]`
} else if (type === 'byteArray' || type === 'intArray' || type === 'longArray') {
const prefix = getArrayPrefix(type)
const arrayElements = getArrayValues(value)
const arrayElements = getArrayValues(value, quotes)
return `[${prefix}${arrayElements}]`
}
let str = value + getSuffix(value, type)
if (type === 'string') str = normalizeString(str)
if (type === 'string') str = normalizeString(str, quotes)
return str
}

function normalizeString (str) {
function normalizeString (str, quotes) {
str = str.replace(/"/g, '\\"')
if (/'|{|}|\[|\]|:|;|,|\(|\)|§|=/g.test(str) || str === '') str = `"${str}"`
if (quotes && !str.startsWith('"')) { str = `"${str}"` }
return str
}

function getArrayValues ({ value: arr, type }) {
function getArrayValues ({ value: arr, type }, quotes) {
const hasMissingEl = hasMissingElements(arr)
const str = []
// add nullable length that way [] is pased as []
for (let i = 0; i < arr.length; i++) {
let curr = arr[i]
if (curr !== undefined) {
curr = stringify({ value: curr, type })
curr = stringify({ value: curr, type }, quotes)
if (hasMissingEl) str.push(`${i}:${curr}`)
else str.push(curr)
}
Expand Down Expand Up @@ -83,8 +84,8 @@ function getSuffix (val, type) {
* @returns {string} the normalized mojangson
*/

function normalize (str) {
return stringify(parse(str))
function normalize (str, quotes = false) {
return stringify(parse(str), quotes)
}

function parse (text) {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"name": "mojangson",
"version": "2.0.2",
"version": "2.0.3",
"description": "A mojangson parser written in node.js",
"main": "index.js",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "git://github.com/rom1504/node-mojangson.git"
Expand Down
28 changes: 28 additions & 0 deletions test/quotes.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* eslint-env mocha */
const assert = require('assert')
const mojangson = require('../')

describe('Always use quotes for names and strings', () => {
// Seems that from a certain MC version SNBTs stopped working without quotes (as for 1.18.2)
[
'{"var":"value1","var1":123b,"var2":"value3","var3":"value4"}',
'[B;1b,2b,3b]',
'{"id":"minecraft:yellow_shulker_box","Count":1b,"tag":{"BlockEntityTag":{"CustomName":"Stacked Totems","x":0,"y":0,"z":0,"id":"minecraft:shulker_box","Lock":""},"display":{"Name":"Stacked Totems"}},"Damage":0s}',
'{"SomeField":"кириллиц А"}',
'{"AField":"\\""}'
].forEach(s => {
it('sould remain unchanged', () => {
assert.strictEqual(mojangson.stringify(mojangson.parse(s), true), s)
})
});
// Formatting tests
[
['{var: value1, var1:123b, "var2":value3, "var3": "value4"}', '{"var":"value1","var1":123b,"var2":"value3","var3":"value4"}'],
['{SomeField: кириллицА}', '{"SomeField":"кириллицА"}'],
['{AField: "\\""}', '{"AField":"\\""}']
].forEach(([input, expected]) => {
it('sould be equal', () => {
assert.strictEqual(mojangson.stringify(mojangson.parse(input), true), expected)
})
})
})