cdk8s
Version:
This is the core library of Cloud Development Kit (CDK) for Kubernetes (cdk8s). cdk8s apps synthesize into standard Kubernetes manifests which can be applied to any Kubernetes cluster.
89 lines (86 loc) • 3.5 kB
JavaScript
import { isNode } from '../nodes/identity.js';
import { Scalar } from '../nodes/Scalar.js';
import { YAMLMap } from '../nodes/YAMLMap.js';
import { YAMLSeq } from '../nodes/YAMLSeq.js';
import { resolveBlockMap } from './resolve-block-map.js';
import { resolveBlockSeq } from './resolve-block-seq.js';
import { resolveFlowCollection } from './resolve-flow-collection.js';
function resolveCollection(CN, ctx, token, onError, tagName, tag) {
const coll = token.type === 'block-map'
? resolveBlockMap(CN, ctx, token, onError, tag)
: token.type === 'block-seq'
? resolveBlockSeq(CN, ctx, token, onError, tag)
: resolveFlowCollection(CN, ctx, token, onError, tag);
const Coll = coll.constructor;
// If we got a tagName matching the class, or the tag name is '!',
// then use the tagName from the node class used to create it.
if (tagName === '!' || tagName === Coll.tagName) {
coll.tag = Coll.tagName;
return coll;
}
if (tagName)
coll.tag = tagName;
return coll;
}
function composeCollection(CN, ctx, token, props, onError) {
const tagToken = props.tag;
const tagName = !tagToken
? null
: ctx.directives.tagName(tagToken.source, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg));
if (token.type === 'block-seq') {
const { anchor, newlineAfterProp: nl } = props;
const lastProp = anchor && tagToken
? anchor.offset > tagToken.offset
? anchor
: tagToken
: (anchor ?? tagToken);
if (lastProp && (!nl || nl.offset < lastProp.offset)) {
const message = 'Missing newline after block sequence props';
onError(lastProp, 'MISSING_CHAR', message);
}
}
const expType = token.type === 'block-map'
? 'map'
: token.type === 'block-seq'
? 'seq'
: token.start.source === '{'
? 'map'
: 'seq';
// shortcut: check if it's a generic YAMLMap or YAMLSeq
// before jumping into the custom tag logic.
if (!tagToken ||
!tagName ||
tagName === '!' ||
(tagName === YAMLMap.tagName && expType === 'map') ||
(tagName === YAMLSeq.tagName && expType === 'seq')) {
return resolveCollection(CN, ctx, token, onError, tagName);
}
let tag = ctx.schema.tags.find(t => t.tag === tagName && t.collection === expType);
if (!tag) {
const kt = ctx.schema.knownTags[tagName];
if (kt?.collection === expType) {
ctx.schema.tags.push(Object.assign({}, kt, { default: false }));
tag = kt;
}
else {
if (kt) {
onError(tagToken, 'BAD_COLLECTION_TYPE', `${kt.tag} used for ${expType} collection, but expects ${kt.collection ?? 'scalar'}`, true);
}
else {
onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, true);
}
return resolveCollection(CN, ctx, token, onError, tagName);
}
}
const coll = resolveCollection(CN, ctx, token, onError, tagName, tag);
const res = tag.resolve?.(coll, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg), ctx.options) ?? coll;
const node = isNode(res)
? res
: new Scalar(res);
node.range = coll.range;
node.tag = tagName;
if (tag?.format)
node.format = tag.format;
return node;
}
export { composeCollection };