Skip to content

Commit

Permalink
style: make use of tagged union literals (#28)
Browse files Browse the repository at this point in the history
* build: use tslint-config-stoplight

* style: make use of tagged union literals

* style: commas
  • Loading branch information
P0lip authored Oct 1, 2019
1 parent eff0088 commit 41fdad4
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 85 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"scripts": {
"build": "sl-scripts build",
"commit": "git-cz",
"lint": "tslint -c tslint.json 'src/**/*.ts'",
"lint": "tslint -c tslint.json -p tsconfig.json 'src/**/*.ts'",
"lint.fix": "yarn lint --fix",
"release": "sl-scripts release",
"release.docs": "sl-scripts release:docs",
Expand All @@ -45,6 +45,7 @@
},
"devDependencies": {
"@stoplight/scripts": "3.1.0",
"tslint-config-stoplight": "^1.3.0",
"typescript": "3.5.3"
},
"lint-staged": {
Expand Down
14 changes: 7 additions & 7 deletions src/__tests__/getLocationForJsonPath.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe('getLocationForJsonPath', () => {
},
},
}
: void 0
: void 0,
);
});
});
Expand Down Expand Up @@ -104,7 +104,7 @@ describe('getLocationForJsonPath', () => {
describe('duplicate keys fixture', () => {
const result = parseWithPointers(
`foo: 2
foo: 4`
foo: 4`,
);

test.each`
Expand Down Expand Up @@ -164,7 +164,7 @@ foo: 4`
<< : [ *BIG, *LEFT, *SMALL ]
x: 1
label: center/big`,
{ mergeKeys: true }
{ mergeKeys: true },
);

test.each`
Expand Down Expand Up @@ -193,7 +193,7 @@ foo: 4`

test('should return proper location for empty mapping value', () => {
expect(
getLocationForJsonPath(result, ['definitions', 'AnotherDefinition', 'properties', 'special', 'description'])
getLocationForJsonPath(result, ['definitions', 'AnotherDefinition', 'properties', 'special', 'description']),
).toEqual({
range: {
start: {
Expand Down Expand Up @@ -223,7 +223,7 @@ foo: 4`
${[5, 6]} | ${[5, 9]} | ${['paths']} | ${true}
`('should return proper location for given JSONPath $path', ({ start, end, path, closest }) => {
expect(getLocationForJsonPath(resultCRLF, path, closest)).toEqual(
getLocationForJsonPath(resultLF, path, closest)
getLocationForJsonPath(resultLF, path, closest),
);
expect(getLocationForJsonPath(resultCRLF, path)).toEqual(getLocationForJsonPath(resultLF, path));
expect(getLocationForJsonPath(resultCRLF, path, closest)).toEqual(
Expand All @@ -240,7 +240,7 @@ foo: 4`
},
},
}
: void 0
: void 0,
);
});
});
Expand All @@ -266,7 +266,7 @@ foo: 4`
},
},
}
: void 0
: void 0,
);
});
});
Expand Down
24 changes: 12 additions & 12 deletions src/__tests__/parseWithPointers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const diverse = fs.readFileSync(path.join(__dirname, './fixtures/diverse.yaml'),
const duplicateMergeKeys = fs.readFileSync(path.join(__dirname, './fixtures/duplicate-merge-keys.yaml'), 'utf-8');
const mergeKeysWithDuplicateProperties = fs.readFileSync(
path.join(__dirname, './fixtures/merge-keys-with-duplicate-props.yaml'),
'utf-8'
'utf-8',
);
const spectral481 = fs.readFileSync(path.join(__dirname, './fixtures/spectral-481.yaml'), 'utf-8');

Expand Down Expand Up @@ -38,15 +38,15 @@ describe('yaml parser', () => {
const { data } = parseWithPointers(spectral481);
expect(data).toHaveProperty(
'components.schemas.RandomRequest.properties.implicit_string_date.example',
'2012-10-12'
'2012-10-12',
);
expect(data).toHaveProperty(
'components.schemas.RandomRequest.properties.another_implicit_string_date.example',
'x20121012'
'x20121012',
);
expect(data).toHaveProperty(
'components.schemas.RandomRequest.properties.explicit_string_date.example',
'2012-10-12'
'2012-10-12',
);
});

Expand Down Expand Up @@ -100,7 +100,7 @@ test: !!css >
`prop1: true
prop2: true
inner 1
val: 2`
val: 2`,
);

expect(result.diagnostics).toEqual([
Expand Down Expand Up @@ -267,7 +267,7 @@ european-cities: &cities

test('throws when duplicate key is encountered and not in JSON-ish mode', () => {
expect(parseWithPointers.bind(null, 'foo: 0\nfoo: 1\n', { json: false })).toThrow(
'Duplicate YAML mapping key encountered'
'Duplicate YAML mapping key encountered',
);
});

Expand Down Expand Up @@ -301,8 +301,8 @@ european-cities: &cities
- yes
- unfortunately, I am a dupe.
`,
{ ignoreDuplicateKeys: false }
)
{ ignoreDuplicateKeys: false },
),
).toHaveProperty('diagnostics', [
{
code: 'YAMLException',
Expand Down Expand Up @@ -354,7 +354,7 @@ european-cities: &cities
<< : *CENTER
r: 10
label: center/big`,
{ mergeKeys: true }
{ mergeKeys: true },
);

expect(result.data![4]).toEqual({
Expand All @@ -376,7 +376,7 @@ european-cities: &cities
- # Merge multiple maps
<< : [ *CENTER, *BIG ]
label: center/big`,
{ mergeKeys: true }
{ mergeKeys: true },
);

expect(result.data![4]).toEqual({
Expand All @@ -398,7 +398,7 @@ european-cities: &cities
- # Merge multiple maps
<< : [ *CENTER, *BIG ]
label: center/big`,
{ mergeKeys: true }
{ mergeKeys: true },
);

expect(result.data![4]).toEqual({
Expand All @@ -421,7 +421,7 @@ european-cities: &cities
<< : [ *BIG, *LEFT, *SMALL ]
x: 1
label: center/big`,
{ mergeKeys: true }
{ mergeKeys: true },
);

expect(result.data![4]).toEqual({
Expand Down
14 changes: 7 additions & 7 deletions src/buildJsonPath.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { JsonPath } from '@stoplight/types';
import { Kind, YAMLMapping, YAMLNode, YAMLScalar, YAMLSequence } from '@stoplight/yaml-ast-parser';
import { Kind, YAMLNode } from './types';
import { isObject } from './utils';

export function buildJsonPath(node: YAMLNode) {
Expand All @@ -10,20 +10,20 @@ export function buildJsonPath(node: YAMLNode) {
while (node) {
switch (node.kind) {
case Kind.SCALAR:
path.unshift((node as YAMLScalar).value);
path.unshift(node.value);
break;
case Kind.MAPPING:
if (prevNode !== (node as YAMLMapping).key) {
if (path.length > 0 && isObject(node.value) && (node as YAMLMapping).value.value === path[0]) {
path[0] = (node as YAMLMapping).key.value;
if (prevNode !== node.key) {
if (path.length > 0 && isObject(node.value) && node.value.value === path[0]) {
path[0] = node.key.value;
} else {
path.unshift((node as YAMLMapping).key.value);
path.unshift(node.key.value);
}
}
break;
case Kind.SEQ:
if (prevNode) {
const index = (node as YAMLSequence).items.indexOf(prevNode);
const index = node.items.indexOf(prevNode);
if (prevNode.kind === Kind.SCALAR) {
path[0] = index;
// always better to point to parent node rather than nothing
Expand Down
25 changes: 12 additions & 13 deletions src/getJsonPathForPosition.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { GetJsonPathForPosition } from '@stoplight/types';
import { Kind, YAMLMapping, YAMLNode, YAMLSequence } from '@stoplight/yaml-ast-parser';
import { buildJsonPath } from './buildJsonPath';
import { YamlParserResult } from './types';
import { Kind, YAMLNode, YamlParserResult } from './types';
import { isObject } from './utils';

export const getJsonPathForPosition: GetJsonPathForPosition<YamlParserResult<unknown>> = (
{ ast, lineMap },
{ line, character }
{ line, character },
) => {
if (line >= lineMap.length || character >= lineMap[line]) {
return;
Expand All @@ -15,7 +14,7 @@ export const getJsonPathForPosition: GetJsonPathForPosition<YamlParserResult<unk
const startOffset = line === 0 ? 0 : lineMap[line - 1] + 1;

const node = findClosestScalar(ast, Math.min(lineMap[line] - 1, startOffset + character), line, lineMap);
if (!node) return;
if (!isObject(node)) return;

const path = buildJsonPath(node);
if (path.length === 0) return;
Expand All @@ -36,17 +35,17 @@ function* walk(node: YAMLNode): IterableIterator<YAMLNode> {
break;
case Kind.MAPPING:
if (isObject(node.key)) {
yield (node as YAMLMapping).key;
yield node.key;
}

if (isObject(node.value)) {
yield (node as YAMLMapping).value;
yield node.value;
}

break;
case Kind.SEQ:
if ((node as YAMLSequence).items.length !== 0) {
for (const item of (node as YAMLSequence).items) {
if (node.items.length !== 0) {
for (const item of node.items) {
if (isObject(item)) {
yield item;
}
Expand All @@ -66,7 +65,7 @@ function getFirstScalarChild(node: YAMLNode, line: number, lineMap: number[]): Y

switch (node.kind) {
case Kind.MAPPING:
return (node as YAMLMapping).key;
return node.key;
case Kind.MAP:
if (node.mappings.length !== 0) {
for (const mapping of node.mappings) {
Expand All @@ -78,8 +77,8 @@ function getFirstScalarChild(node: YAMLNode, line: number, lineMap: number[]): Y

break;
case Kind.SEQ:
if ((node as YAMLSequence).items.length !== 0) {
for (const item of (node as YAMLSequence).items) {
if (node.items.length !== 0) {
for (const item of node.items) {
if (item.startPosition > startOffset && item.startPosition <= endOffset) {
return getFirstScalarChild(item, line, lineMap);
}
Expand Down Expand Up @@ -109,8 +108,8 @@ function findClosestScalar(container: YAMLNode, offset: number, line: number, li
return getFirstScalarChild(container, line, lineMap);
}

if ((container as YAMLMapping).value && (container as YAMLMapping).key.endPosition < offset) {
return getFirstScalarChild((container as YAMLMapping).value, line, lineMap);
if (container.value && container.key.endPosition < offset) {
return getFirstScalarChild(container.value, line, lineMap);
}
}

Expand Down
29 changes: 17 additions & 12 deletions src/getLocationForJsonPath.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { GetLocationForJsonPath, ILocation, JsonPath } from '@stoplight/types';
import { Kind, YAMLMapping, YAMLNode, YAMLSequence } from '@stoplight/yaml-ast-parser';
import { GetLocationForJsonPath, ILocation, JsonPath, Optional } from '@stoplight/types';
import { SpecialMappingKeys } from './consts';
import { lineForPosition } from './lineForPosition';
import { YamlParserResult } from './types';
import { Kind, YAMLMapping, YAMLNode, YamlParserResult } from './types';
import { isObject } from './utils';

export const getLocationForJsonPath: GetLocationForJsonPath<YamlParserResult<unknown>> = (
{ ast, lineMap, metadata },
path,
closest = false
closest = false,
) => {
const node = findNodeAtPath(ast, path, { closest, mergeKeys: metadata !== undefined && metadata.mergeKeys === true });
if (node === void 0) return;
Expand Down Expand Up @@ -41,7 +40,7 @@ function getStartPosition(node: YAMLNode, offset: number): number {
function getEndPosition(node: YAMLNode): number {
switch (node.kind) {
case Kind.SEQ:
const { items } = node as YAMLSequence;
const { items } = node;
if (items.length !== 0 && items[items.length - 1] !== null) {
return getEndPosition(items[items.length - 1]);
}
Expand Down Expand Up @@ -72,10 +71,14 @@ function getEndPosition(node: YAMLNode): number {
function findNodeAtPath(
node: YAMLNode,
path: JsonPath,
{ closest, mergeKeys }: { closest: boolean; mergeKeys: boolean }
{ closest, mergeKeys }: { closest: boolean; mergeKeys: boolean },
) {
pathLoop: for (const segment of path) {
switch (node && node.kind) {
if (!isObject(node)) {
return closest ? node : void 0;
}

switch (node.kind) {
case Kind.MAP:
const mappings = getMappings(node.mappings, mergeKeys);
// we iterate from the last to first to be compliant with JSONish mode
Expand All @@ -94,9 +97,9 @@ function findNodeAtPath(

return closest ? node : void 0;
case Kind.SEQ:
for (let i = 0; i < (node as YAMLSequence).items.length; i++) {
for (let i = 0; i < node.items.length; i++) {
if (i === Number(segment)) {
node = (node as YAMLSequence).items[i];
node = node.items[i];
continue pathLoop;
}
}
Expand All @@ -116,7 +119,7 @@ function getMappings(mappings: YAMLMapping[], mergeKeys: boolean): YAMLMapping[]
return mappings.reduce<YAMLMapping[]>((mergedMappings, mapping) => {
if (isObject(mapping)) {
if (mapping.key.value === SpecialMappingKeys.MergeKey) {
mergedMappings.push(...reduceMergeKeys((mapping as YAMLMapping).value));
mergedMappings.push(...reduceMergeKeys(mapping.value));
} else {
mergedMappings.push(mapping);
}
Expand All @@ -126,10 +129,12 @@ function getMappings(mappings: YAMLMapping[], mergeKeys: boolean): YAMLMapping[]
}, []);
}

function reduceMergeKeys(node: YAMLNode): YAMLMapping[] {
function reduceMergeKeys(node: Optional<YAMLNode | null>): YAMLMapping[] {
if (!isObject(node)) return [];

switch (node.kind) {
case Kind.SEQ:
return (node as YAMLSequence).items.reduceRight<YAMLMapping[]>((items, item) => {
return node.items.reduceRight<YAMLMapping[]>((items, item) => {
items.push(...reduceMergeKeys(item));
return items;
}, []);
Expand Down
3 changes: 2 additions & 1 deletion src/parse.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { load as loadAST } from '@stoplight/yaml-ast-parser';
import { walkAST } from './parseWithPointers';
import { YAMLNode } from './types';

export const parse = <T>(value: string): T => walkAST(loadAST(value)) as T;
export const parse = <T>(value: string): T => walkAST(loadAST(value) as YAMLNode) as T;
Loading

0 comments on commit 41fdad4

Please sign in to comment.