1
0
Fork 0

feat(include): allow consumer to provide fs functions via include schema

BREAKING CHANGE: rather than use the `fs` functions (`existsSync`,
`readSync`, etc) to include files, this uses fields of the `includeSchema`.
To maintain the previous functionality, fields should be set as follows:

- `exists = existsSync`
- `read = readSync`
- `resolve = realpathSync`
This commit is contained in:
ssube 2020-06-30 08:08:03 -05:00
parent bc06121a18
commit 77b6f4cc74
Signed by: ssube
GPG Key ID: 3EED7B957D362AF1
2 changed files with 21 additions and 10 deletions

View File

@ -9,7 +9,5 @@ The schema to be used for included files. This is necessary to work around circu
<b>Signature:</b> <b>Signature:</b>
```typescript ```typescript
includeSchema: { includeSchema: IncludeSchema
schema: import("js-yaml").Schema;
}
``` ```

View File

@ -1,12 +1,25 @@
import { InvalidArgumentError, NotFoundError } from '@apextoaster/js-utils'; import { InvalidArgumentError, NotFoundError } from '@apextoaster/js-utils';
import { existsSync, readFileSync, realpathSync } from 'fs'; import { SAFE_SCHEMA, safeLoad, Schema, Type as YamlType } from 'js-yaml';
import { SAFE_SCHEMA, safeLoad, Type as YamlType } from 'js-yaml';
import { join } from 'path'; import { join } from 'path';
export interface IncludeSchema {
exists(path: string): boolean;
read(path: string, encoding: object): string;
resolve(path: string): string;
schema: Schema;
}
/** /**
* The schema to be used for included files. This is necessary to work around circular dependency errors. * The schema to be used for included files. This is necessary to work around circular dependency errors.
*/ */
export const includeSchema = { export const includeSchema: IncludeSchema = {
exists: (path: string) => false,
read: (path: string, encoding: object) => {
throw new Error('read stub');
},
resolve: (path: string) => {
throw new Error('resolve stub');
},
schema: SAFE_SCHEMA, schema: SAFE_SCHEMA,
}; };
@ -16,7 +29,7 @@ export const includeType = new YamlType('!include', {
try { try {
const canonical = resolvePath(path); const canonical = resolvePath(path);
// throws in node 11+ // throws in node 11+
if (existsSync(canonical)) { if (includeSchema.exists(canonical)) {
return true; return true;
} else { } else {
throw new NotFoundError('included file does not exist'); throw new NotFoundError('included file does not exist');
@ -27,7 +40,7 @@ export const includeType = new YamlType('!include', {
}, },
construct(path: string): unknown { construct(path: string): unknown {
try { try {
return safeLoad(readFileSync(resolvePath(path), { return safeLoad(includeSchema.read(resolvePath(path), {
encoding: 'utf-8', encoding: 'utf-8',
}), { }), {
schema: includeSchema.schema, schema: includeSchema.schema,
@ -40,8 +53,8 @@ export const includeType = new YamlType('!include', {
export function resolvePath(path: string): string { export function resolvePath(path: string): string {
if (path[0] === '.') { if (path[0] === '.') {
return realpathSync(join(__dirname, path)); return includeSchema.resolve(join(__dirname, path));
} else { } else {
return realpathSync(path); return includeSchema.resolve(path);
} }
} }