feat: add join callback to include options
BREAKING CHANGE: usage of the include type now requires a join option
This commit is contained in:
parent
dba9267828
commit
1d07d7c3ed
|
@ -9,5 +9,5 @@ The schema to be used for included files. This is necessary to work around circu
|
|||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
includeSchema: IncludeSchema
|
||||
includeOptions: IncludeOptions
|
||||
```
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export { CONFIG_SCHEMA } from './schema';
|
||||
export { envType } from './type/Env';
|
||||
export { includeSchema, includeType } from './type/Include';
|
||||
export { includeOptions as includeSchema, includeType } from './type/Include';
|
||||
export { regexpType } from './type/Regexp';
|
||||
export { streamType } from './type/Stream';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { DEFAULT_SAFE_SCHEMA, Schema } from 'js-yaml';
|
||||
|
||||
import { envType } from './type/Env';
|
||||
import { includeSchema, includeType } from './type/Include';
|
||||
import { includeOptions, includeType } from './type/Include';
|
||||
import { regexpType } from './type/Regexp';
|
||||
import { streamType } from './type/Stream';
|
||||
|
||||
|
@ -17,4 +17,4 @@ export const CONFIG_SCHEMA = Schema.create([DEFAULT_SAFE_SCHEMA], [
|
|||
streamType,
|
||||
]);
|
||||
|
||||
includeSchema.schema = CONFIG_SCHEMA;
|
||||
includeOptions.schema = CONFIG_SCHEMA;
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import { InvalidArgumentError, NotFoundError } from '@apextoaster/js-utils';
|
||||
import { InvalidArgumentError, NotFoundError, NotImplementedError } from '@apextoaster/js-utils';
|
||||
import { SAFE_SCHEMA, safeLoad, Schema, Type as YamlType } from 'js-yaml';
|
||||
import { join } from 'path';
|
||||
|
||||
export interface IncludeOptions {
|
||||
export interface ReaderOptions {
|
||||
encoding: string;
|
||||
}
|
||||
|
||||
export type IncludeReader = (path: string, options: IncludeOptions) => string;
|
||||
export type IncludeReader = (path: string, options: ReaderOptions) => string;
|
||||
|
||||
export interface IncludeSchema {
|
||||
export interface IncludeOptions {
|
||||
exists: (path: string) => boolean;
|
||||
join: (...path: Array<string>) => string;
|
||||
read: IncludeReader;
|
||||
resolve: (path: string) => string;
|
||||
schema: Schema;
|
||||
|
@ -20,13 +20,16 @@ export interface IncludeSchema {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
export const includeSchema: IncludeSchema = {
|
||||
export const includeOptions: IncludeOptions = {
|
||||
exists: (path: string) => false,
|
||||
read: (path: string, encoding: IncludeOptions) => {
|
||||
throw new Error('read stub');
|
||||
join: (...path: Array<string>) => {
|
||||
throw new NotImplementedError('join stub');
|
||||
},
|
||||
read: (path: string, encoding: ReaderOptions) => {
|
||||
throw new NotImplementedError('read stub');
|
||||
},
|
||||
resolve: (path: string) => {
|
||||
throw new Error('resolve stub');
|
||||
throw new NotImplementedError('resolve stub');
|
||||
},
|
||||
schema: SAFE_SCHEMA,
|
||||
};
|
||||
|
@ -40,7 +43,7 @@ export const includeType = new YamlType('!include', {
|
|||
try {
|
||||
const canonical = resolvePath(path);
|
||||
// throws in node 11+
|
||||
if (includeSchema.exists(canonical)) {
|
||||
if (includeOptions.exists(canonical)) {
|
||||
return true;
|
||||
} else {
|
||||
throw new NotFoundError('included file does not exist');
|
||||
|
@ -51,10 +54,10 @@ export const includeType = new YamlType('!include', {
|
|||
},
|
||||
construct(path: string): unknown {
|
||||
try {
|
||||
return safeLoad(includeSchema.read(resolvePath(path), {
|
||||
return safeLoad(includeOptions.read(resolvePath(path), {
|
||||
encoding: 'utf-8',
|
||||
}), {
|
||||
schema: includeSchema.schema,
|
||||
schema: includeOptions.schema,
|
||||
});
|
||||
} catch (err) {
|
||||
throw new InvalidArgumentError('error including file', err);
|
||||
|
@ -62,10 +65,13 @@ export const includeType = new YamlType('!include', {
|
|||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* @todo take root parameter instead of __dirname
|
||||
*/
|
||||
export function resolvePath(path: string): string {
|
||||
if (path[0] === '.') {
|
||||
return includeSchema.resolve(join(__dirname, path));
|
||||
return includeOptions.resolve(includeOptions.join(__dirname, path));
|
||||
} else {
|
||||
return includeSchema.resolve(path);
|
||||
return includeOptions.resolve(path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,25 +2,27 @@ import { InvalidArgumentError, NotFoundError } from '@apextoaster/js-utils';
|
|||
import { expect } from 'chai';
|
||||
import { join } from 'path';
|
||||
|
||||
import { IncludeSchema, includeSchema, includeType } from '../../src/type/Include';
|
||||
import { IncludeOptions, includeOptions, includeType } from '../../src/type/Include';
|
||||
|
||||
const TEST_ROOT = '../test/type';
|
||||
|
||||
const ORIGINAL_SCHEMA: IncludeSchema = {
|
||||
...includeSchema,
|
||||
const ORIGINAL_SCHEMA: IncludeOptions = {
|
||||
...includeOptions,
|
||||
};
|
||||
|
||||
describe('include config type', async () => {
|
||||
beforeEach(() => {
|
||||
includeSchema.exists = () => true;
|
||||
includeSchema.read = () => 'test';
|
||||
includeSchema.resolve = (path: string) => path;
|
||||
includeOptions.exists = () => true;
|
||||
includeOptions.join = (...path) => path.join('/');
|
||||
includeOptions.read = () => 'test';
|
||||
includeOptions.resolve = (path: string) => path;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
includeSchema.exists = ORIGINAL_SCHEMA.exists;
|
||||
includeSchema.read = ORIGINAL_SCHEMA.read;
|
||||
includeSchema.resolve = ORIGINAL_SCHEMA.resolve;
|
||||
includeOptions.exists = ORIGINAL_SCHEMA.exists;
|
||||
includeOptions.join = ORIGINAL_SCHEMA.join;
|
||||
includeOptions.read = ORIGINAL_SCHEMA.read;
|
||||
includeOptions.resolve = ORIGINAL_SCHEMA.resolve;
|
||||
});
|
||||
|
||||
it('should resolve existing files', async () => {
|
||||
|
@ -28,7 +30,7 @@ describe('include config type', async () => {
|
|||
});
|
||||
|
||||
it('should throw when resolving missing files', async () => {
|
||||
includeSchema.resolve = () => {
|
||||
includeOptions.resolve = () => {
|
||||
throw new NotFoundError();
|
||||
};
|
||||
|
||||
|
@ -42,7 +44,7 @@ describe('include config type', async () => {
|
|||
});
|
||||
|
||||
it('should throw when constructing missing files', async () => {
|
||||
includeSchema.read = () => {
|
||||
includeOptions.read = () => {
|
||||
throw new InvalidArgumentError();
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue