capman 0.1.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.
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolve = resolve;
4
+ const logger_1 = require("./logger");
5
+ function checkPrivacy(capability, auth) {
6
+ const level = capability.privacy.level;
7
+ if (level === 'public')
8
+ return null;
9
+ if (level === 'user_owned') {
10
+ if (!auth?.isAuthenticated) {
11
+ return `Capability "${capability.id}" requires authentication (privacy: user_owned)`;
12
+ }
13
+ return null;
14
+ }
15
+ if (level === 'admin') {
16
+ if (!auth?.isAuthenticated) {
17
+ return `Capability "${capability.id}" requires authentication (privacy: admin)`;
18
+ }
19
+ if (auth.role !== 'admin') {
20
+ return `Capability "${capability.id}" requires admin role (current role: ${auth.role ?? 'none'})`;
21
+ }
22
+ return null;
23
+ }
24
+ return null;
25
+ }
26
+ async function resolve(matchResult, params = {}, options = {}) {
27
+ const { capability } = matchResult;
28
+ if (!capability) {
29
+ logger_1.logger.warn('resolve() called with no matched capability');
30
+ return {
31
+ success: false,
32
+ resolverType: null,
33
+ error: 'No capability matched — cannot resolve',
34
+ };
35
+ }
36
+ // ── Privacy enforcement ──────────────────────────────────────────────────
37
+ const privacyError = checkPrivacy(capability, options.auth);
38
+ if (privacyError) {
39
+ logger_1.logger.warn(`Privacy check failed: ${privacyError}`);
40
+ return {
41
+ success: false,
42
+ resolverType: null,
43
+ error: privacyError,
44
+ };
45
+ }
46
+ // ── Session param injection ───────────────────────────────────────────────
47
+ // Inject auth.userId into any params marked as source: 'session'
48
+ const enrichedParams = { ...params };
49
+ if (options.auth?.userId) {
50
+ for (const param of capability.params) {
51
+ if (param.source === 'session' && options.auth.userId) {
52
+ enrichedParams[param.name] = options.auth.userId;
53
+ logger_1.logger.debug(`Injected session param "${param.name}" = "${options.auth.userId}"`);
54
+ }
55
+ }
56
+ }
57
+ const resolver = capability.resolver;
58
+ logger_1.logger.info(`Resolving capability "${capability.id}" via ${resolver.type} resolver`);
59
+ logger_1.logger.debug(`Params: ${JSON.stringify(params)}`);
60
+ logger_1.logger.debug(`Options: baseUrl=${options.baseUrl} dryRun=${options.dryRun}`);
61
+ try {
62
+ switch (resolver.type) {
63
+ case 'api':
64
+ return await resolveApi(resolver, enrichedParams, options);
65
+ case 'nav':
66
+ return resolveNav(resolver, enrichedParams);
67
+ case 'hybrid': {
68
+ logger_1.logger.debug('Hybrid resolver — running API and nav in parallel');
69
+ const [apiResult, navResult] = await Promise.all([
70
+ resolveApi(resolver.api, enrichedParams, options),
71
+ Promise.resolve(resolveNav(resolver.nav, enrichedParams)),
72
+ ]);
73
+ return {
74
+ success: apiResult.success && navResult.success,
75
+ resolverType: 'hybrid',
76
+ apiCalls: apiResult.apiCalls,
77
+ navTarget: navResult.navTarget,
78
+ error: apiResult.error ?? navResult.error,
79
+ };
80
+ }
81
+ }
82
+ }
83
+ catch (err) {
84
+ logger_1.logger.error(`Resolution failed for "${capability.id}": ${err}`);
85
+ return {
86
+ success: false,
87
+ resolverType: resolver.type,
88
+ error: err instanceof Error ? err.message : String(err),
89
+ };
90
+ }
91
+ }
92
+ async function resolveApi(resolver, params, options) {
93
+ const apiCalls = resolver.endpoints.map(endpoint => ({
94
+ method: endpoint.method,
95
+ url: buildUrl(options.baseUrl ?? '', endpoint.path, params),
96
+ params,
97
+ }));
98
+ if (options.dryRun) {
99
+ return { success: true, resolverType: 'api', apiCalls };
100
+ }
101
+ const fetchFn = options.fetch ?? globalThis.fetch;
102
+ if (!fetchFn) {
103
+ return {
104
+ success: true,
105
+ resolverType: 'api',
106
+ apiCalls,
107
+ error: 'No fetch available — returning call plan only',
108
+ };
109
+ }
110
+ try {
111
+ const responses = await Promise.all(apiCalls.map(c => fetchFn(c.url, {
112
+ method: c.method,
113
+ headers: options.headers ?? {},
114
+ body: ['POST', 'PUT', 'PATCH'].includes(c.method)
115
+ ? JSON.stringify(c.params)
116
+ : undefined,
117
+ })));
118
+ // Check for HTTP errors
119
+ const failed = responses.find(r => !r.ok);
120
+ if (failed) {
121
+ return {
122
+ success: false,
123
+ resolverType: 'api',
124
+ apiCalls,
125
+ error: `API request failed: ${failed.status} ${failed.statusText}`,
126
+ };
127
+ }
128
+ return { success: true, resolverType: 'api', apiCalls };
129
+ }
130
+ catch (err) {
131
+ return {
132
+ success: false,
133
+ resolverType: 'api',
134
+ apiCalls,
135
+ error: err instanceof Error ? err.message : String(err),
136
+ };
137
+ }
138
+ }
139
+ function resolveNav(resolver, params) {
140
+ let destination = resolver.destination;
141
+ for (const [key, value] of Object.entries(params)) {
142
+ destination = destination.replace(`{${key}}`, String(value));
143
+ }
144
+ return { success: true, resolverType: 'nav', navTarget: destination };
145
+ }
146
+ function buildUrl(baseUrl, urlPath, params) {
147
+ let resolved = urlPath;
148
+ const unused = {};
149
+ for (const [key, value] of Object.entries(params)) {
150
+ if (resolved.includes(`{${key}}`)) {
151
+ resolved = resolved.replace(`{${key}}`, encodeURIComponent(String(value)));
152
+ }
153
+ else {
154
+ unused[key] = value;
155
+ }
156
+ }
157
+ const base = `${baseUrl.replace(/\/$/, '')}${resolved}`;
158
+ const qs = Object.entries(unused)
159
+ .filter(([, v]) => v !== null && v !== undefined)
160
+ .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)
161
+ .join('&');
162
+ return qs ? `${base}?${qs}` : base;
163
+ }
164
+ //# sourceMappingURL=resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":";;AAoDA,0BA4EC;AA/HD,qCAAiC;AAsBjC,SAAS,YAAY,CACnB,UAAwC,EACxC,IAAkB;IAElB,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAA;IAEtC,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IAEnC,IAAI,KAAK,KAAK,YAAY,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,EAAE,eAAe,EAAE,CAAC;YAC3B,OAAO,eAAe,UAAU,CAAC,EAAE,iDAAiD,CAAA;QACtF,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,IAAI,EAAE,eAAe,EAAE,CAAC;YAC3B,OAAO,eAAe,UAAU,CAAC,EAAE,4CAA4C,CAAA;QACjF,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC1B,OAAO,eAAe,UAAU,CAAC,EAAE,wCAAwC,IAAI,CAAC,IAAI,IAAI,MAAM,GAAG,CAAA;QACnG,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAGM,KAAK,UAAU,OAAO,CAC3B,WAAwB,EACxB,SAAkC,EAAE,EACpC,UAA0B,EAAE;IAE5B,MAAM,EAAE,UAAU,EAAE,GAAG,WAAW,CAAA;IAElC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,eAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAA;QAC1D,OAAO;YACL,OAAO,EAAE,KAAK;YACd,YAAY,EAAE,IAAI;YAClB,KAAK,EAAE,wCAAwC;SAChD,CAAA;IACH,CAAC;IAED,4EAA4E;IAC5E,MAAM,YAAY,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3D,IAAI,YAAY,EAAE,CAAC;QACjB,eAAM,CAAC,IAAI,CAAC,yBAAyB,YAAY,EAAE,CAAC,CAAA;QACpD,OAAO;YACL,OAAO,EAAE,KAAK;YACd,YAAY,EAAE,IAAI;YAClB,KAAK,EAAE,YAAY;SACpB,CAAA;IACH,CAAC;IAED,6EAA6E;IAC7E,iEAAiE;IACjE,MAAM,cAAc,GAAG,EAAE,GAAG,MAAM,EAAE,CAAA;IACpC,IAAI,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;YACtC,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACtD,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAA;gBAChD,eAAM,CAAC,KAAK,CAAC,2BAA2B,KAAK,CAAC,IAAI,QAAQ,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAA;YACnF,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAA;IACpC,eAAM,CAAC,IAAI,CAAC,yBAAyB,UAAU,CAAC,EAAE,SAAS,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAA;IACpF,eAAM,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACjD,eAAM,CAAC,KAAK,CAAC,oBAAoB,OAAO,CAAC,OAAO,WAAW,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IAE5E,IAAI,CAAC;QACC,QAAQ,QAAQ,CAAC,IAAI,EAAE,CAAC;YACtB,KAAK,KAAK;gBACR,OAAO,MAAM,UAAU,CAAC,QAAQ,EAAE,cAAc,EAAE,OAAO,CAAC,CAAA;YAE5D,KAAK,KAAK;gBACR,OAAO,UAAU,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAA;YAE7C,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,eAAM,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAA;gBACjE,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;oBAC/C,UAAU,CAAC,QAAQ,CAAC,GAAkB,EAAE,cAAc,EAAE,OAAO,CAAC;oBAChE,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAkB,EAAE,cAAc,CAAC,CAAC;iBACzE,CAAC,CAAA;gBAEN,OAAO;oBACL,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO;oBAC/C,YAAY,EAAE,QAAQ;oBACtB,QAAQ,EAAE,SAAS,CAAC,QAAQ;oBAC5B,SAAS,EAAE,SAAS,CAAC,SAAS;oBAC9B,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,SAAS,CAAC,KAAK;iBAC1C,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,eAAM,CAAC,KAAK,CAAC,0BAA0B,UAAU,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,CAAA;QAChE,OAAO;YACL,OAAO,EAAE,KAAK;YACd,YAAY,EAAE,QAAQ,CAAC,IAAI;YAC3B,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAA;IACH,CAAC;AACH,CAAC;AACD,KAAK,UAAU,UAAU,CACvB,QAAiD,EACjD,MAA+B,EAC/B,OAAuB;IAEvB,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QACnD,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAC3D,MAAM;KACP,CAAC,CAAC,CAAA;IAEH,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;IACzD,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAA;IACjD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,IAAI;YACb,YAAY,EAAE,KAAK;YACnB,QAAQ;YACR,KAAK,EAAE,+CAA+C;SACvD,CAAA;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE;YAC/B,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;YAC9B,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;gBAC/C,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;gBAC1B,CAAC,CAAC,SAAS;SACd,CAAC,CAAC,CACJ,CAAA;QAED,wBAAwB;QACxB,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QACzC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,YAAY,EAAE,KAAK;gBACnB,QAAQ;gBACR,KAAK,EAAE,uBAAuB,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,EAAE;aACnE,CAAA;QACH,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;IACzD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,KAAK;YACd,YAAY,EAAE,KAAK;YACnB,QAAQ;YACR,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAA;IACH,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CACjB,QAAiD,EACjD,MAA+B;IAE/B,IAAI,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAA;IACtC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,GAAG,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;IAC9D,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,CAAA;AACvE,CAAC;AAED,SAAS,QAAQ,CACf,OAAe,EACf,OAAe,EACf,MAA+B;IAE/B,IAAI,QAAQ,GAAG,OAAO,CAAA;IACtB,MAAM,MAAM,GAA4B,EAAE,CAAA;IAE1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;YAClC,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,GAAG,GAAG,EAAE,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC5E,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;QACrB,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAA;IACvD,MAAM,EAAE,GAAK,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;SAChC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,CAAC;SAChD,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5E,IAAI,CAAC,GAAG,CAAC,CAAA;IAEZ,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AACpC,CAAC"}