@nexo-alpha/hapi 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # @nexo-alpha/hapi
2
+
3
+ Turns a [`@nexo-alpha/core`](https://www.npmjs.com/package/@nexo-alpha/core) `NexoApplication`'s declared APIs into a real, running [Hapi.js](https://hapi.dev) HTTP server. This is the framework's first package with a real external runtime dependency (`@hapi/hapi`) — everything before it stays dependency-free by design.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @nexo-alpha/hapi @nexo-alpha/core @hapi/hapi
9
+ ```
10
+
11
+ ## Why
12
+
13
+ Nexo's application model is otherwise purely declarative — `NexoApi` describes an endpoint's method, path, and metadata, but nothing runs it. `@nexo-alpha/hapi` is the adapter that turns a `handler`-bearing `NexoApi` into an actual route, keeping `@nexo-alpha/core` itself Hapi-agnostic.
14
+
15
+ ## Usage
16
+
17
+ ```ts
18
+ import { createApplication } from "@nexo-alpha/core";
19
+ import { startHapiServer } from "@nexo-alpha/hapi";
20
+
21
+ const app = createApplication({ name: "shop" });
22
+
23
+ app.module({
24
+ name: "hello",
25
+ apis: [
26
+ {
27
+ name: "sayHello",
28
+ method: "GET",
29
+ path: "/hello",
30
+ handler: async () => ({ message: "Hello from Nexo" })
31
+ }
32
+ ]
33
+ });
34
+
35
+ const server = await startHapiServer(app, { port: 3000 });
36
+ console.log(`Listening on ${server.info.uri}`);
37
+ ```
38
+
39
+ ```bash
40
+ curl http://localhost:3000/hello
41
+ # {"message":"Hello from Nexo"}
42
+ ```
43
+
44
+ ### Auth and validation
45
+
46
+ `NexoApi.auth` and `NexoApi.validate` are plain declarative/function hooks (no Joi, no JWT library — `@nexo-alpha/core` stays dependency-free); the actual verification logic is supplied by you:
47
+
48
+ ```ts
49
+ app.module({
50
+ name: "widgets",
51
+ apis: [
52
+ {
53
+ name: "createWidget",
54
+ method: "POST",
55
+ path: "/widgets",
56
+ auth: { required: true, scopes: ["widgets:write"] },
57
+ validate: (context) => {
58
+ const payload = context.payload;
59
+ if (!payload || typeof payload.name !== "string") {
60
+ return { valid: false, errors: ["name is required"] };
61
+ }
62
+ return { valid: true };
63
+ },
64
+ handler: async (context) => ({ created: context.payload.name })
65
+ }
66
+ ]
67
+ });
68
+
69
+ const server = await startHapiServer(app, {
70
+ authenticate: async (context) => {
71
+ const token = context.headers.authorization;
72
+ // verify the token however you like (JWT, session lookup, API key, ...)
73
+ return token === "Bearer good-token"
74
+ ? { authenticated: true, scopes: ["widgets:write"] }
75
+ : { authenticated: false };
76
+ }
77
+ });
78
+ ```
79
+
80
+ Requests to `/widgets` now run through **Identity → Permission → Validation → Operation** before the handler: no/invalid auth → `401`; authenticated but missing a required scope → `403`; validation fails → `400` with `errors`; otherwise the handler runs, unchanged. If any API declares `auth.required` but no `authenticate` option is passed to `createHapiServer`/`startHapiServer`, server creation fails immediately rather than silently serving an unenforceable route.
81
+
82
+ ### Observability
83
+
84
+ Every route emits through `app.events` (`@nexo-alpha/core`'s `NexoEventBus`), so you can observe traffic without touching the route logic:
85
+
86
+ ```ts
87
+ app.events.on("api.called", ({ api, method, path, statusCode, durationMs }) => {
88
+ console.log(`${method} ${path} (${api}) -> ${statusCode} in ${durationMs}ms`);
89
+ });
90
+
91
+ app.events.on("api.error", ({ api, error }) => {
92
+ console.error(`${api} handler threw:`, error);
93
+ });
94
+ ```
95
+
96
+ `api.called` fires for every completed request — including auth/validation denials (`401`/`403`/`400`) — with the actual status code, so you can see e.g. how much traffic to an endpoint is getting rejected. `api.error` fires only when the handler itself throws; the error still propagates and Hapi still returns its own default `500`, unchanged. `@nexo-alpha/tools`'s `createMetricsCollector(app)` subscribes to these same events to build call/error counts and average durations, if you want aggregated numbers instead of raw events.
97
+
98
+ ## What's here
99
+
100
+ - **`createHapiServer(app, options?)`** — builds a `Hapi.server(...)` and registers a route for every API that has a `handler`. Path params use Express-style `:id` in `NexoApi.path` (matching the rest of Nexo's examples) and are converted to Hapi's `{id}` syntax automatically.
101
+ - **`startHapiServer(app, options?)`** — `createHapiServer` plus `server.start()`.
102
+ - **`toHapiPath(path)`** — the `:id` → `{id}` path converter, exported directly if you need it.
103
+ - A handler receives a plain `NexoRequestContext` (`params`, `query`, `payload`, `headers`) — no Hapi types leak into `@nexo-alpha/core`. Return a value to send it as the response (objects are serialized to JSON automatically); return `undefined` for a `204`.
104
+ - `options.authenticate` — an optional `NexoAuthenticator` used for every API with `auth.required`, checked before validation and before the handler runs.
105
+
106
+ ## Design notes
107
+
108
+ - **APIs without a `handler` get no route.** They stay descriptive-only, exactly as they appear in `@nexo-alpha/context`'s manifest and `@nexo-alpha/cli`'s output.
109
+ - **`HEAD` is not registered as an explicit route** — Hapi generates `HEAD` responses from `GET` routes automatically and rejects `HEAD` as an explicit method.
110
+ - **Auth runs before validation** — both the PRD's stated request pipeline (Identity → Permission → ... → Validation → Operation) and standard security practice: an unauthenticated caller shouldn't learn anything about payload shape from a `400`.
111
+
112
+ ## Related packages
113
+
114
+ - [`@nexo-alpha/core`](https://www.npmjs.com/package/@nexo-alpha/core) — the application/module model, including `NexoRequestContext`, `NexoApiHandler`, `NexoApiAuth`, `NexoRequestValidator`, and `NexoAuthenticator`
115
+
116
+ ## Status
117
+
118
+ **v0.1-alpha.** No lifecycle wiring to `NexoApplication.start()`/`stop()` yet — creating and starting the Hapi server is a separate step from the application's own lifecycle.
119
+
120
+ ## License
121
+
122
+ MIT
@@ -1,8 +1,10 @@
1
1
  import Hapi from "@hapi/hapi";
2
- import type { NexoApplication } from "@nexo-alpha/core";
2
+ import { type NexoApplication, type NexoAuthenticator } from "@nexo-alpha/core";
3
3
  export interface CreateHapiServerOptions {
4
4
  readonly port?: number;
5
5
  readonly host?: string;
6
+ readonly authenticate?: NexoAuthenticator;
7
+ readonly bindLifecycle?: boolean;
6
8
  }
7
9
  export declare function toHapiPath(path: string): string;
8
10
  export declare function createHapiServer(app: NexoApplication, options?: CreateHapiServerOptions): Promise<Hapi.Server>;
@@ -1 +1 @@
1
- {"version":3,"file":"create-server.d.ts","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,YAAY,CAAC;AAC9B,OAAO,KAAK,EAAE,eAAe,EAAsB,MAAM,kBAAkB,CAAC;AAE5E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,eAAe,EACpB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAsCtB;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,eAAe,EACpB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAItB"}
1
+ {"version":3,"file":"create-server.d.ts","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,YAAY,CAAC;AAC9B,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAEvB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAC;IAC1C,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAQD,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,eAAe,EACpB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAyGtB;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,eAAe,EACpB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAgBtB"}
@@ -1,13 +1,25 @@
1
1
  import Hapi from "@hapi/hapi";
2
+ import { NexoEvent } from "@nexo-alpha/core";
2
3
  export function toHapiPath(path) {
3
4
  return path.replace(/:([A-Za-z0-9_]+)/g, "{$1}");
4
5
  }
6
+ function missingScopes(api, granted) {
7
+ const required = api.auth?.scopes ?? [];
8
+ const grantedSet = new Set(granted ?? []);
9
+ return required.filter((scope) => !grantedSet.has(scope));
10
+ }
5
11
  export async function createHapiServer(app, options = {}) {
6
12
  const server = Hapi.server({
7
13
  port: options.port ?? 3000,
8
14
  host: options.host ?? "localhost"
9
15
  });
10
- for (const api of app.getApis()) {
16
+ const apis = app.getApis();
17
+ for (const api of apis) {
18
+ if (api.auth?.required && options.authenticate === undefined) {
19
+ throw new Error(`API "${api.name}" requires auth, but no "authenticate" option was provided to createHapiServer().`);
20
+ }
21
+ }
22
+ for (const api of apis) {
11
23
  if (api.handler === undefined) {
12
24
  continue;
13
25
  }
@@ -21,14 +33,62 @@ export async function createHapiServer(app, options = {}) {
21
33
  method: api.method,
22
34
  path: toHapiPath(api.path),
23
35
  handler: async (request, h) => {
36
+ const startedAt = Date.now();
37
+ const respond = (statusCode, body) => {
38
+ app.events.emit(NexoEvent.API_CALLED, {
39
+ api: api.name,
40
+ method: api.method,
41
+ path: api.path,
42
+ statusCode,
43
+ durationMs: Date.now() - startedAt
44
+ });
45
+ return body === undefined
46
+ ? h.response().code(statusCode)
47
+ : h.response(body).code(statusCode);
48
+ };
24
49
  const context = {
25
50
  params: request.params,
26
51
  query: request.query,
27
52
  payload: request.payload,
28
53
  headers: request.headers
29
54
  };
30
- const result = await handler(context);
31
- return result === undefined ? h.response().code(204) : result;
55
+ if (api.auth?.required) {
56
+ // Guaranteed defined: createHapiServer already rejected before
57
+ // registering any routes if an auth-required API had no
58
+ // "authenticate" option configured.
59
+ const authResult = await options.authenticate(context);
60
+ if (!authResult.authenticated) {
61
+ return respond(401, { error: "Unauthorized" });
62
+ }
63
+ const missing = missingScopes(api, authResult.scopes);
64
+ if (missing.length > 0) {
65
+ return respond(403, { error: "Forbidden", missingScopes: missing });
66
+ }
67
+ }
68
+ if (api.validate) {
69
+ const outcome = await api.validate(context);
70
+ if (!outcome.valid) {
71
+ return respond(400, {
72
+ error: "Validation failed",
73
+ errors: outcome.errors ?? []
74
+ });
75
+ }
76
+ }
77
+ let result;
78
+ try {
79
+ result = await handler(context);
80
+ }
81
+ catch (error) {
82
+ app.events.emit(NexoEvent.API_ERROR, {
83
+ api: api.name,
84
+ method: api.method,
85
+ path: api.path,
86
+ durationMs: Date.now() - startedAt,
87
+ error: error instanceof Error ? error.message : String(error)
88
+ });
89
+ throw error;
90
+ }
91
+ return result === undefined ? respond(204) : respond(200, result);
32
92
  }
33
93
  });
34
94
  }
@@ -37,6 +97,17 @@ export async function createHapiServer(app, options = {}) {
37
97
  export async function startHapiServer(app, options = {}) {
38
98
  const server = await createHapiServer(app, options);
39
99
  await server.start();
100
+ if (options.bindLifecycle !== false) {
101
+ const onStopping = async () => {
102
+ try {
103
+ await server.stop();
104
+ }
105
+ catch {
106
+ // Best effort if already stopped
107
+ }
108
+ };
109
+ app.events.on(NexoEvent.APPLICATION_STOPPING, onStopping);
110
+ }
40
111
  return server;
41
112
  }
42
113
  //# sourceMappingURL=create-server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-server.js","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,YAAY,CAAC;AAQ9B,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAoB,EACpB,UAAmC,EAAE;IAErC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QACzB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI;QAC1B,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,WAAW;KAClC,CAAC,CAAC;IAEH,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;QAChC,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC9B,SAAS;QACX,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC1B,kEAAkE;YAClE,oDAAoD;YACpD,SAAS;QACX,CAAC;QAED,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAE5B,MAAM,CAAC,KAAK,CAAC;YACX,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;YAC1B,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE;gBAC5B,MAAM,OAAO,GAAuB;oBAClC,MAAM,EAAE,OAAO,CAAC,MAAgC;oBAChD,KAAK,EAAE,OAAO,CAAC,KAAgC;oBAC/C,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,OAAO,EAAE,OAAO,CAAC,OAAiC;iBACnD,CAAC;gBAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;gBAEtC,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAChE,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAoB,EACpB,UAAmC,EAAE;IAErC,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACpD,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"create-server.js","sourceRoot":"","sources":["../src/create-server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexo-alpha/hapi",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Hapi.js HTTP adapter for the Nexo framework",
5
5
  "keywords": [
6
6
  "nexo",
@@ -20,12 +20,15 @@
20
20
  "import": "./dist/index.js"
21
21
  }
22
22
  },
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
23
26
  "files": [
24
27
  "dist"
25
28
  ],
26
29
  "dependencies": {
27
30
  "@hapi/hapi": "^21.0.0",
28
- "@nexo-alpha/core": "0.1.2"
31
+ "@nexo-alpha/core": "0.2.0"
29
32
  },
30
33
  "scripts": {
31
34
  "build": "tsc -p tsconfig.json",