Skip to content

Commit

Permalink
Merge pull request #19 from gentlementlegen/feat/schema-validation
Browse files Browse the repository at this point in the history
feat: schema validation
  • Loading branch information
gentlementlegen authored Oct 4, 2024
2 parents cd97812 + 92af35f commit 2f06bd6
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 43 deletions.
58 changes: 58 additions & 0 deletions .github/workflows/update-configuration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: "Update Configuration"

on:
workflow_dispatch:
push:

jobs:
update:
name: "Update Configuration in manifest.json"
runs-on: ubuntu-latest
permissions: write-all

steps:
- uses: actions/checkout@v4

- name: Setup node
uses: actions/setup-node@v4
with:
node-version: "20.10.0"

- name: Install deps and run configuration update
run: |
yarn install --immutable --immutable-cache --check-cache
yarn tsc --noCheck --project tsconfig.json
- name: Update manifest configuration using GitHub Script
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const path = require('path');
const { pluginSettingsSchema } = require('./src/types');
const manifestPath = path.resolve("${{ github.workspace }}", './manifest.json');
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
const configuration = JSON.stringify(pluginSettingsSchema);
manifest["configuration"] = JSON.parse(configuration);
const updatedManifest = JSON.stringify(manifest, null, 2)
console.log('Updated manifest:', updatedManifest);
fs.writeFileSync(manifestPath, updatedManifest);
- name: Commit and Push generated types
run: |
git config --global user.name 'ubiquity-os[bot]'
git config --global user.email 'ubiquity-os[bot]@users.noreply.github.com'
git add ./manifest.json
if [ -n "$(git diff-index --cached --name-only HEAD)" ]; then
git commit -m "chore: updated generated configuration" || echo "Lint-staged check failed"
git push origin HEAD:${{ github.ref_name }}
else
echo "No changes to commit"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35 changes: 33 additions & 2 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
{
"name": "Generate vector embeddings",
"description": "Enables the storage, updating, and deletion of issue comment embeddings.",
"ubiquity:listeners": ["issue_comment.created", "issue_comment.edited", "issue_comment.deleted", "issues.opened", "issues.edited", "issues.deleted", "issues.labeled"]
}
"ubiquity:listeners": [
"issue_comment.created",
"issue_comment.edited",
"issue_comment.deleted",
"issues.opened",
"issues.edited",
"issues.deleted",
"issues.labeled"
],
"configuration": {
"default": {},
"type": "object",
"properties": {
"matchThreshold": {
"default": 0.95,
"type": "number"
},
"warningThreshold": {
"default": 0.75,
"type": "number"
},
"jobMatchingThreshold": {
"default": 0.75,
"type": "number"
}
},
"required": [
"matchThreshold",
"warningThreshold",
"jobMatchingThreshold"
]
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
"supabase": "1.200.3",
"ts-jest": "29.1.5",
"tsx": "4.15.6",
"typescript": "5.4.5",
"typescript": "5.6.2",
"typescript-eslint": "7.13.1",
"wrangler": "3.78.12"
},
Expand Down
36 changes: 36 additions & 0 deletions src/handlers/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { TransformDecodeCheckError, TransformDecodeError, Value, ValueError } from "@sinclair/typebox/value";
import { Env, envValidator, PluginSettings, pluginSettingsSchema, pluginSettingsValidator } from "../types";

export function validateAndDecodeSchemas(env: Env, rawSettings: object) {
const errors: ValueError[] = [];
const settings = Value.Default(pluginSettingsSchema, rawSettings) as PluginSettings;

if (!pluginSettingsValidator.test(settings)) {
for (const error of pluginSettingsValidator.errors(settings)) {
console.error(error);
errors.push(error);
}
}

if (!envValidator.test(env)) {
for (const error of envValidator.errors(env)) {
console.error(error);
errors.push(error);
}
}

if (errors.length) {
throw { errors };
}

try {
const decodedEnv = Value.Decode(envValidator.schema, env);
const decodedSettings = Value.Decode(pluginSettingsSchema, settings);
return { decodedEnv, decodedSettings };
} catch (e) {
if (e instanceof TransformDecodeCheckError || e instanceof TransformDecodeError) {
throw { errors: [e.error] };
}
throw e;
}
}
51 changes: 16 additions & 35 deletions src/worker.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { Value } from "@sinclair/typebox/value";
import { plugin } from "./plugin";
import { Env, envValidator, pluginSettingsSchema, pluginSettingsValidator } from "./types";
import manifest from "../manifest.json";
import { validateAndDecodeSchemas } from "./handlers/validator";
import { plugin } from "./plugin";
import { Env } from "./types";

export default {
async fetch(request: Request, env: Env): Promise<Response> {
try {
if (request.method === "GET") {
const url = new URL(request.url);
if (url.pathname === "/manifest.json") {
const url = new URL(request.url);
if (url.pathname === "/manifest") {
if (request.method === "GET") {
return new Response(JSON.stringify(manifest), {
headers: { "content-type": "application/json" },
});
} else if (request.method === "POST") {
const webhookPayload = await request.json();
validateAndDecodeSchemas(env, webhookPayload.settings);
return new Response(JSON.stringify({ message: "Schema is valid" }), { status: 200, headers: { "content-type": "application/json" } });
}
}
if (request.method !== "POST") {
Expand All @@ -29,42 +33,19 @@ export default {
}

const webhookPayload = await request.json();
const settings = Value.Decode(pluginSettingsSchema, Value.Default(pluginSettingsSchema, webhookPayload.settings));

if (!pluginSettingsValidator.test(settings)) {
const errors: string[] = [];
for (const error of pluginSettingsValidator.errors(settings)) {
console.error(error);
errors.push(`${error.path}: ${error.message}`);
}
return new Response(JSON.stringify({ error: `Error: "Invalid settings provided. ${errors.join("; ")}"` }), {
status: 400,
headers: { "content-type": "application/json" },
});
}
if (!envValidator.test(env)) {
const errors: string[] = [];
for (const error of envValidator.errors(env)) {
console.error(error);
errors.push(`${error.path}: ${error.message}`);
}
return new Response(JSON.stringify({ error: `Error: "Invalid environment provided. ${errors.join("; ")}"` }), {
status: 400,
headers: { "content-type": "application/json" },
});
}
const { decodedSettings, decodedEnv } = validateAndDecodeSchemas(env, webhookPayload.settings);

webhookPayload.settings = settings;
await plugin(webhookPayload, env);
webhookPayload.settings = decodedSettings;
await plugin(webhookPayload, decodedEnv);
return new Response(JSON.stringify("OK"), { status: 200, headers: { "content-type": "application/json" } });
} catch (error) {
return handleUncaughtError(error);
}
},
};

function handleUncaughtError(error: unknown) {
console.error(error);
function handleUncaughtError(errors: unknown) {
console.error(errors);
const status = 500;
return new Response(JSON.stringify({ error }), { status: status, headers: { "content-type": "application/json" } });
return new Response(JSON.stringify(errors), { status: status, headers: { "content-type": "application/json" } });
}
2 changes: 1 addition & 1 deletion tests/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe("Plugin tests", () => {

it("Should serve the manifest file", async () => {
const worker = (await import("../src/worker")).default;
const response = await worker.fetch(new Request("http://localhost/manifest.json"), {
const response = await worker.fetch(new Request("http://localhost/manifest"), {
SUPABASE_KEY: "test",
SUPABASE_URL: "test",
VOYAGEAI_API_KEY: "test",
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6656,10 +6656,10 @@ [email protected]:
"@typescript-eslint/parser" "7.13.1"
"@typescript-eslint/utils" "7.13.1"

typescript@5.4.5:
version "5.4.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611"
integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==
typescript@5.6.2:
version "5.6.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0"
integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==

uc.micro@^2.0.0, uc.micro@^2.1.0:
version "2.1.0"
Expand Down

0 comments on commit 2f06bd6

Please sign in to comment.