@senchou/core
Version:
Generate TypeScript for Kubernetes resources.
1,561 lines • 442 kB
JavaScript
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
import os from "os";
import path from "path";
import { execSync } from "child_process";
import { mkdtemp, writeFile } from "fs/promises";
import littlelog from "@littlethings/log";
import https from "https";
var __defProp2 = Object.defineProperty;
var __getOwnPropSymbols2 = Object.getOwnPropertySymbols;
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
var __propIsEnum2 = Object.prototype.propertyIsEnumerable;
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues2 = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp2.call(b, prop))
__defNormalProp2(a, prop, b[prop]);
if (__getOwnPropSymbols2)
for (var prop of __getOwnPropSymbols2(b)) {
if (__propIsEnum2.call(b, prop))
__defNormalProp2(a, prop, b[prop]);
}
return a;
};
class Coder$1 {
constructor(options = {}) {
this.code = "";
this.currentIndent = 0;
this.indentChar = " ";
this.indentAmount = 1;
if (options == null ? void 0 : options.indentChar) {
this.indentChar = options.indentChar;
}
if (options == null ? void 0 : options.indentAmount) {
this.indentAmount = options.indentAmount;
}
}
getIndentText() {
let text = "";
for (let i = 0; i < this.currentIndent * this.indentAmount; i++) {
text += this.indentChar;
}
return text;
}
reset() {
this.code = "";
this.currentIndent = 0;
}
line(text) {
if (text === void 0) {
this.code += "\n";
} else {
this.code += this.getIndentText() + text + "\n";
}
}
indent() {
this.currentIndent++;
}
dedent() {
this.currentIndent--;
if (this.indentAmount < 0) {
this.indentAmount = 0;
}
}
openBlock(prefix = "") {
this.line(prefix + " {");
this.indent();
}
closeBlock(suffix = "") {
this.dedent();
this.line(`}${suffix}`);
}
}
var camelcase$1 = { exports: {} };
const UPPERCASE = /[\p{Lu}]/u;
const LOWERCASE = /[\p{Ll}]/u;
const LEADING_CAPITAL = /^[\p{Lu}](?![\p{Lu}])/gu;
const IDENTIFIER = /([\p{Alpha}\p{N}_]|$)/u;
const SEPARATORS = /[_.\- ]+/;
const LEADING_SEPARATORS = new RegExp("^" + SEPARATORS.source);
const SEPARATORS_AND_IDENTIFIER = new RegExp(SEPARATORS.source + IDENTIFIER.source, "gu");
const NUMBERS_AND_IDENTIFIER = new RegExp("\\d+" + IDENTIFIER.source, "gu");
const preserveCamelCase = (string, toLowerCase, toUpperCase) => {
let isLastCharLower = false;
let isLastCharUpper = false;
let isLastLastCharUpper = false;
for (let i = 0; i < string.length; i++) {
const character = string[i];
if (isLastCharLower && UPPERCASE.test(character)) {
string = string.slice(0, i) + "-" + string.slice(i);
isLastCharLower = false;
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper = true;
i++;
} else if (isLastCharUpper && isLastLastCharUpper && LOWERCASE.test(character)) {
string = string.slice(0, i - 1) + "-" + string.slice(i - 1);
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper = false;
isLastCharLower = true;
} else {
isLastCharLower = toLowerCase(character) === character && toUpperCase(character) !== character;
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper = toUpperCase(character) === character && toLowerCase(character) !== character;
}
}
return string;
};
const preserveConsecutiveUppercase = (input, toLowerCase) => {
LEADING_CAPITAL.lastIndex = 0;
return input.replace(LEADING_CAPITAL, (m1) => toLowerCase(m1));
};
const postProcess = (input, toUpperCase) => {
SEPARATORS_AND_IDENTIFIER.lastIndex = 0;
NUMBERS_AND_IDENTIFIER.lastIndex = 0;
return input.replace(SEPARATORS_AND_IDENTIFIER, (_, identifier) => toUpperCase(identifier)).replace(NUMBERS_AND_IDENTIFIER, (m) => toUpperCase(m));
};
const camelCase = (input, options) => {
if (!(typeof input === "string" || Array.isArray(input))) {
throw new TypeError("Expected the input to be `string | string[]`");
}
options = __spreadValues2({
pascalCase: false,
preserveConsecutiveUppercase: false
}, options);
if (Array.isArray(input)) {
input = input.map((x) => x.trim()).filter((x) => x.length).join("-");
} else {
input = input.trim();
}
if (input.length === 0) {
return "";
}
const toLowerCase = options.locale === false ? (string) => string.toLowerCase() : (string) => string.toLocaleLowerCase(options.locale);
const toUpperCase = options.locale === false ? (string) => string.toUpperCase() : (string) => string.toLocaleUpperCase(options.locale);
if (input.length === 1) {
return options.pascalCase ? toUpperCase(input) : toLowerCase(input);
}
const hasUpperCase = input !== toLowerCase(input);
if (hasUpperCase) {
input = preserveCamelCase(input, toLowerCase, toUpperCase);
}
input = input.replace(LEADING_SEPARATORS, "");
if (options.preserveConsecutiveUppercase) {
input = preserveConsecutiveUppercase(input, toLowerCase);
} else {
input = toLowerCase(input);
}
if (options.pascalCase) {
input = toUpperCase(input.charAt(0)) + input.slice(1);
}
return postProcess(input, toUpperCase);
};
camelcase$1.exports = camelCase;
camelcase$1.exports.default = camelCase;
var camelcase = camelcase$1.exports;
const camel = (input) => {
return camelcase(input, {
preserveConsecutiveUppercase: true
});
};
const pascal = (input) => {
return camelcase(input, {
pascalCase: true,
preserveConsecutiveUppercase: true
});
};
const normalize = (name) => {
return pascal(name);
};
const serialize$9 = (name) => {
return name.split(".").map(pascal).join("");
};
const serialize$8 = (identifier) => {
return identifier;
};
const serialize$7 = (identifier) => {
return `${identifier}?.toISOString()`;
};
const serialize$6 = (identifier) => {
return identifier;
};
const serialize$5 = (name) => (identifier) => {
return `serialize${name}(${identifier})`;
};
const serializer$1 = (type2) => (identifier) => {
return `prelude.serialize(${identifier}, items => items.map(item => ${type2.serialize("item")}).filter(prelude.isNotUndefined))`;
};
const serialize$4$1 = (type2) => (identifier) => {
return `((${identifier}) === undefined) ? undefined : (Object.entries(${identifier}).reduce((r, i) => (i[1] === undefined) ? r : ({ ...r, [i[0]]: ${type2.serialize("i[1]")} }), {}))`;
};
const serialize$3$1 = (identifier) => {
return identifier;
};
const serialize$2$1 = (identifier) => {
return identifier;
};
const serialize$1$1 = (identifier) => {
return identifier;
};
const serialize$a = (identifier) => {
return identifier;
};
var serializers$1 = /* @__PURE__ */ Object.freeze({
__proto__: null,
[Symbol.toStringTag]: "Module",
name: serialize$9,
union: serialize$8,
date: serialize$7,
"enum": serialize$6,
struct: serialize$5,
array: serializer$1,
map: serialize$4$1,
string: serialize$3$1,
boolean: serialize$2$1,
number: serialize$1$1,
any: serialize$a
});
const generate$3 = ({ coder, name, options }) => {
coder.line(`export type ${name} = ${options.join(" | ")};`);
coder.openBlock(`export const is${name} = (input: any): input is ${name} =>`);
const quotedOptions = options.map((option) => `"${option}"`);
coder.line(`return [${quotedOptions.join(", ")}].includes(typeof input);`);
coder.closeBlock(";");
};
const generate$2 = ({ coder, name, members }) => {
coder.openBlock(`export enum ${name}`);
for (const value of members) {
let member = pascal(value);
if (!/^[a-z].*/i.test(member)) {
member = "_" + member;
}
coder.line(`"${member}" = "${value}",`);
}
coder.closeBlock();
};
const isStruct = (schema2) => {
return schema2.hasOwnProperty("properties");
};
const isRequired = (schema2, name) => {
return Array.isArray(schema2.required) && schema2.required.includes(name);
};
const generate$1 = ({
coder,
name,
schema: schema2,
serializers: serializers2,
emit
}) => {
let additionalPropertiesType = null;
if (schema2.additionalProperties && typeof schema2.additionalProperties === "object") {
const additionalPropertiesTypeName = normalize(serializers2.name(`${name}.additionalProperties`));
additionalPropertiesType = emit(additionalPropertiesTypeName, schema2.additionalProperties);
}
const props = [];
for (const [propName, propSchema] of Object.entries(schema2.properties)) {
const propTypeName = normalize(serializers2.name(`${name}.${propName}`));
props.push({
name: propName,
safeName: camel(propName),
type: emit(propTypeName, propSchema),
required: isRequired(schema2, propName)
});
}
coder.openBlock(`export type ${name} =`);
for (const prop of props) {
coder.line(`readonly ${prop.safeName}${prop.required ? "" : "?"}: ${prop.type.type};`);
}
coder.closeBlock(additionalPropertiesType ? ` & Record<string, ${additionalPropertiesType.type}>;` : ";");
coder.line();
coder.openBlock(`export type Serialized${name} =`);
for (const prop of props) {
coder.line(`"${prop.name}"${prop.required ? "" : "?"}: ${prop.type.serializedType},`);
}
coder.closeBlock(additionalPropertiesType ? ` & Record<string, ${additionalPropertiesType.type}>` : ";");
coder.line();
coder.line(`export function serialize${name}(options: undefined): undefined;`);
coder.line(`export function serialize${name}(options: ${name}): Serialized${name};`);
coder.line(`export function serialize${name}(options: ${name} | undefined): Serialized${name} | undefined;`);
coder.openBlock(`export function serialize${name}(options: ${name} | undefined): Serialized${name} | undefined`);
coder.line("if (options === undefined) return undefined;");
if (additionalPropertiesType) {
coder.line(`const additionalPropertiesKeys = Object.keys(options).filter(key => ![${props.map((prop) => `"${prop.safeName}"`).join(", ")}].includes(key));`);
coder.line();
coder.line(`const additionalProperties: Record<string, any> = {};`);
coder.line();
coder.openBlock(`for (const key of additionalPropertiesKeys)`);
coder.line(`additionalProperties[key] = options[key];`);
coder.closeBlock();
coder.line();
}
coder.openBlock(`const result: Serialized${name} =`);
for (const prop of props) {
coder.line(`"${prop.name}": ${prop.type.serialize(`options.${prop.safeName}`)},`);
}
if (additionalPropertiesType) {
coder.line(`...(${additionalPropertiesType.serialize("additionalProperties")}),`);
}
coder.closeBlock(";");
coder.line();
coder.line("return result;");
coder.closeBlock();
};
const generate$4 = ({ coder, name, pattern }) => {
coder.line(`export type ${name} = string & { __type: "${name}" };`);
coder.openBlock(`export const is${name} = (input: string): input is ${name} =>`);
coder.line(`const regex = new RegExp("${pattern.replaceAll('"', '\\"')}");`);
coder.line(`return regex.test(input);`);
coder.closeBlock(";");
};
var generators$1 = /* @__PURE__ */ Object.freeze({
__proto__: null,
[Symbol.toStringTag]: "Module",
union: generate$3,
"enum": generate$2,
struct: generate$1,
pattern: generate$4
});
const isDate = (schema2) => {
return schema2.format === "date-time";
};
const isEnum = (schema2) => {
return Boolean(schema2.enum && Array.isArray(schema2.enum) && schema2.enum.length > 0 && schema2.enum.every((item) => typeof item === "string"));
};
const id = (x) => x;
const isMap = (schema2) => {
return schema2.hasOwnProperty("additionalProperties") && typeof schema2.additionalProperties === "object";
};
const DEFINITIONS_PREFIX = "#/definitions/";
const isRef = (schema2) => {
return schema2 && typeof schema2 === "object" && typeof schema2.$ref === "string";
};
const removeRefPrefix = (input) => {
return input.replace(DEFINITIONS_PREFIX, "");
};
const isUnion = (schema2) => {
return schema2.hasOwnProperty("anyOf") || schema2.hasOwnProperty("oneOf");
};
const VALID_UNION_OPTION_TYPES = [
"string",
"number",
"integer",
"boolean"
];
const isValidUnionOption = (option) => {
return option && option.type && typeof option.type === "string" && VALID_UNION_OPTION_TYPES.includes(option.type);
};
const getUnionOptions = (schema2) => {
return schema2.anyOf || schema2.oneOf || [];
};
const isPattern = (schema2) => {
return schema2 && schema2.type === "string" && typeof schema2.pattern === "string";
};
class Schemer {
constructor(options = {}) {
this.schemas = {};
this.emitters = {};
this.types = {};
this.serializers = __spreadValues2({}, serializers$1);
this.generators = __spreadValues2({}, generators$1);
if (options.schemas) {
this.schemas = options.schemas;
}
if (options.serializers) {
for (const [name, serializer2] of Object.entries(options.serializers)) {
this.serializers[name] = serializer2;
}
}
if (options.generators) {
for (const [name, generator] of Object.entries(options.generators)) {
this.generators[name] = generator;
}
}
}
render() {
const coder = new Coder$1();
coder.openBlock(`const prelude =`);
coder.line(`id: <T>(x: T) => x,`);
coder.line(`isNotUndefined: <T>(x: T | undefined): x is T => x !== undefined,`);
coder.openBlock(`serialize: <T, U>(x: T, f: (x: T extends undefined ? never : T) => U): T extends undefined ? undefined : U =>`);
coder.line(`// @ts-ignore`);
coder.line(`if (x === undefined) return undefined;`);
coder.line(`// @ts-ignore`);
coder.line(`return f(x);`);
coder.closeBlock(",");
coder.closeBlock(";");
coder.line();
while (Object.keys(this.emitters).length > 0) {
const key = Object.keys(this.emitters)[0];
const emitter = this.emitters[key];
const type2 = emitter(coder);
coder.line();
delete this.emitters[key];
if (type2) {
this.types[key] = type2;
}
}
return coder.code;
}
define(name, schema2) {
this.schemas[name] = schema2;
}
alias(source2, target) {
this.schemas[source2] = {
$ref: `${DEFINITIONS_PREFIX}${target}`
};
}
emit(name, schemaOrEmitter) {
if (typeof schemaOrEmitter === "function") {
if (this.types.hasOwnProperty(name)) {
return;
}
const emitter = schemaOrEmitter;
this.emitters[name] = (coder) => {
const result = emitter(coder);
if (result) {
return result;
} else {
return {
type: name,
serialize: id,
serializedType: name
};
}
};
} else {
if (normalize(name) !== name) {
throw new Error(`Name "${name}" must be normalized to "${normalize(name)}" before emitting.`);
}
const schema2 = schemaOrEmitter || this.schemas[name];
if (!schema2) {
throw new Error(`No schema found for "${name}".`);
}
if (isRef(schema2)) {
return this.ref(schema2);
}
if (isUnion(schema2)) {
const union = this.union(name, schema2);
if (union) {
return union;
}
}
if (isDate(schema2)) {
if (schema2.type && schema2.type !== "string") {
throw new Error(`Expected date-time type to be "string", but got "${schema2.type}".`);
}
return {
type: "Date",
serialize: this.serializers.date,
serializedType: "string"
};
}
if (isEnum(schema2)) {
if (schema2.type && schema2.type !== "string") {
throw new Error(`Expected enum type to be "string", but got "${schema2.type}".`);
}
return this.enum(name, schema2);
}
if (isStruct(schema2)) {
if (schema2.type && schema2.type !== "object") {
throw new Error(`Expected struct type to be "object", but got "${schema2.type}".`);
}
return this.struct(name, schema2);
}
if (isMap(schema2)) {
if (schema2.type && schema2.type !== "object") {
throw new Error(`Expected map type to be "object", but got "${schema2.type}".`);
}
const type2 = this.emit(name, schema2.additionalProperties);
return {
type: `{ [key: string]: ${type2.type} }`,
serialize: this.serializers.map(type2),
serializedType: `{ [key: string]: ${type2.type} }`
};
}
if (isPattern(schema2)) {
return this.pattern(name, schema2);
}
switch (schema2.type) {
case "string":
return {
type: "string",
serialize: this.serializers.string,
serializedType: "string"
};
case "number":
case "integer":
return {
type: "number",
serialize: this.serializers.number,
serializedType: "number"
};
case "boolean":
return {
type: "boolean",
serialize: this.serializers.boolean,
serializedType: "boolean"
};
case "array":
return this.array(name, schema2);
}
return {
type: "any",
serialize: this.serializers.any,
serializedType: "any"
};
}
}
ref(schema2) {
if (!schema2.$ref.startsWith(DEFINITIONS_PREFIX)) {
throw new Error(`Expected $ref to start with ${DEFINITIONS_PREFIX}, but got "${schema2.$ref}".`);
}
const unprefixedName = removeRefPrefix(schema2.$ref);
const serializedName = this.serializers.name(unprefixedName);
const name = normalize(serializedName);
if (this.types[name]) {
return this.types[name];
}
const resolvedSchema = this.schemas[unprefixedName];
if (!resolvedSchema) {
throw new Error(`Unable to resolve $ref for "${unprefixedName}".`);
}
return this.emit(name, resolvedSchema);
}
union(name, schema2) {
const options = [];
for (const option of getUnionOptions(schema2)) {
if (!isValidUnionOption(option)) {
return;
}
const type22 = option.type === "integer" ? "number" : option.type;
options.push(type22);
}
const type2 = {
type: name,
serialize: this.serializers.union,
serializedType: name
};
this.emit(name, (coder) => {
this.generators.union({
coder,
name,
options
});
return type2;
});
return type2;
}
enum(name, schema2) {
const type2 = {
type: name,
serialize: this.serializers.enum,
serializedType: name
};
this.emit(name, (coder) => {
this.generators.enum({
coder,
name,
members: schema2.enum
});
return type2;
});
return type2;
}
struct(name, schema2) {
const type2 = {
type: name,
serialize: this.serializers.struct(name),
serializedType: `Serialized${name}`
};
this.emit(name, (coder) => {
this.generators.struct({
coder,
name,
schema: schema2,
serializers: this.serializers,
emit: this.emit.bind(this)
});
return type2;
});
return type2;
}
array(name, schema2) {
var _a, _b;
if ((!schema2.hasOwnProperty("items") || typeof schema2.items !== "object") && (!schema2.hasOwnProperty("additionalItems") || typeof schema2.additionalItems !== "object")) {
throw new Error(`Expected array items to be "object", but got "${typeof ((_a = schema2.items) != null ? _a : schema2.additionalItems)}".`);
}
const type2 = this.emit(name, (_b = schema2.additionalItems) != null ? _b : schema2.items);
return {
type: `Array<${type2.type}>`,
serialize: this.serializers.array(type2),
serializedType: `Array<${type2.serializedType}>`
};
}
pattern(name, schema2) {
const type2 = {
type: name,
serialize: id,
serializedType: name
};
this.emit(name, (coder) => {
this.generators.pattern({
coder,
name,
pattern: schema2.pattern
});
return type2;
});
return type2;
}
}
const X_KUBERNETES_GROUP_VERSION_KIND = "x-kubernetes-group-version-kind";
const getObjectName = (schema2) => {
var _a;
const names = schema2[X_KUBERNETES_GROUP_VERSION_KIND];
if (!names) {
return null;
}
const [name] = names;
if (!name) {
return null;
}
if (!((_a = schema2.properties) == null ? void 0 : _a.metadata)) {
return null;
}
return name;
};
var APILevel = /* @__PURE__ */ ((APILevel2) => {
APILevel2["Stable"] = "stable";
APILevel2["Alpha"] = "alpha";
APILevel2["Beta"] = "beta";
return APILevel2;
})(APILevel || {});
const VERSION_REGEX = /^v(?<major>[0-9]+)((?<level>[a-z]+)(?<minor>[0-9]+))?$/;
const parseAPIName = (fullName) => {
var _a, _b;
const parts = fullName.split(".");
const kind = parts[parts.length - 1];
const namespace = parts.slice(0, parts.length - 2).join("");
const version = parts[parts.length - 2];
const match = VERSION_REGEX.exec(version);
const result = {
fullName,
kind,
namespace: match ? namespace : `${namespace}.${version}`,
version: match ? {
raw: match[0],
major: parseInt(match.groups.major),
minor: parseInt((_a = match.groups.minor) != null ? _a : "0"),
level: (_b = match.groups.level) != null ? _b : APILevel.Stable
} : null
};
return result;
};
const getTypeName = (fullName, isCustom = false) => {
const { kind, version } = parseAPIName(fullName);
if (!version || isCustom || version.raw === "v1") {
return kind;
}
return `${kind}${pascal(version.raw)}`;
};
const emitApiObject = (apiObject, schemer) => {
const name = getTypeName(apiObject.fullName);
if (apiObject.custom) {
schemer.emit("OwnerReference", {
type: "object",
required: ["apiVersion", "kind", "name", "uid"],
properties: {
apiVersion: {
type: "string"
},
kind: {
type: "string"
},
name: {
type: "string"
},
uid: {
type: "string"
},
controller: {
type: "boolean"
},
blockOwnerDeletion: {
type: "boolean"
}
}
});
schemer.emit("ApiObjectMetadata", {
type: "object",
additionalProperties: {},
properties: {
name: {
type: "string"
},
namespace: {
type: "string"
},
annotations: {
type: "object",
additionalProperties: {
type: "string"
}
},
labels: {
type: "object",
additionalProperties: {
type: "string"
}
},
finalizers: {
type: "array",
additionalItems: {
type: "string"
}
},
ownerReferences: {
type: "array",
additionalItems: {
$ref: "#/definitions/OwnerReference"
}
}
}
});
}
schemer.emit(name, (coder) => {
const createPropsSchema = () => {
var _a;
const schemaCopy = __spreadProps(__spreadValues({}, apiObject.schema), {
required: (_a = apiObject.schema.required) != null ? _a : [],
properties: apiObject.schema.properties || {}
});
delete schemaCopy[X_KUBERNETES_GROUP_VERSION_KIND];
const props = schemaCopy.properties;
delete props.apiVersion;
delete props.kind;
delete props.status;
if (Array.isArray(schemaCopy.required)) {
schemaCopy.required = schemaCopy.required.filter((name2) => name2 !== "apiVersion" && name2 !== "kind" && name2 !== "status");
}
if (apiObject.custom) {
schemaCopy.properties.metadata = {
$ref: "#/definitions/ApiObjectMetadata"
};
}
return schemaCopy;
};
const emitProps = () => {
return schemer.emit(normalize(`${name}Props`), createPropsSchema());
};
const propsTypeName = emitProps();
const hasRequired = apiObject.schema.required && Array.isArray(apiObject.schema.required) && apiObject.schema.required.length > 0;
const defaultProps = hasRequired ? "" : " = {}";
const emit = () => {
var _a, _b;
const apiVersion = `${apiObject.group ? `${apiObject.group}/` : ""}${apiObject.version}`;
coder.openBlock(`export type Serialized${name} =`);
coder.line(`apiVersion: "${apiObject.group ? `${apiObject.group}/` : ""}${apiObject.version}";`);
coder.line(`kind: "${apiObject.kind}";`);
coder.closeBlock(` & ${propsTypeName.serializedType};`);
coder.openBlock(`export const is${name} = (input: any): input is Serialized${name} =>`);
coder.line(`return (`);
coder.indent();
coder.line(`typeof input === "object" && `);
coder.line(`input !== null &&`);
coder.line(`input.apiVersion === "${apiVersion}" &&`);
coder.line(`input.kind === "${apiObject.kind}"`);
coder.dedent();
coder.line(`);`);
coder.closeBlock(";");
coder.line("/**");
coder.line(` * ${(_b = (_a = apiObject.schema) == null ? void 0 : _a.description) != null ? _b : ""}`);
coder.line(" *");
coder.line(` * @schema ${apiObject.fullName}`);
coder.line(" */");
coder.openBlock(`export const ${name} = (props: ${propsTypeName.type}${defaultProps}) =>`);
coder.openBlock("return senchou.wrapTemplate(props,");
coder.indent();
coder.line(`apiVersion: "${apiVersion}" as const,`);
coder.line(`kind: "${apiObject.kind}" as const,`);
coder.line(`...serialize${propsTypeName.type}(props),`);
coder.dedent();
coder.closeBlock(");");
coder.closeBlock();
};
emit();
return {
type: propsTypeName.type,
serialize: (identifier) => `${name}(${identifier})`,
serializedType: `Serialized${name}`
};
});
};
class Coder {
constructor(options = {}) {
this.code = "";
this.currentIndent = 0;
this.indentChar = " ";
this.indentAmount = 1;
if (options == null ? void 0 : options.indentChar) {
this.indentChar = options.indentChar;
}
if (options == null ? void 0 : options.indentAmount) {
this.indentAmount = options.indentAmount;
}
}
getIndentText() {
let text = "";
for (let i = 0; i < this.currentIndent * this.indentAmount; i++) {
text += this.indentChar;
}
return text;
}
reset() {
this.code = "";
this.currentIndent = 0;
}
line(text) {
if (text === void 0) {
this.code += "\n";
} else {
this.code += this.getIndentText() + text + "\n";
}
}
indent() {
this.currentIndent++;
}
dedent() {
this.currentIndent--;
if (this.indentAmount < 0) {
this.indentAmount = 0;
}
}
openBlock(prefix = "") {
this.line(prefix + " {");
this.indent();
}
closeBlock(suffix = "") {
this.dedent();
this.line(`}${suffix}`);
}
}
const render = () => {
const coder = new Coder();
coder.openBlock("const senchou =");
coder.openBlock("wrapTemplate: <T, U>(x: T, y: U): U =>");
coder.line("type MaybeTemplate = { __templateType?: string; __data?: object; };");
coder.line("const xTemplate = x as unknown as MaybeTemplate");
coder.line("const yTemplate = y as unknown as MaybeTemplate");
coder.openBlock("if (x && y && xTemplate.__templateType !== undefined)");
coder.openBlock(`Object.defineProperty(yTemplate, "__templateType", `);
coder.line("value: xTemplate.__templateType,");
coder.line("enumerable: false,");
coder.line("configurable: true,");
coder.line("writable: true,");
coder.closeBlock(");");
coder.openBlock(`Object.defineProperty(yTemplate, "__data", `);
coder.line("value: xTemplate.__data,");
coder.line("enumerable: false,");
coder.line("configurable: true,");
coder.line("writable: true,");
coder.closeBlock(");");
coder.closeBlock();
coder.line("return y");
coder.closeBlock(",");
coder.closeBlock(";");
return coder.code;
};
const source$3 = {
generate: (crd) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
const crds = Array.isArray(crd) ? crd : [crd];
const sorted = crds.sort((a, b) => {
var _a2, _b2, _c2, _d2;
const nameA = `${(_a2 = a.spec) == null ? void 0 : _a2.group}/${(_b2 = a.spec) == null ? void 0 : _b2.names.kind}`.toLocaleLowerCase();
const nameB = `${(_c2 = b.spec) == null ? void 0 : _c2.group}/${(_d2 = b.spec) == null ? void 0 : _d2.names.kind}`.toLocaleLowerCase();
return nameA.localeCompare(nameB);
});
const schemer = new Schemer();
for (const crd2 of sorted) {
const version = (_d = (_a = crd2.spec) == null ? void 0 : _a.version) != null ? _d : (_c = (_b = crd2.spec) == null ? void 0 : _b.versions) == null ? void 0 : _c[0];
emitApiObject({
custom: true,
fullName: (_e = crd2.spec) == null ? void 0 : _e.names.kind,
group: (_f = crd2.spec) == null ? void 0 : _f.group,
kind: (_g = crd2.spec) == null ? void 0 : _g.names.kind,
version: typeof version === "string" ? version : version == null ? void 0 : version.name,
schema: typeof version === "string" ? (_i = (_h = crd2.spec) == null ? void 0 : _h.validation) == null ? void 0 : _i.openAPIV3Schema : (_m = (_j = version == null ? void 0 : version.schema) == null ? void 0 : _j.openAPIV3Schema) != null ? _m : (_l = (_k = crd2.spec) == null ? void 0 : _k.validation) == null ? void 0 : _l.openAPIV3Schema
}, schemer);
}
return render() + schemer.render();
}
};
/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */
function isNothing(subject) {
return typeof subject === "undefined" || subject === null;
}
function isObject(subject) {
return typeof subject === "object" && subject !== null;
}
function toArray(sequence) {
if (Array.isArray(sequence))
return sequence;
else if (isNothing(sequence))
return [];
return [sequence];
}
function extend(target, source2) {
var index, length, key, sourceKeys;
if (source2) {
sourceKeys = Object.keys(source2);
for (index = 0, length = sourceKeys.length; index < length; index += 1) {
key = sourceKeys[index];
target[key] = source2[key];
}
}
return target;
}
function repeat(string, count) {
var result = "", cycle;
for (cycle = 0; cycle < count; cycle += 1) {
result += string;
}
return result;
}
function isNegativeZero(number) {
return number === 0 && Number.NEGATIVE_INFINITY === 1 / number;
}
var isNothing_1 = isNothing;
var isObject_1 = isObject;
var toArray_1 = toArray;
var repeat_1 = repeat;
var isNegativeZero_1 = isNegativeZero;
var extend_1 = extend;
var common = {
isNothing: isNothing_1,
isObject: isObject_1,
toArray: toArray_1,
repeat: repeat_1,
isNegativeZero: isNegativeZero_1,
extend: extend_1
};
function formatError(exception2, compact) {
var where = "", message = exception2.reason || "(unknown reason)";
if (!exception2.mark)
return message;
if (exception2.mark.name) {
where += 'in "' + exception2.mark.name + '" ';
}
where += "(" + (exception2.mark.line + 1) + ":" + (exception2.mark.column + 1) + ")";
if (!compact && exception2.mark.snippet) {
where += "\n\n" + exception2.mark.snippet;
}
return message + " " + where;
}
function YAMLException$1(reason, mark) {
Error.call(this);
this.name = "YAMLException";
this.reason = reason;
this.mark = mark;
this.message = formatError(this, false);
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
} else {
this.stack = new Error().stack || "";
}
}
YAMLException$1.prototype = Object.create(Error.prototype);
YAMLException$1.prototype.constructor = YAMLException$1;
YAMLException$1.prototype.toString = function toString(compact) {
return this.name + ": " + formatError(this, compact);
};
var exception = YAMLException$1;
function getLine(buffer, lineStart, lineEnd, position, maxLineLength) {
var head = "";
var tail = "";
var maxHalfLength = Math.floor(maxLineLength / 2) - 1;
if (position - lineStart > maxHalfLength) {
head = " ... ";
lineStart = position - maxHalfLength + head.length;
}
if (lineEnd - position > maxHalfLength) {
tail = " ...";
lineEnd = position + maxHalfLength - tail.length;
}
return {
str: head + buffer.slice(lineStart, lineEnd).replace(/\t/g, "\u2192") + tail,
pos: position - lineStart + head.length
};
}
function padStart(string, max) {
return common.repeat(" ", max - string.length) + string;
}
function makeSnippet(mark, options) {
options = Object.create(options || null);
if (!mark.buffer)
return null;
if (!options.maxLength)
options.maxLength = 79;
if (typeof options.indent !== "number")
options.indent = 1;
if (typeof options.linesBefore !== "number")
options.linesBefore = 3;
if (typeof options.linesAfter !== "number")
options.linesAfter = 2;
var re = /\r?\n|\r|\0/g;
var lineStarts = [0];
var lineEnds = [];
var match;
var foundLineNo = -1;
while (match = re.exec(mark.buffer)) {
lineEnds.push(match.index);
lineStarts.push(match.index + match[0].length);
if (mark.position <= match.index && foundLineNo < 0) {
foundLineNo = lineStarts.length - 2;
}
}
if (foundLineNo < 0)
foundLineNo = lineStarts.length - 1;
var result = "", i, line;
var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;
var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);
for (i = 1; i <= options.linesBefore; i++) {
if (foundLineNo - i < 0)
break;
line = getLine(mark.buffer, lineStarts[foundLineNo - i], lineEnds[foundLineNo - i], mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]), maxLineLength);
result = common.repeat(" ", options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) + " | " + line.str + "\n" + result;
}
line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);
result += common.repeat(" ", options.indent) + padStart((mark.line + 1).toString(), lineNoLength) + " | " + line.str + "\n";
result += common.repeat("-", options.indent + lineNoLength + 3 + line.pos) + "^\n";
for (i = 1; i <= options.linesAfter; i++) {
if (foundLineNo + i >= lineEnds.length)
break;
line = getLine(mark.buffer, lineStarts[foundLineNo + i], lineEnds[foundLineNo + i], mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]), maxLineLength);
result += common.repeat(" ", options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) + " | " + line.str + "\n";
}
return result.replace(/\n$/, "");
}
var snippet = makeSnippet;
var TYPE_CONSTRUCTOR_OPTIONS = [
"kind",
"multi",
"resolve",
"construct",
"instanceOf",
"predicate",
"represent",
"representName",
"defaultStyle",
"styleAliases"
];
var YAML_NODE_KINDS = [
"scalar",
"sequence",
"mapping"
];
function compileStyleAliases(map2) {
var result = {};
if (map2 !== null) {
Object.keys(map2).forEach(function(style) {
map2[style].forEach(function(alias) {
result[String(alias)] = style;
});
});
}
return result;
}
function Type$1(tag, options) {
options = options || {};
Object.keys(options).forEach(function(name) {
if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {
throw new exception('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.');
}
});
this.options = options;
this.tag = tag;
this.kind = options["kind"] || null;
this.resolve = options["resolve"] || function() {
return true;
};
this.construct = options["construct"] || function(data) {
return data;
};
this.instanceOf = options["instanceOf"] || null;
this.predicate = options["predicate"] || null;
this.represent = options["represent"] || null;
this.representName = options["representName"] || null;
this.defaultStyle = options["defaultStyle"] || null;
this.multi = options["multi"] || false;
this.styleAliases = compileStyleAliases(options["styleAliases"] || null);
if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {
throw new exception('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.');
}
}
var type = Type$1;
function compileList(schema2, name) {
var result = [];
schema2[name].forEach(function(currentType) {
var newIndex = result.length;
result.forEach(function(previousType, previousIndex) {
if (previousType.tag === currentType.tag && previousType.kind === currentType.kind && previousType.multi === currentType.multi) {
newIndex = previousIndex;
}
});
result[newIndex] = currentType;
});
return result;
}
function compileMap() {
var result = {
scalar: {},
sequence: {},
mapping: {},
fallback: {},
multi: {
scalar: [],
sequence: [],
mapping: [],
fallback: []
}
}, index, length;
function collectType(type2) {
if (type2.multi) {
result.multi[type2.kind].push(type2);
result.multi["fallback"].push(type2);
} else {
result[type2.kind][type2.tag] = result["fallback"][type2.tag] = type2;
}
}
for (index = 0, length = arguments.length; index < length; index += 1) {
arguments[index].forEach(collectType);
}
return result;
}
function Schema$1(definition) {
return this.extend(definition);
}
Schema$1.prototype.extend = function extend2(definition) {
var implicit = [];
var explicit = [];
if (definition instanceof type) {
explicit.push(definition);
} else if (Array.isArray(definition)) {
explicit = explicit.concat(definition);
} else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {
if (definition.implicit)
implicit = implicit.concat(definition.implicit);
if (definition.explicit)
explicit = explicit.concat(definition.explicit);
} else {
throw new exception("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");
}
implicit.forEach(function(type$1) {
if (!(type$1 instanceof type)) {
throw new exception("Specified list of YAML types (or a single Type object) contains a non-Type object.");
}
if (type$1.loadKind && type$1.loadKind !== "scalar") {
throw new exception("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");
}
if (type$1.multi) {
throw new exception("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.");
}
});
explicit.forEach(function(type$1) {
if (!(type$1 instanceof type)) {
throw new exception("Specified list of YAML types (or a single Type object) contains a non-Type object.");
}
});
var result = Object.create(Schema$1.prototype);
result.implicit = (this.implicit || []).concat(implicit);
result.explicit = (this.explicit || []).concat(explicit);
result.compiledImplicit = compileList(result, "implicit");
result.compiledExplicit = compileList(result, "explicit");
result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);
return result;
};
var schema = Schema$1;
var str = new type("tag:yaml.org,2002:str", {
kind: "scalar",
construct: function(data) {
return data !== null ? data : "";
}
});
var seq = new type("tag:yaml.org,2002:seq", {
kind: "sequence",
construct: function(data) {
return data !== null ? data : [];
}
});
var map = new type("tag:yaml.org,2002:map", {
kind: "mapping",
construct: function(data) {
return data !== null ? data : {};
}
});
var failsafe = new schema({
explicit: [
str,
seq,
map
]
});
function resolveYamlNull(data) {
if (data === null)
return true;
var max = data.length;
return max === 1 && data === "~" || max === 4 && (data === "null" || data === "Null" || data === "NULL");
}
function constructYamlNull() {
return null;
}
function isNull(object) {
return object === null;
}
var _null = new type("tag:yaml.org,2002:null", {
kind: "scalar",
resolve: resolveYamlNull,
construct: constructYamlNull,
predicate: isNull,
represent: {
canonical: function() {
return "~";
},
lowercase: function() {
return "null";
},
uppercase: function() {
return "NULL";
},
camelcase: function() {
return "Null";
},
empty: function() {
return "";
}
},
defaultStyle: "lowercase"
});
function resolveYamlBoolean(data) {
if (data === null)
return false;
var max = data.length;
return max === 4 && (data === "true" || data === "True" || data === "TRUE") || max === 5 && (data === "false" || data === "False" || data === "FALSE");
}
function constructYamlBoolean(data) {
return data === "true" || data === "True" || data === "TRUE";
}
function isBoolean(object) {
return Object.prototype.toString.call(object) === "[object Boolean]";
}
var bool = new type("tag:yaml.org,2002:bool", {
kind: "scalar",
resolve: resolveYamlBoolean,
construct: constructYamlBoolean,
predicate: isBoolean,
represent: {
lowercase: function(object) {
return object ? "true" : "false";
},
uppercase: function(object) {
return object ? "TRUE" : "FALSE";
},
camelcase: function(object) {
return object ? "True" : "False";
}
},
defaultStyle: "lowercase"
});
function isHexCode(c) {
return 48 <= c && c <= 57 || 65 <= c && c <= 70 || 97 <= c && c <= 102;
}
function isOctCode(c) {
return 48 <= c && c <= 55;
}
function isDecCode(c) {
return 48 <= c && c <= 57;
}
function resolveYamlInteger(data) {
if (data === null)
return false;
var max = data.length, index = 0, hasDigits = false, ch;
if (!max)
return false;
ch = data[index];
if (ch === "-" || ch === "+") {
ch = data[++index];
}
if (ch === "0") {
if (index + 1 === max)
return true;
ch = data[++index];
if (ch === "b") {
index++;
for (; index < max; index++) {
ch = data[index];
if (ch === "_")
continue;
if (ch !== "0" && ch !== "1")
return false;
hasDigits = true;
}
return hasDigits && ch !== "_";
}
if (ch === "x") {
index++;
for (; index < max; index++) {
ch = data[index];
if (ch === "_")
continue;
if (!isHexCode(data.charCodeAt(index)))
return false;
hasDigits = true;
}
return hasDigits && ch !== "_";
}
if (ch === "o") {
index++;
for (; index < max; index++) {
ch = data[index];
if (ch === "_")
continue;
if (!isOctCode(data.charCodeAt(index)))
return false;
hasDigits = true;
}
return hasDigits && ch !== "_";
}
}
if (ch === "_")
return false;
for (; index < max; index++) {
ch = data[index];
if (ch === "_")
continue;
if (!isDecCode(data.charCodeAt(index))) {
return false;
}
hasDigits = true;
}
if (!hasDigits || ch === "_")
return false;
return true;
}
function constructYamlInteger(data) {
var value = data, sign = 1, ch;
if (value.indexOf("_") !== -1) {
value = value.replace(/_/g, "");
}
ch = value[0];
if (ch === "-" || ch === "+") {
if (ch === "-")
sign = -1;
value = value.slice(1);
ch = value[0];
}
if (value === "0")
return 0;
if (ch === "0") {
if (value[1] === "b")
return sign * parseInt(value.slice(2), 2);
if (value[1] === "x")
return sign * parseInt(value.slice(2), 16);
if (value[1] === "o")
return sign * parseInt(value.slice(2), 8);
}
return sign * parseInt(value, 10);
}
function isInteger(object) {
return Object.prototype.toString.call(object) === "[object Number]" && (object % 1 === 0 && !common.isNegativeZero(object));
}
var int = new type("tag:yaml.org,2002:int", {
kind: "scalar",
resolve: resolveYamlInteger,
construct: constructYamlInteger,
predicate: isInteger,
represent: {
binary: function(obj) {
return obj >= 0 ? "0b" + obj.toString(2) : "-0b" + obj.toString(2).slice(1);
},
octal: function(obj) {
return obj >= 0 ? "0o" + obj.toString(8) : "-0o" + obj.toString(8).slice(1);
},
decimal: function(obj) {
return obj.toString(10);
},
hexadecimal: function(obj) {
return obj >= 0 ? "0x" + obj.toString(16).toUpperCase() : "-0x" + obj.toString(16).toUpperCase().slice(1);
}
},
defaultStyle: "decimal",
styleAliases: {
binary: [2, "bin"],
octal: [8, "oct"],
decimal: [10, "dec"],
hexadecimal: [16, "hex"]
}
});
var YAML_FLOAT_PATTERN = new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");
function resolveYamlFloat(data) {
if (data === null)
return false;
if (!YAML_FLOAT_PATTERN.test(data) || data[data.length - 1] === "_") {
return false;
}
return true;
}
function constructYamlFloat(data) {
var value, sign;
value = data.replace(/_/g, "").toLowerCase();
sign = value[0] === "-" ? -1 : 1;
if ("+-".indexOf(value[0]) >= 0) {
value = value.slice(1);
}
if (value === ".inf") {
return sign === 1 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
} else if (value === ".nan") {
return NaN;
}
return sign * parseFloat(value, 10);
}
var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;
function representYamlFloat(object, style) {
var res;
if (isNaN(object)) {
switch (style) {
case "lowercase":
return ".nan";
case "uppercase":
return ".NAN";
case "camelcase":
return ".NaN";
}
} else if (Number.POSITIVE_INFINITY === object) {
switch (style) {
case "lowercase":
return ".inf";
case "uppercase":
return ".INF";
case "camelcase":
return ".Inf";
}
} else if (Number.NEGATIVE_INFINITY === object) {
switch (style) {
case "lowercase":
return "-.inf";
case "uppercase":
return "-.INF";
case "camelcase":
return "-.Inf";
}
} else if (common.isNegativeZero(object)) {
return "-0.0";
}
res = object.toString(10);
return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace("e", ".e") : res;
}
function isFloat(object) {
return Object.prototype.toString.call(object) === "[object Number]" && (object % 1 !== 0 || common.isNegativeZero(object));
}
var float = new type("tag:yaml.org,2002:float", {
kind: "scalar",
resolve: resolveYamlFloat,
construct: constructYamlFloat,
predicate: isFloat,
represent: representYamlFloat,
defaultStyle: "lowercase"
});
var json = failsafe.extend({
implicit: [
_null,
bool,
int,
float
]
});
var core$1 = json;
var YAML_DATE_REGEXP = new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$");
var YAML_TIMESTAMP_REGEXP = new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");
function resolveYamlTimestamp(data) {
if (data === null)
return false;
if (YAML_DATE_REGEXP.exec(data) !== null)
return true;
if (YAML_TIMESTAMP_REGEXP.exec(data) !== null)
return true;
return false;
}
function constructYamlTimestamp(data) {
var match, year, month, day, hour, minute, second, fraction = 0, delta = null, tz_hour, tz_minute, date;
match = YAML_DATE_REGEXP.exec(data);
if (match === null)
match = YAML_TIMESTAMP_REGEXP.exec(data);
if (match === null)
throw new Error("Date resolve error");
year = +match[1];
month = +match[2] - 1;
day = +match[3];
if (!match[4]) {
return new Date(Date.UTC(year, month, day));
}
hour = +match[4];
minute = +match[5];
second = +match[6];
if (match[7]) {
fraction = match[7].slice(0, 3);
while (fraction.length < 3) {
fraction += "0";
}
fraction = +fraction;
}
if (match[9]) {
tz_hour = +match[10];
tz_minute = +(match[11] || 0);
delta = (tz_hour * 60 + tz_minute) * 6e4;
if (match[9] === "-")
delta = -delta;
}
date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));
if (delta)
date.setTime(date.getTime() - delta);
return date;
}
function representYamlTimestamp(object) {
return object.toISOString();
}
var timestamp = new type("tag:yaml.org,2002:timestamp", {
kind: "scalar",
resolve: resolveYamlTimestamp,
construct: constructYamlTimestamp,
instanceOf: Date,
represent: representYamlTimestamp
});
function resolveYamlMerge(data) {
return data === "<<" || data === null;
}
var merge = new type("tag:yaml.org,2002:merge", {
kind: "scalar",
resolve: resolveYamlMerge
});
var BASE64_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";
function resolveYamlBinary(data) {
if (data === null)
return false;
var code