accelerator-core
Version:
[](https://travis-ci.org/furkleindustries/accelerator-core)
124 lines (102 loc) • 3.07 kB
text/typescript
import {
BuiltInTags,
} from '../tags/BuiltInTags';
import {
checkPassageAsset,
} from './checkPassageAsset';
import {
getTag,
} from '../tags/getTag';
import {
IPassagesMap,
} from './IPassagesMap';
import {
assert,
assertValid,
} from 'ts-assertions';
import {
default as manifest,
registry,
} from '../../passages/passages-manifest';
type RegistryType = typeof registry;
export const strings = {
MULTIPLE_DEFAULT_PASSAGES:
'At least two passages had the tag "start". Only one tag is allowed. ' +
'The passages found with this error were named %1% and %2%.',
MULTIPLE_PASSAGES_WITH_SAME_NAME:
'At least two passages had the name %NAME%. The name property of every ' +
'passage must be unique.',
NO_START_PASSAGE:
'There was no passage in the passages/ folder with the "start" tag. One ' +
'and only one passage must have the start tag.',
PASSAGES_MANIFEST_EMPTY:
'The passages-manifest.json file contained an empty array, indicating ' +
'that no passages have been authored in passages/.',
PASSAGES_MANIFEST_INVALID:
'The passages-manifest.json file was not parseable into an array.',
PASSAGE_OBJECT_INVALID:
'One of the passage objects, found at %FILEPATH%, was invalid. ' +
'%REASON%',
};
assert(Array.isArray(manifest), strings.PASSAGES_MANIFEST_INVALID);
assert(manifest.length, strings.PASSAGES_MANIFEST_EMPTY);
/* Memoize results and return them without computation on repeat calls. */
let passagesMap: IPassagesMap | null = null;
let startPassageName: keyof RegistryType | null = null;
export const getPassagesMapAndStartPassageName = (): {
passagesMap: IPassagesMap;
startPassageName: keyof RegistryType;
} => {
/* Return the memoized results if they exist. */
if (passagesMap && startPassageName) {
return {
passagesMap,
startPassageName,
};
}
passagesMap = {} as IPassagesMap;
manifest.forEach(({
asset,
filepath,
}) => {
try {
checkPassageAsset(asset);
} catch (err) {
const errStr = strings.PASSAGE_OBJECT_INVALID
.replace('%FILEPATH%', filepath)
.replace('%REASON%', err);
throw new Error(errStr);
}
const {
name,
tags,
} = asset;
assert(
!(name in passagesMap!),
strings.PASSAGE_OBJECT_INVALID.replace('%NAME%', name),
);
if (getTag(tags, BuiltInTags.Start)) {
/* Throw if a passage with a duplicate name is found. */
if (startPassageName) {
throw new Error(
strings.MULTIPLE_DEFAULT_PASSAGES
.replace('%1%', startPassageName)
.replace('%2%', name)
);
}
startPassageName = name;
}
if (!getTag(tags, BuiltInTags.NoRender)) {
/* Do not place NoRender passages in the passage map. */
passagesMap![name] = asset;
}
});
const safeStartPassageName = assertValid<keyof RegistryType>(
startPassageName,
strings.NO_START_PASSAGE,
);
return {
passagesMap,
startPassageName: safeStartPassageName,
};
};