@forumone/throughline-approvals 0.0.1 → 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/CHANGELOG.md +12 -0
- package/LICENSE +21 -0
- package/README.md +101 -43
- package/dist/collection.d.ts +18 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +95 -0
- package/dist/collection.js.map +1 -0
- package/dist/endpoints/action.d.ts +31 -0
- package/dist/endpoints/action.d.ts.map +1 -0
- package/dist/endpoints/action.js +205 -0
- package/dist/endpoints/action.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/options.d.ts +50 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +28 -0
- package/dist/options.js.map +1 -0
- package/dist/plugin.d.ts +4 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +103 -0
- package/dist/plugin.js.map +1 -0
- package/dist/resolver.d.ts +25 -0
- package/dist/resolver.d.ts.map +1 -0
- package/dist/resolver.js +63 -0
- package/dist/resolver.js.map +1 -0
- package/dist/tokens.d.ts +48 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +103 -0
- package/dist/tokens.js.map +1 -0
- package/dist/tools/get-approval-status.d.ts +11 -0
- package/dist/tools/get-approval-status.d.ts.map +1 -0
- package/dist/tools/get-approval-status.js +47 -0
- package/dist/tools/get-approval-status.js.map +1 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-my-requests.d.ts +11 -0
- package/dist/tools/list-my-requests.d.ts.map +1 -0
- package/dist/tools/list-my-requests.js +55 -0
- package/dist/tools/list-my-requests.js.map +1 -0
- package/dist/tools/list-pending-approvals.d.ts +11 -0
- package/dist/tools/list-pending-approvals.d.ts.map +1 -0
- package/dist/tools/list-pending-approvals.js +62 -0
- package/dist/tools/list-pending-approvals.js.map +1 -0
- package/dist/tools/request-approval.d.ts +13 -0
- package/dist/tools/request-approval.d.ts.map +1 -0
- package/dist/tools/request-approval.js +118 -0
- package/dist/tools/request-approval.js.map +1 -0
- package/dist/tools/respond-to-approval.d.ts +13 -0
- package/dist/tools/respond-to-approval.d.ts.map +1 -0
- package/dist/tools/respond-to-approval.js +107 -0
- package/dist/tools/respond-to-approval.js.map +1 -0
- package/package.json +64 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAA;AAElF,MAAM,WAAW,aAAa;IAC5B,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAA;IACZ,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAA;IACZ,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,YAAY,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAA;CACpE;AAED,MAAM,WAAW,sBAAuB,SAAQ,qBAAqB;IACnE,oDAAoD;IACpD,MAAM,EAAE,aAAa,EAAE,CAAA;IACvB,uDAAuD;IACvD,aAAa,EAAE,aAAa,CAAA;IAC5B,6DAA6D;IAC7D,OAAO,EAAE,OAAO,CAAA;IAChB,0FAA0F;IAC1F,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,sGAAsG;IACtG,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,6FAA6F;IAC7F,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAID;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,sBAAsB,GAC9B,sBAAsB,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CA2BlD"}
|
package/dist/options.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const MIN_TOKEN_SECRET_LENGTH = 32;
|
|
2
|
+
/**
|
|
3
|
+
* Validates options at load time and resolves the token secret. Throws with
|
|
4
|
+
* a targeted error on each obvious misconfiguration.
|
|
5
|
+
*/
|
|
6
|
+
export function validateOptions(options) {
|
|
7
|
+
if (!options.groups || options.groups.length === 0) {
|
|
8
|
+
throw new Error('approvalsPlugin requires at least one group in options.groups');
|
|
9
|
+
}
|
|
10
|
+
if (!options.groupResolver) {
|
|
11
|
+
throw new Error('approvalsPlugin requires a groupResolver in options');
|
|
12
|
+
}
|
|
13
|
+
if (!options.inngest) {
|
|
14
|
+
throw new Error('approvalsPlugin requires an Inngest client in options.inngest');
|
|
15
|
+
}
|
|
16
|
+
const secret = options.tokenSecret ?? process.env['APPROVAL_TOKEN_SECRET'];
|
|
17
|
+
if (!secret || secret.length < MIN_TOKEN_SECRET_LENGTH) {
|
|
18
|
+
throw new Error(`approvalsPlugin requires a tokenSecret in options or an APPROVAL_TOKEN_SECRET env var (${MIN_TOKEN_SECRET_LENGTH}+ characters)`);
|
|
19
|
+
}
|
|
20
|
+
// Group slugs must be unique.
|
|
21
|
+
const slugs = options.groups.map((g) => g.slug);
|
|
22
|
+
const dupes = slugs.filter((s, i) => slugs.indexOf(s) !== i);
|
|
23
|
+
if (dupes.length > 0) {
|
|
24
|
+
throw new Error(`approvalsPlugin: duplicate group slug${dupes.length === 1 ? '' : 's'}: ${dupes.join(', ')}`);
|
|
25
|
+
}
|
|
26
|
+
return { ...options, tokenSecret: secret };
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AA+CA,MAAM,uBAAuB,GAAG,EAAE,CAAA;AAElC;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,OAA+B;IAE/B,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAA;IAClF,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAA;IACxE,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAA;IAClF,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;IAC1E,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,uBAAuB,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CACb,0FAA0F,uBAAuB,eAAe,CACjI,CAAA;IACH,CAAC;IAED,8BAA8B;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;IAC5D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,wCAAwC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7F,CAAA;IACH,CAAC;IAED,OAAO,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,CAAA;AAC5C,CAAC"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAA;AAQvE,OAAO,EAAE,KAAK,sBAAsB,EAAmB,MAAM,cAAc,CAAA;AAmB3E,eAAO,MAAM,eAAe,EAAE,UAAU,CAAC,sBAAsB,CA2G5D,CAAA"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { getPluginRegistry } from '@forumone/throughline-plugin-contract';
|
|
2
|
+
import { createMcpHandler, createNamedLogger, defaultLogger, getAuditWriter, } from '@forumone/throughline-core';
|
|
3
|
+
import { validateOptions } from './options.js';
|
|
4
|
+
import { createApprovalsCollection } from './collection.js';
|
|
5
|
+
import { attachApprovalResolver, createApprovalResolver } from './resolver.js';
|
|
6
|
+
import { createActionEndpoint } from './endpoints/action.js';
|
|
7
|
+
import { createGetApprovalStatusTool, createListMyRequestsTool, createListPendingApprovalsTool, createRequestApprovalTool, createRespondToApprovalTool, } from './tools/index.js';
|
|
8
|
+
const PLUGIN_ID = '@forumone/throughline-approvals';
|
|
9
|
+
const PLUGIN_VERSION = '0.1.0';
|
|
10
|
+
const MCP_HANDLER_SYMBOL = Symbol.for('@forumone/throughline/approvals-mcp-handler');
|
|
11
|
+
const ACTION_HANDLER_SYMBOL = Symbol.for('@forumone/throughline/approvals-action-handler');
|
|
12
|
+
export const approvalsPlugin = (rawOptions) => (incomingConfig) => {
|
|
13
|
+
if (rawOptions.enabled === false)
|
|
14
|
+
return incomingConfig;
|
|
15
|
+
const options = validateOptions(rawOptions);
|
|
16
|
+
const routePrefix = options.routePrefix ?? '/approvals';
|
|
17
|
+
const logger = createNamedLogger('approvals', options.logger ?? defaultLogger);
|
|
18
|
+
const collection = createApprovalsCollection({
|
|
19
|
+
...(options.collectionSlug ? { slug: options.collectionSlug } : {}),
|
|
20
|
+
...(options.usersSlug ? { usersSlug: options.usersSlug } : {}),
|
|
21
|
+
groupSlugs: options.groups.map((g) => g.slug),
|
|
22
|
+
});
|
|
23
|
+
return {
|
|
24
|
+
...incomingConfig,
|
|
25
|
+
collections: [...(incomingConfig.collections ?? []), collection],
|
|
26
|
+
endpoints: [
|
|
27
|
+
...(incomingConfig.endpoints ?? []),
|
|
28
|
+
{
|
|
29
|
+
path: `${routePrefix}/mcp`,
|
|
30
|
+
method: 'post',
|
|
31
|
+
handler: async (req) => {
|
|
32
|
+
const handler = req.payload[MCP_HANDLER_SYMBOL];
|
|
33
|
+
if (!handler) {
|
|
34
|
+
return new Response(JSON.stringify({ error: 'Approvals MCP not initialized' }), { status: 503, headers: { 'content-type': 'application/json' } });
|
|
35
|
+
}
|
|
36
|
+
return handler(req);
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
path: `${routePrefix}/action`,
|
|
41
|
+
method: 'get',
|
|
42
|
+
handler: async (req) => {
|
|
43
|
+
const actionHandler = req.payload[ACTION_HANDLER_SYMBOL];
|
|
44
|
+
if (!actionHandler) {
|
|
45
|
+
return new Response('Approvals action handler not initialized', { status: 503 });
|
|
46
|
+
}
|
|
47
|
+
return actionHandler(req);
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
onInit: async (payload) => {
|
|
52
|
+
if (incomingConfig.onInit) {
|
|
53
|
+
await incomingConfig.onInit(payload);
|
|
54
|
+
}
|
|
55
|
+
const registry = getPluginRegistry(payload);
|
|
56
|
+
registry.requireCapability('audit-log', PLUGIN_ID);
|
|
57
|
+
const auditWriter = getAuditWriter(payload);
|
|
58
|
+
const collectionSlug = options.collectionSlug;
|
|
59
|
+
const resolver = createApprovalResolver(collectionSlug ? { payload, collectionSlug } : { payload });
|
|
60
|
+
attachApprovalResolver(payload, resolver);
|
|
61
|
+
const actionEndpoint = createActionEndpoint({ options, auditWriter });
|
|
62
|
+
Object.defineProperty(payload, ACTION_HANDLER_SYMBOL, {
|
|
63
|
+
value: actionEndpoint.handler,
|
|
64
|
+
enumerable: false,
|
|
65
|
+
writable: false,
|
|
66
|
+
configurable: false,
|
|
67
|
+
});
|
|
68
|
+
const tools = [
|
|
69
|
+
createRequestApprovalTool({ payload, options, auditWriter }),
|
|
70
|
+
createRespondToApprovalTool({ payload, options, auditWriter }),
|
|
71
|
+
createGetApprovalStatusTool({ payload, options }),
|
|
72
|
+
createListPendingApprovalsTool({ payload, options }),
|
|
73
|
+
createListMyRequestsTool({ payload, options }),
|
|
74
|
+
];
|
|
75
|
+
const handler = createMcpHandler({
|
|
76
|
+
payload,
|
|
77
|
+
serverName: 'approvals',
|
|
78
|
+
tools,
|
|
79
|
+
logger,
|
|
80
|
+
});
|
|
81
|
+
Object.defineProperty(payload, MCP_HANDLER_SYMBOL, {
|
|
82
|
+
value: handler,
|
|
83
|
+
enumerable: false,
|
|
84
|
+
writable: false,
|
|
85
|
+
configurable: false,
|
|
86
|
+
});
|
|
87
|
+
registry.register({
|
|
88
|
+
id: PLUGIN_ID,
|
|
89
|
+
version: PLUGIN_VERSION,
|
|
90
|
+
capabilities: ['approvals', 'approval-resolver'],
|
|
91
|
+
});
|
|
92
|
+
logger.info('Approvals server ready', {
|
|
93
|
+
groups: options.groups.map((g) => g.slug),
|
|
94
|
+
expirationDays: options.expirationDays ?? 7,
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
// `createActionEndpoint` is exported from src/index.ts for clients who want
|
|
100
|
+
// to expose the action handler separately (e.g. behind a branded router).
|
|
101
|
+
// Most consumers won't need it — the plugin already registers the action
|
|
102
|
+
// endpoint at `${routePrefix}/action`.
|
|
103
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Payload } from 'payload';
|
|
2
|
+
import type { ApprovalResolver } from '@forumone/throughline-publishing';
|
|
3
|
+
/**
|
|
4
|
+
* Symbol under which the resolver is attached to the Payload instance.
|
|
5
|
+
* Publishing's `approvalStep` looks here when its `options.approvalResolver`
|
|
6
|
+
* is not set; this is the wiring point that lets clients add the approvals
|
|
7
|
+
* plugin without re-configuring publishing.
|
|
8
|
+
*/
|
|
9
|
+
export declare const APPROVALS_RESOLVER_SYMBOL: unique symbol;
|
|
10
|
+
export interface CreateApprovalResolverOptions {
|
|
11
|
+
payload: Payload;
|
|
12
|
+
/** Override the approvals collection slug. Default: 'approvals'. */
|
|
13
|
+
collectionSlug?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Builds the resolver that the publishing server consumes. Looks up the
|
|
17
|
+
* latest granted approval whose `targetVersion` matches the document
|
|
18
|
+
* version under consideration. Multiple decisions are sorted by `decidedAt`
|
|
19
|
+
* descending; first-decision-wins semantics mean the latest grant for a
|
|
20
|
+
* given version is what counts.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createApprovalResolver(options: CreateApprovalResolverOptions): ApprovalResolver;
|
|
23
|
+
/** Attaches the resolver to a Payload instance under the agreed symbol. */
|
|
24
|
+
export declare function attachApprovalResolver(payload: object, resolver: ApprovalResolver): void;
|
|
25
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,KAAK,EAAkB,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AAGxF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,eAErC,CAAA;AAED,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,OAAO,CAAA;IAChB,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,6BAA6B,GACrC,gBAAgB,CAyClB;AAED,2EAA2E;AAC3E,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,gBAAgB,GACzB,IAAI,CAON"}
|
package/dist/resolver.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { DEFAULT_APPROVALS_SLUG } from './collection.js';
|
|
2
|
+
/**
|
|
3
|
+
* Symbol under which the resolver is attached to the Payload instance.
|
|
4
|
+
* Publishing's `approvalStep` looks here when its `options.approvalResolver`
|
|
5
|
+
* is not set; this is the wiring point that lets clients add the approvals
|
|
6
|
+
* plugin without re-configuring publishing.
|
|
7
|
+
*/
|
|
8
|
+
export const APPROVALS_RESOLVER_SYMBOL = Symbol.for('@forumone/throughline/approvals-resolver');
|
|
9
|
+
/**
|
|
10
|
+
* Builds the resolver that the publishing server consumes. Looks up the
|
|
11
|
+
* latest granted approval whose `targetVersion` matches the document
|
|
12
|
+
* version under consideration. Multiple decisions are sorted by `decidedAt`
|
|
13
|
+
* descending; first-decision-wins semantics mean the latest grant for a
|
|
14
|
+
* given version is what counts.
|
|
15
|
+
*/
|
|
16
|
+
export function createApprovalResolver(options) {
|
|
17
|
+
const { payload, collectionSlug = DEFAULT_APPROVALS_SLUG } = options;
|
|
18
|
+
return {
|
|
19
|
+
async getActiveApproval(collection, id, version) {
|
|
20
|
+
const result = await payload.find({
|
|
21
|
+
collection: collectionSlug,
|
|
22
|
+
where: {
|
|
23
|
+
and: [
|
|
24
|
+
{ targetCollection: { equals: collection } },
|
|
25
|
+
{ targetId: { equals: id } },
|
|
26
|
+
{ targetVersion: { equals: version } },
|
|
27
|
+
{ status: { equals: 'granted' } },
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
limit: 1,
|
|
31
|
+
sort: '-decidedAt',
|
|
32
|
+
});
|
|
33
|
+
const approval = result.docs[0];
|
|
34
|
+
if (!approval)
|
|
35
|
+
return null;
|
|
36
|
+
const decidedAt = approval['decidedAt'];
|
|
37
|
+
if (typeof decidedAt !== 'string')
|
|
38
|
+
return null;
|
|
39
|
+
const decidedByRaw = approval['decidedBy'];
|
|
40
|
+
const decidedBy = typeof decidedByRaw === 'string'
|
|
41
|
+
? decidedByRaw
|
|
42
|
+
: decidedByRaw && typeof decidedByRaw === 'object' && 'id' in decidedByRaw
|
|
43
|
+
? String(decidedByRaw.id)
|
|
44
|
+
: '';
|
|
45
|
+
return {
|
|
46
|
+
id: String(approval['id']),
|
|
47
|
+
grantedAt: decidedAt,
|
|
48
|
+
grantedBy: decidedBy,
|
|
49
|
+
version: String(approval['targetVersion']),
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** Attaches the resolver to a Payload instance under the agreed symbol. */
|
|
55
|
+
export function attachApprovalResolver(payload, resolver) {
|
|
56
|
+
Object.defineProperty(payload, APPROVALS_RESOLVER_SYMBOL, {
|
|
57
|
+
value: resolver,
|
|
58
|
+
enumerable: false,
|
|
59
|
+
writable: false,
|
|
60
|
+
configurable: false,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AAExD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,GAAG,CACjD,0CAA0C,CAC3C,CAAA;AAQD;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAsC;IAEtC,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,sBAAsB,EAAE,GAAG,OAAO,CAAA;IAEpE,OAAO;QACL,KAAK,CAAC,iBAAiB,CAAC,UAAU,EAAE,EAAE,EAAE,OAAO;YAC7C,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;gBAChC,UAAU,EAAE,cAAc;gBAC1B,KAAK,EAAE;oBACL,GAAG,EAAE;wBACH,EAAE,gBAAgB,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE;wBAC5C,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE;wBAC5B,EAAE,aAAa,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;wBACtC,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE;qBAClC;iBACF;gBACD,KAAK,EAAE,CAAC;gBACR,IAAI,EAAE,YAAY;aACnB,CAAC,CAAA;YAEF,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAwC,CAAA;YACtE,IAAI,CAAC,QAAQ;gBAAE,OAAO,IAAI,CAAA;YAE1B,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAA;YACvC,IAAI,OAAO,SAAS,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAA;YAE9C,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAA;YAC1C,MAAM,SAAS,GACb,OAAO,YAAY,KAAK,QAAQ;gBAC9B,CAAC,CAAC,YAAY;gBACd,CAAC,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,IAAI,IAAI,YAAY;oBACxE,CAAC,CAAC,MAAM,CAAE,YAAgC,CAAC,EAAE,CAAC;oBAC9C,CAAC,CAAC,EAAE,CAAA;YAEV,OAAO;gBACL,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC1B,SAAS,EAAE,SAAS;gBACpB,SAAS,EAAE,SAAS;gBACpB,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;aAC3C,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,sBAAsB,CACpC,OAAe,EACf,QAA0B;IAE1B,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,yBAAyB,EAAE;QACxD,KAAK,EAAE,QAAQ;QACf,UAAU,EAAE,KAAK;QACjB,QAAQ,EAAE,KAAK;QACf,YAAY,EAAE,KAAK;KACpB,CAAC,CAAA;AACJ,CAAC"}
|
package/dist/tokens.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HMAC-signed action tokens used in inline action emails (Approve / Decline /
|
|
3
|
+
* Request changes / Discuss). Each token is bound to one approval, one
|
|
4
|
+
* action, and one approver. Tokens are valid for a configurable window
|
|
5
|
+
* (default 14 days) and consumed via the `consumedTokens` array on the
|
|
6
|
+
* approval record so they can't be replayed.
|
|
7
|
+
*
|
|
8
|
+
* Crypto uses the Web Crypto API (`crypto.subtle`) so the same code runs
|
|
9
|
+
* in Node and edge runtimes.
|
|
10
|
+
*/
|
|
11
|
+
export type ActionTokenAction = 'approve' | 'decline' | 'changes' | 'discuss';
|
|
12
|
+
export interface ActionToken {
|
|
13
|
+
approvalId: string;
|
|
14
|
+
action: ActionTokenAction;
|
|
15
|
+
approverId: string;
|
|
16
|
+
/** Issued-at timestamp in milliseconds since epoch. */
|
|
17
|
+
issuedAt: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Mints an action token. Returns a base64url-encoded payload with the
|
|
21
|
+
* format `<approvalId>:<action>:<approverId>:<issuedAt>:<signature>`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function generateActionToken(token: ActionToken, secret: string): Promise<string>;
|
|
24
|
+
export interface VerifyOptions {
|
|
25
|
+
/** Override the default 14-day token lifetime. */
|
|
26
|
+
maxAgeMs?: number;
|
|
27
|
+
/** Override "now" — useful in tests. Defaults to `Date.now()`. */
|
|
28
|
+
now?: number;
|
|
29
|
+
}
|
|
30
|
+
export type VerifyResult = {
|
|
31
|
+
ok: true;
|
|
32
|
+
token: ActionToken;
|
|
33
|
+
} | {
|
|
34
|
+
ok: false;
|
|
35
|
+
error: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Verifies a base64url-encoded action token with constant-time signature
|
|
39
|
+
* comparison. Returns either the parsed token or a structured error.
|
|
40
|
+
*/
|
|
41
|
+
export declare function verifyActionToken(encoded: string, secret: string, options?: VerifyOptions): Promise<VerifyResult>;
|
|
42
|
+
/**
|
|
43
|
+
* Returns the absolute URL an approver visits to invoke the action. The
|
|
44
|
+
* server-side endpoint (added by the plugin) verifies the token and
|
|
45
|
+
* presents a confirmation page before recording the decision.
|
|
46
|
+
*/
|
|
47
|
+
export declare function buildActionUrl(publicUrl: string, token: string): string;
|
|
48
|
+
//# sourceMappingURL=tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAA;AAE7E,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,iBAAiB,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAA;CACjB;AAOD;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED,MAAM,WAAW,aAAa;IAC5B,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,GAChC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAEhC;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CAiDvB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAGvE"}
|
package/dist/tokens.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HMAC-signed action tokens used in inline action emails (Approve / Decline /
|
|
3
|
+
* Request changes / Discuss). Each token is bound to one approval, one
|
|
4
|
+
* action, and one approver. Tokens are valid for a configurable window
|
|
5
|
+
* (default 14 days) and consumed via the `consumedTokens` array on the
|
|
6
|
+
* approval record so they can't be replayed.
|
|
7
|
+
*
|
|
8
|
+
* Crypto uses the Web Crypto API (`crypto.subtle`) so the same code runs
|
|
9
|
+
* in Node and edge runtimes.
|
|
10
|
+
*/
|
|
11
|
+
const DEFAULT_MAX_AGE_MS = 14 * 24 * 60 * 60 * 1000;
|
|
12
|
+
const TOKEN_PARTS = 5;
|
|
13
|
+
const VALID_ACTIONS = new Set(['approve', 'decline', 'changes', 'discuss']);
|
|
14
|
+
const ENCODER = new TextEncoder();
|
|
15
|
+
/**
|
|
16
|
+
* Mints an action token. Returns a base64url-encoded payload with the
|
|
17
|
+
* format `<approvalId>:<action>:<approverId>:<issuedAt>:<signature>`.
|
|
18
|
+
*/
|
|
19
|
+
export async function generateActionToken(token, secret) {
|
|
20
|
+
ensureSafeForEncoding(token);
|
|
21
|
+
const payload = `${token.approvalId}:${token.action}:${token.approverId}:${token.issuedAt}`;
|
|
22
|
+
const signature = await hmacSignHex(payload, secret);
|
|
23
|
+
return base64UrlEncode(`${payload}:${signature}`);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Verifies a base64url-encoded action token with constant-time signature
|
|
27
|
+
* comparison. Returns either the parsed token or a structured error.
|
|
28
|
+
*/
|
|
29
|
+
export async function verifyActionToken(encoded, secret, options = {}) {
|
|
30
|
+
let decoded;
|
|
31
|
+
try {
|
|
32
|
+
decoded = base64UrlDecode(encoded);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return { ok: false, error: 'Token decode failed' };
|
|
36
|
+
}
|
|
37
|
+
const parts = decoded.split(':');
|
|
38
|
+
if (parts.length !== TOKEN_PARTS)
|
|
39
|
+
return { ok: false, error: 'Invalid token format' };
|
|
40
|
+
const [approvalId, action, approverId, issuedAtRaw, providedSignature] = parts;
|
|
41
|
+
if (!approvalId || !action || !approverId || !issuedAtRaw || !providedSignature) {
|
|
42
|
+
return { ok: false, error: 'Invalid token format' };
|
|
43
|
+
}
|
|
44
|
+
const issuedAt = Number.parseInt(issuedAtRaw, 10);
|
|
45
|
+
if (!Number.isFinite(issuedAt)) {
|
|
46
|
+
return { ok: false, error: 'Invalid token timestamp' };
|
|
47
|
+
}
|
|
48
|
+
if (!VALID_ACTIONS.has(action)) {
|
|
49
|
+
return { ok: false, error: 'Invalid action' };
|
|
50
|
+
}
|
|
51
|
+
const expectedSignature = await hmacSignHex(`${approvalId}:${action}:${approverId}:${issuedAt}`, secret);
|
|
52
|
+
if (!constantTimeEqual(providedSignature, expectedSignature)) {
|
|
53
|
+
return { ok: false, error: 'Invalid token signature' };
|
|
54
|
+
}
|
|
55
|
+
const maxAge = options.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
|
|
56
|
+
const now = options.now ?? Date.now();
|
|
57
|
+
if (now - issuedAt > maxAge) {
|
|
58
|
+
return { ok: false, error: 'Token has expired' };
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
ok: true,
|
|
62
|
+
token: { approvalId, action: action, approverId, issuedAt },
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Returns the absolute URL an approver visits to invoke the action. The
|
|
67
|
+
* server-side endpoint (added by the plugin) verifies the token and
|
|
68
|
+
* presents a confirmation page before recording the decision.
|
|
69
|
+
*/
|
|
70
|
+
export function buildActionUrl(publicUrl, token) {
|
|
71
|
+
const base = publicUrl.replace(/\/$/, '');
|
|
72
|
+
return `${base}/api/approvals/action?token=${encodeURIComponent(token)}`;
|
|
73
|
+
}
|
|
74
|
+
async function hmacSignHex(payload, secret) {
|
|
75
|
+
const key = await crypto.subtle.importKey('raw', ENCODER.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
|
76
|
+
const signature = await crypto.subtle.sign('HMAC', key, ENCODER.encode(payload));
|
|
77
|
+
return Array.from(new Uint8Array(signature))
|
|
78
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
79
|
+
.join('');
|
|
80
|
+
}
|
|
81
|
+
function constantTimeEqual(a, b) {
|
|
82
|
+
if (a.length !== b.length)
|
|
83
|
+
return false;
|
|
84
|
+
let result = 0;
|
|
85
|
+
for (let i = 0; i < a.length; i++) {
|
|
86
|
+
result |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
87
|
+
}
|
|
88
|
+
return result === 0;
|
|
89
|
+
}
|
|
90
|
+
function ensureSafeForEncoding(token) {
|
|
91
|
+
if (token.approvalId.includes(':') ||
|
|
92
|
+
token.approverId.includes(':') ||
|
|
93
|
+
token.action.includes(':')) {
|
|
94
|
+
throw new Error('Token field contains a reserved colon character');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function base64UrlEncode(input) {
|
|
98
|
+
return Buffer.from(input, 'utf-8').toString('base64url');
|
|
99
|
+
}
|
|
100
|
+
function base64UrlDecode(encoded) {
|
|
101
|
+
return Buffer.from(encoded, 'base64url').toString('utf-8');
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Payload } from 'payload';
|
|
2
|
+
import type { McpToolDefinition } from '@forumone/throughline-plugin-contract';
|
|
3
|
+
import type { ApprovalsPluginOptions } from '../options.js';
|
|
4
|
+
export interface GetApprovalStatusDeps {
|
|
5
|
+
payload: Payload;
|
|
6
|
+
options: ApprovalsPluginOptions & {
|
|
7
|
+
tokenSecret: string;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export declare function createGetApprovalStatusTool(deps: GetApprovalStatusDeps): McpToolDefinition;
|
|
11
|
+
//# sourceMappingURL=get-approval-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-approval-status.d.ts","sourceRoot":"","sources":["../../src/tools/get-approval-status.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAE9E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAE3D,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,sBAAsB,GAAG;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;CAC1D;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,qBAAqB,GAAG,iBAAiB,CAkC1F"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { withMeta } from '@forumone/throughline-core';
|
|
3
|
+
import { DEFAULT_APPROVALS_SLUG } from '../collection.js';
|
|
4
|
+
export function createGetApprovalStatusTool(deps) {
|
|
5
|
+
const inputSchema = withMeta({
|
|
6
|
+
approvalId: z.string(),
|
|
7
|
+
});
|
|
8
|
+
return {
|
|
9
|
+
name: 'get_approval_status',
|
|
10
|
+
description: "Returns the current status of an approval request including who decided, when, and any notes. Read-only; no audit record is written.",
|
|
11
|
+
inputSchema,
|
|
12
|
+
handler: async (input) => {
|
|
13
|
+
const approval = (await deps.payload.findByID({
|
|
14
|
+
collection: deps.options.collectionSlug ?? DEFAULT_APPROVALS_SLUG,
|
|
15
|
+
id: input.approvalId,
|
|
16
|
+
}));
|
|
17
|
+
if (!approval)
|
|
18
|
+
return { error: 'Approval not found' };
|
|
19
|
+
return {
|
|
20
|
+
approvalId: String(approval['id']),
|
|
21
|
+
status: approval['status'],
|
|
22
|
+
targetCollection: approval['targetCollection'],
|
|
23
|
+
targetId: approval['targetId'],
|
|
24
|
+
targetTitle: approval['targetTitle'],
|
|
25
|
+
targetVersion: approval['targetVersion'],
|
|
26
|
+
requestedBy: unwrapRelationshipId(approval['requestedBy']),
|
|
27
|
+
requestedAt: approval['requestedAt'],
|
|
28
|
+
approverGroups: approval['approverGroups'],
|
|
29
|
+
decidedBy: unwrapRelationshipId(approval['decidedBy']),
|
|
30
|
+
decidedAt: approval['decidedAt'],
|
|
31
|
+
decisionNotes: approval['decisionNotes'],
|
|
32
|
+
expiresAt: approval['expiresAt'],
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function unwrapRelationshipId(value) {
|
|
38
|
+
if (value === null || value === undefined)
|
|
39
|
+
return null;
|
|
40
|
+
if (typeof value === 'string')
|
|
41
|
+
return value;
|
|
42
|
+
if (typeof value === 'object' && 'id' in value) {
|
|
43
|
+
return String(value.id);
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=get-approval-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-approval-status.js","sourceRoot":"","sources":["../../src/tools/get-approval-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AAErD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;AAQzD,MAAM,UAAU,2BAA2B,CAAC,IAA2B;IACrE,MAAM,WAAW,GAAG,QAAQ,CAAC;QAC3B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;KACvB,CAAC,CAAA;IAEF,OAAO;QACL,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EACT,sIAAsI;QACxI,WAAW;QACX,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACvB,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;gBAC5C,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,sBAAsB;gBACjE,EAAE,EAAE,KAAK,CAAC,UAAU;aACrB,CAAC,CAAmC,CAAA;YACrC,IAAI,CAAC,QAAQ;gBAAE,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAA;YAErD,OAAO;gBACL,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAClC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC;gBAC1B,gBAAgB,EAAE,QAAQ,CAAC,kBAAkB,CAAC;gBAC9C,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC;gBAC9B,WAAW,EAAE,QAAQ,CAAC,aAAa,CAAC;gBACpC,aAAa,EAAE,QAAQ,CAAC,eAAe,CAAC;gBACxC,WAAW,EAAE,oBAAoB,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;gBAC1D,WAAW,EAAE,QAAQ,CAAC,aAAa,CAAC;gBACpC,cAAc,EAAE,QAAQ,CAAC,gBAAgB,CAAC;gBAC1C,SAAS,EAAE,oBAAoB,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;gBACtD,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC;gBAChC,aAAa,EAAE,QAAQ,CAAC,eAAe,CAAC;gBACxC,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC;aACjC,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IACtD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;QAC/C,OAAO,MAAM,CAAE,KAAyB,CAAC,EAAE,CAAC,CAAA;IAC9C,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { createRequestApprovalTool, type RequestApprovalDeps, } from './request-approval.js';
|
|
2
|
+
export { createRespondToApprovalTool, type RespondToApprovalDeps, } from './respond-to-approval.js';
|
|
3
|
+
export { createGetApprovalStatusTool, type GetApprovalStatusDeps, } from './get-approval-status.js';
|
|
4
|
+
export { createListPendingApprovalsTool, type ListPendingApprovalsDeps, } from './list-pending-approvals.js';
|
|
5
|
+
export { createListMyRequestsTool, type ListMyRequestsDeps, } from './list-my-requests.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,KAAK,mBAAmB,GACzB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,2BAA2B,EAC3B,KAAK,qBAAqB,GAC3B,MAAM,0BAA0B,CAAA;AACjC,OAAO,EACL,2BAA2B,EAC3B,KAAK,qBAAqB,GAC3B,MAAM,0BAA0B,CAAA;AACjC,OAAO,EACL,8BAA8B,EAC9B,KAAK,wBAAwB,GAC9B,MAAM,6BAA6B,CAAA;AACpC,OAAO,EACL,wBAAwB,EACxB,KAAK,kBAAkB,GACxB,MAAM,uBAAuB,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { createRequestApprovalTool, } from './request-approval.js';
|
|
2
|
+
export { createRespondToApprovalTool, } from './respond-to-approval.js';
|
|
3
|
+
export { createGetApprovalStatusTool, } from './get-approval-status.js';
|
|
4
|
+
export { createListPendingApprovalsTool, } from './list-pending-approvals.js';
|
|
5
|
+
export { createListMyRequestsTool, } from './list-my-requests.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,GAE1B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,2BAA2B,GAE5B,MAAM,0BAA0B,CAAA;AACjC,OAAO,EACL,2BAA2B,GAE5B,MAAM,0BAA0B,CAAA;AACjC,OAAO,EACL,8BAA8B,GAE/B,MAAM,6BAA6B,CAAA;AACpC,OAAO,EACL,wBAAwB,GAEzB,MAAM,uBAAuB,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Payload } from 'payload';
|
|
2
|
+
import type { McpToolDefinition } from '@forumone/throughline-plugin-contract';
|
|
3
|
+
import type { ApprovalsPluginOptions } from '../options.js';
|
|
4
|
+
export interface ListMyRequestsDeps {
|
|
5
|
+
payload: Payload;
|
|
6
|
+
options: ApprovalsPluginOptions & {
|
|
7
|
+
tokenSecret: string;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export declare function createListMyRequestsTool(deps: ListMyRequestsDeps): McpToolDefinition;
|
|
11
|
+
//# sourceMappingURL=list-my-requests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-my-requests.d.ts","sourceRoot":"","sources":["../../src/tools/list-my-requests.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAE9E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAE3D,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,sBAAsB,GAAG;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;CAC1D;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,kBAAkB,GAAG,iBAAiB,CAqDpF"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { withMeta } from '@forumone/throughline-core';
|
|
3
|
+
import { DEFAULT_APPROVALS_SLUG } from '../collection.js';
|
|
4
|
+
export function createListMyRequestsTool(deps) {
|
|
5
|
+
const inputSchema = withMeta({
|
|
6
|
+
status: z
|
|
7
|
+
.enum(['pending', 'granted', 'declined', 'changes-requested', 'expired'])
|
|
8
|
+
.optional()
|
|
9
|
+
.describe('Filter by status. Defaults to all.'),
|
|
10
|
+
limit: z
|
|
11
|
+
.number()
|
|
12
|
+
.int()
|
|
13
|
+
.positive()
|
|
14
|
+
.max(100)
|
|
15
|
+
.optional()
|
|
16
|
+
.describe('Max results. Default: 25'),
|
|
17
|
+
});
|
|
18
|
+
return {
|
|
19
|
+
name: 'list_my_requests',
|
|
20
|
+
description: "Returns approval requests the current user has submitted, optionally filtered by status. Use to answer 'what's the state of my pending approvals?'. Read-only.",
|
|
21
|
+
inputSchema,
|
|
22
|
+
handler: async (input, ctx) => {
|
|
23
|
+
if (!ctx.user)
|
|
24
|
+
return { error: 'Must be authenticated to list approval requests' };
|
|
25
|
+
const result = await deps.payload.find({
|
|
26
|
+
collection: deps.options.collectionSlug ?? DEFAULT_APPROVALS_SLUG,
|
|
27
|
+
where: input.status
|
|
28
|
+
? {
|
|
29
|
+
and: [
|
|
30
|
+
{ requestedBy: { equals: ctx.user.id } },
|
|
31
|
+
{ status: { equals: input.status } },
|
|
32
|
+
],
|
|
33
|
+
}
|
|
34
|
+
: { requestedBy: { equals: ctx.user.id } },
|
|
35
|
+
limit: input.limit ?? 25,
|
|
36
|
+
sort: '-requestedAt',
|
|
37
|
+
});
|
|
38
|
+
const docs = result.docs;
|
|
39
|
+
return {
|
|
40
|
+
requests: docs.map((doc) => ({
|
|
41
|
+
approvalId: String(doc['id']),
|
|
42
|
+
status: doc['status'],
|
|
43
|
+
targetCollection: doc['targetCollection'],
|
|
44
|
+
targetId: doc['targetId'],
|
|
45
|
+
targetTitle: doc['targetTitle'],
|
|
46
|
+
requestedAt: doc['requestedAt'],
|
|
47
|
+
decidedAt: doc['decidedAt'],
|
|
48
|
+
decisionNotes: doc['decisionNotes'],
|
|
49
|
+
expiresAt: doc['expiresAt'],
|
|
50
|
+
})),
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=list-my-requests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-my-requests.js","sourceRoot":"","sources":["../../src/tools/list-my-requests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AAErD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;AAQzD,MAAM,UAAU,wBAAwB,CAAC,IAAwB;IAC/D,MAAM,WAAW,GAAG,QAAQ,CAAC;QAC3B,MAAM,EAAE,CAAC;aACN,IAAI,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,mBAAmB,EAAE,SAAS,CAAC,CAAC;aACxE,QAAQ,EAAE;aACV,QAAQ,CAAC,oCAAoC,CAAC;QACjD,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,GAAG,EAAE;aACL,QAAQ,EAAE;aACV,GAAG,CAAC,GAAG,CAAC;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,0BAA0B,CAAC;KACxC,CAAC,CAAA;IAEF,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,WAAW,EACT,gKAAgK;QAClK,WAAW;QACX,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAC5B,IAAI,CAAC,GAAG,CAAC,IAAI;gBAAE,OAAO,EAAE,KAAK,EAAE,iDAAiD,EAAE,CAAA;YAElF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;gBACrC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,sBAAsB;gBACjE,KAAK,EAAE,KAAK,CAAC,MAAM;oBACjB,CAAC,CAAC;wBACE,GAAG,EAAE;4BACH,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE;4BACxC,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE;yBACrC;qBACF;oBACH,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE;gBAC5C,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;gBACxB,IAAI,EAAE,cAAc;aACrB,CAAC,CAAA;YAEF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAsC,CAAA;YAC1D,OAAO;gBACL,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;oBAC3B,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC7B,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC;oBACrB,gBAAgB,EAAE,GAAG,CAAC,kBAAkB,CAAC;oBACzC,QAAQ,EAAE,GAAG,CAAC,UAAU,CAAC;oBACzB,WAAW,EAAE,GAAG,CAAC,aAAa,CAAC;oBAC/B,WAAW,EAAE,GAAG,CAAC,aAAa,CAAC;oBAC/B,SAAS,EAAE,GAAG,CAAC,WAAW,CAAC;oBAC3B,aAAa,EAAE,GAAG,CAAC,eAAe,CAAC;oBACnC,SAAS,EAAE,GAAG,CAAC,WAAW,CAAC;iBAC5B,CAAC,CAAC;aACJ,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Payload } from 'payload';
|
|
2
|
+
import type { McpToolDefinition } from '@forumone/throughline-plugin-contract';
|
|
3
|
+
import type { ApprovalsPluginOptions } from '../options.js';
|
|
4
|
+
export interface ListPendingApprovalsDeps {
|
|
5
|
+
payload: Payload;
|
|
6
|
+
options: ApprovalsPluginOptions & {
|
|
7
|
+
tokenSecret: string;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export declare function createListPendingApprovalsTool(deps: ListPendingApprovalsDeps): McpToolDefinition;
|
|
11
|
+
//# sourceMappingURL=list-pending-approvals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-pending-approvals.d.ts","sourceRoot":"","sources":["../../src/tools/list-pending-approvals.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAA;AAE9E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AAE3D,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,sBAAsB,GAAG;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAA;CAC1D;AAED,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,wBAAwB,GAC7B,iBAAiB,CAiDnB"}
|