171 lines
3.7 KiB
TypeScript
171 lines
3.7 KiB
TypeScript
import type { Schema, SchemaProperty } from '../../common'
|
|
|
|
import type { ResourceType, ScriptLang } from '../../gen'
|
|
|
|
import { capitalize, toCamel } from '$lib/utils'
|
|
import YAML from 'yaml'
|
|
|
|
export const getCommentSymbol = (
|
|
lang: ScriptLang | 'bunnative' | 'jsx' | 'tsx' | 'json'
|
|
): string => {
|
|
switch (lang) {
|
|
case 'python3':
|
|
case 'go':
|
|
case 'bash':
|
|
case 'powershell':
|
|
case 'graphql':
|
|
case 'ansible':
|
|
case 'nu':
|
|
return '#'
|
|
case 'nativets':
|
|
case 'bun':
|
|
case 'deno':
|
|
case 'php':
|
|
case 'csharp':
|
|
case 'java':
|
|
case 'bunnative':
|
|
return '//'
|
|
case 'rust':
|
|
case 'postgresql':
|
|
case 'mysql':
|
|
case 'bigquery':
|
|
case 'snowflake':
|
|
case 'mssql':
|
|
case 'oracledb':
|
|
case 'duckdb':
|
|
return '--'
|
|
default:
|
|
return '//'
|
|
}
|
|
}
|
|
|
|
export function compile(schema: Schema) {
|
|
function rec(x: { [name: string]: SchemaProperty }, root = false) {
|
|
let res = '{\n'
|
|
const entries = Object.entries(x)
|
|
if (entries.length == 0) {
|
|
return 'any'
|
|
}
|
|
let i = 0
|
|
for (let [name, prop] of entries) {
|
|
if (prop.type == 'object') {
|
|
res += ` ${name}: ${rec(prop.properties ?? {})}`
|
|
} else if (prop.type == 'array') {
|
|
res += ` ${name}: ${prop?.items?.type ?? 'any'}[]`
|
|
} else {
|
|
let typ = prop?.type ?? 'any'
|
|
if (typ == 'integer') {
|
|
typ = 'number'
|
|
}
|
|
res += ` ${name}: ${typ}`
|
|
}
|
|
i++
|
|
if (i < entries.length) {
|
|
res += ',\n'
|
|
}
|
|
}
|
|
res += '\n}'
|
|
return res
|
|
}
|
|
|
|
return rec(schema.properties, true)
|
|
}
|
|
|
|
export function pythonCompile(schema: Schema) {
|
|
let res = ''
|
|
const entries = Object.entries(schema.properties)
|
|
if (entries.length === 0) {
|
|
return 'dict'
|
|
}
|
|
let i = 0
|
|
for (let [name, prop] of entries) {
|
|
let typ = 'dict'
|
|
if (prop.type === 'array') {
|
|
typ = 'list'
|
|
} else if (prop.type === 'string') {
|
|
typ = 'str'
|
|
} else if (prop.type === 'number') {
|
|
typ = 'float'
|
|
} else if (prop.type === 'integer') {
|
|
typ = 'int'
|
|
} else if (prop.type === 'boolean') {
|
|
typ = 'bool'
|
|
}
|
|
res += ` ${name}: ${typ}`
|
|
i++
|
|
if (i < entries.length) {
|
|
res += '\n'
|
|
}
|
|
}
|
|
return res
|
|
}
|
|
|
|
export function phpCompile(schema: Schema) {
|
|
let res = ''
|
|
const entries = Object.entries(schema.properties)
|
|
if (entries.length === 0) {
|
|
return 'array'
|
|
}
|
|
let i = 0
|
|
for (let [name, prop] of entries) {
|
|
let typ = 'array'
|
|
if (prop.type === 'array') {
|
|
typ = 'array'
|
|
} else if (prop.type === 'string') {
|
|
typ = 'string'
|
|
} else if (prop.type === 'number') {
|
|
typ = 'float'
|
|
} else if (prop.type === 'integer') {
|
|
typ = 'int'
|
|
} else if (prop.type === 'boolean') {
|
|
typ = 'bool'
|
|
}
|
|
res += ` public ${typ} $${name};`
|
|
i++
|
|
if (i < entries.length) {
|
|
res += '\n'
|
|
}
|
|
}
|
|
return res
|
|
}
|
|
|
|
export function formatResourceTypes(
|
|
resourceTypes: ResourceType[],
|
|
lang: 'python3' | 'typescript' | 'php'
|
|
) {
|
|
if (lang === 'python3') {
|
|
const result = resourceTypes.map((resourceType) => {
|
|
return `class ${resourceType.name}(TypedDict):\n${pythonCompile(resourceType.schema as any)}`
|
|
})
|
|
return '\n' + result.join('\n\n')
|
|
} else if (lang === 'php') {
|
|
const result = resourceTypes.map((resourceType) => {
|
|
return `class ${toCamel(capitalize(resourceType.name))} {\n${phpCompile(
|
|
resourceType.schema as any
|
|
)}\n}`
|
|
})
|
|
return '\n' + result.join('\n\n')
|
|
} else {
|
|
const result = resourceTypes
|
|
.filter(
|
|
(resourceType) => Boolean(resourceType.schema) && typeof resourceType.schema === 'object'
|
|
)
|
|
.map((resourceType) => {
|
|
return `type ${toCamel(capitalize(resourceType.name))} = ${compile(
|
|
resourceType.schema as any
|
|
)}`
|
|
})
|
|
return '\n' + result.join('\n\n')
|
|
}
|
|
}
|
|
|
|
export function yamlStringifyExceptKeys(obj: any, keys: string[]) {
|
|
return YAML.stringify(obj, (key, val) => {
|
|
if (keys.includes(key)) {
|
|
return undefined
|
|
} else {
|
|
return val
|
|
}
|
|
})
|
|
}
|