[d24f17c] | 1 | import { isEmpty } from 'ramda';
|
---|
| 2 | import * as url from "../util/url.mjs";
|
---|
| 3 | import File from "../util/File.mjs";
|
---|
| 4 | import * as plugins from "../util/plugins.mjs";
|
---|
| 5 | import ParseError from "../errors/ParseError.mjs";
|
---|
| 6 | import UnmatchedResolverError from "../errors/UnmatchedResolverError.mjs";
|
---|
| 7 | import { readFile } from "../resolve/util.mjs";
|
---|
| 8 | /**
|
---|
| 9 | * Parses the given file's contents, using the configured parser plugins.
|
---|
| 10 | */
|
---|
| 11 | const parseFile = async (file, options) => {
|
---|
| 12 | const optsBoundParsers = options.parse.parsers.map(parser => {
|
---|
| 13 | const clonedParser = Object.create(parser);
|
---|
| 14 | return Object.assign(clonedParser, options.parse.parserOpts);
|
---|
| 15 | });
|
---|
| 16 | const parsers = await plugins.filter('canParse', file, optsBoundParsers);
|
---|
| 17 |
|
---|
| 18 | // we couldn't find any parser for this File
|
---|
| 19 | if (isEmpty(parsers)) {
|
---|
| 20 | throw new UnmatchedResolverError(file.uri);
|
---|
| 21 | }
|
---|
| 22 | try {
|
---|
| 23 | const {
|
---|
| 24 | plugin,
|
---|
| 25 | result
|
---|
| 26 | } = await plugins.run('parse', [file], parsers);
|
---|
| 27 |
|
---|
| 28 | // empty files handling
|
---|
| 29 | if (!plugin.allowEmpty && result.isEmpty) {
|
---|
| 30 | return Promise.reject(new ParseError(`Error while parsing file "${file.uri}". File is empty.`));
|
---|
| 31 | }
|
---|
| 32 | return result;
|
---|
| 33 | } catch (error) {
|
---|
| 34 | throw new ParseError(`Error while parsing file "${file.uri}"`, {
|
---|
| 35 | cause: error
|
---|
| 36 | });
|
---|
| 37 | }
|
---|
| 38 | };
|
---|
| 39 |
|
---|
| 40 | /**
|
---|
| 41 | * Parses a file into ApiDOM.
|
---|
| 42 | */
|
---|
| 43 | const parse = async (uri, options) => {
|
---|
| 44 | /**
|
---|
| 45 | * If the path is a filesystem path, then convert it to a URL.
|
---|
| 46 | *
|
---|
| 47 | * NOTE: According to the JSON Reference spec, these should already be URLs,
|
---|
| 48 | * but, in practice, many people use local filesystem paths instead.
|
---|
| 49 | * So we're being generous here and doing the conversion automatically.
|
---|
| 50 | * This is not intended to be a 100% bulletproof solution.
|
---|
| 51 | * If it doesn't work for your use-case, then use a URL instead.
|
---|
| 52 | */
|
---|
| 53 | const file = File({
|
---|
| 54 | uri: url.sanitize(url.stripHash(uri)),
|
---|
| 55 | mediaType: options.parse.mediaType
|
---|
| 56 | });
|
---|
| 57 | const data = await readFile(file, options);
|
---|
| 58 | return parseFile(File({
|
---|
| 59 | ...file,
|
---|
| 60 | data
|
---|
| 61 | }), options);
|
---|
| 62 | };
|
---|
| 63 | export default parse; |
---|