Skip to content

Commit 90a2b64

Browse files
authored
Merge pull request #479 from PretendoNetwork/feat/port-community-datasource
[part 1] Add community endpoints + revise internal API structure
2 parents 02abc31 + aeb703f commit 90a2b64

75 files changed

Lines changed: 1720 additions & 3738 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/lint.yml

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ on:
44
pull_request: {}
55

66
jobs:
7-
lint:
8-
name: Lint
7+
lint_base:
8+
name: Lint common packages
99
runs-on: ubuntu-latest
1010
strategy:
1111
matrix:
12-
repo: ["miiverse-api", "juxtaposition-ui"]
12+
repo: ["miiverse-api"]
1313
steps:
1414
- name: Checkout
1515
uses: actions/checkout@v6
@@ -25,3 +25,30 @@ jobs:
2525
- name: Lint
2626
run: npm run lint -- --max-warnings=0
2727
working-directory: ./apps/${{ matrix.repo }}
28+
lint_juxt:
29+
# Juxtaposition-ui has a couple extra build steps before linting is possible
30+
name: Lint Juxtaposition-UI
31+
runs-on: ubuntu-latest
32+
steps:
33+
- name: Checkout
34+
uses: actions/checkout@v6
35+
36+
- name: Setup Node.js
37+
uses: actions/setup-node@v6
38+
with:
39+
node-version: "24"
40+
41+
- name: Install dependencies
42+
run: npm ci
43+
44+
- name: Build miiverse-api
45+
run: npm run build
46+
working-directory: ./apps/miiverse-api
47+
48+
- name: Build juxtaposition-ui
49+
run: npm run build
50+
working-directory: ./apps/juxtaposition-ui
51+
52+
- name: Lint
53+
run: npm run lint -- --max-warnings=0
54+
working-directory: ./apps/juxtaposition-ui

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ uploads/
1111

1212
# auto generated files
1313
apps/juxtaposition-ui/webfiles/ctr/css/sprites.css
14-
apps/juxtaposition-ui/webfiles/ctr/images/sprites.png
14+
apps/juxtaposition-ui/webfiles/ctr/images/sprites.png
15+
apps/juxtaposition-ui/src/api/generated
16+
apps/miiverse-api/internal.openapi.json

apps/juxtaposition-ui/eslint.config.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,9 @@ export default defineConfig([
5252
}
5353
},
5454
ignores: ['webfiles/**/*.js', 'webfiles/**/*.ts']
55+
},
56+
{
57+
// Ignore generated code
58+
ignores: ['src/api/generated']
5559
}
5660
]);

apps/juxtaposition-ui/nodemon.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
{
22
"watch": [
33
"src/",
4-
"webfiles/"
4+
"webfiles/",
5+
"../miiverse-api/internal.openapi.json"
56
],
67
"ext": "js,ts,tsx,jsx,json,css",
78
"ignore": [
89
"webfiles/ctr/css/sprites.css",
9-
"webfiles/ctr/images/sprites.png"
10+
"webfiles/ctr/images/sprites.png",
11+
"src/api/generated/**/*"
1012
],
1113
"env": {
1214
"NODE_ENV": "development"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { defineConfig } from '@hey-api/openapi-ts';
2+
3+
export default defineConfig({
4+
input: '../miiverse-api/internal.openapi.json',
5+
output: './src/api/generated',
6+
plugins: [
7+
{
8+
name: '@hey-api/client-fetch',
9+
throwOnError: true
10+
},
11+
{
12+
name: '@hey-api/sdk',
13+
paramsStructure: 'flat',
14+
operations: {
15+
strategy: 'single',
16+
containerName: 'InternalApi',
17+
nesting: 'operationId'
18+
}
19+
}
20+
]
21+
});

apps/juxtaposition-ui/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@
1212
"lint": "eslint .",
1313
"lint:fix": "eslint . --fix",
1414
"build": "tsup && tsc --noEmit",
15-
"start": "node --enable-source-maps dist/server.js",
16-
"build:sprites": "node scripts/sprites.ts"
15+
"start": "node --enable-source-maps dist/server.js"
1716
},
1817
"dependencies": {
1918
"@aws-sdk/client-s3": "^3.1004.0",
19+
"@hey-api/openapi-ts": "^0.95.0",
2020
"@imagemagick/magick-wasm": "^0.0.38",
2121
"@neato/config": "^4.1.0",
2222
"@pretendonetwork/grpc": "^2.4.3",
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { Metadata } from 'nice-grpc';
2+
import { InternalApi } from '@/api/generated';
3+
import { createClient } from '@/api/generated/client';
4+
import { config } from '@/config';
5+
import { grpcClient } from '@/grpc';
6+
import type { UserTokens } from '@/types/juxt/tokens';
7+
8+
export class InternalApiError extends Error {
9+
status: number;
10+
response: any;
11+
12+
constructor(res: Response, body: any) {
13+
super(`Interal API fetch call failed with status ${res.status}`);
14+
this.status = res.status;
15+
this.response = body;
16+
}
17+
}
18+
19+
export const customFetch: typeof globalThis.fetch = async (input, init) => {
20+
const req = new Request(input, init);
21+
const url = new URL(req.url);
22+
const metadata = Metadata({
23+
'X-API-Key': config.grpc.miiverse.apiKey
24+
});
25+
const method = req.method.toUpperCase();
26+
const grpcResponse = await grpcClient.sendPacket({
27+
path: url.pathname + url.search,
28+
method,
29+
headers: JSON.stringify(Object.fromEntries(req.headers.entries())),
30+
payload: req.body ? await new Response(req.body).text() : undefined
31+
}, {
32+
metadata
33+
});
34+
35+
// Mask 404's as a succesfull `null` response
36+
if (grpcResponse.status === 404 && req.method === 'GET') {
37+
grpcResponse.status = 200;
38+
grpcResponse.payload = JSON.stringify(null);
39+
}
40+
41+
const response = new Response(Buffer.from(grpcResponse.payload), {
42+
status: grpcResponse.status,
43+
headers: {
44+
'content-type': 'application/json'
45+
}
46+
});
47+
return response;
48+
};
49+
50+
export function createInternalApiClient(tokens: UserTokens): InternalApi {
51+
const client = createClient({
52+
fetch: customFetch,
53+
baseUrl: 'https://example.com/api/v1', // Hostname is ignored by `customFetch`
54+
headers: {
55+
'x-service-token': tokens.serviceToken,
56+
'x-oauth-token': tokens.oauthToken
57+
},
58+
throwOnError: true
59+
});
60+
61+
client.interceptors.error.use((err, response, _req, options) => {
62+
if (!options.throwOnError) {
63+
return err;
64+
}
65+
66+
return new InternalApiError(response, err);
67+
});
68+
69+
return new InternalApi({
70+
client
71+
});
72+
}

apps/juxtaposition-ui/src/api/empathy.ts

Lines changed: 0 additions & 34 deletions
This file was deleted.

apps/juxtaposition-ui/src/api/page.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.

apps/juxtaposition-ui/src/api/post.ts

Lines changed: 0 additions & 116 deletions
This file was deleted.

0 commit comments

Comments
 (0)