amazon-route-53-dns-zone-file
Version:
Makes DNS Zone File easy. Parses and validates BIND zone files and can be extended for custom features. Functionality is modular. Features are made open for extension and closed for runtime mutation. Written in TypeScript.
152 lines (136 loc) • 3.59 kB
text/typescript
/**
* start of every record is:
* @format $start = `[name?] [ttl?] IN _TYPE_ `
*/
import { ParsedTypings } from '../shared/types_domain_specific';
import {
InstructionType,
ErrorKeyKind,
DirectiveKind,
} from '../shared/constants_domain_specific';
/**
* @note ParsingRecordDataType + ClientRecordType & ApiRecordType
* @description parts of a resource record being-parsed or already parsed
*/
export interface ParsingRecordDataType {
tokens: string[];
values: string[];
name: string;
/** nested parsing */
previousName: string;
ttl?: number;
}
export interface Common {
/** directive or record type */
instructionType: unknown;
/** usually a string */
value: unknown;
/** raw input */
lineContent: string;
/** actual error */
error?: unknown;
/** ErrorKeyKind */
errorType?: string;
}
namespace Internals {
type SOA = Common & {
instructionType: 'SOA';
value: ParsedTypings.Obj['SOA'];
};
type Records = { SOA: SOA } & {
[Key in InputTypings.SupportedRecordType]: Common & {
instructionType: Key;
value: ParsedTypings.ByType[Key];
};
};
interface TimeToLive extends Common {
instructionType: DirectiveKind.TimeToLive;
value: number;
errorType:
| ErrorKeyKind.TtlInvalidFormat
| ErrorKeyKind.TtlOverflow
| ErrorKeyKind.TtlMissingDefault;
}
interface Origin extends Common {
instructionType: DirectiveKind.Origin;
value: string;
}
type Directives = {
[DirectiveKind.TimeToLive]: TimeToLive;
[DirectiveKind.Origin]: Origin;
};
type Problems = {
[Key in ErrorKeyKind]: Common & {
instructionType: Key;
value: string;
};
};
export type Indexed = Directives & Problems & Records;
}
/** import zone file text input */
export namespace InputTypings {
/** supported by the parser */
export type SupportedRecordType =
| 'TXT'
| 'NS'
| 'A'
| 'AAAA'
| 'CNAME'
| 'MX'
| 'PTR'
| 'SPF'
| 'SRV'
| 'CAA'
| 'NAPTR';
/** @desc a directive or a record - the beginning of a line */
export type Instruction = InstructionType;
/** @note currently unused, here for future possible usage */
export type FileFormatVariations =
| ['name', 'ttl', 'class', 'type', 'data']
| ['ttl', 'class', 'type', 'data']
| ['class', 'type', 'data'];
}
export namespace SourceMapTypings {
export type Value = Internals.Indexed[keyof Internals.Indexed];
/** @example type Store = Map<number, Value> */
export interface Store extends Map<number, any> {
has(key: number): boolean;
get<Instruction extends Value['instructionType']>(
key: number
): Internals.Indexed[Instruction] | undefined;
set<Instruction extends Value['instructionType']>(
key: number,
value: Internals.Indexed[Instruction]
): this;
}
}
export namespace ParserTypings {
export interface Parser {
zoneObj: ParsedTypings.Obj;
parsingMeta: SourceMapTypings.Store;
stack: { name?: string }[];
visitors: Visitor[];
input: {
$originName?: string;
textInput: string;
textInputFlattened: string;
textInputSplitByLine: string[];
};
}
export type MetaArg = Omit<
SourceMapTypings.Value,
'lineContent' | 'value'
> & {
value?: SourceMapTypings.Value['value'];
};
export interface Node {
addMeta: (meta: MetaArg) => void;
index: number;
lineContent: string;
lineParts: string[];
}
export type Visitor = {
isSatisfied(node: Node): boolean;
visit(parser: Parser, node: Node): void;
};
}