core-types
Version:
Generic type declarations for e.g. TypeScript, GraphQL and JSON Schema
122 lines (121 loc) • 3.21 kB
JavaScript
export function uniq(arr) {
return arr
.filter((t, index) => {
for (let i = 0; i < index; ++i) {
const u = arr[i];
if (isEqual(t, u))
return false;
}
return true;
});
}
export function ensureArray(t) {
if (t == null)
return [];
return Array.isArray(t) ? t : [t];
}
export const isPrimitiveType = (node) => ["null", "string", "number", "integer", "boolean"].includes(node.type);
export const constEnumTypes = new Set([
'any',
'string',
'number',
'integer',
'boolean',
'object',
'array',
'tuple',
'ref'
]);
export const hasConstEnum = (node) => constEnumTypes.has(node.type);
export function isEqual(a, b) {
if (typeof a !== typeof b)
return false;
else if ((a === null) !== (b === null))
return false;
else if (a === null)
return true;
else if (Array.isArray(a) && Array.isArray(b)) {
if (a.length !== b.length)
return false;
return !a.some((value, index) => !isEqual(value, b[index]));
}
else if (Array.isArray(a) !== Array.isArray(b))
return false;
else if (typeof a === 'object') {
const keysA = Object.keys(a).sort();
const keysB = Object.keys(b).sort();
if (!isEqual(keysA, keysB))
return false;
return !keysA.some(key => !isEqual(a[key], b[key]));
}
else
return a === b;
}
export function intersection(a, b) {
const ret = [];
a.forEach(aItem => {
b.forEach(bItem => {
if (isEqual(aItem, bItem))
ret.push(aItem);
});
});
return ret;
}
export function union(a, b) {
const ret = [...a];
b.forEach(aItem => {
const unique = !a.some(bItem => isEqual(aItem, bItem));
if (unique)
ret.push(aItem);
});
return ret;
}
// Split a set of types into individual sets per-type
export function splitTypes(nodes) {
const ret = {
and: [],
or: [],
ref: [],
any: [],
null: [],
string: [],
number: [],
integer: [],
boolean: [],
object: [],
array: [],
tuple: [],
};
nodes.forEach((node, index) => {
if (node.type !== 'and' && node.type !== 'or'
||
node.type === 'and' && node.and.length > 0
||
node.type === 'or' && node.or.length > 0) {
const nodeWithOrder = {
node,
order: index,
};
ret[node.type].push(nodeWithOrder);
}
});
return ret;
}
export function flattenSplitTypeValues(splitTypes) {
return [].concat(Object.values(splitTypes)
.flat()
.sort((a, b) => a.order - b.order)
.map(({ node }) => node));
}
export function firstSplitTypeIndex(nodes) {
return Math.min(...nodes.map(({ order }) => order));
}
export function copyName(from, to) {
return typeof from.name === 'undefined' ? to : { ...to, name: from.name };
}
export function isNonNullable(t) {
return t != null;
}
export function isNodeDocument(t) {
return Array.isArray(t.types);
}