@fmlang/fml-to-schema
Version:
Convert Forms Markup Language (FML) to jsonv-ts (JSON Schema)
1,604 lines (1,586 loc) • 53.9 kB
JavaScript
// @bun
// node_modules/@fmlang/tokenizer/lib/main.js
class Result {
value;
error;
constructor(value, error) {
this.value = value;
this.error = error;
}
IsError() {
return this.error != null || this.value == null;
}
HasValue() {
return this.value != null;
}
}
class Token {
token_type;
lexeme;
literal;
line;
constructor(token_type, lexeme, literal, line) {
this.token_type = token_type;
this.lexeme = lexeme;
this.literal = literal;
this.line = line;
}
}
var TokenType = {
IDENTIFIER: 0,
STRING: 1,
NUMBER: 2,
MARKDOWN: 3,
ASTERISK: 4,
COMMA: 5,
DOT: 6,
MINUS: 7,
PLUS: 8,
SEMICOLON: 9,
FORWARD_SLASH: 10,
BACK_SLASH: 11,
POUND: 12,
LEFT_BRACE: 13,
RIGHT_BRACE: 14,
LEFT_BRACKET: 15,
RIGHT_BRACKET: 16,
LEFT_PARENTHESIS: 17,
RIGHT_PARENTHESIS: 18,
EXCLAMATION_POINT: 19,
EXCLAMATION_POINT_EQUAL: 20,
EQUAL: 21,
EQUAL_EQUAL: 22,
GREATER_THAN: 23,
GREATER_THAN_EQUAL: 24,
LESS_THAN: 25,
LESS_THAN_EQUAL: 26,
AND: 27,
ELSE: 28,
FALSE: 29,
LOOP: 30,
IF: 31,
OR: 32,
PRINT: 33,
RETURN: 34,
TRUE: 35,
LET: 36,
CONST: 37,
EOL: 99,
EOF: 100
};
var KeywordMap = {
and: TokenType.AND,
else: TokenType.ELSE,
false: TokenType.FALSE,
loop: TokenType.LOOP,
if: TokenType.IF,
or: TokenType.OR,
print: TokenType.PRINT,
return: TokenType.RETURN,
true: TokenType.TRUE,
let: TokenType.LET,
const: TokenType.CONST
};
class Tokenizer {
tokens = [];
start = 0;
current = 0;
line = 1;
source = "";
constructor(fml) {
this.source = fml;
this.start = 0;
this.tokens = [];
this.current = 0;
this.line = 1;
}
Tokenize() {
while (!this.IsAtEnd()) {
this.start = this.current;
this.ScanToken();
}
this.tokens.push(new Token(TokenType.EOF, "", null, this.line));
return new Result(this.tokens, null);
}
IsAtEnd() {
return this.current >= this.source.length;
}
ScanToken() {
let c = this.Advance();
switch (c) {
case "(":
this.AddToken(TokenType.LEFT_PARENTHESIS);
break;
case ")":
this.AddToken(TokenType.RIGHT_PARENTHESIS);
break;
case "{":
this.AddToken(TokenType.LEFT_BRACE);
break;
case "}":
this.AddToken(TokenType.RIGHT_BRACE);
break;
case "[":
this.AddToken(TokenType.LEFT_BRACKET);
break;
case "]":
this.AddToken(TokenType.RIGHT_BRACKET);
break;
case ",":
this.AddToken(TokenType.COMMA);
break;
case ".":
this.AddToken(TokenType.DOT);
break;
case "-":
this.AddToken(TokenType.MINUS);
break;
case "+":
this.AddToken(TokenType.PLUS);
break;
case "*":
this.AddToken(TokenType.ASTERISK);
break;
case "":
this.AddToken(TokenType.SEMICOLON);
break;
case "!":
this.AddToken(this.MatchNext("=") ? TokenType.EXCLAMATION_POINT_EQUAL : TokenType.EXCLAMATION_POINT);
break;
case "=":
this.AddToken(this.MatchNext("=") ? TokenType.EQUAL_EQUAL : TokenType.EQUAL);
break;
case "<":
this.AddToken(this.MatchNext("=") ? TokenType.LESS_THAN_EQUAL : TokenType.LESS_THAN);
break;
case ">":
this.AddToken(this.MatchNext("=") ? TokenType.GREATER_THAN_EQUAL : TokenType.GREATER_THAN);
break;
case "/": {
if (this.MatchNext("/")) {
while (this.PeekNext() != `
` && !this.IsAtEnd()) {
this.Advance();
}
} else {
this.AddToken(TokenType.FORWARD_SLASH);
}
break;
}
case "#": {
if (this.MatchNext("{")) {
this.ReadMarkdown();
}
this.AddToken(TokenType.POUND);
break;
}
case '"': {
this.ReadString();
break;
}
case " ":
case "\r":
case "\t":
break;
case `
`:
this.line++;
break;
default:
if (this.IsDigit(c)) {
this.ReadNumber();
} else if (this.IsAlpha(c)) {
this.ReadIdentifier();
} else {
throw new Error(`Unexpected character ${c}`);
}
break;
}
}
Advance() {
this.current++;
return this.source[this.current - 1];
}
MatchNext(expected) {
if (this.IsAtEnd())
return false;
if (this.source[this.current] != expected)
return false;
this.current++;
return true;
}
IsDigit(lexeme) {
return lexeme >= "0" && lexeme <= "9";
}
ReadNumber() {
while (this.IsDigit(this.PeekNext())) {
this.Advance();
}
if (this.PeekNext() == "." && this.IsDigit(this.PeekNext(1))) {
this.Advance();
while (this.IsDigit(this.PeekNext())) {
this.Advance();
}
}
let num = parseFloat(this.source.substring(this.start, this.current));
this.AddToken(TokenType.NUMBER, num);
}
PeekNext(offset = 0) {
if (this.IsAtEnd())
return "\x00";
return this.source[this.current + offset];
}
ReadString() {
while (this.PeekNext() != '"' && !this.IsAtEnd()) {
let next = this.PeekNext();
if (this.PeekNext() == "\\" && this.PeekNext(1) == '"') {
this.Advance();
}
if (this.PeekNext() == `
`) {
this.line++;
}
this.Advance();
}
if (this.IsAtEnd()) {
throw new Error("Unterminated string on line " + this.line);
}
this.Advance();
let value = this.source.substring(this.start + 1, this.current - 1);
value = value.replace(/\\"/g, '"');
this.AddToken(TokenType.STRING, value);
}
IsAlpha(c) {
return c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c == "_";
}
IsAlphaNumeric(c) {
return this.IsAlpha(c) || this.IsDigit(c);
}
ReadIdentifier() {
while (this.IsAlphaNumeric(this.PeekNext())) {
this.Advance();
}
let text = this.source.substring(this.start, this.current);
let token_type = KeywordMap[text] || TokenType.IDENTIFIER;
this.AddToken(token_type);
}
AddToken(token_type, literal = null) {
let text = this.source.substring(this.start, this.current);
this.tokens.push(new Token(token_type, text, literal, this.line));
}
ReadMarkdown() {
while (!this.IsAtEnd()) {
if (this.PeekNext() != "}") {
this.Advance();
} else {
if (this.PeekNext(1) == "#") {
break;
} else {
if (this.IsAtEnd()) {
throw new Error(`Unterminated markdown on line ${this.line}: ${this.source.substring(this.start)}`);
}
this.Advance();
}
}
}
if (this.IsAtEnd()) {
throw new Error(`Unterminated markdown on line ${this.line}: ${this.source.substring(this.start)}`);
}
if (!this.MatchNext("}")) {
throw new Error(`Unterminated markdown on line ${this.line}: ${this.source.substring(this.start)}`);
}
if (!this.MatchNext("#")) {
throw new Error(`Unterminated markdown on line ${this.line}: ${this.source.substring(this.start)}`);
}
let value = this.source.substring(this.start + 2, this.current - 2);
value = value.trim().split(`
`).map((line) => line.trim()).join(`
`);
this.AddToken(TokenType.MARKDOWN, value);
this.line += value.split(`
`).length + 1;
this.start = this.current;
}
}
// node_modules/@fmlang/parser/lib/main.js
class Expr {
}
class Attribute extends Expr {
left;
right;
line_number;
constructor(left, right, line_number) {
super();
this.left = left;
this.right = right;
this.line_number = line_number;
}
accept(visitor) {
return visitor.visitAttributeExpr(this);
}
}
class Control extends Expr {
identifier;
attributes;
line_number;
constructor(identifier, attributes, line_number) {
super();
this.identifier = identifier;
this.attributes = attributes;
this.line_number = line_number;
}
accept(visitor) {
return visitor.visitControlExpr(this);
}
}
class Identifier extends Expr {
name;
line_number;
constructor(name, line_number) {
super();
this.name = name;
this.line_number = line_number;
}
accept(visitor) {
return visitor.visitIdentifierExpr(this);
}
}
class Container extends Expr {
identifier;
attributes;
children;
line_number;
constructor(identifier, attributes, children, line_number) {
super();
this.identifier = identifier;
this.attributes = attributes;
this.children = children;
this.line_number = line_number;
}
accept(visitor) {
return visitor.visitContainerExpr(this);
}
}
class Literal extends Expr {
value;
line_number;
constructor(value, line_number) {
super();
this.value = value;
this.line_number = line_number;
}
accept(visitor) {
return visitor.visitLiteralExpr(this);
}
}
class Markdown extends Expr {
attributes;
value;
line_number;
constructor(attributes, value, line_number) {
super();
this.attributes = attributes;
this.value = value;
this.line_number = line_number;
}
accept(visitor) {
return visitor.visitMarkdownExpr(this);
}
}
class Select extends Expr {
identifier;
attributes;
children;
line_number;
constructor(identifier, attributes, children, line_number) {
super();
this.identifier = identifier;
this.attributes = attributes;
this.children = children;
this.line_number = line_number;
}
accept(visitor) {
return visitor.visitSelectExpr(this);
}
}
class Radio extends Expr {
identifier;
attributes;
children;
line_number;
constructor(identifier, attributes, children, line_number) {
super();
this.identifier = identifier;
this.attributes = attributes;
this.children = children;
this.line_number = line_number;
}
accept(visitor) {
return visitor.visitRadioExpr(this);
}
}
class CheckList extends Expr {
identifier;
attributes;
children;
line_number;
constructor(identifier, attributes, children, line_number) {
super();
this.identifier = identifier;
this.attributes = attributes;
this.children = children;
this.line_number = line_number;
}
accept(visitor) {
return visitor.visitCheckListExpr(this);
}
}
class Result2 {
value;
error;
constructor(value, error) {
this.value = value;
this.error = error;
}
IsError() {
return this.error != null || this.value == null;
}
HasValue() {
return this.value != null;
}
}
var TokenType2 = {
IDENTIFIER: 0,
STRING: 1,
NUMBER: 2,
MARKDOWN: 3,
ASTERISK: 4,
COMMA: 5,
DOT: 6,
MINUS: 7,
PLUS: 8,
SEMICOLON: 9,
FORWARD_SLASH: 10,
BACK_SLASH: 11,
POUND: 12,
LEFT_BRACE: 13,
RIGHT_BRACE: 14,
LEFT_BRACKET: 15,
RIGHT_BRACKET: 16,
LEFT_PARENTHESIS: 17,
RIGHT_PARENTHESIS: 18,
EXCLAMATION_POINT: 19,
EXCLAMATION_POINT_EQUAL: 20,
EQUAL: 21,
EQUAL_EQUAL: 22,
GREATER_THAN: 23,
GREATER_THAN_EQUAL: 24,
LESS_THAN: 25,
LESS_THAN_EQUAL: 26,
AND: 27,
ELSE: 28,
FALSE: 29,
LOOP: 30,
IF: 31,
OR: 32,
PRINT: 33,
RETURN: 34,
TRUE: 35,
LET: 36,
CONST: 37,
EOL: 99,
EOF: 100
};
var KeywordMap2 = {
and: TokenType2.AND,
else: TokenType2.ELSE,
false: TokenType2.FALSE,
loop: TokenType2.LOOP,
if: TokenType2.IF,
or: TokenType2.OR,
print: TokenType2.PRINT,
return: TokenType2.RETURN,
true: TokenType2.TRUE,
let: TokenType2.LET,
const: TokenType2.CONST
};
class Parser {
tokens;
current = 0;
constructor(tokens) {
this.tokens = tokens;
}
Parse() {
let expr = this.root();
return new Result2(expr, null);
}
root() {
return this.container();
}
container() {
let identifier = this.identifier();
if (identifier == null) {
return null;
}
let attributes = this.attributes();
if (attributes == null) {
this.current--;
return null;
}
let elements = this.elements();
if (elements == null) {
for (const attribute of attributes) {
this.current = this.current - 3;
}
return null;
}
let line_number = this.peek_at_previous().line;
return new Container(identifier, attributes, elements, line_number);
}
identifier() {
const line_number = this.peek_at_current().line;
if (this.match(TokenType2.IDENTIFIER)) {
return new Identifier(this.tokens[this.current - 1].lexeme, line_number);
}
return null;
}
attributes() {
if (this.match(TokenType2.LEFT_PARENTHESIS)) {
let attributes = this.attribute();
if (this.match(TokenType2.RIGHT_PARENTHESIS)) {
return attributes || [];
}
}
return null;
}
attribute() {
let attributes = [];
let left = this.identifier();
let equal = this.match(TokenType2.EQUAL);
let right = this.literal();
if (left == null || right == null) {
return null;
}
while (left != null && right != null) {
let line_number = this.peek_at_previous().line;
attributes.push(new Attribute(left, right, line_number));
left = this.identifier();
equal = this.match(TokenType2.EQUAL);
right = this.literal();
}
return attributes;
}
elements() {
if (this.match(TokenType2.LEFT_BRACE)) {
let children = this.element();
this.match(TokenType2.RIGHT_BRACE);
return children;
}
return null;
}
element() {
let result = [];
let identifier = this.identifier();
if (identifier == null) {
return null;
}
let attributes = this.attributes();
if (attributes == null) {
return null;
}
let peeked = this.peek_at_current();
let elements = this.elements();
if (this.match(TokenType2.MARKDOWN)) {
this.advance();
this.advance();
let markdown = peeked.literal;
const line_number = this.peek_at_previous().line;
result.push(new Markdown(attributes, markdown, line_number));
} else if (this.peek_at_current().token_type == TokenType2.LEFT_BRACKET) {
let children = this.read_list();
if (children == null) {
throw new Error("Expected list of children on line " + this.peek_at_current().line);
}
let id = identifier;
const line_number = this.peek_at_previous().line;
switch (id.name) {
case "select":
result.push(new Select(identifier, attributes, children, line_number));
break;
case "radio":
result.push(new Radio(identifier, attributes, children, line_number));
break;
case "checklist":
result.push(new CheckList(identifier, attributes, children, line_number));
break;
default:
result.push(new Select(identifier, attributes, children, line_number));
break;
}
} else if (elements == null) {
const line_number = this.peek_at_previous().line;
result.push(new Control(identifier, attributes, line_number));
} else {
const line_number = this.peek_at_previous().line;
result.push(new Container(identifier, attributes, elements, line_number));
}
while (true) {
identifier = this.identifier();
if (identifier == null) {
return result;
}
attributes = this.attributes();
if (attributes == null) {
return result;
}
let peeked2 = this.peek_at_current();
elements = this.elements();
const line_number = this.peek_at_previous().line;
if (peeked2.token_type == TokenType2.MARKDOWN) {
this.advance();
this.advance();
let markdown = peeked2.literal;
result.push(new Markdown(attributes, markdown, line_number));
} else if (this.peek_at_current().token_type == TokenType2.LEFT_BRACKET) {
let children = this.read_list();
if (children == null) {
throw new Error("Expected list of children on line " + this.peek_at_current().line);
}
let id = identifier;
switch (id.name) {
case "select":
result.push(new Select(identifier, attributes, children, line_number));
break;
case "radio":
result.push(new Radio(identifier, attributes, children, line_number));
break;
case "checklist":
result.push(new CheckList(identifier, attributes, children, line_number));
break;
default:
result.push(new Select(identifier, attributes, children, line_number));
break;
}
} else if (elements == null) {
result.push(new Control(identifier, attributes, line_number));
} else {
result.push(new Container(identifier, attributes, elements, line_number));
}
}
}
match(...token_types) {
for (let token_type of token_types) {
if (this.check(token_type)) {
this.advance();
return true;
}
}
return false;
}
check(token_type) {
if (this.is_at_end()) {
return false;
}
let peeked = this.peek_at_current();
return peeked.token_type == token_type;
}
advance() {
if (!this.is_at_end()) {
this.current++;
}
}
is_at_end() {
const peeked = this.peek_at_current();
if (peeked == null) {
return true;
}
return peeked.token_type == TokenType2.EOF;
}
peek_at_current() {
return this.tokens[this.current];
}
peek_at_previous() {
return this.tokens[this.current - 1];
}
peek_at_next() {
return this.tokens[this.current + 1];
}
literal() {
let literal_types = [TokenType2.STRING, TokenType2.NUMBER, TokenType2.TRUE, TokenType2.FALSE];
for (let token_type of literal_types) {
if (this.check(token_type)) {
this.advance();
let previous = this.peek_at_previous();
let line_number = previous.line;
return new Literal(previous, line_number);
}
}
return null;
}
control() {
let identifier = this.identifier();
let attributes = this.attributes();
if (identifier == null || attributes == null) {
return null;
}
this.match(TokenType2.EOL);
const line_number = this.peek_at_previous().line;
return new Control(identifier, attributes, line_number);
}
read_list() {
let items = [];
this.match(TokenType2.LEFT_BRACKET);
while (!this.check(TokenType2.RIGHT_BRACKET)) {
let item = this.literal();
if (item == null) {
return null;
}
items.push(item);
this.match(TokenType2.COMMA);
}
this.match(TokenType2.RIGHT_BRACKET);
return items;
}
}
// node_modules/jsonv-ts/dist/lib/index.js
var C = Symbol.for("kind");
var A = Symbol.for("optional");
var b = Symbol.for("raw");
var O = class extends Error {
constructor(t) {
super(`Expected ${t}`);
}
};
var E = class extends Error {
constructor(n, r) {
super(`${n}, got: '${JSON.stringify(r)}'`);
this.value = r;
}
};
function M(e) {
return e === null;
}
function p(e) {
return !Array.isArray(e) && typeof e == "object" && e !== null;
}
function l(e) {
return typeof e == "string";
}
function h(e) {
return typeof e == "number";
}
function q(e) {
return typeof e == "number" && Number.isInteger(e);
}
function g(e) {
return typeof e == "boolean";
}
function y(e) {
return Array.isArray(e);
}
function L(e) {
return typeof e == "string" && /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(e);
}
function d(e) {
return p(e) && C in e;
}
function K(e) {
return d(e) && g(e[b]);
}
function N(e, t, n) {
if (!e)
throw new E(t, n);
}
function x(e) {
if (y(e))
return e.map(x).sort();
if (p(e)) {
let t = Object.entries(e).sort(([n], [r]) => n.localeCompare(r)).map(([n, r]) => [n, x(r)]);
return Object.fromEntries(t);
}
return l(e) ? e.normalize("NFC") : e;
}
var z = (e = [], t = "") => "/" + [t, ...e.map((n) => String(n).replace(/\./g, "/"))].filter(Boolean).join("/");
var ze = (e) => e.split("/").slice(1);
function D(e, t, n = undefined) {
let r = typeof t == "string" ? ze(t) : z(t);
return _(e, r, n);
}
function _(e, t, n = undefined) {
let r = typeof t == "string" ? t.split(/[.\[\]\"]+/).filter((o) => o) : t;
if (r.length === 0)
return e;
try {
let [o, ...i] = r;
return !o || !(o in e) ? n : _(e[o], i, n);
} catch {
if (typeof n < "u")
return n;
throw new Error(`Invalid path: ${r.join(".")}`);
}
}
var c = (e = {}, t, n, r) => ({ valid: false, errors: [...e.errors ?? [], { keywordLocation: z([...e.keywordPath ?? [], t]), instanceLocation: z(e.instancePath), error: typeof n == "string" ? n : `Invalid value for ${t}`, data: r }] });
var a = () => ({ valid: true, errors: [] });
var w = (e, t, n) => {
let r = Array.isArray(t) ? t : [t], o = n ? Array.isArray(n) ? n : [n] : [];
return { ...e, keywordPath: [...e.keywordPath ?? [], ...r], instancePath: o ? [...e.instancePath ?? [], ...o] : e.instancePath };
};
var j = (e = {}) => ({ ...e, errors: [] });
var H = ({ type: e }, t, n = {}) => {
if (e === undefined)
return a();
let r, o = { string: l, number: h, integer: q, object: p, array: y, boolean: g, null: M };
if (Array.isArray(e)) {
for (let i of e) {
if (!(i in o))
throw new O(`Unknown type: ${i}`);
if (o[i](t))
return a();
}
r = `Expected one of: ${e.join(", ")}`;
} else {
if (!(e in o))
throw new O(`Unknown type: ${e}`);
o[e](t) || (r = `Expected ${e}`);
}
return r ? c(n, "type", r, t) : a();
};
var W = ({ const: e }, t, n = {}) => {
let r = JSON.stringify(x(e)), o = JSON.stringify(x(t));
return r !== o ? c(n, "const", `Expected const: ${r}`, o) : a();
};
var Y = ({ enum: e = [] }, t, n = {}) => {
let r = JSON.stringify(e.map(x)), o = JSON.stringify(x(t));
return r.includes(o) ? a() : c(n, "enum", `Expected enum: ${r}`, t);
};
function $(e, t, n = {}) {
return e.map((r) => r.validate(t, j(n)).valid ? r : undefined).filter(Boolean);
}
var Z = ({ anyOf: e = [] }, t, n = {}) => $(e, t, n).length > 0 ? a() : c(n, "anyOf", "Expected at least one to match", t);
var G = ({ oneOf: e = [] }, t, n = {}) => $(e, t).length === 1 ? a() : c(n, "oneOf", "Expected exactly one to match", t);
var Q = ({ allOf: e = [] }, t, n = {}) => $(e, t, n).length === e.length ? a() : c(n, "allOf", "Expected all to match", t);
var X = ({ not: e }, t, n = {}) => d(e) && e.validate(t, n).valid ? c(n, "not", "Expected not to match", t) : a();
var ee = ({ if: e, then: t, else: n }, r, o = {}) => {
if (e && (t || n)) {
if (e.validate(r, j(o)).valid)
return t ? t.validate(r, j(o)) : a();
if (n)
return n.validate(r, j(o));
}
return a();
};
var te = ({ pattern: e = "" }, t, n = {}) => l(t) ? new RegExp(e, "u").test(t) ? a() : c(n, "pattern", `Expected string matching pattern ${e}`, t) : a();
var ne = ({ minLength: e = 0 }, t, n = {}) => l(t) ? [...x(t)].length >= e ? a() : c(n, "minLength", `Expected string with minimum length of ${e}`, t) : a();
var re = ({ maxLength: e = 0 }, t, n = {}) => l(t) ? [...x(t)].length <= e ? a() : c(n, "maxLength", `Expected string with maximum length of ${e}`, t) : a();
var oe = ({ multipleOf: e = 0 }, t, n = {}) => {
if (!h(t))
return a();
if (!(Number.isFinite(t) && Number.isFinite(e)) || e <= 0)
throw new O("number");
let r = t / e, o = Number.EPSILON * Math.max(1, Math.abs(r));
return Math.abs(r - Math.round(r)) <= o ? a() : c(n, "multipleOf", `Expected number being a multiple of ${e}`, t);
};
var ie = ({ maximum: e = 0 }, t, n = {}) => !h(t) || t <= e ? a() : c(n, "maximum", `Expected number less than or equal to ${e}`, t);
var ae = ({ exclusiveMaximum: e = 0 }, t, n = {}) => !h(t) || t < e ? a() : c(n, "exclusiveMaximum", `Expected number less than ${e}`, t);
var se = ({ minimum: e = 0 }, t, n = {}) => !h(t) || t >= e ? a() : c(n, "minimum", `Expected number greater than or equal to ${e}`, t);
var ce = ({ exclusiveMinimum: e = 0 }, t, n = {}) => !h(t) || t > e ? a() : c(n, "exclusiveMinimum", `Expected number greater than ${e}`, t);
var me = ({ properties: e = {} }, t, n = {}) => {
if (!p(t))
return a();
for (let [r, o] of Object.entries(t)) {
let i = e[r];
if (!d(i))
continue;
let s = i.validate(o, w(n, ["properties", r], r));
if (!s.valid)
return s;
}
return a();
};
var pe = ({ properties: e = {}, additionalProperties: t, patternProperties: n }, r, o = {}) => {
if (!p(r))
return a();
if (!d(t))
throw new O("additionalProperties must be a boolean or a managed schema");
let i = Object.keys(e), s = p(n) ? Object.keys(r).filter((u) => Object.keys(n).some((S) => new RegExp(S).test(u))) : [], f = Object.keys(r).filter((u) => !i.includes(u) && !s.includes(u));
if (f.length > 0) {
if (K(t))
return t.validate(undefined);
if (d(t))
for (let u of f) {
let S = t.validate(r[u], w(o, ["additionalProperties"], u));
if (!S.valid)
return S;
}
}
return a();
};
var fe = ({ dependentRequired: e }, t, n = {}) => {
if (!p(t))
return a();
let r = Object.keys(t).filter((o) => typeof t[o] != "function");
if (p(e)) {
for (let [o, i] of Object.entries(e))
if (r.includes(o)) {
for (let s of i)
if (!r.includes(s))
return c(n, "dependentRequired", `Expected dependent required property ${s}`, t);
}
}
return a();
};
var ue = ({ required: e = [] }, t, n = {}) => {
if (!p(t))
return a();
let r = Object.keys(t).filter((o) => typeof t[o] != "function");
return e.every((o) => r.includes(o)) ? a() : c(n, "required", `Expected object with required properties ${e.join(", ")}`, t);
};
var de = ({ dependentSchemas: e }, t, n = {}) => {
if (!p(t))
return a();
let r = Object.keys(t).filter((o) => typeof t[o] != "function");
if (p(e)) {
for (let [o, i] of Object.entries(e))
if (r.includes(o)) {
let s = i.validate(t, n);
if (!s.valid)
return s;
}
}
return a();
};
var le = ({ minProperties: e = 0 }, t, n = {}) => p(t) ? Object.keys(t).length >= e ? a() : c(n, "minProperties", `Expected object with at least ${e} properties`, t) : a();
var he = ({ maxProperties: e = 0 }, t, n = {}) => !p(t) || Object.keys(t).length <= e ? a() : c(n, "maxProperties", `Expected object with at most ${e} properties`, t);
var ye = ({ patternProperties: e = {} }, t, n = {}) => {
if (!p(t))
return a();
if (!p(e))
throw new O("patternProperties must be an object");
for (let [r, o] of Object.entries(t))
for (let [i, s] of Object.entries(e))
if (new RegExp(i, "u").test(r)) {
let f = s.validate(o, w(n, ["patternProperties"], r));
if (!f.valid)
return f;
}
return a();
};
var Se = ({ propertyNames: e }, t, n = {}) => {
if (!p(t) || e === undefined)
return a();
if (!d(e))
throw new O("propertyNames must be a managed schema");
for (let r of Object.keys(t)) {
let o = e.validate(r, w(n, ["propertyNames"], r));
if (!o.valid)
return o;
}
return a();
};
var Te = ({ items: e, prefixItems: t = [] }, n, r = {}) => {
if (!y(n) || e === undefined)
return a();
if (!d(e))
throw new O("items must be a managed schema");
for (let [o, i] of n.slice(t.length).entries()) {
let s = e.validate(i, w(r, ["items"], String(o)));
if (!s.valid)
return s;
}
return a();
};
var Oe = ({ minItems: e = 0 }, t, n = {}) => !y(t) || t.length >= e ? a() : c(n, "minItems", `Expected array with at least ${e} items`, t);
var xe = ({ maxItems: e = 0 }, t, n = {}) => !y(t) || t.length <= e ? a() : c(n, "maxItems", `Expected array with at most ${e} items`, t);
var be = ({ uniqueItems: e = false }, t, n = {}) => {
if (!y(t) || !e)
return a();
let r = t.map(x);
return new Set(r.map((o) => JSON.stringify(o))).size === t.length ? a() : c(n, "uniqueItems", "Expected array with unique items", t);
};
var ge = ({ contains: e, minContains: t, maxContains: n }, r, o = {}) => {
if (!d(e))
throw new Error("contains must be a managed schema");
if (!y(r))
return a();
let i = r.filter((s) => e.validate(s).valid).length;
return i < (t ?? 1) ? c(o, t ? "minContains" : "contains", `Expected array to contain at least ${t ?? 1}, but found ${i}`, r) : n !== undefined && i > n ? c(o, "maxContains", `Expected array to contain at most ${n}, but found ${i}`, r) : a();
};
var we = ({ prefixItems: e = [] }, t, n = {}) => {
if (!y(t))
return a();
for (let r = 0;r < t.length; r++) {
let o = e[r]?.validate(t[r], w(n, String(r), String(r)));
if (o && o?.valid !== true)
return o;
}
return a();
};
var ke = { email: (e) => {
if (e.length > 318)
return false;
if (/^[a-z0-9!#$%&'*+/=?^_`{|}~-]{1,20}(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]{1,21}){0,2}@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,60}[a-z0-9])?){0,3}$/i.test(e))
return true;
if (!e.includes("@") || /(^\.|^"|\.@|\.\.)/.test(e))
return false;
let [n, r, ...o] = e.split("@");
return !n || !r || o.length !== 0 || n.length > 64 || r.length > 253 || !/^[a-z0-9.-]+$/i.test(r) || !/^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+$/i.test(n) ? false : r.split(".").every((i) => /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/i.test(i));
}, hostname: (e) => e.length > (e.endsWith(".") ? 254 : 253) ? false : /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*\.?$/i.test(e), date: (e) => {
if (e.length !== 10)
return false;
if (e[5] === "0" && e[6] === "2") {
if (/^\d\d\d\d-02-(?:[012][1-8]|[12]0|[01]9)$/.test(e))
return true;
let t = e.match(/^(\d\d\d\d)-02-29$/);
if (!t)
return false;
let n = Number(t[1]);
return n % 16 === 0 || n % 4 === 0 && n % 25 !== 0;
}
return e.endsWith("31") ? /^\d\d\d\d-(?:0[13578]|1[02])-31$/.test(e) : /^\d\d\d\d-(?:0[13-9]|1[012])-(?:[012][1-9]|[123]0)$/.test(e);
}, time: (e) => {
if (e.length > 27 || !/^(?:2[0-3]|[0-1]\d):[0-5]\d:(?:[0-5]\d|60)(?:\.\d+)?(?:z|[+-](?:2[0-3]|[0-1]\d)(?::?[0-5]\d)?)?$/i.test(e))
return false;
if (!/:60/.test(e))
return true;
let n = e.match(/([0-9.]+|[^0-9.])/g);
if (!n)
return false;
let r = Number(n[0]) * 60 + Number(n[2]);
return n[5] === "+" ? r += 24 * 60 - Number(n[6] || 0) * 60 - Number(n[8] || 0) : n[5] === "-" && (r += Number(n[6] || 0) * 60 + Number(n[8] || 0)), r % (24 * 60) === 23 * 60 + 59;
}, "date-time": (e) => {
if (e.length > 38)
return false;
let t = /^\d\d\d\d-(?:0[1-9]|1[0-2])-(?:[0-2]\d|3[01])[t\s](?:2[0-3]|[0-1]\d):[0-5]\d:(?:[0-5]\d|60)(?:\.\d+)?(?:z|[+-](?:2[0-3]|[0-1]\d)(?::?[0-5]\d)?)$/i, n = e[5] === "0" && e[6] === "2";
if (n && e[8] === "3" || !t.test(e))
return false;
if (e[17] === "6") {
let r = e.slice(11).match(/([0-9.]+|[^0-9.])/g);
if (!r)
return false;
let o = Number(r[0]) * 60 + Number(r[2]);
if (r[5] === "+" ? o += 24 * 60 - Number(r[6] || 0) * 60 - Number(r[8] || 0) : r[5] === "-" && (o += Number(r[6] || 0) * 60 + Number(r[8] || 0)), o % (24 * 60) !== 23 * 60 + 59)
return false;
}
if (n) {
if (/^\d\d\d\d-02-(?:[012][1-8]|[12]0|[01]9)/.test(e))
return true;
let r = e.match(/^(\d\d\d\d)-02-29/);
if (!r)
return false;
let o = Number(r[1] ?? 0);
return o % 16 === 0 || o % 4 === 0 && o % 25 !== 0;
}
return e[8] === "3" && e[9] === "1" ? /^\d\d\d\d-(?:0[13578]|1[02])-31/.test(e) : /^\d\d\d\d-(?:0[13-9]|1[012])-(?:[012][1-9]|[123]0)/.test(e);
}, ipv4: (e) => e.length <= 15 && /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d\d?)$/.test(e), ipv6: (e) => {
if (e.length > 45 || e.length < 2)
return false;
let t = 0, n = 0, r = 0, o = false, i = false, s = 0, f = true;
for (let S = 0;S < e.length; S++) {
let T = e.charCodeAt(S);
if (S === 1 && s === 58 && T !== 58)
return false;
if (T >= 48 && T <= 57) {
if (++r > 4)
return false;
} else if (T === 46) {
if (t > 6 || n >= 3 || r === 0 || i)
return false;
n++, r = 0;
} else if (T === 58) {
if (n > 0 || t >= 7)
return false;
if (s === 58) {
if (o)
return false;
o = true;
} else
S === 0 && (f = false);
t++, r = 0, i = false;
} else if (T >= 97 && T <= 102 || T >= 65 && T <= 70) {
if (n > 0 || ++r > 4)
return false;
i = true;
} else
return false;
s = T;
}
if (t < 2 || n > 0 && (n !== 3 || r === 0))
return false;
if (o && e.length === 2)
return true;
if (n > 0 && !/(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/.test(e))
return false;
let u = n > 0 ? 6 : 7;
return o ? (f || r > 0) && t < u : t === u && f && r > 0;
}, uri: (e) => /^[a-z][a-z0-9+\-.]*:(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|v[0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/?(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i.test(e), "uri-reference": (e) => /^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|v[0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/?(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?)?(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i.test(e), "uri-template": (e) => /^(?:[^\x00-\x20"'<>%\\^`{|}]|%[0-9a-f]{2}|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i.test(e), "json-pointer": (e) => /^(?:|\/(?:[^~]|~0|~1)*)$/.test(e), "relative-json-pointer": (e) => /^(?:0|[1-9][0-9]*)(?:|#|\/(?:[^~]|~0|~1)*)$/.test(e), uuid: (e) => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e), duration: (e) => e.length > 1 && e.length < 80 && (/^P\d+([.,]\d+)?W$/.test(e) || /^P[\dYMDTHS]*(\d[.,]\d+)?[YMDHS]$/.test(e) && /^P([.,\d]+Y)?([.,\d]+M)?([.,\d]+D)?(T([.,\d]+H)?([.,\d]+M)?([.,\d]+S)?)?$/.test(e)), regex: (e) => {
if (/[^\\]\\Z/.test(e))
return false;
try {
return new RegExp(e, "u"), true;
} catch {
return false;
}
} };
var $e = ({ format: e }, t, n = {}) => !l(t) || !e ? a() : ke[e] ? ke[e](t) ? a() : c(n, "format", `Expected format: ${e}`, t) : a();
var k = class {
constructor(t) {
this.root = t;
this.cache = new Map;
}
cache;
hasRef(t, n) {
return n !== undefined && "$ref" in t && l(t.$ref);
}
resolve(t) {
let n = this.cache.get(t);
if (!n) {
if (n = D(this.root, t), !d(n))
throw new Error(`ref not found: ${t}`);
if ("$ref" in n && n.$ref === t)
throw new Error(`ref loop: ${t}`);
this.cache.set(t, n);
}
return n;
}
};
var Be = { type: H, const: W, enum: Y, allOf: Q, anyOf: Z, oneOf: G, not: X, minLength: ne, maxLength: re, pattern: te, format: $e, minimum: se, exclusiveMinimum: ce, maximum: ie, exclusiveMaximum: ae, multipleOf: oe, required: ue, dependentRequired: fe, dependentSchemas: de, minProperties: le, maxProperties: he, propertyNames: Se, properties: me, patternProperties: ye, additionalProperties: pe, minItems: Oe, maxItems: xe, uniqueItems: be, contains: ge, prefixItems: we, items: Te, if: ee };
function Pe(e, t, n = {}) {
let r = { keywordPath: n.keywordPath || [], instancePath: n.instancePath || [], coerce: n.coerce || false, errors: n.errors || [], shortCircuit: n.shortCircuit || false, ignoreUnsupported: n.ignoreUnsupported || false, resolver: n.resolver || new k(e), depth: n.depth ? n.depth + 1 : 0 }, o = structuredClone(n?.coerce ? e.coerce(t, { resolver: r.resolver, depth: r.depth }) : t);
if (n.ignoreUnsupported !== true) {
let i = ["$defs"];
for (let s of i)
if (e[s])
throw new Error(`${s} not implemented`);
}
if (r.resolver.hasRef(e, o)) {
let i = r.resolver.resolve(e.$ref).validate(o, { ...r, errors: [] });
i.valid || r.errors.push(...i.errors);
} else
for (let [i, s] of Object.entries(Be)) {
if (e[i] === undefined)
continue;
let f = s(e, o, { ...r, errors: [] });
if (!f.valid) {
if (n.shortCircuit)
return f;
r.errors.push(...f.errors);
}
}
return { valid: r.errors.length === 0, errors: r.errors };
}
function Ce(e, t, n = {}) {
let r = structuredClone(t), o = { resolver: n.resolver || new k(e), depth: n.depth || 0 };
return o.resolver.hasRef(e, r) ? o.resolver.resolve(e.$ref).coerce(r, { ...o, depth: o.depth + 1 }) : r;
}
var m = (e = {}, t = "any") => {
let n = p(e) ? e : {}, r = g(e) ? e : (b in e) ? e[b] : undefined, o = { ...n, [C]: t, [b]: r, optional: function() {
return m({ ...this, validate: undefined, [b]: r, [A]: true }, t);
}, template: function(i = {}) {
if (n.const !== undefined)
return n.const;
if (n.default !== undefined)
return n.default;
if (n.enum !== undefined)
return n.enum[0];
if (n.template)
return n.template(i);
}, toJSON: function() {
let i = this[b];
return g(i) ? i : JSON.parse(JSON.stringify(n));
} };
return o.coerce = function(i, s = {}) {
let f = { ...s, resolver: s.resolver || new k(o), depth: s.depth ? s.depth + 1 : 0 }, u = i;
return "coerce" in n && n.coerce !== undefined ? n.coerce(u, f) : Ce(o, u, f);
}, o.validate = function(i, s = {}) {
if (g(r))
return r === false ? c(s, "", "Always fails") : a();
let f = s.errors || [];
if ("validate" in n && n.validate !== undefined) {
let u = n.validate(i, s);
u.valid || (f = [...f, ...u.errors]);
}
return Pe(o, i, { ...s, errors: f });
}, o;
};
var v = (e, t = {}) => {
for (let o of Object.keys(e || {}))
N(L(o), "invalid property name", o), N(d(e[o]), "properties must be managed schemas", e[o]);
let n = Object.entries(e || {}).filter(([, o]) => !(A in o)).map(([o]) => o), r = t.additionalProperties === false ? m(false) : t.additionalProperties;
return m({ template: Ae, coerce: Ne, ...t, additionalProperties: r, type: "object", properties: e, required: n.length > 0 ? n : undefined }, "object");
};
function Ae(e = {}) {
let t = {};
if (this.properties)
for (let [n, r] of Object.entries(this.properties)) {
if (e.withOptional !== true && !this.required?.includes(n))
continue;
let o = r.template(e);
o !== undefined && (t[n] = o);
}
return t;
}
function Ne(e, t = {}) {
let n = e;
if (typeof n == "string" && (n.match(/^\{/) || n.match(/^\[/)) && (n = JSON.parse(n)), !(typeof n != "object" || n === null)) {
if (this.properties)
for (let [r, o] of Object.entries(this.properties)) {
let i = n[r];
i !== undefined && (n[r] = o.coerce(i, t));
}
return n;
}
}
var B = (e = {}) => m({ template: () => "", coerce: (t) => h(t) ? String(t) : t, ...e, type: "string" }, "string");
var I = (e = {}) => m({ coerce: (t) => l(t) ? Number(t) : t, template: je, ...e, type: "number" }, "number");
var U = (e = {}) => m({ coerce: (t) => l(t) ? Number.parseInt(t) : t, template: je, ...e, type: "integer" }, "integer");
function je() {
if (this.minimum)
return this.minimum;
if (this.exclusiveMinimum) {
if (this.multipleOf) {
let e = this.exclusiveMinimum;
for (;e % this.multipleOf !== 0; )
e++;
return e;
}
return this.exclusiveMinimum + 1;
}
return 0;
}
var J = (e = {}) => m({ ...e, coerce: function(t) {
if ("coerce" in e && e.coerce)
return e.coerce(t);
if (l(t) && ["true", "false", "1", "0"].includes(t))
return t === "true" || t === "1";
if (h(t)) {
if (t === 1)
return true;
if (t === 0)
return false;
}
return t;
}, type: "boolean" }, "boolean");
// src/ComponentForIdentifier.ts
function ComponentForIdentifier(identifier, attributes, children) {
const component = identifier;
const id = attributes["id"];
const name = attributes["name"];
const namespace = attributes["namespace"];
const childrenArray = attributes["children"];
const min = attributes["min"];
const max = attributes["max"];
const required = attributes["required"];
const readonly = attributes["readonly"];
const disabled = attributes["disabled"];
let entry = {};
switch (component) {
case "page":
case "form":
case "section":
case "repeater":
case "header":
case "markdown": {
if (childrenArray || children)
entry = {
container: true,
children
};
break;
}
case "time": {
const validator = B({ format: "time" });
if (!required) {
validator.optional();
}
entry = {
[`${namespace}.${id}`]: validator
};
break;
}
case "select": {
const validator = B();
if (!required) {
validator.optional();
}
entry = {
[`${namespace}.${id}`]: validator
};
break;
}
case "radio":
case "checklist": {
const validator = B();
if (!required) {
validator.optional();
}
entry = {
[`${namespace}.${id}`]: validator
};
break;
}
case "currency": {
const validator = U();
if (!required) {
validator.optional();
}
entry = {
[`${namespace}.${id}`]: validator
};
break;
}
case "date": {
const validator = B({ format: "date" });
if (!required) {
validator.optional();
}
entry = {
[`${namespace}.${id}`]: validator
};
break;
}
case "phone": {
const validator = B({ maxLength: 15 });
if (!required) {
validator.optional();
}
entry = {
[`${namespace}.${id}`]: validator
};
break;
}
case "text": {
let string_options = {};
if (min) {
string_options = { min };
}
if (max) {
string_options = { ...string_options, max };
}
const validator = B();
if (!required) {
validator.optional();
}
entry = {
[`${namespace}.${id}`]: validator
};
break;
}
case "email": {
const validator = B({ format: "email" });
if (!required) {
validator.optional();
}
entry = {
[`${namespace}.${id}`]: validator
};
break;
}
case "textarea": {
const validator = B();
if (!required) {
validator.optional();
}
entry = {
[`${namespace}.${id}`]: validator
};
break;
}
case "checkbox": {
const validator = J();
if (!required) {
validator.optional();
}
entry = {
[`${namespace}.${id}`]: validator
};
break;
}
case "integer": {
let entry2 = U();
if (min) {
entry2 = entry2.min(min);
}
if (max) {
entry2 = entry2.max(max);
}
if (!required) {
entry2 = entry2.optional();
}
entry2 = {
[`${namespace}.${id}`]: entry2
};
break;
}
case "decimal": {
const validator = I();
if (!required) {
validator.optional();
}
entry = {
[`${namespace}.${id}`]: validator
};
break;
}
default: {
const validator = B();
if (!required) {
validator.optional();
}
entry = {
[`${namespace}.${id}`]: validator
};
console.warn(`Unknown component type: ${component}`);
break;
}
}
return entry;
}
// src/ToSpacedTitleCase.ts
function ToSpacedTitleCase(s) {
let words = [];
let word = "";
for (let character of s) {
if (character == " " || character == "_" || character == "-") {
words.push(word);
word = "";
} else if (character >= "0" && character <= "9") {
const last_character = word[word.length - 1];
if (last_character == undefined) {
word = character;
} else if (last_character >= "0" && last_character <= "9") {
word += character;
} else {
words.push(word);
word = character;
}
} else if (character == character.toUpperCase()) {
if (word != "") {
words.push(word);
}
word = character;
} else {
word += character;
}
}
if (word != "") {
words.push(word);
}
words = words.map((word2) => {
if (word2 == "") {
return "";
}
let result = word2.toLowerCase() || word2;
return result[0]?.toUpperCase() + result.slice(1);
});
return words.join(" ");
}
// src/EvaluateToSchema.ts
class EvaluateToSchema {
namespace = {};
name_stack = [];
visitCheckListExpr(checklist) {
const identifier = checklist.identifier.accept(this);
const attributes = checklist.attributes.map((attribute) => {
const name = attribute.left.name;
let right = attribute.right.value.literal;
if (!right) {
right = attribute.right.value.lexeme == "true";
}
return { [name]: right };
});
const attributes_merged = this.ProcessControlAttributes(attributes, identifier, checklist.line_number);
const children = checklist.children.map((child_expr) => {
const child = child_expr.accept(this);
const name = child.literal;
return { name };
}).map((x2) => {
return `"${x2.name}"`;
});
return ComponentForIdentifier(identifier, attributes_merged, "");
}
visitAttributeExpr(attribute) {
return attribute.accept(this);
}
visitControlExpr(control) {
const identifier = control.identifier.accept(this);
const attributes = control.attributes.map((attribute) => {
const name = attribute.left.name;
let right = attribute.right.value.literal;
if (!right) {
right = attribute.right.value.lexeme == "true";
}
return { [name]: right };
});
const attributes_merged = this.ProcessControlAttributes(attributes, identifier, control.line_number);
return ComponentForIdentifier(identifier, attributes_merged, "");
}
visitIdentifierExpr(identifier) {
const ident = identifier;
return ident.name;
}
visitContainerExpr(container) {
const identifier = container.identifier.accept(this);
const attributes = container.attributes.map((attribute) => {
const name = attribute.left.name;
let right = attribute.right.value.literal;
if (!right) {
right = attribute.right.value.lexeme == "true";
}
return { [name]: right };
});
let attributes_merged = {};
if (attributes.length > 0) {
attributes_merged = attributes.reduce((acc, curr) => {
return { ...acc, ...curr };
});
}
const id = attributes_merged["id"];
if (id) {
if (identifier == "repeater") {
this.name_stack.push(`${id}[]`);
} else {
this.name_stack.push(id);
}
}
const children = container.children.map((child) => {
return child.accept(this);
});
this.name_stack.pop();
return ComponentForIdentifier(identifier, attributes_merged, children);
}
visitLiteralExpr(literal) {
return literal.value;
}
visitMarkdownExpr(markdown) {
return {};
}
visitSelectExpr(select) {
const identifier = select.identifier.accept(this);
const attributes = select.attributes.map((attribute) => {
const name = attribute.left.name;
let right = attribute.right.value.literal;
if (!right) {
right = attribute.right.value.lexeme == "true";
}
return { [name]: right };
});
const attributes_merged = this.ProcessControlAttributes(attributes, identifier, select.line_number);
const children = select.children.map((child_expr) => {
const child = child_expr.accept(this);
const name = child.literal;
return { name };
}).join("");
return ComponentForIdentifier(identifier, attributes_merged, children);
}
visitRadioExpr(radio) {
const identifier = radio.identifier.accept(this);
const attributes = radio.attributes.map((attribute) => {
const name = attribute.left.name;
let right = attribute.right.value.literal;
if (!right) {
right = attribute.right.value.lexeme == "true";
}
return { [name]: right };
});
const attributes_merged = this.ProcessControlAttributes(attributes, identifier, radio.line_number);
const children = radio.children.map((chil