New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

js-toml

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

js-toml - npm Package Compare versions

Comparing version 0.1.0 to 0.1.1

src/load/tokens/ArrayNewline.ts

23

package.json
{
"name": "js-toml",
"version": "0.1.0",
"version": "0.1.1",
"description": "A TOML parser for JavaScript/TypeScript, targeting TOML 1.0.0 Spec",

@@ -31,2 +31,10 @@ "keywords": [

},
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts",
"test": "jest",
"test:cov": "jest --coverage",
"diagram": "esr script/generateDiagram.ts",
"lint": "prettier --check . && eslint .",
"lint:fix": "prettier --write . && eslint . --fix"
},
"devDependencies": {

@@ -41,2 +49,3 @@ "@types/jest": "^29.2.1",

"eslint-config-prettier": "^8.5.0",
"glob": "^8.0.3",
"jest": "^29.2.2",

@@ -52,11 +61,3 @@ "prettier": "^2.7.1",

},
"packageManager": "pnpm@7.15.0",
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts",
"test": "jest",
"test:cov": "jest --coverage",
"diagram": "esr script/generateDiagram.ts",
"lint": "prettier --check . && eslint .",
"lint:fix": "prettier --write . && eslint . --fix"
}
}
"packageManager": "pnpm@7.15.0"
}

@@ -6,1 +6,53 @@ # js-toml

[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
[![npm version](https://badge.fury.io/js/js-toml.svg)](https://badge.fury.io/js/js-toml)
A TOML parser for JavaScript and TypeScript. Fully tested and 100% compatible with the TOML v1.0.0 spec.
## Installation
```bash
npm install js-toml
```
or with yarn
```bash
yarn add js-toml
```
or with pnpm
```bash
pnpm add js-toml
```
## Usage
```typescript
import {load} from 'js-toml';
const toml = `
title = "TOML Example"
[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00 # First class dates
`;
const data = load(toml);
console.log(data);
```
## API
### load(toml: string): object
Parses a TOML string and returns a JavaScript object.
### dump(object: object): string
Under development.
## License
MIT

@@ -1,1 +0,7 @@

export { load, SyntaxParseError } from './load';
export { SyntaxParseError } from './load';
import { load } from './load';
const jstoml = { load };
export default jstoml;
export { load };

@@ -28,3 +28,5 @@ import { parser } from './parser';

const tableDeclared = Symbol('tableDeclared');
const explicitlyDeclared = Symbol('explicitlyDeclared');
const implicitlyDeclared = Symbol('implicitlyDeclared');
const notEditable = Symbol('notEditable');

@@ -178,7 +180,7 @@

private assignPrimitiveValue(key, value, object) {
if (object[key]) {
if (key in object) {
throw new DuplicateKeyError();
}
if (isPlainObject(value)) {
value[tableDeclared] = true;
value[explicitlyDeclared] = true;
}

@@ -190,7 +192,14 @@

private tryCreatingObject(key, object, declareTable, ignoreDeclared) {
private tryCreatingObject(
key,
object,
declareSymbol,
ignoreImplicitDeclared,
ignoreExplicitDeclared
) {
if (object[key]) {
if (
!isPlainObject(object[key]) ||
(!ignoreDeclared && object[key][tableDeclared]) ||
(!ignoreExplicitDeclared && object[key][explicitlyDeclared]) ||
(!ignoreImplicitDeclared && object[key][implicitlyDeclared]) ||
object[key][notEditable]

@@ -202,4 +211,4 @@ ) {

object[key] = {};
if (declareTable) {
object[key][tableDeclared] = true;
if (declareSymbol) {
object[key][declareSymbol] = true;
}

@@ -214,3 +223,3 @@ }

if (rest.length > 0) {
this.tryCreatingObject(first, object, true, true);
this.tryCreatingObject(first, object, implicitlyDeclared, true, false);
return this.assignValue(rest, value, object[first]);

@@ -226,9 +235,18 @@ }

if (Array.isArray(object[first])) {
if (object[first][notEditable]) {
throw new DuplicateKeyError();
}
const toAdd = object[first][object[first].length - 1];
return this.createTable(rest, toAdd);
}
this.tryCreatingObject(first, object, false, true);
this.tryCreatingObject(first, object, null, true, true);
return this.createTable(rest, object[first]);
}
return this.tryCreatingObject(first, object, true, false);
return this.tryCreatingObject(
first,
object,
explicitlyDeclared,
false,
false
);
}

@@ -243,3 +261,3 @@

}
this.tryCreatingObject(first, object, false, true);
this.tryCreatingObject(first, object, null, true, true);
return this.getOrCreateArray(rest, object[first]);

@@ -246,0 +264,0 @@ }

@@ -24,2 +24,3 @@ import { CstParser } from 'chevrotain';

import { ArrayTableOpen } from './tokens/ArrayTableOpen';
import { ExpressionNewLine } from './tokens/ExpressionNewLine';

@@ -40,2 +41,7 @@ class Parser extends CstParser {

});
private keyValue = this.RULE('keyValue', () => {
this.SUBRULE(this.key);
this.CONSUME(KeyValueSeparator);
this.SUBRULE(this.value);
});
private inlineTableKeyValues = this.RULE('inlineTableKeyValues', () => {

@@ -52,2 +58,16 @@ this.MANY_SEP({

});
private arrayValues = this.RULE('arrayValues', () => {
this.SUBRULE(this.value);
let havingMore = true;
this.MANY({
GATE: () => havingMore,
DEF: () => {
this.CONSUME(ArraySep);
const found = this.OPTION(() => this.SUBRULE1(this.value));
if (!found) {
havingMore = false;
}
},
});
});
private array = this.RULE('array', () => {

@@ -69,21 +89,2 @@ this.CONSUME(ArrayOpen);

});
private keyValue = this.RULE('keyValue', () => {
this.SUBRULE(this.key);
this.CONSUME(KeyValueSeparator);
this.SUBRULE(this.value);
});
private arrayValues = this.RULE('arrayValues', () => {
this.SUBRULE(this.value);
let havingMore = true;
this.MANY({
GATE: () => havingMore,
DEF: () => {
this.CONSUME(ArraySep);
const found = this.OPTION(() => this.SUBRULE1(this.value));
if (!found) {
havingMore = false;
}
},
});
});
private stdTable = this.RULE('stdTable', () => {

@@ -112,8 +113,10 @@ this.CONSUME(StdTableOpen);

toml = this.RULE('toml', () => {
this.OPTION(() => this.SUBRULE(this.expression));
this.MANY(() => {
this.CONSUME(Newline);
this.MANY(() => this.CONSUME(ExpressionNewLine));
this.MANY1(() => {
this.SUBRULE1(this.expression);
this.OPTION2(() => {
this.CONSUME1(Newline);
this.MANY3(() => this.CONSUME2(ExpressionNewLine));
});
});
this.OPTION1(() => this.CONSUME1(Newline));
});

@@ -120,0 +123,0 @@

@@ -23,3 +23,3 @@ import { WhiteSpace } from './WhiteSpace';

import { ArrayClose } from './ArrayClose';
import { IgnoredNewline } from './IgnoredNewline';
import { ArrayNewline } from './ArrayNewline';
import { InlineTableSep } from './InlineTableSep';

@@ -32,2 +32,3 @@ import { SimpleKey } from './SimpleKey';

import { ArrayTableClose } from './ArrayTableClose';
import { ExpressionNewLine } from './ExpressionNewLine';

@@ -64,3 +65,3 @@ const keyTokens = [

Comment,
IgnoredNewline,
ExpressionNewLine,
KeyValueSeparator,

@@ -74,3 +75,3 @@ ArrayTableOpen,

[Mode.Value]: [...valueTokens, Newline, InlineTableSep, InlineTableClose],
[Mode.Array]: [...valueTokens, IgnoredNewline, ArraySep, ArrayClose],
[Mode.Array]: [...valueTokens, ArrayNewline, ArraySep, ArrayClose],
[Mode.InlineTable]: [...keyTokens, InlineTableKeyValSep, InlineTableClose],

@@ -77,0 +78,0 @@ },

import { createToken } from 'chevrotain';
import { nonAscii } from './patterns';
import XRegExp = require('xregexp');
import { nonAscii } from './patterns';
const commentStartChar = /#/;
const nonEol = XRegExp.build('\t|[\x20-\x7F]|{{nonAscii}}', { nonAscii });
const nonEol = XRegExp.build('\t|[\x20-\x7E]|{{nonAscii}}', { nonAscii });
const comment = XRegExp.build('{{commentStartChar}}{{nonEol}}*', {

@@ -8,0 +8,0 @@ commentStartChar,

@@ -5,2 +5,3 @@ import XRegExp = require('xregexp');

import { registerTokenInterpreter } from './tokenInterpreters';
import { SyntaxParseError } from '../exception';

@@ -70,3 +71,60 @@ const dateFullYear = XRegExp.build('{{digit}}{4}', { digit });

const isValidDate = (value: string) => {
const datePattern = XRegExp.build(
'({{dateFullYear}})-({{dateMonth}})-({{dateMDay}})',
{
dateFullYear,
dateMonth,
dateMDay,
}
);
const date = XRegExp.exec(value, datePattern);
if (date) {
const year = Number(date[1]);
const month = Number(date[2]);
const day = Number(date[3]);
const dateObject = new Date(year, month - 1, day);
return (
dateObject.getFullYear() === year &&
dateObject.getMonth() + 1 === month &&
dateObject.getDate() === day
);
}
return true;
};
const isValidTime = (value: string) => {
const timePattern = XRegExp.build(
'({{timeHour}}):({{timeMinute}}):({{timeSecond}})',
{
timeHour,
timeMinute,
timeSecond,
}
);
const time = XRegExp.exec(value, timePattern);
if (time) {
const hour = Number(time[1]);
const minute = Number(time[2]);
const second = Number(time[3]);
const dateObject = new Date(0, 0, 0, hour, minute, second);
return (
dateObject.getHours() === hour &&
dateObject.getMinutes() === minute &&
dateObject.getSeconds() === second
);
}
return true;
};
const isValidDateTime = (value: string) =>
isValidDate(value) && isValidTime(value);
registerTokenInterpreter(DateTime, (raw) => {
if (!isValidDateTime(raw)) {
throw new SyntaxParseError(`Invalid date time: ${raw}`);
}
const onlyTime = raw.match(localTime)?.index === 0;

@@ -73,0 +131,0 @@ if (onlyTime) {

@@ -80,9 +80,5 @@ import { createToken } from 'chevrotain';

const skipWhitespaceIfFindBackslash = (string) =>
string.replace(/\\[ \t]*(\r\n|\n)+[ \t]*/g, '');
registerTokenInterpreter(MultiLineBasicString, (raw) => {
const content = getMultiLineContent(raw);
const result = skipWhitespaceIfFindBackslash(content);
return unescapeString(result);
return unescapeString(content);
});

@@ -0,1 +1,18 @@

import XRegExp = require('xregexp');
import { newline, whiteSpaceChar } from './patterns';
import { SyntaxParseError } from '../exception';
const escapingWhitespaces = XRegExp.build(
'^{{whiteSpaceChar}}*{{newline}}(?:{{whiteSpaceChar}}|{{newline}})*',
{
whiteSpaceChar,
newline,
}
);
const getWhitespaceAndNewline = (str: string) => {
const match = XRegExp.exec(str, escapingWhitespaces);
return match ? match[0].length : 0;
};
export const unescapeString = (string) => {

@@ -7,2 +24,9 @@ let result = '';

i++;
const whitespaceAndNewline = getWhitespaceAndNewline(string.slice(i));
if (whitespaceAndNewline > 0) {
i += whitespaceAndNewline - 1;
continue;
}
switch (string[i]) {

@@ -30,14 +54,23 @@ case 'b':

break;
case 'u':
result += String.fromCharCode(
parseInt(string.substring(i + 1, i + 5), 16)
);
case 'u': {
const hex = string.slice(i + 1, i + 5);
const codePoint = parseInt(hex, 16);
if (codePoint > 0xd7ff && codePoint < 0xe000) {
throw new SyntaxParseError(`Invalid Unicode code point: \\u${hex}`);
}
result += String.fromCodePoint(codePoint);
i += 4;
break;
case 'U':
result += String.fromCodePoint(
parseInt(string.substring(i + 1, i + 9), 16)
);
}
case 'U': {
const hex = string.slice(i + 1, i + 9);
const codePoint = parseInt(hex, 16);
if (codePoint > 0x10ffff) {
throw new SyntaxParseError(`Invalid Unicode code point: \\U${hex}`);
}
result += String.fromCodePoint(codePoint);
i += 8;
break;
}
case string.match(/^[0-7]{1,3}$/):
}

@@ -44,0 +77,0 @@ } else {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc