@capixjs/core 0.1.0-alpha.1
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/LICENSE +21 -0
- package/README.md +329 -0
- package/dist/capability.d.ts +165 -0
- package/dist/capability.d.ts.map +1 -0
- package/dist/capability.js +268 -0
- package/dist/capability.js.map +1 -0
- package/dist/context.d.ts +35 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +28 -0
- package/dist/context.js.map +1 -0
- package/dist/enhancers.d.ts +92 -0
- package/dist/enhancers.d.ts.map +1 -0
- package/dist/enhancers.js +251 -0
- package/dist/enhancers.js.map +1 -0
- package/dist/errors.d.ts +53 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +74 -0
- package/dist/errors.js.map +1 -0
- package/dist/event-bus.d.ts +56 -0
- package/dist/event-bus.d.ts.map +1 -0
- package/dist/event-bus.js +51 -0
- package/dist/event-bus.js.map +1 -0
- package/dist/execution-engine.d.ts +39 -0
- package/dist/execution-engine.d.ts.map +1 -0
- package/dist/execution-engine.js +210 -0
- package/dist/execution-engine.js.map +1 -0
- package/dist/guards.d.ts +78 -0
- package/dist/guards.d.ts.map +1 -0
- package/dist/guards.js +56 -0
- package/dist/guards.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +28 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +43 -0
- package/dist/plugin.js.map +1 -0
- package/dist/server.d.ts +70 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +97 -0
- package/dist/server.js.map +1 -0
- package/dist/type-tests.d.ts +12 -0
- package/dist/type-tests.d.ts.map +1 -0
- package/dist/type-tests.js +175 -0
- package/dist/type-tests.js.map +1 -0
- package/package.json +47 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* server.ts — server creation and transport orchestration
|
|
3
|
+
* Depends on: all above
|
|
4
|
+
*/
|
|
5
|
+
import { compileRegistry } from './capability.js';
|
|
6
|
+
import { createExecutionEngine } from './execution-engine.js';
|
|
7
|
+
import { mergePlugins } from './plugin.js';
|
|
8
|
+
/**
|
|
9
|
+
* Creates a Capix server from a config object.
|
|
10
|
+
*
|
|
11
|
+
* Compiles the capability tree into a registry, wires plugins, and returns a
|
|
12
|
+
* server with `start()` / `stop()` lifecycle methods and a direct `invoke()`
|
|
13
|
+
* entry point (useful for testing without HTTP).
|
|
14
|
+
*
|
|
15
|
+
* Per-transport capabilities: pass `capabilities` to a transport factory to
|
|
16
|
+
* override the server-level default for that transport only:
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* createServer({
|
|
20
|
+
* context: buildContext,
|
|
21
|
+
* transports: [
|
|
22
|
+
* restTransport({ port: 3000, capabilities: publicCaps }),
|
|
23
|
+
* queueTransport({ queues: ['jobs'], adapter, capabilities: jobCaps }),
|
|
24
|
+
* ],
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @throws {Error} At construction time if a plugin capability name collides with
|
|
29
|
+
* a user capability name.
|
|
30
|
+
* @throws {Error} In `start()` if a transport has no capabilities (neither its
|
|
31
|
+
* own nor a server-level default).
|
|
32
|
+
*/
|
|
33
|
+
export function createServer(config) {
|
|
34
|
+
const plugins = config.plugins ?? [];
|
|
35
|
+
const { wrapContext, additionalCapabilities } = mergePlugins(plugins);
|
|
36
|
+
const wrappedContext = wrapContext(config.context);
|
|
37
|
+
// Detect collisions between server-level capabilities and plugin capabilities
|
|
38
|
+
if (config.capabilities) {
|
|
39
|
+
for (const key of Object.keys(additionalCapabilities)) {
|
|
40
|
+
if (key in config.capabilities) {
|
|
41
|
+
throw new Error(`[capix] Capability name collision: '${key}' is defined by both the user and a plugin. ` +
|
|
42
|
+
`Plugin capabilities must use unique top-level names.`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Server-level registry — backs server.invoke() regardless of transport config
|
|
47
|
+
const serverTree = {
|
|
48
|
+
...(config.capabilities ?? {}),
|
|
49
|
+
...additionalCapabilities,
|
|
50
|
+
};
|
|
51
|
+
const serverRegistry = compileRegistry(serverTree);
|
|
52
|
+
const serverInvoke = createExecutionEngine({
|
|
53
|
+
registry: serverRegistry,
|
|
54
|
+
buildContext: wrappedContext,
|
|
55
|
+
isDevelopment: config.isDevelopment ?? process.env['NODE_ENV'] !== 'production',
|
|
56
|
+
});
|
|
57
|
+
const isDev = config.isDevelopment ?? process.env['NODE_ENV'] !== 'production';
|
|
58
|
+
return {
|
|
59
|
+
invoke: serverInvoke,
|
|
60
|
+
async start() {
|
|
61
|
+
if (config.transports.length === 0) {
|
|
62
|
+
console.warn('[capix] Warning: no transports registered. The server will start but cannot receive requests. ' +
|
|
63
|
+
'Add at least one transport to createServer({ transports: [...] }).');
|
|
64
|
+
}
|
|
65
|
+
// Warn only when there are genuinely no capabilities anywhere
|
|
66
|
+
const hasPerTransportCaps = config.transports.some((t) => t._capabilities != null);
|
|
67
|
+
if (serverRegistry.size === 0 && !hasPerTransportCaps) {
|
|
68
|
+
console.warn('[capix] Warning: no capabilities registered. ' +
|
|
69
|
+
'Add capabilities to createServer({ capabilities: { ... } }).');
|
|
70
|
+
}
|
|
71
|
+
for (const transport of config.transports) {
|
|
72
|
+
const transportCaps = transport._capabilities;
|
|
73
|
+
const caps = transportCaps ?? config.capabilities;
|
|
74
|
+
if (caps == null) {
|
|
75
|
+
throw new Error('[capix] Transport has no capabilities. ' +
|
|
76
|
+
'Either set capabilities on the transport or provide a ' +
|
|
77
|
+
'top-level capabilities map in createServer().');
|
|
78
|
+
}
|
|
79
|
+
// Plugin additional capabilities are always merged in
|
|
80
|
+
const tree = { ...caps, ...additionalCapabilities };
|
|
81
|
+
const registry = compileRegistry(tree);
|
|
82
|
+
const invoke = createExecutionEngine({ registry, buildContext: wrappedContext, isDevelopment: isDev });
|
|
83
|
+
await transport.mount(invoke, { registry, invoke });
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
async stop() {
|
|
87
|
+
for (const transport of config.transports) {
|
|
88
|
+
await transport.unmount();
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/** Pass-through for config type inference. */
|
|
94
|
+
export function defineConfig(config) {
|
|
95
|
+
return config;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* type-tests.ts — compile-time verification of type narrowing behavior.
|
|
3
|
+
*
|
|
4
|
+
* These are NOT runtime tests. Each block verifies a specific TypeScript
|
|
5
|
+
* inference guarantee. Lines marked @ts-expect-error must produce a type
|
|
6
|
+
* error; if they stop producing an error, tsc will fail, alerting us that
|
|
7
|
+
* behavior changed.
|
|
8
|
+
*
|
|
9
|
+
* Run: pnpm --filter capix build (tsc covers this file automatically)
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=type-tests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-tests.d.ts","sourceRoot":"","sources":["../src/type-tests.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* type-tests.ts — compile-time verification of type narrowing behavior.
|
|
3
|
+
*
|
|
4
|
+
* These are NOT runtime tests. Each block verifies a specific TypeScript
|
|
5
|
+
* inference guarantee. Lines marked @ts-expect-error must produce a type
|
|
6
|
+
* error; if they stop producing an error, tsc will fail, alerting us that
|
|
7
|
+
* behavior changed.
|
|
8
|
+
*
|
|
9
|
+
* Run: pnpm --filter capix build (tsc covers this file automatically)
|
|
10
|
+
*/
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
import { capability } from './capability.js';
|
|
13
|
+
import { defineContext } from './context.js';
|
|
14
|
+
import { defineError, defineGuard, defineGuardFor } from './index.js';
|
|
15
|
+
const buildContext = defineContext(async () => ({
|
|
16
|
+
requestId: 'test',
|
|
17
|
+
user: null,
|
|
18
|
+
token: null,
|
|
19
|
+
}));
|
|
20
|
+
void buildContext;
|
|
21
|
+
const errors = {
|
|
22
|
+
Unauthorized: defineError(401, 'Unauthorized'),
|
|
23
|
+
Forbidden: defineError(403, 'Forbidden'),
|
|
24
|
+
};
|
|
25
|
+
void errors;
|
|
26
|
+
const mustBeAuthenticated = defineGuard((ctx) => {
|
|
27
|
+
if (!ctx.token)
|
|
28
|
+
throw errors.Unauthorized();
|
|
29
|
+
});
|
|
30
|
+
const mustHaveUser = defineGuard((ctx) => {
|
|
31
|
+
if (!ctx.user)
|
|
32
|
+
throw errors.Unauthorized();
|
|
33
|
+
});
|
|
34
|
+
void _vng;
|
|
35
|
+
void _invng;
|
|
36
|
+
const _narrowingCheck = true;
|
|
37
|
+
void _narrowingCheck;
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// Test 3: Single guard narrows capability context type
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
const Input = z.object({ id: z.string() });
|
|
42
|
+
const capWithGuard = capability(Input, (_input, ctx) => ctx.token.toUpperCase()).guard(mustBeAuthenticated);
|
|
43
|
+
// Verify the narrowed type has token as non-null
|
|
44
|
+
const _guardedCtxCheck = { requestId: '', user: null, token: 'tok' };
|
|
45
|
+
void _guardedCtxCheck;
|
|
46
|
+
// @ts-expect-error — token must be string, not null, in the narrowed context
|
|
47
|
+
const _guardedCtxBad = { requestId: '', user: null, token: null };
|
|
48
|
+
void _guardedCtxBad;
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Test 4: Chained guards narrow progressively
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
const capChained = capability(Input, (_input, ctx) => `${ctx.token}-${ctx.user.id}`)
|
|
53
|
+
.guard(mustBeAuthenticated)
|
|
54
|
+
.guard(mustHaveUser);
|
|
55
|
+
// Both token (string) and user (non-null) must be present
|
|
56
|
+
const _chainedCtxCheck = {
|
|
57
|
+
requestId: '',
|
|
58
|
+
user: { id: '1', name: 'Alice' },
|
|
59
|
+
token: 'tok',
|
|
60
|
+
};
|
|
61
|
+
void _chainedCtxCheck;
|
|
62
|
+
// @ts-expect-error — token must be string (non-null) in the chained context
|
|
63
|
+
const _chainedCtxBad = { requestId: '', user: { id: '1', name: 'A' }, token: null };
|
|
64
|
+
void _chainedCtxBad;
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// Test 5: Non-narrowing (void) guard preserves TContext
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
const rateGuard = defineGuard((_ctx) => {
|
|
69
|
+
// plain void guard — no narrowing
|
|
70
|
+
});
|
|
71
|
+
const capWithVoidGuard = capability(Input, (_input, ctx) => ctx.requestId).guard(rateGuard);
|
|
72
|
+
// TContext should remain AppContext — token is still string | null
|
|
73
|
+
const _voidCtxCheck = { requestId: '', user: null, token: null };
|
|
74
|
+
void _voidCtxCheck;
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Test 6: KNOWN LIMITATION — resolver ctx is not inferred backward from .guard()
|
|
77
|
+
//
|
|
78
|
+
// TypeScript cannot retroactively narrow the resolver's ctx parameter based on
|
|
79
|
+
// guards added via method chaining. You must explicitly annotate ctx in the
|
|
80
|
+
// resolver or provide an explicit type parameter to capability().
|
|
81
|
+
//
|
|
82
|
+
// This WORKS (explicit ctx annotation):
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
const capExplicit = capability(Input, (_input, ctx) => ctx.token.toUpperCase()).guard(mustBeAuthenticated);
|
|
85
|
+
void capExplicit;
|
|
86
|
+
// This does NOT work without annotation:
|
|
87
|
+
// capability(Input, (_input, ctx) => ctx.token.toUpperCase()).guard(mustBeAuthenticated)
|
|
88
|
+
// ^^^^^^^^^^^^^^^^^
|
|
89
|
+
// Error: 'token' does not exist on type 'BaseContext'
|
|
90
|
+
//
|
|
91
|
+
// Solution: use capability.withContext<AppContext>() (see Test 7 below).
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
// Test 7: capability.withContext pre-binds TContext — no resolver annotation needed
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
const appCapability = capability.withContext();
|
|
96
|
+
const capViaFactory = appCapability(Input, (_input, ctx) => {
|
|
97
|
+
// ctx is AppContext — no annotation required
|
|
98
|
+
return ctx.requestId;
|
|
99
|
+
});
|
|
100
|
+
const _factoryCtxCheck = { requestId: '', user: null, token: null };
|
|
101
|
+
void _factoryCtxCheck;
|
|
102
|
+
// Guards work directly — no `any` escape hatch needed
|
|
103
|
+
const capFactoryWithGuard = appCapability(Input, (_input, ctx) => ctx.requestId).guard(mustBeAuthenticated);
|
|
104
|
+
const _factoryGuardedCheck = { requestId: '', user: null, token: 'tok' };
|
|
105
|
+
void _factoryGuardedCheck;
|
|
106
|
+
// @ts-expect-error — token must be non-null in the narrowed context
|
|
107
|
+
const _factoryGuardedBad = { requestId: '', user: null, token: null };
|
|
108
|
+
void _factoryGuardedBad;
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
// Test 8: InferInput / InferOutput / InferContext utility types
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
const TypedCap = capability(z.object({ id: z.string(), count: z.number() }), (_input, _ctx) => ({ result: 'ok' }));
|
|
113
|
+
const _inputCheck = { id: 'x', count: 1 };
|
|
114
|
+
void _inputCheck;
|
|
115
|
+
const _outputCheck = { result: 'ok' };
|
|
116
|
+
void _outputCheck;
|
|
117
|
+
const _contextCheck = { requestId: '', user: null, token: null };
|
|
118
|
+
void _contextCheck;
|
|
119
|
+
// @ts-expect-error — id must be string, not number
|
|
120
|
+
const _inputBad = { id: 42, count: 1 };
|
|
121
|
+
void _inputBad;
|
|
122
|
+
// InferContext after .guard() reflects the narrowed context
|
|
123
|
+
const GuardedTypedCap = TypedCap.guard(mustBeAuthenticated);
|
|
124
|
+
const _guardedInferred = { requestId: '', user: null, token: 'tok' };
|
|
125
|
+
void _guardedInferred;
|
|
126
|
+
// @ts-expect-error — token must be string after guard
|
|
127
|
+
const _guardedInferredBad = { requestId: '', user: null, token: null };
|
|
128
|
+
void _guardedInferredBad;
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// Test 9: defineGuardFor — typed guard factory without repeated annotation
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
const defineAppGuard = defineGuardFor();
|
|
133
|
+
// Plain void guard
|
|
134
|
+
const appRateGuard = defineAppGuard((_ctx) => {
|
|
135
|
+
// _ctx is AppContext — no annotation needed
|
|
136
|
+
});
|
|
137
|
+
void appRateGuard;
|
|
138
|
+
// Narrowing guard — assertion types are preserved
|
|
139
|
+
const appAuthGuard = defineAppGuard((ctx) => {
|
|
140
|
+
if (!ctx.token)
|
|
141
|
+
throw errors.Unauthorized();
|
|
142
|
+
});
|
|
143
|
+
const _appAuthGuardCheck = true;
|
|
144
|
+
void _appAuthGuardCheck;
|
|
145
|
+
// defineGuardFor validates context type — wrong context errors
|
|
146
|
+
// @ts-expect-error — guard must accept AppContext, not an incompatible shape
|
|
147
|
+
defineGuardFor()((ctx) => { void ctx; });
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
// Test 10: .guard() requires guard to be compatible with current TContext
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
// Guard typed for BaseContext works with any capability (it's more permissive)
|
|
152
|
+
const baseGuard = defineGuard((_ctx) => { });
|
|
153
|
+
const capWithBaseGuard = appCapability(Input, (_input, _ctx) => 'ok').guard(baseGuard);
|
|
154
|
+
void capWithBaseGuard;
|
|
155
|
+
// Guard typed for AppContext works when TContext = AppContext
|
|
156
|
+
const capWithAppGuard = appCapability(Input, (_input, _ctx) => 'ok').guard(mustBeAuthenticated);
|
|
157
|
+
void capWithAppGuard;
|
|
158
|
+
// Guard typed for AppContext does NOT work when TContext = BaseContext
|
|
159
|
+
// (default TContext when no resolver annotation and no withContext)
|
|
160
|
+
// @ts-expect-error — mustBeAuthenticated requires AppContext but TContext = BaseContext here
|
|
161
|
+
capability(Input, (_input, _ctx) => 'ok').guard(mustBeAuthenticated);
|
|
162
|
+
const minCap = capability.withContext();
|
|
163
|
+
// no-schema, no intent
|
|
164
|
+
const _t11a = minCap(() => 42);
|
|
165
|
+
void _t11a;
|
|
166
|
+
// no-schema + intent
|
|
167
|
+
const _t11b = minCap(() => 42, 'query');
|
|
168
|
+
void _t11b;
|
|
169
|
+
// schema + resolver
|
|
170
|
+
const _t11d = minCap(z.object({ id: z.string() }), ({ id }) => id);
|
|
171
|
+
void _t11d;
|
|
172
|
+
// schema + resolver + intent
|
|
173
|
+
const _t11e = minCap(z.object({ id: z.string() }), ({ id }) => id, 'query');
|
|
174
|
+
void _t11e;
|
|
175
|
+
//# sourceMappingURL=type-tests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-tests.js","sourceRoot":"","sources":["../src/type-tests.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@capixjs/core",
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"description": "Capability-based Node.js server framework — core",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"!dist/**/*.test.*",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"keywords": [
|
|
21
|
+
"capix",
|
|
22
|
+
"capability",
|
|
23
|
+
"rpc",
|
|
24
|
+
"server",
|
|
25
|
+
"framework",
|
|
26
|
+
"typescript",
|
|
27
|
+
"zod",
|
|
28
|
+
"guards",
|
|
29
|
+
"enhancers"
|
|
30
|
+
],
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=20"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc",
|
|
36
|
+
"test": "vitest run",
|
|
37
|
+
"typecheck": "tsc --noEmit"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"zod": "^3.23.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/node": "^20.0.0",
|
|
44
|
+
"typescript": "^5.5.0",
|
|
45
|
+
"vitest": "^1.6.0"
|
|
46
|
+
}
|
|
47
|
+
}
|