@wootsup/mcp 0.1.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/LICENSE +21 -0
  3. package/README.md +179 -0
  4. package/SECURITY.md +163 -0
  5. package/dist/auth/keychain.d.ts +47 -0
  6. package/dist/auth/keychain.js +262 -0
  7. package/dist/auth/keychain.js.map +1 -0
  8. package/dist/auth/oauth-provider.d.ts +68 -0
  9. package/dist/auth/oauth-provider.js +232 -0
  10. package/dist/auth/oauth-provider.js.map +1 -0
  11. package/dist/auth/profiles.d.ts +52 -0
  12. package/dist/auth/profiles.js +200 -0
  13. package/dist/auth/profiles.js.map +1 -0
  14. package/dist/auth/token.d.ts +27 -0
  15. package/dist/auth/token.js +88 -0
  16. package/dist/auth/token.js.map +1 -0
  17. package/dist/index.d.ts +13 -0
  18. package/dist/index.js +137 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/install-skill.d.ts +23 -0
  21. package/dist/install-skill.js +73 -0
  22. package/dist/install-skill.js.map +1 -0
  23. package/dist/modules/apimapper/cache.d.ts +2 -0
  24. package/dist/modules/apimapper/cache.js +71 -0
  25. package/dist/modules/apimapper/cache.js.map +1 -0
  26. package/dist/modules/apimapper/client.d.ts +85 -0
  27. package/dist/modules/apimapper/client.js +523 -0
  28. package/dist/modules/apimapper/client.js.map +1 -0
  29. package/dist/modules/apimapper/connections.d.ts +2 -0
  30. package/dist/modules/apimapper/connections.js +406 -0
  31. package/dist/modules/apimapper/connections.js.map +1 -0
  32. package/dist/modules/apimapper/credential-sanitizer.d.ts +7 -0
  33. package/dist/modules/apimapper/credential-sanitizer.js +70 -0
  34. package/dist/modules/apimapper/credential-sanitizer.js.map +1 -0
  35. package/dist/modules/apimapper/credentials.d.ts +2 -0
  36. package/dist/modules/apimapper/credentials.js +258 -0
  37. package/dist/modules/apimapper/credentials.js.map +1 -0
  38. package/dist/modules/apimapper/diagnose.d.ts +18 -0
  39. package/dist/modules/apimapper/diagnose.js +305 -0
  40. package/dist/modules/apimapper/diagnose.js.map +1 -0
  41. package/dist/modules/apimapper/flows.d.ts +2 -0
  42. package/dist/modules/apimapper/flows.js +372 -0
  43. package/dist/modules/apimapper/flows.js.map +1 -0
  44. package/dist/modules/apimapper/get-skill.d.ts +4 -0
  45. package/dist/modules/apimapper/get-skill.js +88 -0
  46. package/dist/modules/apimapper/get-skill.js.map +1 -0
  47. package/dist/modules/apimapper/graph-builder.d.ts +47 -0
  48. package/dist/modules/apimapper/graph-builder.js +117 -0
  49. package/dist/modules/apimapper/graph-builder.js.map +1 -0
  50. package/dist/modules/apimapper/graph.d.ts +2 -0
  51. package/dist/modules/apimapper/graph.js +117 -0
  52. package/dist/modules/apimapper/graph.js.map +1 -0
  53. package/dist/modules/apimapper/index.d.ts +2 -0
  54. package/dist/modules/apimapper/index.js +43 -0
  55. package/dist/modules/apimapper/index.js.map +1 -0
  56. package/dist/modules/apimapper/inspect.d.ts +20 -0
  57. package/dist/modules/apimapper/inspect.js +86 -0
  58. package/dist/modules/apimapper/inspect.js.map +1 -0
  59. package/dist/modules/apimapper/library.d.ts +2 -0
  60. package/dist/modules/apimapper/library.js +237 -0
  61. package/dist/modules/apimapper/library.js.map +1 -0
  62. package/dist/modules/apimapper/license.d.ts +2 -0
  63. package/dist/modules/apimapper/license.js +142 -0
  64. package/dist/modules/apimapper/license.js.map +1 -0
  65. package/dist/modules/apimapper/local-sources.d.ts +2 -0
  66. package/dist/modules/apimapper/local-sources.js +123 -0
  67. package/dist/modules/apimapper/local-sources.js.map +1 -0
  68. package/dist/modules/apimapper/misc.d.ts +2 -0
  69. package/dist/modules/apimapper/misc.js +149 -0
  70. package/dist/modules/apimapper/misc.js.map +1 -0
  71. package/dist/modules/apimapper/node-schema.d.ts +217 -0
  72. package/dist/modules/apimapper/node-schema.js +218 -0
  73. package/dist/modules/apimapper/node-schema.js.map +1 -0
  74. package/dist/modules/apimapper/normalizers.d.ts +13 -0
  75. package/dist/modules/apimapper/normalizers.js +37 -0
  76. package/dist/modules/apimapper/normalizers.js.map +1 -0
  77. package/dist/modules/apimapper/onboarding.d.ts +51 -0
  78. package/dist/modules/apimapper/onboarding.js +201 -0
  79. package/dist/modules/apimapper/onboarding.js.map +1 -0
  80. package/dist/modules/apimapper/schema.d.ts +2 -0
  81. package/dist/modules/apimapper/schema.js +84 -0
  82. package/dist/modules/apimapper/schema.js.map +1 -0
  83. package/dist/modules/apimapper/settings.d.ts +2 -0
  84. package/dist/modules/apimapper/settings.js +157 -0
  85. package/dist/modules/apimapper/settings.js.map +1 -0
  86. package/dist/modules/apimapper/skill-resources.d.ts +4 -0
  87. package/dist/modules/apimapper/skill-resources.js +85 -0
  88. package/dist/modules/apimapper/skill-resources.js.map +1 -0
  89. package/dist/modules/apimapper/types.d.ts +111 -0
  90. package/dist/modules/apimapper/types.js +14 -0
  91. package/dist/modules/apimapper/types.js.map +1 -0
  92. package/dist/modules/apimapper/use-profile.d.ts +34 -0
  93. package/dist/modules/apimapper/use-profile.js +176 -0
  94. package/dist/modules/apimapper/use-profile.js.map +1 -0
  95. package/dist/modules/apimapper/workflows.d.ts +2 -0
  96. package/dist/modules/apimapper/workflows.js +301 -0
  97. package/dist/modules/apimapper/workflows.js.map +1 -0
  98. package/dist/platform/index.d.ts +71 -0
  99. package/dist/platform/index.js +377 -0
  100. package/dist/platform/index.js.map +1 -0
  101. package/dist/server-http.d.ts +22 -0
  102. package/dist/server-http.js +159 -0
  103. package/dist/server-http.js.map +1 -0
  104. package/dist/setup/detect-clients.d.ts +39 -0
  105. package/dist/setup/detect-clients.js +152 -0
  106. package/dist/setup/detect-clients.js.map +1 -0
  107. package/dist/setup/probe-handshake.d.ts +26 -0
  108. package/dist/setup/probe-handshake.js +159 -0
  109. package/dist/setup/probe-handshake.js.map +1 -0
  110. package/dist/setup/write-config.d.ts +25 -0
  111. package/dist/setup/write-config.js +247 -0
  112. package/dist/setup/write-config.js.map +1 -0
  113. package/dist/setup-cli.d.ts +49 -0
  114. package/dist/setup-cli.js +292 -0
  115. package/dist/setup-cli.js.map +1 -0
  116. package/dist/skill-instructions.d.ts +10 -0
  117. package/dist/skill-instructions.js +68 -0
  118. package/dist/skill-instructions.js.map +1 -0
  119. package/dist/transports/http.d.ts +29 -0
  120. package/dist/transports/http.js +267 -0
  121. package/dist/transports/http.js.map +1 -0
  122. package/dist/transports/stdio.d.ts +9 -0
  123. package/dist/transports/stdio.js +19 -0
  124. package/dist/transports/stdio.js.map +1 -0
  125. package/docs/architecture.md +140 -0
  126. package/docs/customgraph-internal-migration.md +210 -0
  127. package/docs/security.md +126 -0
  128. package/docs/tools.md +230 -0
  129. package/manifest.json +76 -0
  130. package/package.json +61 -0
  131. package/skills/apimapper/SKILL.md +57 -0
  132. package/skills/apimapper/reference/joomla.md +85 -0
  133. package/skills/apimapper/reference/oauth.md +94 -0
  134. package/skills/apimapper/reference/troubleshooting.md +123 -0
  135. package/skills/apimapper/reference/yootheme.md +96 -0
@@ -0,0 +1,149 @@
1
+ import { z } from "zod";
2
+ import { formatResult, autoFormatTable, readOnly, creating } from "@getimo/mcp-toolkit";
3
+ import { request, hintFor } from "./client.js";
4
+ export function registerMiscTools(server) {
5
+ // ── apimapper_release_list ─────────────────────────────────────────
6
+ server.registerTool("apimapper_release_list", {
7
+ title: "List Available Releases",
8
+ description: "List API Mapper plugin releases available for download." +
9
+ "\n\nExample:\n apimapper_release_list({})",
10
+ inputSchema: {
11
+ channel: z
12
+ .enum(["stable", "beta", "all"])
13
+ .default("stable")
14
+ .describe("Release channel filter"),
15
+ limit: z.number().min(1).max(50).default(10).describe("Max items (1-50)"),
16
+ },
17
+ annotations: readOnly(),
18
+ }, async ({ channel, limit }) => {
19
+ const params = new URLSearchParams({ channel, limit: String(limit) });
20
+ const r = await request(`/releases?${params.toString()}`);
21
+ if (!r.success) {
22
+ return formatResult({
23
+ error: r.error,
24
+ status: r.status,
25
+ errorCode: r.errorCode,
26
+ context: { channel, limit },
27
+ hint: hintFor(r.errorCode),
28
+ }, true);
29
+ }
30
+ const releases = Array.isArray(r.data?.releases) ? r.data.releases : [];
31
+ return autoFormatTable(releases.map((rel) => ({
32
+ version: rel.version,
33
+ channel: rel.channel,
34
+ date: rel.date,
35
+ notes: rel.notes_url || "—",
36
+ })), {
37
+ columns: [
38
+ { key: "version", label: "VERSION", width: 12 },
39
+ { key: "channel", label: "CHANNEL", width: 10 },
40
+ { key: "date", label: "DATE", width: 22 },
41
+ { key: "notes", label: "NOTES_URL", width: 50 },
42
+ ],
43
+ header: (n) => `${n} releases`,
44
+ footer: "Use apimapper_release_download to fetch a ZIP.",
45
+ });
46
+ });
47
+ // ── apimapper_release_download ─────────────────────────────────────
48
+ server.registerTool("apimapper_release_download", {
49
+ title: "Get Release Download URL",
50
+ description: "Request a signed download URL for a release ZIP. Read-only operation server-side " +
51
+ "(generates a temporary signed URL — no state change)." +
52
+ "\n\nExample:\n apimapper_release_download({ version: '2.0.6' })",
53
+ inputSchema: {
54
+ version: z.string().describe('Release version (e.g., "2.0.7")'),
55
+ product: z.enum(["wordpress", "joomla"]).describe("Product variant"),
56
+ },
57
+ annotations: creating(),
58
+ }, async ({ version, product }) => {
59
+ const r = await request("/releases/download", {
60
+ method: "POST",
61
+ body: JSON.stringify({ version, product }),
62
+ });
63
+ if (!r.success) {
64
+ return formatResult({
65
+ error: r.error,
66
+ status: r.status,
67
+ errorCode: r.errorCode,
68
+ context: { version, product },
69
+ hint: hintFor(r.errorCode),
70
+ }, true);
71
+ }
72
+ if (!r.data?.download_url) {
73
+ return formatResult({
74
+ error: "no download URL returned",
75
+ status: r.status,
76
+ context: { version, product },
77
+ hint: "Server returned 200 but no download_url field. Verify version+product combination.",
78
+ }, true);
79
+ }
80
+ return formatResult({
81
+ download_url: r.data.download_url,
82
+ expires_at: r.data.expires_at,
83
+ version,
84
+ product,
85
+ }, false, { maxChars: 2000 });
86
+ });
87
+ // ── apimapper_brandfetch ───────────────────────────────────────────
88
+ server.registerTool("apimapper_brandfetch", {
89
+ title: "Brandfetch Logo Proxy",
90
+ description: "Fetch a brand's logo metadata via the Brandfetch proxy. Returns logo_svg, logo_png, logo_hex." +
91
+ "\n\nExample:\n apimapper_brandfetch({ domain: 'pexels.com' })",
92
+ inputSchema: {
93
+ domain: z.string().describe('Domain (e.g., "calendly.com", "google.com")'),
94
+ },
95
+ annotations: readOnly(),
96
+ }, async ({ domain }) => {
97
+ const r = await request(`/brandfetch/${encodeURIComponent(domain)}`);
98
+ if (!r.success) {
99
+ return formatResult({ error: r.error, status: r.status, errorCode: r.errorCode, context: { domain }, hint: hintFor(r.errorCode) }, true);
100
+ }
101
+ return formatResult({
102
+ domain,
103
+ name: r.data?.name,
104
+ logo_hex: r.data?.logo_hex,
105
+ has_svg: Boolean(r.data?.logo_svg),
106
+ has_png: Boolean(r.data?.logo_png),
107
+ logo_svg_size: r.data?.logo_svg?.length ?? 0,
108
+ }, false, { maxChars: 2000 });
109
+ });
110
+ // ── apimapper_feedback_submit ──────────────────────────────────────
111
+ server.registerTool("apimapper_feedback_submit", {
112
+ title: "Submit Feedback",
113
+ description: "Submit user feedback (bug report, feature request, support question) to the API Mapper team. " +
114
+ "Returns submitted:true ONLY when server confirms; 200 + queued:false → structured error." +
115
+ "\n\nExample:\n apimapper_feedback_submit({ category: 'bug', message: 'Schema detection misses nested array fields.' })",
116
+ inputSchema: {
117
+ type: z.enum(["bug", "feature", "support", "other"]).describe("Feedback type"),
118
+ subject: z.string().min(1).describe("Subject (short)"),
119
+ message: z.string().min(1).describe("Full message body"),
120
+ email: z.string().email().optional().describe("Reply email (optional)"),
121
+ attachments: z
122
+ .array(z.string().url())
123
+ .optional()
124
+ .describe("Optional attachment URLs (e.g., screenshots already uploaded elsewhere)"),
125
+ },
126
+ annotations: creating(),
127
+ }, async ({ type, subject, message, email, attachments }) => {
128
+ const r = await request("/feedback", { method: "POST", body: JSON.stringify({ type, subject, message, email, attachments }) }, { unwrapInnerSuccess: true });
129
+ if (!r.success) {
130
+ return formatResult({
131
+ error: r.error,
132
+ status: r.status,
133
+ errorCode: r.errorCode,
134
+ payloadFailed: r.payloadFailed,
135
+ context: { type, subject_len: subject.length },
136
+ hint: r.payloadFailed
137
+ ? "Server accepted the request but did not queue. Reason in error field."
138
+ : hintFor(r.errorCode),
139
+ }, true);
140
+ }
141
+ // unwrapInnerSuccess already caught success:false, so here queued is true.
142
+ return formatResult({
143
+ submitted: true,
144
+ queued: r.data?.queued ?? true,
145
+ ticket_id: r.data?.ticket_id,
146
+ }, false, { maxChars: 2000 });
147
+ });
148
+ }
149
+ //# sourceMappingURL=misc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"misc.js","sourceRoot":"","sources":["../../../src/modules/apimapper/misc.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,217 @@
1
+ import { z } from "zod";
2
+ export declare const sourceNodeSchema: z.ZodObject<{
3
+ id: z.ZodString;
4
+ type: z.ZodLiteral<"source">;
5
+ position: z.ZodObject<{
6
+ x: z.ZodNumber;
7
+ y: z.ZodNumber;
8
+ }, z.core.$strip>;
9
+ data: z.ZodObject<{
10
+ connectionId: z.ZodString;
11
+ endpointId: z.ZodOptional<z.ZodString>;
12
+ templateFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
13
+ itemsPath: z.ZodOptional<z.ZodString>;
14
+ itemsShape: z.ZodOptional<z.ZodString>;
15
+ }, z.core.$loose>;
16
+ }, z.core.$strip>;
17
+ export declare const localSourceNodeSchema: z.ZodObject<{
18
+ id: z.ZodString;
19
+ type: z.ZodLiteral<"local-source">;
20
+ position: z.ZodObject<{
21
+ x: z.ZodNumber;
22
+ y: z.ZodNumber;
23
+ }, z.core.$strip>;
24
+ data: z.ZodObject<{
25
+ contentType: z.ZodString;
26
+ limit: z.ZodOptional<z.ZodNumber>;
27
+ filters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
28
+ }, z.core.$loose>;
29
+ }, z.core.$strip>;
30
+ export declare const filterNodeSchema: z.ZodObject<{
31
+ id: z.ZodString;
32
+ type: z.ZodLiteral<"filter">;
33
+ position: z.ZodObject<{
34
+ x: z.ZodNumber;
35
+ y: z.ZodNumber;
36
+ }, z.core.$strip>;
37
+ data: z.ZodObject<{
38
+ conditions: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
39
+ logic: z.ZodOptional<z.ZodEnum<{
40
+ or: "or";
41
+ and: "and";
42
+ }>>;
43
+ }, z.core.$loose>;
44
+ }, z.core.$strip>;
45
+ export declare const transformNodeSchema: z.ZodObject<{
46
+ id: z.ZodString;
47
+ type: z.ZodLiteral<"transform">;
48
+ position: z.ZodObject<{
49
+ x: z.ZodNumber;
50
+ y: z.ZodNumber;
51
+ }, z.core.$strip>;
52
+ data: z.ZodObject<{
53
+ expression: z.ZodString;
54
+ }, z.core.$loose>;
55
+ }, z.core.$strip>;
56
+ export declare const mergeNodeSchema: z.ZodObject<{
57
+ id: z.ZodString;
58
+ type: z.ZodLiteral<"merge">;
59
+ position: z.ZodObject<{
60
+ x: z.ZodNumber;
61
+ y: z.ZodNumber;
62
+ }, z.core.$strip>;
63
+ data: z.ZodObject<{
64
+ strategy: z.ZodEnum<{
65
+ concat: "concat";
66
+ join: "join";
67
+ }>;
68
+ joinKey: z.ZodOptional<z.ZodString>;
69
+ joinKeyRight: z.ZodOptional<z.ZodString>;
70
+ joinType: z.ZodOptional<z.ZodEnum<{
71
+ left: "left";
72
+ right: "right";
73
+ inner: "inner";
74
+ outer: "outer";
75
+ }>>;
76
+ }, z.core.$loose>;
77
+ }, z.core.$strip>;
78
+ export declare const outputNodeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
79
+ id: z.ZodString;
80
+ type: z.ZodLiteral<"output">;
81
+ position: z.ZodObject<{
82
+ x: z.ZodNumber;
83
+ y: z.ZodNumber;
84
+ }, z.core.$strip>;
85
+ data: z.ZodObject<{
86
+ name: z.ZodOptional<z.ZodString>;
87
+ slug: z.ZodOptional<z.ZodString>;
88
+ }, z.core.$loose>;
89
+ }, z.core.$strip>, z.ZodObject<{
90
+ id: z.ZodString;
91
+ type: z.ZodLiteral<"output-yootheme">;
92
+ position: z.ZodObject<{
93
+ x: z.ZodNumber;
94
+ y: z.ZodNumber;
95
+ }, z.core.$strip>;
96
+ data: z.ZodObject<{
97
+ name: z.ZodOptional<z.ZodString>;
98
+ slug: z.ZodOptional<z.ZodString>;
99
+ }, z.core.$loose>;
100
+ }, z.core.$strip>, z.ZodObject<{
101
+ id: z.ZodString;
102
+ type: z.ZodLiteral<"output-shortcode">;
103
+ position: z.ZodObject<{
104
+ x: z.ZodNumber;
105
+ y: z.ZodNumber;
106
+ }, z.core.$strip>;
107
+ data: z.ZodObject<{
108
+ name: z.ZodOptional<z.ZodString>;
109
+ slug: z.ZodOptional<z.ZodString>;
110
+ }, z.core.$loose>;
111
+ }, z.core.$strip>], "type">;
112
+ export declare const nodeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
113
+ id: z.ZodString;
114
+ type: z.ZodLiteral<"source">;
115
+ position: z.ZodObject<{
116
+ x: z.ZodNumber;
117
+ y: z.ZodNumber;
118
+ }, z.core.$strip>;
119
+ data: z.ZodObject<{
120
+ connectionId: z.ZodString;
121
+ endpointId: z.ZodOptional<z.ZodString>;
122
+ templateFields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
123
+ itemsPath: z.ZodOptional<z.ZodString>;
124
+ itemsShape: z.ZodOptional<z.ZodString>;
125
+ }, z.core.$loose>;
126
+ }, z.core.$strip>, z.ZodObject<{
127
+ id: z.ZodString;
128
+ type: z.ZodLiteral<"local-source">;
129
+ position: z.ZodObject<{
130
+ x: z.ZodNumber;
131
+ y: z.ZodNumber;
132
+ }, z.core.$strip>;
133
+ data: z.ZodObject<{
134
+ contentType: z.ZodString;
135
+ limit: z.ZodOptional<z.ZodNumber>;
136
+ filters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
137
+ }, z.core.$loose>;
138
+ }, z.core.$strip>, z.ZodObject<{
139
+ id: z.ZodString;
140
+ type: z.ZodLiteral<"filter">;
141
+ position: z.ZodObject<{
142
+ x: z.ZodNumber;
143
+ y: z.ZodNumber;
144
+ }, z.core.$strip>;
145
+ data: z.ZodObject<{
146
+ conditions: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
147
+ logic: z.ZodOptional<z.ZodEnum<{
148
+ or: "or";
149
+ and: "and";
150
+ }>>;
151
+ }, z.core.$loose>;
152
+ }, z.core.$strip>, z.ZodObject<{
153
+ id: z.ZodString;
154
+ type: z.ZodLiteral<"transform">;
155
+ position: z.ZodObject<{
156
+ x: z.ZodNumber;
157
+ y: z.ZodNumber;
158
+ }, z.core.$strip>;
159
+ data: z.ZodObject<{
160
+ expression: z.ZodString;
161
+ }, z.core.$loose>;
162
+ }, z.core.$strip>, z.ZodObject<{
163
+ id: z.ZodString;
164
+ type: z.ZodLiteral<"merge">;
165
+ position: z.ZodObject<{
166
+ x: z.ZodNumber;
167
+ y: z.ZodNumber;
168
+ }, z.core.$strip>;
169
+ data: z.ZodObject<{
170
+ strategy: z.ZodEnum<{
171
+ concat: "concat";
172
+ join: "join";
173
+ }>;
174
+ joinKey: z.ZodOptional<z.ZodString>;
175
+ joinKeyRight: z.ZodOptional<z.ZodString>;
176
+ joinType: z.ZodOptional<z.ZodEnum<{
177
+ left: "left";
178
+ right: "right";
179
+ inner: "inner";
180
+ outer: "outer";
181
+ }>>;
182
+ }, z.core.$loose>;
183
+ }, z.core.$strip>, z.ZodObject<{
184
+ id: z.ZodString;
185
+ type: z.ZodLiteral<"output">;
186
+ position: z.ZodObject<{
187
+ x: z.ZodNumber;
188
+ y: z.ZodNumber;
189
+ }, z.core.$strip>;
190
+ data: z.ZodObject<{
191
+ name: z.ZodOptional<z.ZodString>;
192
+ slug: z.ZodOptional<z.ZodString>;
193
+ }, z.core.$loose>;
194
+ }, z.core.$strip>, z.ZodObject<{
195
+ id: z.ZodString;
196
+ type: z.ZodLiteral<"output-yootheme">;
197
+ position: z.ZodObject<{
198
+ x: z.ZodNumber;
199
+ y: z.ZodNumber;
200
+ }, z.core.$strip>;
201
+ data: z.ZodObject<{
202
+ name: z.ZodOptional<z.ZodString>;
203
+ slug: z.ZodOptional<z.ZodString>;
204
+ }, z.core.$loose>;
205
+ }, z.core.$strip>, z.ZodObject<{
206
+ id: z.ZodString;
207
+ type: z.ZodLiteral<"output-shortcode">;
208
+ position: z.ZodObject<{
209
+ x: z.ZodNumber;
210
+ y: z.ZodNumber;
211
+ }, z.core.$strip>;
212
+ data: z.ZodObject<{
213
+ name: z.ZodOptional<z.ZodString>;
214
+ slug: z.ZodOptional<z.ZodString>;
215
+ }, z.core.$loose>;
216
+ }, z.core.$strip>], "type">;
217
+ export type FlowNode = z.infer<typeof nodeSchema>;
@@ -0,0 +1,218 @@
1
+ // node-schema.ts — Discriminated-union schemas for flow nodes
2
+ //
3
+ // Closes R9 Round-1 A2 P0 #3 (audit 2026-05-18). Before this module the MCP
4
+ // layer validated `nodes` as `z.array(z.record(z.string(), z.unknown()))` —
5
+ // agents could pass `type:'end'` or `type:'append'` and only the PHP backend
6
+ // would reject (after compile attempt). With the discriminated union the
7
+ // rejection happens at the zod boundary with a clear error message.
8
+ //
9
+ // Ground truth (verified 2026-05-18 against PHP executors at
10
+ // src/modules/core/src/Graph/Node/*Executor.php):
11
+ // • source → connectionId (SourceNodeExecutor.php:48)
12
+ // • local-source → contentType (LocalSourceNodeExecutor.php:42)
13
+ // • filter → conditions, logic (FilterNodeExecutor.php:45–61)
14
+ // • transform → expression (TransformNodeExecutor.php:39)
15
+ // • merge → strategy ∈ SUPPORTED_STRATEGIES (MergeNodeExecutor.php:50)
16
+ // • output / output-yootheme / output-shortcode → terminal passthrough
17
+ // (FlowCompiler.php OUTPUT_NODE_TYPES)
18
+ //
19
+ // Design choices:
20
+ // 1. Per-type schemas use `.passthrough()` on the inner data object so
21
+ // Admin-UI helper fields (e.g. _detected_shape, sourceContext,
22
+ // template_field_labels) round-trip untouched. Only the type-required
23
+ // fields are enforced.
24
+ // 2. Position is required (React-Flow runtime needs it). All other shell
25
+ // fields (sourceHandle, targetHandle on edges) live elsewhere.
26
+ // 3. Discriminated union on `type` gives the agent a clean error like
27
+ // `Invalid discriminator value. Expected 'source' | 'transform' | ...`.
28
+ import { z } from "zod";
29
+ /** React-Flow node position. */
30
+ const positionSchema = z
31
+ .object({ x: z.number(), y: z.number() })
32
+ .describe("React-Flow canvas position");
33
+ // ── source ───────────────────────────────────────────────────────────────
34
+ export const sourceNodeSchema = z
35
+ .object({
36
+ id: z.string().describe("Unique node ID within the flow"),
37
+ type: z.literal("source"),
38
+ position: positionSchema,
39
+ data: z
40
+ .object({
41
+ connectionId: z
42
+ .string()
43
+ .min(1)
44
+ .describe("Connection ID from apimapper_connection_list"),
45
+ endpointId: z
46
+ .string()
47
+ .optional()
48
+ .describe("Endpoint within the connection (e.g. 'list', 'search')"),
49
+ templateFields: z
50
+ .record(z.string(), z.unknown())
51
+ .optional()
52
+ .describe("Library-template field values (e.g. sheet_id, channel)"),
53
+ itemsPath: z
54
+ .string()
55
+ .optional()
56
+ .describe("JMESPath into response that points at the items array"),
57
+ itemsShape: z
58
+ .string()
59
+ .optional()
60
+ .describe("Shape hint ('array', 'object_values', 'headers_rows')"),
61
+ })
62
+ .passthrough()
63
+ .describe("Source-node payload"),
64
+ })
65
+ .describe("API-source node (fetches from a Connection)");
66
+ // ── local-source ─────────────────────────────────────────────────────────
67
+ export const localSourceNodeSchema = z
68
+ .object({
69
+ id: z.string(),
70
+ type: z.literal("local-source"),
71
+ position: positionSchema,
72
+ data: z
73
+ .object({
74
+ contentType: z
75
+ .string()
76
+ .min(1)
77
+ .describe("Local content type (e.g. 'post', 'page', 'product')"),
78
+ limit: z.number().int().min(1).optional().describe("Max items to fetch"),
79
+ filters: z.record(z.string(), z.unknown()).optional().describe("Server-side filters"),
80
+ })
81
+ .passthrough()
82
+ .describe("Local-source payload (queries WP/Joomla DB directly)"),
83
+ })
84
+ .describe("Local-source node (CMS-native content)");
85
+ // ── filter ───────────────────────────────────────────────────────────────
86
+ export const filterNodeSchema = z
87
+ .object({
88
+ id: z.string(),
89
+ type: z.literal("filter"),
90
+ position: positionSchema,
91
+ data: z
92
+ .object({
93
+ conditions: z
94
+ .array(z.record(z.string(), z.unknown()))
95
+ .describe("Array of filter conditions ({field, operator, value})"),
96
+ logic: z
97
+ .enum(["and", "or"])
98
+ .optional()
99
+ .describe("Combinator across conditions; defaults to 'and'"),
100
+ })
101
+ .passthrough()
102
+ .describe("Filter payload"),
103
+ })
104
+ .describe("Filter node (drops items that fail conditions)");
105
+ // ── transform ────────────────────────────────────────────────────────────
106
+ export const transformNodeSchema = z
107
+ .object({
108
+ id: z.string(),
109
+ type: z.literal("transform"),
110
+ position: positionSchema,
111
+ data: z
112
+ .object({
113
+ expression: z
114
+ .string()
115
+ .min(1)
116
+ .describe("JMESPath expression. Example: '[*].{title: title, slug: slug}'. " +
117
+ "For per-item coalesce use '[*].coalesce_empty(c1, c2)'."),
118
+ })
119
+ .passthrough()
120
+ .describe("Transform payload"),
121
+ })
122
+ .describe("Transform node (per-item JMESPath projection)");
123
+ // ── merge ────────────────────────────────────────────────────────────────
124
+ //
125
+ // SUPPORTED_STRATEGIES is mirrored from
126
+ // src/modules/core/src/Graph/Node/MergeNodeExecutor.php:50.
127
+ // 'append' is a customer-UI alias normalized to 'concat' downstream — at the
128
+ // MCP boundary we accept ONLY the canonical set so agents see the same names
129
+ // the PHP executor enforces. (Normalization happens in normalizers.ts.)
130
+ export const mergeNodeSchema = z
131
+ .object({
132
+ id: z.string(),
133
+ type: z.literal("merge"),
134
+ position: positionSchema,
135
+ data: z
136
+ .object({
137
+ strategy: z
138
+ .enum(["concat", "join"])
139
+ .describe("'concat' = stack items from both inputs; 'join' = relational join on key. " +
140
+ "Strategies 'append', 'chronological', etc. are NOT valid here."),
141
+ joinKey: z.string().optional().describe("Field on input-A (required if strategy='join')"),
142
+ joinKeyRight: z
143
+ .string()
144
+ .optional()
145
+ .describe("Field on input-B (defaults to joinKey when omitted)"),
146
+ joinType: z
147
+ .enum(["left", "right", "inner", "outer"])
148
+ .optional()
149
+ .describe("SQL-style join kind; defaults to 'left'"),
150
+ })
151
+ .passthrough()
152
+ .describe("Merge payload"),
153
+ })
154
+ .describe("Merge node (combines two upstream inputs)");
155
+ // ── output (terminal: output / output-yootheme / output-shortcode) ───────
156
+ //
157
+ // Mirrored from FlowCompiler.php OUTPUT_NODE_TYPES const.
158
+ const outputDataSchema = z
159
+ .object({
160
+ name: z.string().optional().describe("Display name in the YOOtheme source dropdown"),
161
+ slug: z.string().optional().describe("URL-safe slug (auto-derived from name when omitted)"),
162
+ })
163
+ .passthrough();
164
+ export const outputNodeSchema = z
165
+ .discriminatedUnion("type", [
166
+ z.object({
167
+ id: z.string(),
168
+ type: z.literal("output"),
169
+ position: positionSchema,
170
+ data: outputDataSchema,
171
+ }),
172
+ z.object({
173
+ id: z.string(),
174
+ type: z.literal("output-yootheme"),
175
+ position: positionSchema,
176
+ data: outputDataSchema,
177
+ }),
178
+ z.object({
179
+ id: z.string(),
180
+ type: z.literal("output-shortcode"),
181
+ position: positionSchema,
182
+ data: outputDataSchema,
183
+ }),
184
+ ])
185
+ .describe("Output node (terminal: YOOtheme source, shortcode, or generic)");
186
+ // ── union — the schema flows.ts/graph.ts consume ─────────────────────────
187
+ //
188
+ // NOTE: z.discriminatedUnion requires every member to be a plain ZodObject on
189
+ // the discriminator path. Since outputNodeSchema is itself a discriminated
190
+ // union, we inline its three members here rather than nest unions.
191
+ export const nodeSchema = z
192
+ .discriminatedUnion("type", [
193
+ sourceNodeSchema,
194
+ localSourceNodeSchema,
195
+ filterNodeSchema,
196
+ transformNodeSchema,
197
+ mergeNodeSchema,
198
+ z.object({
199
+ id: z.string(),
200
+ type: z.literal("output"),
201
+ position: positionSchema,
202
+ data: outputDataSchema,
203
+ }),
204
+ z.object({
205
+ id: z.string(),
206
+ type: z.literal("output-yootheme"),
207
+ position: positionSchema,
208
+ data: outputDataSchema,
209
+ }),
210
+ z.object({
211
+ id: z.string(),
212
+ type: z.literal("output-shortcode"),
213
+ position: positionSchema,
214
+ data: outputDataSchema,
215
+ }),
216
+ ])
217
+ .describe("Flow node. Discriminator: `type` ∈ source | local-source | filter | transform | merge | output | output-yootheme | output-shortcode");
218
+ //# sourceMappingURL=node-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-schema.js","sourceRoot":"","sources":["../../../src/modules/apimapper/node-schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export type MergeStrategy = "concat" | "join";
2
+ export declare function normalizeMergeStrategy(input: string): MergeStrategy;
3
+ /**
4
+ * Strip leading/trailing slashes from a URL path to keep our encoded paths
5
+ * consistent regardless of how callers pass them.
6
+ */
7
+ export declare function trimSlashes(s: string): string;
8
+ /**
9
+ * Encode each segment of a path but preserve forward slashes. Used for
10
+ * routes whose param is `platform/type` (LocalSourceController) where the
11
+ * slash is structural, not a path separator.
12
+ */
13
+ export declare function encodePathPreservingSlashes(s: string): string;
@@ -0,0 +1,37 @@
1
+ // src/modules/apimapper/normalizers.ts — wire-format aliases + small helpers.
2
+ //
3
+ // Backend canonical merge strategies are "concat" and "join". The "append"
4
+ // alias is a customer-facing UI label; the FlowCompiler ultimately persists
5
+ // "concat". Centralised here so workflow tools + tests share one source.
6
+ export function normalizeMergeStrategy(input) {
7
+ if (input === "append")
8
+ return "concat";
9
+ if (input === "concat" || input === "join")
10
+ return input;
11
+ // All current call sites validate input via zod enum upstream. This
12
+ // fallback exists only for direct programmatic callers that skipped
13
+ // the schema layer; surface a console.warn so the deviation is visible
14
+ // in operator logs.
15
+ // eslint-disable-next-line no-console
16
+ console.warn(`[apimapper-rest:normalizers] unknown merge strategy "${input}" — defaulting to "concat"`);
17
+ return "concat";
18
+ }
19
+ /**
20
+ * Strip leading/trailing slashes from a URL path to keep our encoded paths
21
+ * consistent regardless of how callers pass them.
22
+ */
23
+ export function trimSlashes(s) {
24
+ return s.replace(/^\/+|\/+$/g, "");
25
+ }
26
+ /**
27
+ * Encode each segment of a path but preserve forward slashes. Used for
28
+ * routes whose param is `platform/type` (LocalSourceController) where the
29
+ * slash is structural, not a path separator.
30
+ */
31
+ export function encodePathPreservingSlashes(s) {
32
+ return s
33
+ .split("/")
34
+ .map((seg) => encodeURIComponent(seg))
35
+ .join("/");
36
+ }
37
+ //# sourceMappingURL=normalizers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizers.js","sourceRoot":"","sources":["../../../src/modules/apimapper/normalizers.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,yEAAyE;AAIzE,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IACxC,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACzD,oEAAoE;IACpE,oEAAoE;IACpE,uEAAuE;IACvE,oBAAoB;IACpB,sCAAsC;IACtC,OAAO,CAAC,IAAI,CACV,wDAAwD,KAAK,4BAA4B,CAC1F,CAAC;IACF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,OAAO,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,CAAS;IACnD,OAAO,CAAC;SACL,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;SACrC,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC"}