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

fixes: miscellaneous #18

Merged
merged 5 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 5 additions & 1 deletion src/applets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const proctoroom = `<!doctype html>
<script src="https://cdn.tailwindcss.com?plugins=forms,typography"></script>
<script src="https://cdn.jsdelivr.net/npm/cash-dom/dist/cash.min.js"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@slangroom/browser"></script>
<link rel="stylesheet" href="https://unpkg.com/spectre.css/dist/spectre-icons.min.css">

<script>
tailwind.config = {
theme: {
Expand Down Expand Up @@ -193,7 +195,9 @@ const proctoroom = `<!doctype html>
disable_properties: true,
required_by_default: true,
show_errors: 'interaction',
use_name_attributes: false
use_name_attributes: false,
theme: 'tailwind',
iconlib: 'spectre'
});

$(document).ready(() => {
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Dir.ready(async () => {
.writeHeader('Content-Type', 'application/json')
.end(JSON.stringify(definition));
});

generateRoutes(app);

app.listen(config.port, (socket) => {
Expand Down
12 changes: 6 additions & 6 deletions src/openapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Type } from '@sinclair/typebox';
import { getSchema } from './utils.js';
import { Endpoints } from './types.js';

export const generateRawPath = () => {
export function generateRawPath(): OpenAPIV3_1.PathItemObject {
return {
get: {
tags: ['📜 Raw contracts'],
Expand All @@ -15,9 +15,9 @@ export const generateRawPath = () => {
}
}
};
};
}

export const generateAppletPath = () => {
export function generateAppletPath(): OpenAPIV3_1.PathItemObject {
return {
get: {
tags: ['📱 Generated applets'],
Expand All @@ -29,9 +29,9 @@ export const generateAppletPath = () => {
}
}
};
};
}

export const generatePath = async (endpoints: Endpoints) => {
export async function generatePath(endpoints: Endpoints): Promise<OpenAPIV3_1.PathItemObject> {
const { contract } = endpoints;
const schema = await getSchema(endpoints);
const getParams = schema.required?.map((n: string) => {
Expand Down Expand Up @@ -94,7 +94,7 @@ export const generatePath = async (endpoints: Endpoints) => {
}
}
};
};
}

export const definition: Partial<OpenAPIV3_1.Document> = {
openapi: '3.1.0',
Expand Down
29 changes: 10 additions & 19 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { introspect } from 'zenroom';
import { Type } from '@sinclair/typebox';
import { ValueErrorIterator } from '@sinclair/typebox/compiler';
import { Codec, Endpoints } from './types';
import _ from 'lodash';
import Ajv from 'ajv';
import Ajv, { type ValidateFunction } from 'ajv';

//

export const getSchema = async (endpoints: Endpoints) => {
const { contract, keys } = endpoints;
// TODO: validate json schema
if (endpoints.schema) return endpoints.schema;

const codec: Codec = await introspect(contract);
Expand All @@ -28,27 +26,20 @@ export const getSchema = async (endpoints: Endpoints) => {
return schema;
};

export const validateData = (schema: any, data: JSON | Record<string, unknown>) => {
export const validateData = (
schema: Awaited<ReturnType<typeof getSchema>>,
data: JSON | Record<string, unknown>
) => {
const ajv = new Ajv();
const validate = ajv.compile(schema);
const valid = validate(data);
if (!valid) throw new Error(JSON.stringify(validate.errors));
if (!validate(data))
throw new Error(`Invalid data provided:\n${formatAjvErrors(validate.errors)}`);
return data;
// console.log(ajv);
// const C = TypeCompiler.Compile(schema);
// if (C.Check(data)) {
// return data;
// } else {
// throw new Error(`Invalid data provided:
// ${JSON.stringify(formatTypeboxErrors(C.Errors(data)), null, 2)}
// `);
// }
};

export function formatTypeboxErrors(typeboxErrors: ValueErrorIterator): Record<string, string[]> {
const errors = [...typeboxErrors];
const groups = _.groupBy(errors, (error) => error.path);
return _.mapValues(groups, (group) => group.map((error) => error.message));
export function formatAjvErrors(ajvErrors: ValidateFunction['errors']): string {
if (!ajvErrors) return '';
return JSON.stringify(ajvErrors, null, 2);
}

//
Expand Down