@warmio/contracts 2.0.0 → 3.0.2
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 +3 -3
- package/dist/api/endpoints.d.ts +34 -48
- package/dist/api/endpoints.d.ts.map +1 -1
- package/dist/api/endpoints.js +36 -56
- package/dist/api/endpoints.js.map +1 -1
- package/dist/examples/financial-context.d.ts.map +1 -1
- package/dist/examples/financial-context.js +2 -1
- package/dist/examples/financial-context.js.map +1 -1
- package/dist/generated/base-openapi.d.ts +1 -1
- package/dist/generated/base-openapi.d.ts.map +1 -1
- package/dist/generated/base-openapi.js +1 -1
- package/dist/generated/base-openapi.js.map +1 -1
- package/dist/generated/mcp-package-release-metadata.d.ts +7 -0
- package/dist/generated/mcp-package-release-metadata.d.ts.map +1 -0
- package/dist/generated/mcp-package-release-metadata.js +7 -0
- package/dist/generated/mcp-package-release-metadata.js.map +1 -0
- package/dist/generated/private-mcp-tool-descriptors.d.ts +28 -43
- package/dist/generated/private-mcp-tool-descriptors.d.ts.map +1 -1
- package/dist/generated/private-mcp-tool-descriptors.js +38 -52
- package/dist/generated/private-mcp-tool-descriptors.js.map +1 -1
- package/dist/generated/protected-crawler-paths.d.ts +1 -1
- package/dist/generated/protected-crawler-paths.d.ts.map +1 -1
- package/dist/generated/protected-crawler-paths.js +3 -0
- package/dist/generated/protected-crawler-paths.js.map +1 -1
- package/dist/generated/warm-app-api-manifest.d.ts +1264 -0
- package/dist/generated/warm-app-api-manifest.d.ts.map +1 -0
- package/dist/generated/warm-app-api-manifest.js +1884 -0
- package/dist/generated/warm-app-api-manifest.js.map +1 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +600 -1176
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +31 -35
- package/dist/manifest.js.map +1 -1
- package/dist/mcp/distribution.d.ts +241 -71
- package/dist/mcp/distribution.d.ts.map +1 -1
- package/dist/mcp/distribution.js +137 -56
- package/dist/mcp/distribution.js.map +1 -1
- package/dist/mcp/tools.d.ts +1030 -29
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +11 -30
- package/dist/mcp/tools.js.map +1 -1
- package/dist/openapi/base.yaml +44 -67
- package/dist/openapi/build-openapi.d.ts +8 -2
- package/dist/openapi/build-openapi.d.ts.map +1 -1
- package/dist/openapi/build-openapi.js +93 -21
- package/dist/openapi/build-openapi.js.map +1 -1
- package/dist/product.d.ts.map +1 -1
- package/dist/product.js +9 -1
- package/dist/product.js.map +1 -1
- package/dist/schemas/financial-context.d.ts +33 -0
- package/dist/schemas/financial-context.d.ts.map +1 -1
- package/dist/schemas/financial-context.js +21 -6
- package/dist/schemas/financial-context.js.map +1 -1
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +1 -0
- package/dist/schemas/index.js.map +1 -1
- package/dist/schemas/public-api.d.ts +1368 -0
- package/dist/schemas/public-api.d.ts.map +1 -0
- package/dist/schemas/public-api.js +181 -0
- package/dist/schemas/public-api.js.map +1 -0
- package/dist/types.d.ts +8 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -8
- package/dist/public-discovery.d.ts +0 -116
- package/dist/public-discovery.d.ts.map +0 -1
- package/dist/public-discovery.js +0 -91
- package/dist/public-discovery.js.map +0 -1
package/dist/mcp/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAoB,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAY3E,eAAO,MAAM,kBAAkB,IAA2B,CAAC;AAC3D,eAAO,MAAM,4BAA4B;;CAMlB,CAAC;AACxB,eAAO,MAAM,6BAA6B;;CAEnB,CAAC;AACxB,eAAO,MAAM,8BAA8B;;;;;;;;;;;;CAKpB,CAAC;AACxB,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;CAOlB,CAAC;AAExB,eAAO,MAAM,6BAA6B;;;;;;EAAkD,CAAC;AAE7F,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC;;;;;;EAKrD;AAsBD,KAAK,mBAAmB,GAAG,eAAe,GAAG;IAC3C,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,WAAW,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAA;KAAE,GAAG,SAAS,CAAC;CAC9D,CAAC;AAWF,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwCW,CAAC;AAElD,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAUrC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC"}
|
package/dist/mcp/tools.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
/* oxlint-disable anti-slop/no-shape-in-symbol-names -- ZodRawShape and inputShape are canonical Zod/MCP contract terms. */
|
|
1
2
|
import { z } from 'zod';
|
|
2
3
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
3
|
-
import { automationInputSchema, automationOperationDescriptionResponseSchema, automationOperationSearchResponseSchema, financialContextSchema, latestTransactionsSchema, transactionMonthSchema, } from '../schemas/index.js';
|
|
4
|
+
import { automationInputSchema, automationOperationDescriptionResponseSchema, automationOperationSearchResponseSchema, financialContextMonthSchema, FINANCIAL_CONTEXT_POSITION_DESCRIPTION, financialContextSchema, latestTransactionsSchema, transactionMonthSchema, } from '../schemas/index.js';
|
|
4
5
|
export const emptyMcpInputShape = {};
|
|
5
6
|
export const getTransactionsMcpInputShape = {
|
|
6
7
|
period: z
|
|
7
|
-
.
|
|
8
|
-
.regex(/^(?:latest|\d{4}-\d{2})$/, 'Expected "latest" or a YYYY-MM month.')
|
|
8
|
+
.union([z.literal('latest'), financialContextMonthSchema])
|
|
9
9
|
.describe('Use "latest" for the fixed 10-day window or a YYYY-MM month. Months outside the covered range return an error.'),
|
|
10
10
|
};
|
|
11
11
|
export const searchOperationsMcpInputShape = {
|
|
@@ -31,13 +31,6 @@ export function normalizeGetTransactionsMcpInput(input) {
|
|
|
31
31
|
? { latest: true }
|
|
32
32
|
: { month: input.period };
|
|
33
33
|
}
|
|
34
|
-
const verifyKeyOutputSchema = z
|
|
35
|
-
.object({
|
|
36
|
-
audience: z.enum(['automation', 'context', 'oauth']).optional(),
|
|
37
|
-
status: z.string(),
|
|
38
|
-
valid: z.boolean(),
|
|
39
|
-
})
|
|
40
|
-
.strict();
|
|
41
34
|
const operationInvokeOutputSchema = z
|
|
42
35
|
.object({
|
|
43
36
|
body: z.unknown(),
|
|
@@ -47,23 +40,22 @@ const operationInvokeOutputSchema = z
|
|
|
47
40
|
})
|
|
48
41
|
.strict();
|
|
49
42
|
const tool = (definition) => definition;
|
|
50
|
-
const normalizeJsonSchema = (schema) =>
|
|
51
|
-
...schema
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
43
|
+
const normalizeJsonSchema = (schema) => {
|
|
44
|
+
const normalizedSchema = { ...schema };
|
|
45
|
+
if (normalizedSchema.$schema === 'http://json-schema.org/draft-07/schema#') {
|
|
46
|
+
normalizedSchema.$schema = 'https://json-schema.org/draft-07/schema#';
|
|
47
|
+
}
|
|
48
|
+
return normalizedSchema;
|
|
49
|
+
};
|
|
56
50
|
export const privateMcpToolDefinitions = [
|
|
57
51
|
tool({
|
|
58
|
-
mode: 'context',
|
|
59
52
|
name: 'get_financial_context',
|
|
60
|
-
description:
|
|
53
|
+
description: `Read-only compact FinancialContext JSON. Includes status.position, status.accounts, transaction index total/months, recurring, budgets, goals, snapshots, liabilities, holdings, and health. ${FINANCIAL_CONTEXT_POSITION_DESCRIPTION} Transaction items are not inline; use get_transactions for items.`,
|
|
61
54
|
annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
|
|
62
55
|
inputShape: emptyMcpInputShape,
|
|
63
56
|
outputSchema: financialContextSchema,
|
|
64
57
|
}),
|
|
65
58
|
tool({
|
|
66
|
-
mode: 'context',
|
|
67
59
|
name: 'get_transactions',
|
|
68
60
|
description: 'Read-only transactions from the FinancialContext artifact. Pass `period: "latest"` for the fixed 10-day latest window or `period: "YYYY-MM"` for a month page. The latest window is not caller-configurable. Months outside the covered range return an error.',
|
|
69
61
|
annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
|
|
@@ -71,15 +63,6 @@ export const privateMcpToolDefinitions = [
|
|
|
71
63
|
outputSchema: z.union([transactionMonthSchema, latestTransactionsSchema]),
|
|
72
64
|
}),
|
|
73
65
|
tool({
|
|
74
|
-
mode: 'context',
|
|
75
|
-
name: 'verify_key',
|
|
76
|
-
description: 'Read-only API key validation for the configured Warm account.',
|
|
77
|
-
annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
|
|
78
|
-
inputShape: emptyMcpInputShape,
|
|
79
|
-
outputSchema: verifyKeyOutputSchema,
|
|
80
|
-
}),
|
|
81
|
-
tool({
|
|
82
|
-
mode: 'automation',
|
|
83
66
|
name: 'search_operations',
|
|
84
67
|
description: 'Search the supported Warm operation catalog. Use this first to find the smallest matching operation.',
|
|
85
68
|
annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
|
|
@@ -87,7 +70,6 @@ export const privateMcpToolDefinitions = [
|
|
|
87
70
|
outputSchema: automationOperationSearchResponseSchema,
|
|
88
71
|
}),
|
|
89
72
|
tool({
|
|
90
|
-
mode: 'automation',
|
|
91
73
|
name: 'describe_operation',
|
|
92
74
|
description: 'Describe one operation, including its input schema and risk. For write operations, pass the exact intended input to receive an approval with its ID, status, URL, and expiry.',
|
|
93
75
|
annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false },
|
|
@@ -95,7 +77,6 @@ export const privateMcpToolDefinitions = [
|
|
|
95
77
|
outputSchema: automationOperationDescriptionResponseSchema,
|
|
96
78
|
}),
|
|
97
79
|
tool({
|
|
98
|
-
mode: 'automation',
|
|
99
80
|
name: 'invoke_operation',
|
|
100
81
|
description: 'Invoke one previously discovered Warm operation. Every write operation requires the approval_id returned for the exact same input by describe_operation.',
|
|
101
82
|
annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: false },
|
package/dist/mcp/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAoB,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA,2HAA2H;AAC3H,OAAO,EAAE,CAAC,EAAoB,MAAM,KAAK,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAwB,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EACL,qBAAqB,EACrB,4CAA4C,EAC5C,uCAAuC,EACvC,2BAA2B,EAC3B,sCAAsC,EACtC,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAwB,CAAC;AAC3D,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,MAAM,EAAE,CAAC;SACN,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,2BAA2B,CAAC,CAAC;SACzD,QAAQ,CACP,gHAAgH,CACjH;CACkB,CAAC;AACxB,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;CAC1E,CAAC;AACxB,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,KAAK,EAAE,qBAAqB;SACzB,QAAQ,EAAE;SACV,QAAQ,CAAC,0EAA0E,CAAC;CAClE,CAAC;AACxB,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,GAAG,8BAA8B;IACjC,WAAW,EAAE,CAAC;SACX,MAAM,EAAE;SACR,IAAI,EAAE;SACN,QAAQ,EAAE;SACV,QAAQ,CAAC,uEAAuE,CAAC;CAC/D,CAAC;AAExB,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,MAAM,EAAE,CAAC;AAE7F,MAAM,UAAU,gCAAgC,CAC9C,KAAoD;IAEpD,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;QAC9B,CAAC,CAAE,EAAE,MAAM,EAAE,IAAI,EAAY;QAC7B,CAAC,CAAE,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAY,CAAC;AACzC,CAAC;AAED,MAAM,2BAA2B,GAAG,CAAC;KAClC,MAAM,CAAC;IACN,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;IACjB,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAC7B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;CACzB,CAAC;KACD,MAAM,EAAE,CAAC;AAUZ,MAAM,IAAI,GAAG,CAA6C,UAAsB,EAAc,EAAE,CAC9F,UAAU,CAAC;AAMb,MAAM,mBAAmB,GAAG,CAAC,MAA2B,EAAuB,EAAE;IAC/E,MAAM,gBAAgB,GAAwB,EAAE,GAAG,MAAM,EAAE,CAAC;IAE5D,IAAI,gBAAgB,CAAC,OAAO,KAAK,yCAAyC,EAAE,CAAC;QAC3E,gBAAgB,CAAC,OAAO,GAAG,0CAA0C,CAAC;IACxE,CAAC;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,IAAI,CAAC;QACH,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EAAE,gMAAgM,sCAAsC,oEAAoE;QACvT,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE;QACjF,UAAU,EAAE,kBAAkB;QAC9B,YAAY,EAAE,sBAAsB;KACrC,CAAC;IACF,IAAI,CAAC;QACH,IAAI,EAAE,kBAAkB;QACxB,WAAW,EACT,gQAAgQ;QAClQ,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE;QACjF,UAAU,EAAE,4BAA4B;QACxC,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,sBAAsB,EAAE,wBAAwB,CAAC,CAAC;KAC1E,CAAC;IACF,IAAI,CAAC;QACH,IAAI,EAAE,mBAAmB;QACzB,WAAW,EACT,sGAAsG;QACxG,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE;QACjF,UAAU,EAAE,6BAA6B;QACzC,YAAY,EAAE,uCAAuC;KACtD,CAAC;IACF,IAAI,CAAC;QACH,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EACT,+KAA+K;QACjL,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE;QAClF,UAAU,EAAE,8BAA8B;QAC1C,YAAY,EAAE,4CAA4C;KAC3D,CAAC;IACF,IAAI,CAAC;QACH,IAAI,EAAE,kBAAkB;QACxB,WAAW,EACT,0JAA0J;QAC5J,WAAW,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE;QACjF,UAAU,EAAE,4BAA4B;QACxC,YAAY,EAAE,2BAA2B;KAC1C,CAAC;CAC6C,CAAC;AAElD,MAAM,CAAC,MAAM,yBAAyB,GAAG,yBAAyB,CAAC,GAAG,CACpE,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,cAAc,EAAE,EAAE,EAAE,CAAC,CAAC;IACpD,GAAG,cAAc;IACjB,YAAY,EAAE,mBAAmB,CAC/B,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,EAAE;QAC7C,YAAY,EAAE,MAAM;KACrB,CAAC,CACH;IACD,aAAa,EAAE,mBAAmB,CAAC,eAAe,CAAC,YAAY,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;CAC5F,CAAC,CACH,CAAC"}
|
package/dist/openapi/base.yaml
CHANGED
|
@@ -5,20 +5,17 @@ info:
|
|
|
5
5
|
Read your financial context or invoke supported Warm actions through a compact operation catalog.
|
|
6
6
|
|
|
7
7
|
## Authentication
|
|
8
|
-
All requests use `Authorization: Bearer`.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Read/export routes accept `Authorization: Bearer YOUR_API_KEY_OR_ACCESS_TOKEN`.
|
|
12
|
-
Automation routes require an automation key (`warm_auto_...`) and do not accept access tokens.
|
|
8
|
+
All requests use `Authorization: Bearer`. Each account has one non-expiring full-access
|
|
9
|
+
API key (`warm_...`) for raw API and local MCP use. Read/export routes also accept a
|
|
10
|
+
signed-in access token; access tokens never authorize automation operations.
|
|
13
11
|
|
|
14
12
|
Unauthenticated responses include `WWW-Authenticate` guidance and protected resource metadata.
|
|
15
13
|
|
|
16
14
|
## Rate Limits
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
- Rate limit headers included in authenticated responses
|
|
15
|
+
- API keys: 500 requests per hour per key
|
|
16
|
+
- Rate limit headers are included only on routes that document a `429` response
|
|
20
17
|
- `/api/export` supports dataset-scoped delta sync with `since` and publishes edge-cache metadata headers
|
|
21
|
-
version: '
|
|
18
|
+
version: '3.0.2'
|
|
22
19
|
contact:
|
|
23
20
|
name: Warm Support
|
|
24
21
|
url: https://warm.io/support
|
|
@@ -39,9 +36,7 @@ paths:
|
|
|
39
36
|
operationId: verifyApiAccess
|
|
40
37
|
summary: Verify API credentials
|
|
41
38
|
description: |
|
|
42
|
-
Validate a Warm API key or signed-in user access token
|
|
43
|
-
|
|
44
|
-
This endpoint is the canonical readiness check for public API clients and discovery tools.
|
|
39
|
+
Validate a Warm API key or signed-in user access token for installer and Settings flows.
|
|
45
40
|
tags:
|
|
46
41
|
- Verification
|
|
47
42
|
responses:
|
|
@@ -50,30 +45,11 @@ paths:
|
|
|
50
45
|
content:
|
|
51
46
|
application/json:
|
|
52
47
|
schema:
|
|
53
|
-
|
|
54
|
-
required:
|
|
55
|
-
- status
|
|
56
|
-
- valid
|
|
57
|
-
- auth
|
|
58
|
-
properties:
|
|
59
|
-
status:
|
|
60
|
-
type: string
|
|
61
|
-
enum: [ok]
|
|
62
|
-
valid:
|
|
63
|
-
type: boolean
|
|
64
|
-
auth:
|
|
65
|
-
type: string
|
|
66
|
-
description: Auth method used to satisfy verification
|
|
67
|
-
audience:
|
|
68
|
-
type: string
|
|
69
|
-
enum: [context, automation, oauth]
|
|
48
|
+
$ref: '#/components/schemas/VerifyApiResponse'
|
|
70
49
|
'401':
|
|
71
50
|
$ref: '#/components/responses/Unauthorized'
|
|
72
51
|
'403':
|
|
73
52
|
$ref: '#/components/responses/Forbidden'
|
|
74
|
-
'429':
|
|
75
|
-
$ref: '#/components/responses/RateLimited'
|
|
76
|
-
|
|
77
53
|
/api/export:
|
|
78
54
|
get:
|
|
79
55
|
operationId: getDatasetExport
|
|
@@ -82,7 +58,7 @@ paths:
|
|
|
82
58
|
Fetch a canonical financial dataset export from the unified `/api/export` surface.
|
|
83
59
|
|
|
84
60
|
Use `dataset=transactions` for paginated transaction history. Other datasets return
|
|
85
|
-
a typed JSON object keyed by the dataset name
|
|
61
|
+
a typed JSON object keyed by the documented dataset name.
|
|
86
62
|
|
|
87
63
|
Preferred dataset names are `accounts`, `transactions`, `snapshots`, `recurring`,
|
|
88
64
|
`budgets`, `goals`, `health`, `liabilities`, and `holdings`.
|
|
@@ -91,7 +67,7 @@ paths:
|
|
|
91
67
|
parameters:
|
|
92
68
|
- name: dataset
|
|
93
69
|
in: query
|
|
94
|
-
description: Dataset identifier
|
|
70
|
+
description: Dataset identifier
|
|
95
71
|
required: true
|
|
96
72
|
schema:
|
|
97
73
|
type: string
|
|
@@ -112,13 +88,6 @@ paths:
|
|
|
112
88
|
schema:
|
|
113
89
|
type: string
|
|
114
90
|
format: date-time
|
|
115
|
-
- name: last_knowledge
|
|
116
|
-
in: query
|
|
117
|
-
description: Legacy alias for `since`
|
|
118
|
-
required: false
|
|
119
|
-
schema:
|
|
120
|
-
type: string
|
|
121
|
-
format: date-time
|
|
122
91
|
- name: limit
|
|
123
92
|
in: query
|
|
124
93
|
description: Maximum transactions per page when `dataset=transactions`
|
|
@@ -153,21 +122,22 @@ paths:
|
|
|
153
122
|
content:
|
|
154
123
|
application/json:
|
|
155
124
|
schema:
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
pagination:
|
|
167
|
-
$ref: '#/components/schemas/Pagination'
|
|
168
|
-
additionalProperties: true
|
|
125
|
+
oneOf:
|
|
126
|
+
- $ref: '#/components/schemas/ExportAccountsResponse'
|
|
127
|
+
- $ref: '#/components/schemas/ExportTransactionsResponse'
|
|
128
|
+
- $ref: '#/components/schemas/ExportSnapshotsResponse'
|
|
129
|
+
- $ref: '#/components/schemas/ExportRecurringResponse'
|
|
130
|
+
- $ref: '#/components/schemas/ExportBudgetsResponse'
|
|
131
|
+
- $ref: '#/components/schemas/ExportGoalsResponse'
|
|
132
|
+
- $ref: '#/components/schemas/ExportHealthResponse'
|
|
133
|
+
- $ref: '#/components/schemas/ExportLiabilitiesResponse'
|
|
134
|
+
- $ref: '#/components/schemas/ExportHoldingsResponse'
|
|
169
135
|
'400':
|
|
170
136
|
description: Invalid query parameters
|
|
137
|
+
content:
|
|
138
|
+
application/json:
|
|
139
|
+
schema:
|
|
140
|
+
$ref: '#/components/schemas/Error'
|
|
171
141
|
'401':
|
|
172
142
|
$ref: '#/components/responses/Unauthorized'
|
|
173
143
|
'403':
|
|
@@ -221,7 +191,7 @@ paths:
|
|
|
221
191
|
The raw API requires exactly one selector: `month=YYYY-MM` or `latest=1`.
|
|
222
192
|
Bare calls are invalid on the raw API. The current `@warmio/mcp` `get_transactions` tool
|
|
223
193
|
accepts one required `period` string: `latest` for the fixed latest window or `YYYY-MM`
|
|
224
|
-
for a month. It does not accept
|
|
194
|
+
for a month. It does not accept export pagination or filtering controls.
|
|
225
195
|
Transaction amounts use the Warm/Plaid sign convention:
|
|
226
196
|
positive = expense/debit, negative = income/credit.
|
|
227
197
|
|
|
@@ -317,7 +287,7 @@ paths:
|
|
|
317
287
|
summary: Search supported automation operations
|
|
318
288
|
tags: [Automation]
|
|
319
289
|
security:
|
|
320
|
-
-
|
|
290
|
+
- BearerAuth: []
|
|
321
291
|
requestBody:
|
|
322
292
|
required: false
|
|
323
293
|
content:
|
|
@@ -360,7 +330,7 @@ paths:
|
|
|
360
330
|
summary: Describe one operation and request owner approval when required
|
|
361
331
|
tags: [Automation]
|
|
362
332
|
security:
|
|
363
|
-
-
|
|
333
|
+
- BearerAuth: []
|
|
364
334
|
requestBody:
|
|
365
335
|
required: true
|
|
366
336
|
content:
|
|
@@ -412,7 +382,7 @@ paths:
|
|
|
412
382
|
summary: Invoke one supported operation
|
|
413
383
|
tags: [Automation]
|
|
414
384
|
security:
|
|
415
|
-
-
|
|
385
|
+
- BearerAuth: []
|
|
416
386
|
requestBody:
|
|
417
387
|
required: true
|
|
418
388
|
content:
|
|
@@ -451,10 +421,6 @@ components:
|
|
|
451
421
|
type: http
|
|
452
422
|
scheme: bearer
|
|
453
423
|
description: 'Read/export format: `Authorization: Bearer YOUR_API_KEY_OR_ACCESS_TOKEN`'
|
|
454
|
-
AutomationKeyAuth:
|
|
455
|
-
type: http
|
|
456
|
-
scheme: bearer
|
|
457
|
-
description: 'Automation format: `Authorization: Bearer warm_auto_...`'
|
|
458
424
|
|
|
459
425
|
headers:
|
|
460
426
|
ETag:
|
|
@@ -604,7 +570,7 @@ components:
|
|
|
604
570
|
next_knowledge:
|
|
605
571
|
type: string
|
|
606
572
|
format: date-time
|
|
607
|
-
description: Use as `
|
|
573
|
+
description: Use as `since` in the next request for delta sync
|
|
608
574
|
example: '2026-01-10T15:30:00Z'
|
|
609
575
|
accounts:
|
|
610
576
|
type: array
|
|
@@ -1063,13 +1029,22 @@ components:
|
|
|
1063
1029
|
|
|
1064
1030
|
Error:
|
|
1065
1031
|
type: object
|
|
1032
|
+
additionalProperties: false
|
|
1066
1033
|
required:
|
|
1067
1034
|
- error
|
|
1068
1035
|
properties:
|
|
1069
1036
|
error:
|
|
1070
1037
|
type: string
|
|
1071
|
-
|
|
1072
|
-
|
|
1038
|
+
VerifyApiResponse:
|
|
1039
|
+
type: object
|
|
1040
|
+
additionalProperties: false
|
|
1041
|
+
required: [valid]
|
|
1042
|
+
properties:
|
|
1043
|
+
valid:
|
|
1044
|
+
type: boolean
|
|
1045
|
+
enum: [true]
|
|
1046
|
+
description: True when the credential is valid and has API access
|
|
1047
|
+
example: true
|
|
1073
1048
|
|
|
1074
1049
|
FinancialContext:
|
|
1075
1050
|
type: object
|
|
@@ -1137,6 +1112,7 @@ components:
|
|
|
1137
1112
|
- accounts
|
|
1138
1113
|
properties:
|
|
1139
1114
|
position:
|
|
1115
|
+
description: The status.position field is a point-in-time (as-of-date) balance snapshot, separate from transaction and behavior windows. A null position means no position snapshot is available.
|
|
1140
1116
|
oneOf:
|
|
1141
1117
|
- $ref: '#/components/schemas/FinancialContextPosition'
|
|
1142
1118
|
- type: 'null'
|
|
@@ -1147,6 +1123,7 @@ components:
|
|
|
1147
1123
|
|
|
1148
1124
|
FinancialContextPosition:
|
|
1149
1125
|
type: object
|
|
1126
|
+
description: The status.position field is a point-in-time (as-of-date) balance snapshot, separate from transaction and behavior windows. A null position means no position snapshot is available.
|
|
1150
1127
|
required:
|
|
1151
1128
|
- date
|
|
1152
1129
|
- net_worth
|
|
@@ -1247,7 +1224,7 @@ components:
|
|
|
1247
1224
|
properties:
|
|
1248
1225
|
month:
|
|
1249
1226
|
type: string
|
|
1250
|
-
pattern: '^\d{4}
|
|
1227
|
+
pattern: '^\d{4}-(0[1-9]|1[0-2])$'
|
|
1251
1228
|
count:
|
|
1252
1229
|
type: integer
|
|
1253
1230
|
minimum: 0
|
|
@@ -1263,7 +1240,7 @@ components:
|
|
|
1263
1240
|
properties:
|
|
1264
1241
|
month:
|
|
1265
1242
|
type: string
|
|
1266
|
-
pattern: '^\d{4}
|
|
1243
|
+
pattern: '^\d{4}-(0[1-9]|1[0-2])$'
|
|
1267
1244
|
start_date:
|
|
1268
1245
|
type: string
|
|
1269
1246
|
format: date
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
+
type OpenApiValue = string | number | boolean | null | OpenApiValue[] | OpenApiRecord;
|
|
2
|
+
interface OpenApiRecord {
|
|
3
|
+
[key: string]: OpenApiValue;
|
|
4
|
+
}
|
|
1
5
|
type OpenApiOperation = {
|
|
6
|
+
description?: string;
|
|
2
7
|
operationId?: string;
|
|
8
|
+
responses?: OpenApiRecord;
|
|
3
9
|
security?: Array<Record<string, never[]>>;
|
|
4
10
|
summary?: string;
|
|
5
11
|
};
|
|
6
12
|
type OpenApiDocument = {
|
|
7
13
|
components?: {
|
|
8
|
-
schemas?:
|
|
9
|
-
securitySchemes?:
|
|
14
|
+
schemas?: OpenApiRecord;
|
|
15
|
+
securitySchemes?: OpenApiRecord;
|
|
10
16
|
};
|
|
11
17
|
info?: {
|
|
12
18
|
description?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-openapi.d.ts","sourceRoot":"","sources":["../../src/openapi/build-openapi.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"build-openapi.d.ts","sourceRoot":"","sources":["../../src/openapi/build-openapi.ts"],"names":[],"mappings":"AAgDA,KAAK,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,YAAY,EAAE,GAAG,aAAa,CAAC;AACtF,UAAU,aAAa;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAAC;CAC7B;AAMD,KAAK,gBAAgB,GAAG;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AACF,KAAK,eAAe,GAAG;IACrB,UAAU,CAAC,EAAE;QAEX,OAAO,CAAC,EAAE,aAAa,CAAC;QAExB,eAAe,CAAC,EAAE,aAAa,CAAC;KACjC,CAAC;IACF,IAAI,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzD,CAAC;AAmBF;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,eAAe,CA2ItD;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC"}
|
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
2
2
|
import { parse, stringify } from 'yaml';
|
|
3
|
-
import {
|
|
3
|
+
import { apiAuthorizationCapabilities, apiEndpointManifest, apiKeyAuthScheme, API_ORIGIN, WARM_API_KEY_RATE_LIMIT_PER_HOUR, } from '../api/index.js';
|
|
4
4
|
import { baseOpenApiYaml } from '../generated/base-openapi.js';
|
|
5
|
-
import { automationInputSchema, automationInvocationResponseSchema, automationOperationSchema, describeOperationRequestSchema, financialContextMetaSchema, financialContextAccountSchema, financialContextBudgetSchema, financialContextGoalSchema, financialContextHealthSchema, financialContextHoldingSchema, financialContextLiabilitySchema, financialContextPositionSchema, financialContextRecurringSchema, financialContextSchema, financialContextSnapshotSchema, financialContextStatusSchema, financialContextTransactionIndexSchema, financialContextTransactionSchema, invokeOperationRequestSchema, latestTransactionsSchema, transactionMonthSchema, } from '../schemas/index.js';
|
|
5
|
+
import { automationInputSchema, automationInvocationResponseSchema, automationOperationSchema, describeOperationRequestSchema, exportAccountSchema, exportBudgetSchema, exportDatasetResponseSchemas, exportGoalSchema, exportHealthSchema, exportHoldingSchema, exportLiabilitySchema, exportPaginationSchema, exportRecurringSchema, exportSnapshotSchema, exportTransactionSchema, financialContextMetaSchema, financialContextAccountSchema, financialContextBudgetSchema, financialContextGoalSchema, financialContextHealthSchema, financialContextHoldingSchema, financialContextLiabilitySchema, financialContextPositionSchema, financialContextRecurringSchema, financialContextSchema, financialContextSnapshotSchema, financialContextStatusSchema, financialContextTransactionIndexSchema, financialContextTransactionSchema, invokeOperationRequestSchema, latestTransactionsSchema, publicApiErrorSchema, transactionMonthSchema, verifyApiResponseSchema, } from '../schemas/index.js';
|
|
6
|
+
function isOpenApiRecord(value) {
|
|
7
|
+
return Object(value) === value && !Array.isArray(value);
|
|
8
|
+
}
|
|
6
9
|
function cloneBaseDocument() {
|
|
7
|
-
|
|
10
|
+
const parsed = parse(baseOpenApiYaml);
|
|
11
|
+
if (!isOpenApiRecord(parsed))
|
|
12
|
+
throw new Error('The OpenAPI base document must be an object.');
|
|
13
|
+
return parsed;
|
|
8
14
|
}
|
|
9
15
|
function schema(value) {
|
|
10
16
|
const generated = zodToJsonSchema(value, { $refStrategy: 'none' });
|
|
17
|
+
if (!isOpenApiRecord(generated))
|
|
18
|
+
throw new Error('Generated OpenAPI schema must be an object.');
|
|
11
19
|
return {
|
|
12
20
|
...generated,
|
|
13
|
-
...(generated
|
|
14
|
-
|
|
15
|
-
|
|
21
|
+
...(generated['$schema'] === 'http://json-schema.org/draft-07/schema#' && {
|
|
22
|
+
$schema: 'https://json-schema.org/draft-07/schema#',
|
|
23
|
+
}),
|
|
16
24
|
};
|
|
17
25
|
}
|
|
18
26
|
/**
|
|
@@ -32,24 +40,18 @@ export function buildOpenApiDocument() {
|
|
|
32
40
|
document.info.description = `Read your financial context or invoke supported Warm actions through a compact operation catalog.
|
|
33
41
|
|
|
34
42
|
## Authentication
|
|
35
|
-
All requests use \`Authorization: Bearer\`. ${
|
|
36
|
-
${
|
|
43
|
+
All requests use \`Authorization: Bearer\`. ${apiKeyAuthScheme.description}
|
|
44
|
+
${apiAuthorizationCapabilities.read_only.openApiDescription} ${apiAuthorizationCapabilities.automation.openApiDescription} API keys begin with \`${apiKeyAuthScheme.bearer_prefix}\`.
|
|
37
45
|
|
|
38
46
|
## Rate Limits
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
- Rate limit headers are included in authenticated responses.
|
|
47
|
+
- API keys: ${WARM_API_KEY_RATE_LIMIT_PER_HOUR} requests per hour per key
|
|
48
|
+
- Rate limit headers are included only on routes that document a \`429\` response.
|
|
42
49
|
- \`/api/export\` supports dataset-scoped delta sync with \`since\` and publishes edge-cache metadata headers.`;
|
|
43
50
|
document.servers[0].url = API_ORIGIN;
|
|
44
51
|
document.components.securitySchemes = {
|
|
45
|
-
AutomationKeyAuth: {
|
|
46
|
-
description: `Automation format: Authorization: Bearer ${apiAuthSchemes.automation.bearer_prefix}...`,
|
|
47
|
-
scheme: apiAuthSchemes.automation.scheme,
|
|
48
|
-
type: 'http',
|
|
49
|
-
},
|
|
50
52
|
BearerAuth: {
|
|
51
|
-
description:
|
|
52
|
-
scheme:
|
|
53
|
+
description: `API key format: Authorization: Bearer warm_...; ${apiAuthorizationCapabilities.read_only.openApiDescription.toLowerCase()}`,
|
|
54
|
+
scheme: apiKeyAuthScheme.scheme,
|
|
53
55
|
type: 'http',
|
|
54
56
|
},
|
|
55
57
|
};
|
|
@@ -59,14 +61,41 @@ ${apiAuthSchemes.automation.description} Automation keys begin with \`${apiAuthS
|
|
|
59
61
|
throw new Error(`The OpenAPI base document is missing ${endpoint.method} ${endpoint.path}.`);
|
|
60
62
|
}
|
|
61
63
|
operation.operationId = endpoint.operation_id;
|
|
62
|
-
operation.security = [
|
|
63
|
-
endpoint.audience === 'automation' ? { AutomationKeyAuth: [] } : { BearerAuth: [] },
|
|
64
|
-
];
|
|
64
|
+
operation.security = [{ BearerAuth: [] }];
|
|
65
65
|
operation.summary = endpoint.summary;
|
|
66
|
+
operation.description = [
|
|
67
|
+
operation.description,
|
|
68
|
+
`Authentication: ${apiAuthorizationCapabilities[endpoint.authorization].openApiDescription}`,
|
|
69
|
+
]
|
|
70
|
+
.filter(Boolean)
|
|
71
|
+
.join('\n\n');
|
|
72
|
+
}
|
|
73
|
+
const verifyResponseSchema = schema(verifyApiResponseSchema);
|
|
74
|
+
const responseProperties = verifyResponseSchema['properties'];
|
|
75
|
+
if (isOpenApiRecord(responseProperties) && isOpenApiRecord(responseProperties['valid'])) {
|
|
76
|
+
responseProperties['valid']['example'] = true;
|
|
66
77
|
}
|
|
67
78
|
Object.assign(document.components.schemas, {
|
|
68
79
|
AutomationInvocationResponse: schema(automationInvocationResponseSchema),
|
|
69
80
|
AutomationOperation: schema(automationOperationSchema),
|
|
81
|
+
ExportAccount: schema(exportAccountSchema),
|
|
82
|
+
ExportAccountsResponse: schema(exportDatasetResponseSchemas.accounts),
|
|
83
|
+
ExportBudget: schema(exportBudgetSchema),
|
|
84
|
+
ExportBudgetsResponse: schema(exportDatasetResponseSchemas.budgets),
|
|
85
|
+
ExportGoal: schema(exportGoalSchema),
|
|
86
|
+
ExportGoalsResponse: schema(exportDatasetResponseSchemas.goals),
|
|
87
|
+
ExportHealthResponse: schema(exportHealthSchema),
|
|
88
|
+
ExportHolding: schema(exportHoldingSchema),
|
|
89
|
+
ExportHoldingsResponse: schema(exportDatasetResponseSchemas.holdings),
|
|
90
|
+
ExportLiability: schema(exportLiabilitySchema),
|
|
91
|
+
ExportLiabilitiesResponse: schema(exportDatasetResponseSchemas.liabilities),
|
|
92
|
+
ExportPagination: schema(exportPaginationSchema),
|
|
93
|
+
ExportRecurring: schema(exportRecurringSchema),
|
|
94
|
+
ExportRecurringResponse: schema(exportDatasetResponseSchemas.recurring),
|
|
95
|
+
ExportSnapshot: schema(exportSnapshotSchema),
|
|
96
|
+
ExportSnapshotsResponse: schema(exportDatasetResponseSchemas.snapshots),
|
|
97
|
+
ExportTransaction: schema(exportTransactionSchema),
|
|
98
|
+
ExportTransactionsResponse: schema(exportDatasetResponseSchemas.transactions),
|
|
70
99
|
FinancialContext: schema(financialContextSchema),
|
|
71
100
|
FinancialContextAccount: schema(financialContextAccountSchema),
|
|
72
101
|
FinancialContextBudget: schema(financialContextBudgetSchema),
|
|
@@ -86,7 +115,50 @@ ${apiAuthSchemes.automation.description} Automation keys begin with \`${apiAuthS
|
|
|
86
115
|
OperationRequest: schema(describeOperationRequestSchema),
|
|
87
116
|
TransactionMonth: schema(transactionMonthSchema),
|
|
88
117
|
TransactionIndex: schema(financialContextTransactionIndexSchema),
|
|
118
|
+
Error: schema(publicApiErrorSchema),
|
|
119
|
+
VerifyApiResponse: verifyResponseSchema,
|
|
89
120
|
});
|
|
121
|
+
const verifyOperation = document.paths['/api/verify']?.['get'];
|
|
122
|
+
const exportOperation = document.paths['/api/export']?.['get'];
|
|
123
|
+
if (!verifyOperation || !exportOperation) {
|
|
124
|
+
throw new Error('The OpenAPI base document is missing verify or export operations.');
|
|
125
|
+
}
|
|
126
|
+
verifyOperation.responses = {
|
|
127
|
+
...(verifyOperation.responses ?? {}),
|
|
128
|
+
'200': {
|
|
129
|
+
content: {
|
|
130
|
+
'application/json': {
|
|
131
|
+
schema: { $ref: '#/components/schemas/VerifyApiResponse' },
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
description: 'Credentials are valid and the caller has API access',
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
exportOperation.responses = {
|
|
138
|
+
...(exportOperation.responses ?? {}),
|
|
139
|
+
'200': {
|
|
140
|
+
content: {
|
|
141
|
+
'application/json': {
|
|
142
|
+
schema: {
|
|
143
|
+
oneOf: [
|
|
144
|
+
'Accounts',
|
|
145
|
+
'Transactions',
|
|
146
|
+
'Snapshots',
|
|
147
|
+
'Recurring',
|
|
148
|
+
'Budgets',
|
|
149
|
+
'Goals',
|
|
150
|
+
'Health',
|
|
151
|
+
'Liabilities',
|
|
152
|
+
'Holdings',
|
|
153
|
+
].map((dataset) => ({
|
|
154
|
+
$ref: `#/components/schemas/Export${dataset}Response`,
|
|
155
|
+
})),
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
description: 'Successful dataset export',
|
|
160
|
+
},
|
|
161
|
+
};
|
|
90
162
|
return document;
|
|
91
163
|
}
|
|
92
164
|
export function buildOpenApiYaml() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-openapi.js","sourceRoot":"","sources":["../../src/openapi/build-openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"build-openapi.js","sourceRoot":"","sources":["../../src/openapi/build-openapi.ts"],"names":[],"mappings":"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"}
|
package/dist/product.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,kBAAkB,YAAI,MAAM,EAAE,KAAK,CAAU,CAAC;AAC3D,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,eAAO,MAAM,4BAA4B;aACvC,kBAAkB;iBAAI,KAAK,EAAE,oBAAoB;iBAAE,KAAK;;aACxD,UAAU;iBAAI,KAAK,EAAE,2BAA2B;iBAAE,KAAK;;aACvD,SAAS;iBAAI,KAAK,EAAE,qBAAqB;iBAAE,KAAK;;aAChD,aAAa;iBAAI,KAAK,EAAE,mBAAmB;iBAAE,KAAK;;aAClD,sBAAsB;iBAAI,KAAK,EAAE,wBAAwB;iBAAE,KAAK;;aAChE,kBAAkB;iBAAI,KAAK,EAAE,oBAAoB;iBAAE,KAAK;;aACxD,OAAO;iBAAI,KAAK,EAAE,SAAS;iBAAE,KAAK;;aAClC,eAAe;iBAAI,KAAK,EAAE,iBAAiB;iBAAE,KAAK;;CAC1C,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,MAAM,OAAO,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"product.d.ts","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,kBAAkB,YAAI,MAAM,EAAE,KAAK,CAAU,CAAC;AAC3D,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,eAAO,MAAM,4BAA4B;aACvC,kBAAkB;iBAAI,KAAK,EAAE,oBAAoB;iBAAE,KAAK;;aACxD,UAAU;iBAAI,KAAK,EAAE,2BAA2B;iBAAE,KAAK;;aACvD,SAAS;iBAAI,KAAK,EAAE,qBAAqB;iBAAE,KAAK;;aAChD,aAAa;iBAAI,KAAK,EAAE,mBAAmB;iBAAE,KAAK;;aAClD,sBAAsB;iBAAI,KAAK,EAAE,wBAAwB;iBAAE,KAAK;;aAChE,kBAAkB;iBAAI,KAAK,EAAE,oBAAoB;iBAAE,KAAK;;aACxD,OAAO;iBAAI,KAAK,EAAE,SAAS;iBAAE,KAAK;;aAClC,eAAe;iBAAI,KAAK,EAAE,iBAAiB;iBAAE,KAAK;;CAC1C,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,MAAM,OAAO,4BAA4B,CAAC;AAM5E,eAAO,MAAM,iCAAiC,EAAE,aAAa,CAAC;IAC5D,EAAE,EAAE,mBAAmB,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACrC,CAIC,CAAC"}
|
package/dist/product.js
CHANGED
|
@@ -13,5 +13,13 @@ export const productCapabilityDefinitions = {
|
|
|
13
13
|
support: { label: 'Support', tiers: publicProductTiers },
|
|
14
14
|
wealth_tracking: { label: 'Wealth tracking', tiers: publicProductTiers },
|
|
15
15
|
};
|
|
16
|
-
|
|
16
|
+
function isProductCapabilityId(value) {
|
|
17
|
+
return value in productCapabilityDefinitions;
|
|
18
|
+
}
|
|
19
|
+
export const publicProductCapabilityProjection = Object.keys(productCapabilityDefinitions).map((id) => {
|
|
20
|
+
if (!isProductCapabilityId(id))
|
|
21
|
+
throw new Error(`Unknown product capability: ${id}`);
|
|
22
|
+
const definition = productCapabilityDefinitions[id];
|
|
23
|
+
return { id, label: definition.label, tiers: definition.tiers };
|
|
24
|
+
});
|
|
17
25
|
//# sourceMappingURL=product.js.map
|
package/dist/product.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product.js","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,KAAK,CAAU,CAAC;AAG3D,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,kBAAkB,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IAC9E,UAAU,EAAE,EAAE,KAAK,EAAE,2BAA2B,EAAE,KAAK,EAAE,kBAAkB,EAAE;IAC7E,SAAS,EAAE,EAAE,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACtE,aAAa,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACxE,sBAAsB,EAAE,EAAE,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACtF,kBAAkB,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IAC9E,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACxD,eAAe,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,kBAAkB,EAAE;CAChE,CAAC;AAIX,MAAM,CAAC,MAAM,iCAAiC,
|
|
1
|
+
{"version":3,"file":"product.js","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,KAAK,CAAU,CAAC;AAG3D,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,kBAAkB,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IAC9E,UAAU,EAAE,EAAE,KAAK,EAAE,2BAA2B,EAAE,KAAK,EAAE,kBAAkB,EAAE;IAC7E,SAAS,EAAE,EAAE,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACtE,aAAa,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACxE,sBAAsB,EAAE,EAAE,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACtF,kBAAkB,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,kBAAkB,EAAE;IAC9E,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACxD,eAAe,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,kBAAkB,EAAE;CAChE,CAAC;AAIX,SAAS,qBAAqB,CAAC,KAAa;IAC1C,OAAO,KAAK,IAAI,4BAA4B,CAAC;AAC/C,CAAC;AAED,MAAM,CAAC,MAAM,iCAAiC,GAIzC,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;IACxD,IAAI,CAAC,qBAAqB,CAAC,EAAE,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,EAAE,EAAE,CAAC,CAAC;IACrF,MAAM,UAAU,GAAG,4BAA4B,CAAC,EAAE,CAAC,CAAC;IACpD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,CAAC;AAClE,CAAC,CAAC,CAAC"}
|