@owlmeans/server-context 0.1.18-rc.8 → 0.1.18

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 CHANGED
@@ -12,7 +12,7 @@ Server-side context factory with file-based config, trusted keys, and Ed25519 gu
12
12
  ## Installation
13
13
 
14
14
  ```bash
15
- bun add @owlmeans/server-context
15
+ bun add @owlmeans/server-context@^0.1.18
16
16
  ```
17
17
 
18
18
  ## Usage
@@ -70,7 +70,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
70
70
  your project's skill store (`.agents/skills/`):
71
71
 
72
72
  ```sh
73
- npx @owlmeans/agent-skills
73
+ npx @owlmeans/agent-skills@^0.1.18
74
74
  ```
75
75
 
76
76
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
- "schemaVersion": 2,
2
+ "schemaVersion": 3,
3
3
  "package": "@owlmeans/server-context",
4
- "version": "0.1.18-rc.7",
5
- "generatedAt": "2026-08-24T21:14:00.122Z",
4
+ "version": "0.1.18",
5
+ "generatedAt": "2026-10-28T00:31:34.732Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: server-context
3
- description: How to use @owlmeans/server-context — server-side context factory (makeServerContext / makeBackendContext) used as the base in your server makeContext(). Auto-invoked when building a server context.
3
+ description: How to use @owlmeans/server-context — makeServerContext() as the base of a server makeContext(), the ServerConfig shape, config() to build one, and the fileConfigReader middleware. Auto-invoked when building a server context or asking what a bare server context already carries.
4
4
  user-invocable: false
5
5
  ---
6
6
  <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
@@ -8,35 +8,78 @@ user-invocable: false
8
8
  # @owlmeans/server-context
9
9
 
10
10
  **Layer:** Server
11
- **Install:** `"@owlmeans/server-context": "^0.1.18-rc.7"` in `dependencies`
11
+ **Install:** `"@owlmeans/server-context": "^0.1.18"` in `dependencies`
12
12
 
13
13
  ## Key Exports
14
14
 
15
15
  | Export | Description |
16
16
  |--------|-------------|
17
- | `makeServerContext` / `makeBackendContext` | Server context factory — base for your `makeContext` |
18
- | `Context` (server) types | Server-side Context interface |
19
- | Server config types | Server-specific config shape |
17
+ | `makeServerContext(cfg)` | Server context factory — the base your `makeContext` builds on |
18
+ | `config(service, cfg?)` | Build a `ServerConfig` for `service` — app type `Backend`, `trusted` defaulted to an empty list |
19
+ | `ServerContext<C>` | Server-side context interface — a basic context plus the config-resource accessors |
20
+ | `ServerConfig` | Server config shape — the server and client config bases plus `services: Record<string, ServiceRoute>` |
20
21
 
21
22
  ## Subpath Exports
22
23
 
23
- - `./utils` — server context utilities
24
+ - `./utils` — `fileConfigReader`, the config-reading middleware
25
+
26
+ ## What a bare server context already carries
27
+
28
+ `makeServerContext` is not an empty container. Before it returns it registers:
29
+
30
+ - `fileConfigReader` — a `Config`/`Configuration`-stage middleware that walks the whole config tree
31
+ and replaces every writable string starting with `/` by that file's trimmed contents (through
32
+ `readConfigValue` from `@owlmeans/server-config`, so mount secrets at absolute paths). This is how
33
+ a mounted secret becomes a plain config value.
34
+
35
+ **Read converted values after `init()`, never straight after `configure()`.** `configure()` is not
36
+ an async function: it starts the `Config`/`Configuration` middlewares in a detached promise and
37
+ returns the context immediately, so nothing in the tree is converted yet when it returns. The
38
+ ordering guarantee comes from `waitForConfigured()`, and from `init()`, which awaits it first.
39
+
40
+ That detachment also decides how a bad path fails. `readConfigValue` is synchronous and unguarded,
41
+ and the middleware runner is a bare `Promise.all` with no catch, so a config string that looks
42
+ like a path but names no file does **not** throw out of `configure()` — the `ENOENT` escapes as an
43
+ unhandled rejection. The stage is never advanced past `Configuration` either, so the promise
44
+ `init()` awaits never resolves and the boot hangs instead of failing. Read an unhandled `ENOENT`
45
+ at boot as a missing mount, and install an `unhandledRejection` handler that exits non-zero if the
46
+ boot has to be loud.
47
+ - Three config resources — the default record store, one keyed on `trusted`, and one keyed on
48
+ `plugins` — reachable through `getConfigResource(alias?)`.
49
+ - The basic Ed25519 guard over the `trusted` list, which is what authenticates service-to-service
50
+ calls.
51
+ - `authMiddleware`, which wraps the `invoke` of every guarded backend entrypoint so outbound calls
52
+ carry an authentication header.
53
+
54
+ So a downstream factory adds its own services on top rather than assembling these again.
24
55
 
25
56
  ## Usage
26
57
 
27
- A downstream `backend` package typically wraps `makeBackendContext` and re-exports its own `makeContext`:
58
+ A downstream `backend` package wraps `makeServerContext` and exports its own `makeContext`. It calls
59
+ the factory below it, applies its own idempotent `append*(context)` mixins and service
60
+ registrations, and returns that same context — the process gets one context, built once:
28
61
 
29
62
  ```typescript
30
- // viable-backend/src/context.ts
31
- import { makeBackendContext as makeBaseBackendContext } from '@owlmeans/server-context'
63
+ // src/context.ts
64
+ import { makeServerContext } from '@owlmeans/server-context'
65
+ import type { ServerConfig, ServerContext } from '@owlmeans/server-context'
32
66
 
33
- export const makeBackendContext = <C extends Config, T extends Context<C>>(cfg: C): T => {
34
- const context = makeBaseBackendContext<C, T>(cfg)
67
+ export const makeBackendContext = <C extends ServerConfig, T extends ServerContext<C>>(cfg: C): T => {
68
+ const context = makeServerContext<C, T>(cfg)
35
69
  // ... register shared services
36
70
  return context
37
71
  }
38
72
  ```
39
73
 
74
+ An application server usually starts from `@owlmeans/server-app#makeContext` instead, which builds on
75
+ this and adds the API server, API client, sockets, the static resource and auth.
76
+
40
77
  ## Depends On
41
78
 
42
- - `@owlmeans/context`, `@owlmeans/server-config`, `@owlmeans/server-entrypoint`, `@owlmeans/server-route`
79
+ Declared: `@owlmeans/context`, `@owlmeans/config`, `@owlmeans/client-config`,
80
+ `@owlmeans/server-config`, `@owlmeans/route`.
81
+
82
+ Imported but **not** declared in this package's manifest: `@owlmeans/auth-common` (the Ed25519
83
+ guard and the outbound-auth middleware registered above) and `@owlmeans/server-route` (the
84
+ `ServiceRoute` type `ServerConfig` is built from). A workspace resolves them anyway; a standalone
85
+ install has to name them in its own dependencies.
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAMxD,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,KAAG,CAc9F,CAAA"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAOxD,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,KAAG,CAc9F,CAAA"}
package/build/context.js CHANGED
@@ -3,10 +3,12 @@ import { fileConfigReader } from './utils/context.js';
3
3
  import { makeBasicContext } from '@owlmeans/context';
4
4
  import { PLUGINS, TRUSTED } from '@owlmeans/config';
5
5
  import { authMiddleware, makeBasicEd25519Guard } from '@owlmeans/auth-common';
6
+ import { appendLog } from '@owlmeans/log';
6
7
  export const makeServerContext = (cfg) => {
7
8
  const context = makeBasicContext(cfg);
8
9
  context.registerMiddleware(fileConfigReader);
9
- context.makeContext = makeServerContext;
10
+ // After the file reader, so a level given as `/etc/app-config/log-level` is applied resolved.
11
+ appendLog(context);
10
12
  appendConfigResource(context);
11
13
  appendConfigResource(context, TRUSTED, TRUSTED);
12
14
  appendConfigResource(context, PLUGINS, PLUGIN_RECORD);
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAE7E,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAqD,GAAM,EAAK,EAAE;IACjG,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAM,CAAA;IAE1C,OAAO,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAA;IAE5C,OAAO,CAAC,WAAW,GAAG,iBAA+C,CAAA;IAErE,oBAAoB,CAAO,OAAO,CAAC,CAAA;IACnC,oBAAoB,CAAO,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACrD,oBAAoB,CAAO,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,CAAA;IAC3D,OAAO,CAAC,eAAe,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAA;IACvD,OAAO,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAA;IAE1C,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAEzC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAqD,GAAM,EAAK,EAAE;IACjG,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAM,CAAA;IAE1C,OAAO,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAA;IAC5C,8FAA8F;IAC9F,SAAS,CAAC,OAAO,CAAC,CAAA;IAElB,oBAAoB,CAAO,OAAO,CAAC,CAAA;IACnC,oBAAoB,CAAO,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACrD,oBAAoB,CAAO,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,CAAA;IAC3D,OAAO,CAAC,eAAe,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAA;IACvD,OAAO,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAA;IAE1C,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
@@ -1,3 +1,3 @@
1
- import type { Middleware } from '@owlmeans/context';
1
+ import { type Middleware } from '@owlmeans/context';
2
2
  export declare const fileConfigReader: Middleware;
3
3
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/utils/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAGnD,eAAO,MAAM,gBAAgB,EAAE,UAO9B,CAAA"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/utils/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAmC,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAIpF,eAAO,MAAM,gBAAgB,EAAE,UAO9B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/utils/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEnE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAEzD,MAAM,CAAC,MAAM,gBAAgB,GAAe;IAC1C,IAAI,EAAE,cAAc,CAAC,MAAM;IAC3B,KAAK,EAAE,eAAe,CAAC,aAAa;IACpC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACvB,MAAM,IAAI,GAAS,OAAO,CAAC,GAAsB,CAAA;QACjD,gBAAgB,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC;CACF,CAAA;AAED,8BAA8B;AAC9B,MAAM,gBAAgB,GAAG,CAAC,IAAU,EAAE,EAAE,CACtC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,MAAM,CAAC,wBAAwB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAC7D,IAAI,UAAU,EAAE,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;QACpC,CAAC;IACH,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,gBAAgB,CAAC,IAAY,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;IAC3D,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACrC,gBAAgB,CAAC,KAAa,CAAC,CAAA;IACjC,CAAC;AACH,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/utils/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAmB,MAAM,mBAAmB,CAAA;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAGzD,MAAM,CAAC,MAAM,gBAAgB,GAAe;IAC1C,IAAI,EAAE,cAAc,CAAC,MAAM;IAC3B,KAAK,EAAE,eAAe,CAAC,aAAa;IACpC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACvB,MAAM,IAAI,GAAS,OAAO,CAAC,GAAsB,CAAA;QACjD,gBAAgB,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC;CACF,CAAA;AAED,8BAA8B;AAC9B,MAAM,gBAAgB,GAAG,CAAC,IAAU,EAAE,EAAE,CACtC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,MAAM,CAAC,wBAAwB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAC7D,IAAI,UAAU,EAAE,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAA;QACpC,CAAC;IACH,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,gBAAgB,CAAC,IAAY,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;IAC3D,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACrC,gBAAgB,CAAC,KAAa,CAAC,CAAA;IACjC,CAAC;AACH,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA"}
@@ -0,0 +1,5 @@
1
+ export type TreeKey = string | number | symbol;
2
+ export type TreeValue = unknown | Array<unknown> | string;
3
+ export interface Tree extends Record<TreeKey, TreeValue | Tree> {
4
+ }
5
+ //# sourceMappingURL=types.local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.local.d.ts","sourceRoot":"","sources":["../../src/utils/types.local.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;AAE9C,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,MAAM,CAAA;AAEzD,MAAM,WAAW,IAAK,SAAQ,MAAM,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;CAAI"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.local.js","sourceRoot":"","sources":["../../src/utils/types.local.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/server-context",
3
- "version": "0.1.18-rc.8",
3
+ "version": "0.1.18",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -28,15 +28,16 @@
28
28
  }
29
29
  },
30
30
  "dependencies": {
31
- "@owlmeans/client-config": "^0.1.18-rc.8",
32
- "@owlmeans/config": "^0.1.18-rc.8",
33
- "@owlmeans/context": "^0.1.18-rc.6",
34
- "@owlmeans/route": "^0.1.18-rc.6",
35
- "@owlmeans/server-config": "^0.1.18-rc.8"
31
+ "@owlmeans/client-config": "^0.1.18",
32
+ "@owlmeans/config": "^0.1.18",
33
+ "@owlmeans/context": "^0.1.18",
34
+ "@owlmeans/log": "^0.1.18",
35
+ "@owlmeans/route": "^0.1.18",
36
+ "@owlmeans/server-config": "^0.1.18"
36
37
  },
37
38
  "devDependencies": {
38
- "@owlmeans/dep-config": "workspace:*",
39
- "@types/node": "^26.1.0",
39
+ "@owlmeans/dep-config": "^0.1.18",
40
+ "@types/node": "^26.6.4",
40
41
  "nodemon": "^3.1.14",
41
42
  "typescript": "^7.0.2"
42
43
  },
package/src/context.ts CHANGED
@@ -4,13 +4,14 @@ import { fileConfigReader } from './utils/context.js'
4
4
  import { makeBasicContext } from '@owlmeans/context'
5
5
  import { PLUGINS, TRUSTED } from '@owlmeans/config'
6
6
  import { authMiddleware, makeBasicEd25519Guard } from '@owlmeans/auth-common'
7
+ import { appendLog } from '@owlmeans/log'
7
8
 
8
9
  export const makeServerContext = <C extends ServerConfig, T extends ServerContext<C>>(cfg: C): T => {
9
10
  const context = makeBasicContext(cfg) as T
10
11
 
11
12
  context.registerMiddleware(fileConfigReader)
12
-
13
- context.makeContext = makeServerContext as typeof context.makeContext
13
+ // After the file reader, so a level given as `/etc/app-config/log-level` is applied resolved.
14
+ appendLog(context)
14
15
 
15
16
  appendConfigResource<C, T>(context)
16
17
  appendConfigResource<C, T>(context, TRUSTED, TRUSTED)
@@ -1,7 +1,7 @@
1
1
 
2
- import { MiddlewareStage, MiddlewareType } from '@owlmeans/context'
3
- import type { Middleware } from '@owlmeans/context'
2
+ import { MiddlewareStage, MiddlewareType, type Middleware } from '@owlmeans/context'
4
3
  import { readConfigValue } from '@owlmeans/server-config'
4
+ import type { Tree } from './types.local.js'
5
5
 
6
6
  export const fileConfigReader: Middleware = {
7
7
  type: MiddlewareType.Config,
@@ -27,6 +27,3 @@ const visitConfigLeafs = (tree: Tree) =>
27
27
  }
28
28
  }) : tree
29
29
 
30
- type TreeKey = string | number | symbol
31
- type TreeValue = unknown | Array<unknown> | string
32
- interface Tree extends Record<TreeKey, TreeValue | Tree> { }
@@ -0,0 +1,5 @@
1
+ export type TreeKey = string | number | symbol
2
+
3
+ export type TreeValue = unknown | Array<unknown> | string
4
+
5
+ export interface Tree extends Record<TreeKey, TreeValue | Tree> { }
package/build/.gitkeep DELETED
File without changes