Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: Manual api generation #2

Draft
wants to merge 30 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore: tidying
Julusian committed Feb 27, 2024
commit c525f933af10ad731124efef8988e2e8f4526c57
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
"main": "./build/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rimraf build && tsc",
"build": "yarn tool:generate && rimraf build && tsc",
"dev": "DEBUG_WRITE_TO_FILE=1 nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/main.ts",
"submodules": "git submodule init && git submodule update",
"release": "release-it",
39 changes: 34 additions & 5 deletions tools/ApiGenerator.mts → tools/NMOSApiGenerator.mts
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
import * as changeCase from "change-case";
import { HTTP_VERBS } from "./Generator2.mjs";

export class ApiGenerator {
const HTTP_VERBS = [
"get",
"post",
"put",
"delete",
"head",
"options",
"trace",
"patch",
"connect",
];

/** Generate the types for a portion of a NMOS standard */
export class NMOSApiGenerator {
public typeDefinitionLines: string[] = [];

constructor(
public readonly schemaResources: Map<string, string>,
private readonly schemaResources: Map<string, string>,
private readonly traits: any = {},
) {}

/** Run the generator */
public async generate(name: string, raml: any): Promise<string[]> {
const lines = [];
const lines: string[] = [];

lines.push(`export class ${name} extends runtime.BaseAPI {`);

@@ -28,6 +41,13 @@ export class ApiGenerator {
return lines;
}

/**
* Generate a resource
* @param uriPrefix Prefix for the resource
* @param pathPrefix Path for the resouce
* @param ramlResources RAML to parse
* @returns Typescript code lines
*/
async #processResources(
uriPrefix: string,
pathPrefix: string,
@@ -103,11 +123,20 @@ export class ApiGenerator {
return lines;
}

/**
* Generate a method
* @param uriPath Path for the method
* @param displayName Name to display for the method
* @param verb HTTP verb of the method
* @param uriParameters URI parameters
* @param resource RAML for the resouce
* @returns Typescript code lines
*/
async #processMethod(
uriPath: string,
displayName: string,
verb: string,
uriParameters: any,
uriParameters: Record<string, any>,
resource: any,
): Promise<string[]> {
const lines: string[] = [];
37 changes: 22 additions & 15 deletions tools/Generator2.mts → tools/NMOSStandardVersionGenerator.mts
Original file line number Diff line number Diff line change
@@ -3,34 +3,32 @@ import { compile } from "json-schema-to-typescript";
import { generateName } from "json-schema-to-typescript/dist/src/utils.js";
import path from "path";
import { readRamlFile } from "./lib.mjs";
import { ApiGenerator } from "./ApiGenerator.mjs";
import { NMOSApiGenerator } from "./NMOSApiGenerator.mjs";
import * as changeCase from "change-case";

export const HTTP_VERBS = [
"get",
"post",
"put",
"delete",
"head",
"options",
"trace",
"patch",
"connect",
];

export class Generator {
/** Generate the types for an NMOS standard */
export class NMOSStandardVersionGenerator {
constructor(
private readonly sourcePath: string,
private readonly destPath: string,
) {}

/**
* Run the generator
* @param version Version number of this standard
*/
public async run(version: string): Promise<void> {
await fs.mkdir(this.destPath, { recursive: true });

const schemaTypes = await this.#compileSchemas(version);
await this.#generateApis(schemaTypes);
}

/**
* Compile the typescript schemas to interfaces
* @param version Version number of this standard
* @returns Map of schema types names
*/
async #compileSchemas(version: string): Promise<Map<string, string>> {
const typeNames = new Map<string, string>();

@@ -82,6 +80,10 @@ export class Generator {
return typeNames;
}

/**
* Compile the api schemas to classes
* @param schemaTypes Map of schema types names
*/
async #generateApis(schemaTypes: Map<string, string>): Promise<void> {
const names: string[] = [];

@@ -103,6 +105,11 @@ export class Generator {
);
}

/**
* Compile the api schemas to a class
* @param schemaTypes Map of schema types names
* @param filename Filename of the api portion to generate
*/
async #generateApi(
schemaResources: Map<string, string>,
filename: string,
@@ -121,7 +128,7 @@ export class Generator {
}
}

const apiGenerator = new ApiGenerator(localResources, raml.traits);
const apiGenerator = new NMOSApiGenerator(localResources, raml.traits);

const lines = [
`/* eslint-disable */`,
77 changes: 34 additions & 43 deletions tools/generate.mts
Original file line number Diff line number Diff line change
@@ -3,52 +3,11 @@ import path from "path";
import { rimraf } from "rimraf";
import { fileURLToPath } from "url";
import fs from "fs/promises";
import { Generator } from "./Generator2.mjs";
import { NMOSStandardVersionGenerator } from "./NMOSStandardVersionGenerator.mjs";

const __dirname = fileURLToPath(new URL(".", import.meta.url));
const generatedBasePath = path.join(__dirname, "../src/generated");

async function legacy() {
// Delete previous generation
await rimraf(generatedBasePath).catch(() => null);
await fs.mkdir(generatedBasePath, { recursive: true });

const standards = ["is-04", "is-05"];

const paths: string[] = [];

for (const standard of standards) {
const versions = await getVersions(standard);
for (const version of versions) {
console.log(`Generating ${standard} - ${version}`);

await new Generator(
path.join(
__dirname,
"..",
"submodules",
standard,
version,
"APIs",
),
path.join(generatedBasePath, standard, version),
).run(version);

const filePath = path.join(".", standard, version, "index.js");
const exportName = `${standard.replace(
/\W+/g,
"",
)}_v${version.replace(/\D+/g, "")}`;
paths.push(`export * as ${exportName} from './${filePath}'`);
}

await fs.writeFile(
path.join(generatedBasePath, "index.ts"),
paths.join("\n"),
);
}
}

// function assertKnownKeys(obj: any, keys: string[]) {
// for (const key of Object.keys(obj)) {
// if (keys.indexOf(key) === -1)
@@ -64,4 +23,36 @@ async function legacy() {

// is-05 is missing definition of some parameters

legacy();
// Delete previous generation
await rimraf(generatedBasePath).catch(() => null);
await fs.mkdir(generatedBasePath, { recursive: true });

const standards = ["is-04", "is-05"];

const paths: string[] = [];

// run the generator for each standard and version
for (const standard of standards) {
const versions = await getVersions(standard);
for (const version of versions) {
console.log(`Generating ${standard} - ${version}`);

await new NMOSStandardVersionGenerator(
path.join(__dirname, "..", "submodules", standard, version, "APIs"),
path.join(generatedBasePath, standard, version),
).run(version);

// re-export the types
const filePath = path.join(".", standard, version, "index.js");
const exportName = `${standard.replace(/\W+/g, "")}_v${version.replace(
/\D+/g,
"",
)}`;
paths.push(`export * as ${exportName} from './${filePath}'`);
}

await fs.writeFile(
path.join(generatedBasePath, "index.ts"),
paths.join("\n"),
);
}