Skip to content

Commit

Permalink
feat: yaml loader
Browse files Browse the repository at this point in the history
  • Loading branch information
tada5hi committed Jan 9, 2024
1 parent e6a538b commit e3b2f8d
Show file tree
Hide file tree
Showing 12 changed files with 156 additions and 63 deletions.
4 changes: 2 additions & 2 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"@tada5hi/eslint-config-typescript"
],
"parserOptions": {
"project": "./tsconfig.json"
"project": "./tsconfig.eslint.json"
},
"ignorePatterns": ["**/dist/*", "**/*.d.ts", "**/test/*"],
"ignorePatterns": ["**/dist/*", "**/*.d.ts"],
"globals": {
"NodeJS": true
},
Expand Down
11 changes: 10 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"ebec": "^2.3.0",
"flat": "^5.0.2",
"glob": "^10.3.10",
"jiti": "^1.21.0"
"jiti": "^1.21.0",
"yaml": "^2.3.4"
}
}
8 changes: 8 additions & 0 deletions src/loader/built-in/yaml/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright (c) 2023.
* Author Peter Placzek (tada5hi)
* For the full copyright and license information,
* view the LICENSE file that was distributed with this source code.
*/

export * from './module';
36 changes: 36 additions & 0 deletions src/loader/built-in/yaml/module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2022-2023.
* Author Peter Placzek (tada5hi)
* For the full copyright and license information,
* view the LICENSE file that was distributed with this source code.
*/

import { parse } from 'yaml';
import fs from 'node:fs';
import { buildFilePath } from '../../../locator';
import { handleException } from '../../../utils';
import type { Loader } from '../../type';

export class YAMLLoader implements Loader {
async execute(input: string) {
const filePath = buildFilePath(input);

try {
const file = await fs.promises.readFile(filePath, { encoding: 'utf-8' });
return parse(file);
} catch (e) {
return handleException(e);
}
}

executeSync(input: string) {
const filePath = buildFilePath(input);

try {
const file = fs.readFileSync(filePath, { encoding: 'utf-8' });
return parse(file);
} catch (e) {
return handleException(e);
}
}
}
1 change: 1 addition & 0 deletions src/loader/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export enum LoaderId {
MODULE = 'module',
JSON = 'json',
CONF = 'conf',
YAML = 'yaml',
}
8 changes: 8 additions & 0 deletions src/loader/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import path from 'node:path';
import { buildFilePath, pathToLocatorInfo } from '../locator';
import { isFilePath } from '../utils';
import { ConfLoader, JSONLoader, ModuleLoader } from './built-in';
import { YAMLLoader } from './built-in/yaml';
import { LoaderId } from './constants';
import type { Loader, Rule } from './type';

Expand All @@ -30,6 +31,9 @@ export class LoaderManager implements Loader {
{
test: ['.json'], loader: LoaderId.JSON,
},
{
test: ['.yml'], loader: LoaderId.YAML,
},
];
}

Expand Down Expand Up @@ -118,6 +122,10 @@ export class LoaderManager implements Loader {
loader = new JSONLoader();
break;
}
case LoaderId.YAML: {
loader = new YAMLLoader();
break;
}
/* istanbul ignore next */
default: {
const pluginPath = this.normalizePath(id);
Expand Down
6 changes: 6 additions & 0 deletions test/data/file.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
YAML:
- A human-readable data serialization language
- https://en.wikipedia.org/wiki/YAML
yaml:
- A complete JavaScript implementation
- https://www.npmjs.com/package/yaml
81 changes: 47 additions & 34 deletions test/unit/loader.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@
* view the LICENSE file that was distributed with this source code.
*/

import path from "node:path";
import path from 'node:path';
import {
LoaderManager,
getModuleExport,
load,
loadSync,
getModuleExport,
LoaderManager
} from "../../src";
import {LoaderId} from "../../src/loader/constants";
} from '../../src';
import { LoaderId } from '../../src/loader/constants';

const basePath = path.join(__dirname, '..', 'data');

describe('src/loader/**', () => {
it('should load .conf file', async() => {
it('should load .conf file', async () => {
const filePath = path.join(basePath, 'file.conf');

const loaderContent = await load(filePath) as Record<string, any>;
Expand All @@ -28,7 +28,7 @@ describe('src/loader/**', () => {
expect(loaderContent.bar.b).toEqual('boz');
});

it('should load .conf file sync', async() => {
it('should load .conf file sync', async () => {
const filePath = path.join(basePath, 'file.conf');

const loaderContent = loadSync(filePath) as Record<string, any>;
Expand All @@ -37,7 +37,25 @@ describe('src/loader/**', () => {
expect(loaderContent.bar).toBeDefined();
expect(loaderContent.bar.a).toEqual('baz');
expect(loaderContent.bar.b).toEqual('boz');
})
});

it('should load .yml file', async () => {
const filePath = path.join(basePath, 'file.yml');

const loaderContent = await load(filePath) as Record<string, any>;
expect(loaderContent).toBeDefined();
expect(loaderContent.YAML).toBeDefined();
expect(loaderContent.yaml).toBeDefined();
});

it('should load .yml file sync', () => {
const filePath = path.join(basePath, 'file.yml');

const loaderContent = loadSync(filePath) as Record<string, any>;
expect(loaderContent).toBeDefined();
expect(loaderContent.YAML).toBeDefined();
expect(loaderContent.yaml).toBeDefined();
});

it('should load .mjs file', async () => {
const filePath = path.join(basePath, 'file.mjs');
Expand All @@ -52,7 +70,7 @@ describe('src/loader/**', () => {
const loaderContent = loadSync(filePath) as Record<string, any>;
expect(loaderContent).toBeDefined();
expect(loaderContent.foo).toEqual('bar');
})
});

it('should load .mjs file with default export', async () => {
const filePath = path.join(basePath, 'file-default.mjs');
Expand All @@ -78,7 +96,7 @@ describe('src/loader/**', () => {
expect(loaderContent.foo).toEqual('bar');
});

it('should load .js file sync', () => {
it('should load .js file sync', () => {
const filePath = path.join(basePath, 'file.js');

const loaderContent = loadSync(filePath) as Record<string, any>;
Expand All @@ -87,16 +105,15 @@ describe('src/loader/**', () => {
expect(loaderContent.foo).toEqual('bar');
});


it('should load .js file with named export', async () => {
const filePath = path.join(basePath, 'file.js');

let loaderContent = await load(filePath) as Record<string, any>;
loaderContent = getModuleExport(loaderContent);
expect(loaderContent).toBeDefined();
expect(loaderContent.key).toEqual('default');
expect(loaderContent.value).toEqual({foo: 'bar'});
})
expect(loaderContent.value).toEqual({ foo: 'bar' });
});

it('should load .js file with named export sync', () => {
const filePath = path.join(basePath, 'file.js');
Expand All @@ -105,13 +122,13 @@ describe('src/loader/**', () => {
loaderContent = getModuleExport(loaderContent);
expect(loaderContent).toBeDefined();
expect(loaderContent.key).toEqual('default');
expect(loaderContent.value).toEqual({foo: 'bar'});
expect(loaderContent.value).toEqual({ foo: 'bar' });
});

it('should load .ts file', async () => {
const filePath = path.join(basePath, 'file-ts.ts');

let loaderContent = await load(filePath) as Record<string, any>;
const loaderContent = await load(filePath) as Record<string, any>;
expect(loaderContent).toBeDefined();
expect(loaderContent.bar).toEqual('baz');
});
Expand All @@ -123,34 +140,32 @@ describe('src/loader/**', () => {
loaderContent = getModuleExport(loaderContent);
expect(loaderContent).toBeDefined();
expect(loaderContent.key).toEqual('default');
expect(loaderContent.value).toEqual({bar: 'baz'});
expect(loaderContent.value).toEqual({ bar: 'baz' });
});

it('should load .ts file sync', () => {
it('should load .ts file sync', () => {
const filePath = path.join(basePath, 'file-ts.ts');

let loaderContent = loadSync(filePath) as Record<string, any>;
const loaderContent = loadSync(filePath) as Record<string, any>;
expect(loaderContent).toBeDefined();
expect(loaderContent.bar).toEqual('baz');
});

it('should load .ts file with named export sync', () => {
it('should load .ts file with named export sync', () => {
const filePath = path.join(basePath, 'file-ts.ts');

let loaderContent = loadSync(filePath) as Record<string, any>;
loaderContent = getModuleExport(loaderContent);
expect(loaderContent).toBeDefined();
expect(loaderContent.key).toEqual('default');
expect(loaderContent.value).toEqual({bar: 'baz'});
expect(loaderContent.value).toEqual({ bar: 'baz' });
});

it('should filter .ts file', async () => {
const filePath = path.join(basePath, 'file-many-ts.ts');

let loaderContent = await load(filePath) as Record<string, any>;
loaderContent = await getModuleExport(loaderContent, (key) => {
return key === 'bar';
}) as Record<string, any>;
loaderContent = await getModuleExport(loaderContent, (key) => key === 'bar') as Record<string, any>;

expect(loaderContent).toBeDefined();
expect(loaderContent.key).toEqual('bar');
Expand All @@ -161,26 +176,24 @@ describe('src/loader/**', () => {
const filePath = path.join(basePath, 'file-many-ts.ts');

let loaderContent = loadSync(filePath) as Record<string, any>;
loaderContent = getModuleExport(loaderContent, (key) => {
return key === 'bar';
}) as Record<string, any>;
loaderContent = getModuleExport(loaderContent, (key) => key === 'bar') as Record<string, any>;
expect(loaderContent).toBeDefined();
expect(loaderContent.key).toEqual('bar');
expect(loaderContent.value).toEqual('baz');
})
});

it('should load .json file', async () => {
it('should load .json file', async () => {
const filePath = path.join(basePath, 'file.json');

let loaderContent : Record<string, any> = await load(filePath) as Record<string, any>;
const loaderContent : Record<string, any> = await load(filePath) as Record<string, any>;
expect(loaderContent).toBeDefined();
expect(loaderContent.foo).toEqual('bar');
});

it('should load .json file sync', () => {
it('should load .json file sync', () => {
const filePath = path.join(basePath, 'file.json');

let loaderContent = loadSync(filePath) as Record<string, any>;
const loaderContent = loadSync(filePath) as Record<string, any>;
expect(loaderContent).toBeDefined();
expect(loaderContent.foo).toEqual('bar');
});
Expand Down Expand Up @@ -209,13 +222,13 @@ describe('src/loader/**', () => {
},
executeSync(input: string) {
return input;
}
})
},
});
});

it('should use module loader as fallback', () => {
const manager = new LoaderManager();
const loader = manager.findLoader('foo');
expect(loader).toEqual(LoaderId.MODULE);
})
});
});
Loading

0 comments on commit e3b2f8d

Please sign in to comment.