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
5 changes: 5 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ Keep implementation, runtime tests, and type tests close together in `src/`.
When adding a public symbol, export it through the nearest barrel file and make
sure it is reachable from `src/index.ts`.

The folder barrel files intentionally enumerate the public API. Do not replace
their named exports with `export *`: registration, resolution, identity, cache,
and builder implementations must remain internal. Internal code should import
those symbols from their defining files rather than from a public barrel.

## Runtime model and invariants

- A module registers, in order: hooks, installers, controllers, then child
Expand Down
3 changes: 1 addition & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
"license": "MIT",
"devDependencies": {
"@eslint/js": "^9.39.4",
"@sinclair/typebox": "^0.34.49",
"@types/node": "^25.9.4",
"c8": "^10.1.3",
"eslint": "^9.39.4",
Expand All @@ -51,6 +50,7 @@
"typescript-eslint": "^8.62.0"
},
"dependencies": {
"@sinclair/typebox": "^0.34.49",
"fastify": "^5.8.5",
"fastify-plugin": "^5.1.0"
},
Expand Down
4 changes: 2 additions & 2 deletions src/container/container.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ModuleContext } from "../modules";
import type { ModuleContext } from "../modules/module.types";
import type {
DepValues,
ProviderAny,
ProviderDef,
BaseProviderDepsMap,
} from "../providers";
} from "../providers/providers.types";

export class Container {
private singletons = new WeakMap<object, Promise<unknown>>();
Expand Down
14 changes: 5 additions & 9 deletions src/controllers/controllers.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import type { ProvidersMap } from "../providers";
import type { ProvidersMap } from "../providers/providers.types";
import { RoutesBuilder } from "./routes-builder";
import {
ControllerConfig,
ControllerOptions,
resolveProviderMap,
} from "../modules";
import { AdapterMap, resolveAdapterMap } from "../fastify";
import type { ControllerConfig, ControllerOptions } from "./controllers.types";
import { resolveProviderMap } from "../modules/module";
import { resolveAdapterMap } from "../fastify/adapters";
import type { AdapterMap } from "../fastify/adapters.types";

export function createController<
Providers extends ProvidersMap,
Expand Down Expand Up @@ -46,5 +44,3 @@ export function createController<
},
};
}

export const controller = createController;
8 changes: 6 additions & 2 deletions src/controllers/controllers.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@ import { Static, TSchema } from "@sinclair/typebox";
import { ExposeDeps, ProvidersMap } from "../providers";
import { RoutesBuilder } from "./routes-builder";
import { Container } from "../container/container";
import { AdapterCache, AdapterMap, AdapterValues } from "../fastify";
import { ModuleContext } from "../modules";
import type {
AdapterCache,
AdapterMap,
AdapterValues,
} from "../fastify/adapters.types";
import type { ModuleContext } from "../modules/module.types";

type ErrorHandler = (
error: unknown,
Expand Down
15 changes: 12 additions & 3 deletions src/controllers/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
export * from "./routes-builder";
export * from "./controllers";
export * from "./controllers.types";
export {
createController,
createController as controller,
} from "./controllers";
export type {
BaseStratifyRouteOptions,
ControllerBuilderCallback,
ControllerConfig,
ControllerOptions,
ExtractRouteGenerics,
StratifyRouteOptions,
} from "./controllers.types";
11 changes: 6 additions & 5 deletions src/fastify/adapter-fastify-instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ const forbiddenAdapterFastifyProperties = [
"addHttpMethod",
"addConstraintStrategy",
"supportedMethods",
Symbol.asyncDispose,
] as const;

type ForbiddenAdapterFastifyProperty =
(typeof forbiddenAdapterFastifyProperties)[number];
| (typeof forbiddenAdapterFastifyProperties)[number]
| Extract<keyof FastifyInstance, symbol>;

/**
* Read-only Fastify view available to adapters.
Expand All @@ -68,9 +68,10 @@ export type AdapterFastifyInstance = Readonly<
Omit<FastifyInstance, ForbiddenAdapterFastifyProperty>
>;

const forbiddenProperties = new Set<PropertyKey>(
forbiddenAdapterFastifyProperties,
);
const forbiddenProperties = new Set<PropertyKey>([
...forbiddenAdapterFastifyProperties,
Symbol.asyncDispose,
]);

export function restrictFastifyForAdapter(
fastify: FastifyInstance,
Expand Down
2 changes: 0 additions & 2 deletions src/fastify/adapters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,3 @@ export async function resolveAdapterMap<AMap extends AdapterMap>(

return out as AdapterValues<AMap>;
}

export const adapter = createAdapter;
19 changes: 15 additions & 4 deletions src/fastify/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
export * from "./installers";
export * from "./installers.types";
export * from "./adapters";
export * from "./adapters.types";
export { createAdapter, createAdapter as adapter } from "./adapters";
export { createInstaller, createInstaller as installer } from "./installers";
export type {
AdapterAny,
AdapterDef,
AdapterFastifyInstance,
AdapterMap,
AdapterOptions,
AdapterValues,
} from "./adapters.types";
export type {
InstallerBuilderCallback,
InstallerConfig,
InstallerOptions,
} from "./installers.types";
7 changes: 3 additions & 4 deletions src/fastify/installers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { FastifyInstance } from "fastify";
import type { ProvidersMap } from "../../src/providers";
import type { ProvidersMap } from "../providers/providers.types";
import type { Container } from "../../src/container/container";
import { resolveProviderMap, type ModuleContext } from "../../src/modules";
import { resolveProviderMap } from "../modules/module";
import type { ModuleContext } from "../modules/module.types";
import type { InstallerOptions, InstallerConfig } from "./installers.types";

export function createInstaller<Providers extends ProvidersMap>(
Expand All @@ -28,5 +29,3 @@ export function createInstaller<Providers extends ProvidersMap>(
},
};
}

export const installer = createInstaller;
2 changes: 1 addition & 1 deletion src/fastify/installers.types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { FastifyInstance } from "fastify";
import type { ProvidersMap, ExposeDeps } from "../../src/providers";
import type { Container } from "../../src/container/container";
import { ModuleContext } from "../modules";
import type { ModuleContext } from "../modules/module.types";

/**
* Installer builder callback.
Expand Down
10 changes: 5 additions & 5 deletions src/hooks/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FastifyInstance } from "fastify";
import { ProvidersMap } from "../providers";
import type { ProvidersMap } from "../providers/providers.types";
import {
AppHooksConfig,
AppHooksOptions,
Expand All @@ -9,8 +9,10 @@ import {
import { Container } from "../container/container";
import { HttpHooksBuilder } from "./http-hooks-builder";
import { AppHooksBuilder } from "./application-hooks-builder";
import { ModuleContext, resolveProviderMap } from "../modules";
import { AdapterCache, AdapterMap, resolveAdapterMap } from "../fastify";
import { resolveProviderMap } from "../modules/module";
import type { ModuleContext } from "../modules/module.types";
import { resolveAdapterMap } from "../fastify/adapters";
import type { AdapterCache, AdapterMap } from "../fastify/adapters.types";

export function createHooks<
Providers extends ProvidersMap,
Expand Down Expand Up @@ -71,5 +73,3 @@ export function createHooks<
},
};
}

export const hooks = createHooks;
17 changes: 10 additions & 7 deletions src/hooks/hooks.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ import {
RequestPayload,
RouteOptions,
} from "fastify";
import { ApplicationHook, LifecycleHook } from "fastify/types/hooks";
import { HttpHooksBuilder } from "./http-hooks-builder";
import { ExposeDeps, ProvidersMap } from "../providers";
import { Container } from "../container/container";
import { AppHooksBuilder } from "./application-hooks-builder";
import { AdapterCache, AdapterMap, AdapterValues } from "../fastify";
import { ModuleContext } from "../modules";
import type {
AdapterCache,
AdapterMap,
AdapterValues,
} from "../fastify/adapters.types";
import type { ModuleContext } from "../modules/module.types";

// --- HTTP hooks ---
export type OnRequestHandler = (
Expand Down Expand Up @@ -60,8 +63,6 @@ export type OnRequestAbortHandler = (
request: FastifyRequest,
) => Promise<unknown>;

export type HttpHookName = LifecycleHook;

export type HttpHookMap = {
onRequest: OnRequestHandler[];
preParsing: OnPreParsingHandler[];
Expand All @@ -75,6 +76,8 @@ export type HttpHookMap = {
onRequestAbort: OnRequestAbortHandler[];
};

export type HttpHookName = keyof HttpHookMap;

export type HttpHookHandlers<K extends keyof HttpHookMap> = HttpHookMap[K];
export type HttpHookHandler<K extends keyof HttpHookMap> =
HttpHookHandlers<K>[number];
Expand Down Expand Up @@ -133,8 +136,6 @@ export type OnRegisterHandler = (
opts: RegisterOptions & FastifyPluginOptions,
) => void;

export type AppHookName = ApplicationHook;

export type AppHookMap = {
onReady: OnReadyHandler[];
onClose: OnCloseHandler[];
Expand All @@ -144,6 +145,8 @@ export type AppHookMap = {
preClose: OnPreCloseHandler[];
};

export type AppHookName = keyof AppHookMap;

type ApplicationHooksBuilderCallback<
Providers extends ProvidersMap,
Adaps extends AdapterMap,
Expand Down
33 changes: 29 additions & 4 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,29 @@
export * from "./hooks.types";
export * from "./hooks";
export * from "./http-hooks-builder";
export * from "./application-hooks-builder";
export { createHooks, createHooks as hooks } from "./hooks";
export type {
AppHookMap,
AppHookName,
AppHooksConfig,
AppHooksOptions,
HttpHookHandler,
HttpHookHandlers,
HttpHookMap,
HttpHookName,
HttpHooksConfig,
HttpHooksOptions,
OnCloseHandler,
OnErrorHookHandler,
OnListenHandler,
OnPreCloseHandler,
OnPreHandlerHandler,
OnPreParsingHandler,
OnPreSerializationHandler,
OnPreValidationHandler,
OnReadyHandler,
OnRegisterHandler,
OnRequestAbortHandler,
OnRequestHandler,
OnResponseHandler,
OnRouteHandler,
OnSendHookHandler,
OnTimeoutHandler,
} from "./hooks.types";
6 changes: 4 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ export * from "./hooks";
export * from "./controllers";
export * from "./fastify";

import { getProviderId, resolveDeps, type ProviderAny } from "./providers";
import { getProviderId, resolveDeps } from "./providers/providers";
import type { ProviderAny } from "./providers/providers.types";
import { Container } from "./container/container";
import { describeTree } from "./printer/describe-tree";
import { getModuleId, ModuleAny, registerModule } from "./modules";
import { getModuleId, registerModule } from "./modules/module";
import type { ModuleAny } from "./modules/module.types";

export interface CreateAppOptions {
root: ModuleAny;
Expand Down
10 changes: 7 additions & 3 deletions src/modules/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export * from "./module";
export * from "./module.types";
export * from "../controllers/controllers.types";
export { createModule, createModule as mod } from "./module";
export type {
ModuleAny,
ModuleDef,
ModuleOptions,
SubModulesMap,
} from "./module.types";
6 changes: 2 additions & 4 deletions src/modules/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import {
ModuleOptions,
SubModulesMap,
} from "./module.types";
import { ProvidersMap } from "../providers";
import { AdapterCache } from "../fastify";
import type { AdapterCache } from "../fastify/adapters.types";
import type { ProvidersMap } from "../providers/providers.types";

const kModuleId = Symbol("fastify-dependency-injection:moduleId");
let __seq = 0;
Expand Down Expand Up @@ -97,5 +97,3 @@ export async function resolveProviderMap(

return out;
}

export const mod = createModule;
8 changes: 5 additions & 3 deletions src/printer/describe-tree.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { AdapterAny } from "../fastify";
import { getModuleId, type ModuleAny } from "../modules";
import { getProviderId, type ProviderAny } from "../providers";
import type { AdapterAny } from "../fastify/adapters.types";
import { getModuleId } from "../modules/module";
import type { ModuleAny } from "../modules/module.types";
import { getProviderId } from "../providers/providers";
import type { ProviderAny } from "../providers/providers.types";

const useColor = process.stdout.isTTY;
const wrap = (code: number, s: string, enabled: boolean) => {
Expand Down
18 changes: 16 additions & 2 deletions src/providers/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
export * from "./providers";
export * from "./providers.types";
export {
contract,
createProvider,
createProvider as provider,
} from "./providers";
export type {
BaseProviderDepsMap,
DepValues,
ExposeDeps,
InferProviderContract,
ProviderAny,
ProviderContract,
ProviderDef,
ProviderOptions,
ProvidersMap,
} from "./providers.types";
Loading
Loading