Skip to content
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
4 changes: 2 additions & 2 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
# provides a job-level "allow-failure"/neutral-conclusion feature
# (see: https://github.com/actions/runner/issues/2347 for discussion).

eslint:
lint-fmt:
# ESLint job inlined from check-shared-steps.yml
needs: detect-quota
if: ${{ always() }}
Expand Down Expand Up @@ -78,7 +78,7 @@ jobs:
commitlint:
# Commitlint job inlined from check-shared-steps.yml
needs: detect-quota
if: ${{ always() }}
if: ${{ always() && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
runs-on: ${{ needs.detect-quota.result == 'success' && 'ubuntu-latest' || 'self-hosted' }}
timeout-minutes: 2
continue-on-error: true
Expand Down
1 change: 0 additions & 1 deletion .husky/commit-msg

This file was deleted.

5 changes: 4 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
# corepack yarn test
#!/usr/bin/env sh

yarn dlx lint-staged
yarn compile
3 changes: 3 additions & 0 deletions .husky/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env sh

yarn test
62 changes: 37 additions & 25 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,55 +7,67 @@
"scripts": {
"dev": "fastify start --import=tsx --watch --log-level=debug --pretty-logs --options src/app.ts",
"test": "tsx --test --test-timeout=5000 --experimental-test-coverage test/**/*.test.ts",
"compile": "tsc --noEmit && tsc -p test/tsconfig.json --noEmit",
"compile": "tsgo --noEmit && tsgo -p test/tsconfig.json --noEmit",
"lint": "eslint --fix .",
"lint:check": "eslint .",
"fmt": "prettier --write .",
"fmt": "prettier --write --list-different .",
"fmt:check": "prettier --check .",
"build": "rimraf dist && tsc",
"build": "yarn clean && tsgo",
"start": "fastify start --log-level=info --options dist/src/app.js",
"commitlint": "commitlint --last --strict --verbose",
"clean": "rimraf dist",
"prepare": "husky"
},
"lint-staged": {
"!(*.{js,ts})": [
"yarn fmt",
"git add"
],
"*.{js,ts}": [
"yarn lint",
"yarn fmt",
"git add"
]
},
"engines": {
"node": ">= 24"
},
"author": "USThing Team",
"license": "MIT",
"dependencies": {
"@fastify/autoload": "^6.3.1",
"@fastify/cors": "^11.1.0",
"@fastify/mongodb": "^9.0.2",
"@fastify/cors": "^11.2.0",
"@fastify/mongodb": "^10.0.0",
"@fastify/sensible": "^6.0.4",
"@fastify/swagger": "^9.6.1",
"@fastify/swagger-ui": "^5.2.3",
"@fastify/type-provider-typebox": "^5.2.0",
"@scalar/fastify-api-reference": "^1.40.0",
"@sinclair/typebox": "^0.34.41",
"fastify": "^5.7.3",
"@fastify/swagger": "^9.7.0",
"@fastify/swagger-ui": "^5.2.5",
"@fastify/type-provider-typebox": "^6.1.0",
"@scalar/fastify-api-reference": "^1.44.15",
"fastify": "^5.7.4",
"fastify-cli": "^7.4.1",
"fastify-plugin": "^5.1.0",
"jsonwebtoken": "^9.0.2",
"jwks-rsa": "^3.2.0",
"openid-client": "^6.8.1"
"jsonwebtoken": "^9.0.3",
"jwks-rsa": "^3.2.2",
"openid-client": "^6.8.2",
"typebox": "^1.0.81"
},
"devDependencies": {
"@commitlint/cli": "^20.1.0",
"@commitlint/config-conventional": "^20.0.0",
"@eslint/js": "^9.39.1",
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
"@commitlint/cli": "^20.4.1",
"@commitlint/config-conventional": "^20.4.1",
"@eslint/js": "^9.39.2",
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
"@types/jsonwebtoken": "^9.0.10",
"@types/node": "^24.10.1",
"eslint": "^9.39.1",
"@types/node": "^25.2.2",
"@typescript/native-preview": "^7.0.0-dev.20260212.1",
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"fastify-tsconfig": "^3.0.0",
"husky": "^9.1.7",
"prettier": "^3.7.4",
"prettier-plugin-jsdoc": "^1.7.0",
"lint-staged": "^16.2.7",
"prettier": "^3.8.1",
"prettier-plugin-jsdoc": "^1.8.0",
"rimraf": "^6.1.2",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.48.1"
"typescript-eslint": "^8.54.0"
},
"packageManager": "yarn@4.12.0+sha512.f45ab632439a67f8bc759bf32ead036a1f413287b9042726b7cc4818b7b49e14e9423ba49b18f9e06ea4941c1ad062385b1d8760a8d5091a1a31e5f6219afca8"
}
2 changes: 0 additions & 2 deletions update-from-template → scripts/update-from-template
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/bin/bash

git fetch https://github.com/USThing/template-api.git main # fetches to `FETCH_HEAD`
git merge FETCH_HEAD -m "chore(template): update from upstream"

Expand Down
2 changes: 1 addition & 1 deletion src/plugins/auth.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { ResponseSchema } from "../utils/schema.js";
import { UnionOneOf } from "../utils/typebox/union-oneof.js";
import { Type } from "@sinclair/typebox";
import { FastifyReply, FastifyRequest } from "fastify";
import fp from "fastify-plugin";
import jwt, { JwtHeader, SigningKeyCallback } from "jsonwebtoken";
import { JwksClient } from "jwks-rsa";
import * as client from "openid-client";
import { skipSubjectCheck, WWWAuthenticateChallengeError } from "openid-client";
import { Type } from "typebox";

export interface AuthPluginOptions {
/** The discovery URL of the OpenID Connect provider. */
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/init-mongo.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fp from "fastify-plugin";

// import { Collection } from "mongodb";
// import { Collection, Document } from "mongodb";

export type InitMongoPluginOptions = Record<never, unknown>;

Expand All @@ -18,7 +18,7 @@ export default fp<InitMongoPluginOptions>(async (fastify, opts) => {
// declare module "fastify" {
// export interface FastifyInstance {
// collections: {
// example: Collection<unknown>;
// example: Collection<Document>;
// };
// }
// }
2 changes: 1 addition & 1 deletion src/plugins/sensible.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import sensible from "@fastify/sensible";
import { Type } from "@sinclair/typebox";
import fp from "fastify-plugin";
import { Type } from "typebox";

export const HttpError = Type.Ref("HttpError");

Expand Down
2 changes: 1 addition & 1 deletion src/routes/auth-example/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { FastifyTypebox } from "../../app.js";
import { AuthResponseSchema } from "../../plugins/auth.js";
import { mergeResponse } from "../../utils/schema.js";
import { Type } from "@sinclair/typebox";
import { FastifyPluginAsync } from "fastify";
import { Type } from "typebox";

const authExample: FastifyPluginAsync = async (
fastify: FastifyTypebox,
Expand Down
2 changes: 1 addition & 1 deletion src/routes/example/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FastifyTypebox } from "../../app.js";
import { HttpError } from "../../plugins/sensible.js";
import { Type } from "@sinclair/typebox";
import { FastifyPluginAsync } from "fastify";
import { Type } from "typebox";

const example: FastifyPluginAsync = async (
fastify: FastifyTypebox,
Expand Down
2 changes: 1 addition & 1 deletion src/routes/root.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FastifyTypebox } from "../app.js";
import { Type } from "@sinclair/typebox";
import { FastifyPluginAsync } from "fastify";
import { Type } from "typebox";

const root: FastifyPluginAsync = async (
fastify: FastifyTypebox,
Expand Down
2 changes: 1 addition & 1 deletion src/utils/schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { UnionOneOf } from "./typebox/union-oneof.js";
import { TSchema } from "@sinclair/typebox";
import { TSchema } from "typebox";

export type ResponseSchema = Record<number, TSchema>;

Expand Down
37 changes: 12 additions & 25 deletions src/utils/typebox/union-oneof.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable */
/*--------------------------------------------------------------------------

@sinclair/typebox/prototypes
Expand Down Expand Up @@ -26,42 +25,30 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

---------------------------------------------------------------------------*/
import {
TypeRegistry,
Kind,
Static,
TSchema,
SchemaOptions,
} from "@sinclair/typebox";
import { Value } from "@sinclair/typebox/value";
import { TSchema, TSchemaOptions, Static } from "typebox";

// -------------------------------------------------------------------------------------
// TUnionOneOf
// -------------------------------------------------------------------------------------
export interface TUnionOneOf<T extends TSchema[]> extends TSchema {
[Kind]: "UnionOneOf";
"~kind": "UnionOneOf";
static: { [K in keyof T]: Static<T[K]> }[number];
oneOf: T;
}
// -------------------------------------------------------------------------------------
// UnionOneOf
// -------------------------------------------------------------------------------------
/** `[Experimental]` Creates a Union type with a `oneOf` schema representation */
/**
* `[Experimental]` Creates a Union type with a `oneOf` schema representation
*
* Note: Runtime validation of oneOf is handled by the JSON Schema validator (e.g., Ajv)
* which is used by Fastify. The oneOf keyword is a standard JSON Schema keyword that
* ensures exactly one of the schemas matches. This implementation doesn't need custom
* validation logic as the standard validator handles it.
*/
export function UnionOneOf<T extends TSchema[]>(
oneOf: [...T],
options: SchemaOptions = {},
options: TSchemaOptions = {},
) {
function UnionOneOfCheck(schema: TUnionOneOf<TSchema[]>, value: unknown) {
return (
1 ===
schema.oneOf.reduce(
(acc: number, schema: any) =>
Value.Check(schema, value) ? acc + 1 : acc,
0,
)
);
}
if (!TypeRegistry.Has("UnionOneOf"))
TypeRegistry.Set("UnionOneOf", UnionOneOfCheck);
return { ...options, [Kind]: "UnionOneOf", oneOf } as TUnionOneOf<T>;
return { ...options, "~kind": "UnionOneOf", oneOf } as TUnionOneOf<T>;
}
9 changes: 7 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
{
"extends": "fastify-tsconfig",
"compilerOptions": {
"outDir": "dist"
"outDir": "dist",
"module": "nodenext",
"target": "esnext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"moduleResolution": "nodenext"
},
"include": ["src/**/*.ts"]
}
Loading
Loading