snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s

This commit is contained in:
upstream-mirror
2026-09-18 01:22:23 +05:00
commit 7e385fc126
8391 changed files with 1766236 additions and 0 deletions

View File

@@ -0,0 +1,118 @@
import lodash from 'lodash'
import fs from 'fs'
import yaml from 'js-yaml'
import handlebars from 'handlebars'
import { template } from './template.js'
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'
// Get equivalent of __dirname in ES modules
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
let path
if (process.argv.length >= 3) {
path = process.argv[2]
} else {
// Assume "standard" dev environment
// where corteza server source could be found
// next to this lib
path = '../../server'
}
const dst = join(__dirname, '../../src/api-clients')
const namespaces = [
{
path: `${path}/system/rest.yaml`,
namespace: 'system',
className: 'System',
},
{
path: `${path}/compose/rest.yaml`,
namespace: 'compose',
className: 'Compose',
},
{
path: `${path}/federation/rest.yaml`,
namespace: 'federation',
className: 'Federation',
},
{
path: `${path}/automation/rest.yaml`,
namespace: 'automation',
className: 'Automation',
},
]
namespaces.forEach(({ path, namespace, className }) => {
console.log(`Generating '${className}' from specs file '${path}'`)
let spec
try {
spec = yaml.load(fs.readFileSync(path)).endpoints
} catch (err) {
switch (err.code) {
case 'ENOENT':
console.error('Could not find specs file')
return
}
throw err
}
if (!spec) {
console.error('Endpoints are undefined')
return
}
const endpoints = [].concat.apply([], spec.map(e => {
const { get = [], post = [], path = [] } = e.parameters || {}
const parentGet = get
const parentPost = post
const parentPath = path
return e.apis.map(a => {
let { get = [], post = [], path = [] } = a.parameters || {}
path = [...parentPath, ...path]
get = [...parentGet, ...get]
post = [...parentPost, ...post]
const allvars = [...path, ...get, ...post]
return {
title: a.title,
description: a.description,
fname: lodash.camelCase(e.entrypoint + ' ' + a.name),
fargs: allvars.map(v => v.name),
pathParams: path.map(v => v.name),
required: allvars.filter(v => v.required).map(v => v.name),
method: a.method.toLowerCase(),
path: (e.path + a.path).replace(/\{/g, '${'),
hasParams: get.length > 0,
params: get ? get.map(p => p.name) : [],
hasData: post.length > 0,
data: post ? post.map(p => p.name) : [],
}
})
}))
try {
const tpl = handlebars.compile(template.trimStart())
let gen = tpl({ endpoints, className, namespace })
// Remove trailing whitespace from lines while preserving newlines
gen = gen.replace(/[^\S\n]+$/gm, '')
fs.writeFileSync(`${dst}/${namespace}.ts`, gen)
} catch (err) {
console.error(err)
}
})

View File

@@ -0,0 +1,156 @@
export const template = `
/* eslint-disable padded-blocks */
// This is a generated file.
// See README.md file for update instructions
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
interface KV {
[header: string]: unknown;
}
interface Headers {
[header: string]: string;
}
interface Ctor {
baseURL?: string;
accessTokenFn?: () => string | undefined;
headers?: Headers;
}
interface CortezaResponse {
error?: string;
response?: unknown;
}
interface ExtraConfig {
headers?: Headers;
}
function stdResolve (response: AxiosResponse<CortezaResponse>): KV|Promise<never> {
if (response.data.error) {
return Promise.reject(response.data.error)
} else {
return response.data.response as KV
}
}
export default class {{className}} {
protected baseURL?: string;
protected accessTokenFn?: () => (string | undefined);
protected headers: Headers = {};
constructor ({ baseURL, headers, accessTokenFn }: Ctor) {
this.baseURL = baseURL
this.accessTokenFn = accessTokenFn
this.headers = {
/**
* All we send is JSON
*/
'Content-Type': 'application/json',
}
this.setHeaders(headers)
}
setAccessTokenFn (fn: () => string | undefined): {{className}} {
this.accessTokenFn = fn
return this
}
setHeaders (headers?: Headers): {{className}} {
if (typeof headers === 'object') {
this.headers = headers
}
return this
}
setHeader (name: string, value: string | undefined): {{className}} {
if (value === undefined) {
delete this.headers[name]
} else {
this.headers[name] = value
}
return this
}
api (): AxiosInstance {
const headers = { ...this.headers }
const accessToken = this.accessTokenFn ? this.accessTokenFn() : undefined
if (accessToken) {
headers.Authorization = 'Bearer ' + accessToken
}
return axios.create({
withCredentials: true,
baseURL: this.baseURL,
headers,
})
}
{{#endpoints}}
// {{title}}{{#description}}
// {{description}}{{/description}}
async {{fname}} ({{#if fargs}}a: KV, {{/if}}extra: AxiosRequestConfig = {}): Promise<KV> {
{{#if fargs}}const {
{{#fargs}}
{{.}},
{{/fargs}}
} = (a as KV) || {}{{/if}}
{{#required}}
if (!{{.}}) {
throw Error('field {{.}} is empty')
}
{{/required}}
const cfg: AxiosRequestConfig = {
...extra,
method: '{{method}}',
url: this.{{fname}}Endpoint({{#if pathParams}}{
{{#pathParams}}{{.}}, {{/pathParams}}
}{{/if}}),
}
{{#hasParams}}cfg.params = {
{{#params}}
{{.}},
{{/params}}
}
{{/hasParams}}{{#hasData}}cfg.data = {
{{#data}}
{{.}},
{{/data}}
}{{/hasData}}
return this.api().request(cfg).then(result => stdResolve(result))
}
{{fname}}Cancellable ({{#if fargs}}a: KV, {{/if}}extra: AxiosRequestConfig = {}): { response: (a: KV, extra?: AxiosRequestConfig) => Promise<KV>; cancel: () => void; } {
const cancelTokenSource = axios.CancelToken.source();
const options = {...extra, cancelToken: cancelTokenSource.token }
return {
response: () => this.{{fname}}({{#if fargs}}a, {{/if}}options),
cancel: () => {
cancelTokenSource.cancel();
},
}
}
{{fname}}Endpoint ({{#if pathParams}}a: KV{{/if}}): string {
{{#if pathParams}}
const {
{{#pathParams}}
{{.}},
{{/pathParams}}
} = a || {}
return \`{{path}}\`
{{else}}
return '{{path}}'
{{/if}}
}
{{/endpoints}}
}
`