@maestrogtm/maestro-gtm 0.10.16
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/dist/ai-RNHSWSNV.js +158 -0
- package/dist/ai-RNHSWSNV.js.map +1 -0
- package/dist/app-PSZH2J56.js +54 -0
- package/dist/app-PSZH2J56.js.map +1 -0
- package/dist/batch-ZCHN54YJ.js +28 -0
- package/dist/batch-ZCHN54YJ.js.map +1 -0
- package/dist/campaign-XDXQA7KX.js +119 -0
- package/dist/campaign-XDXQA7KX.js.map +1 -0
- package/dist/chunk-365Q36GF.js +54 -0
- package/dist/chunk-365Q36GF.js.map +1 -0
- package/dist/chunk-4IV6QS4U.js +122 -0
- package/dist/chunk-4IV6QS4U.js.map +1 -0
- package/dist/chunk-6GLLK5KO.js +64 -0
- package/dist/chunk-6GLLK5KO.js.map +1 -0
- package/dist/chunk-6UNBW5SN.js +686 -0
- package/dist/chunk-6UNBW5SN.js.map +1 -0
- package/dist/chunk-A7JD6EYV.js +92 -0
- package/dist/chunk-A7JD6EYV.js.map +1 -0
- package/dist/chunk-ARNVJPFM.js +139 -0
- package/dist/chunk-ARNVJPFM.js.map +1 -0
- package/dist/chunk-AX6BOEF2.js +345 -0
- package/dist/chunk-AX6BOEF2.js.map +1 -0
- package/dist/chunk-C3T7QPSO.js +507 -0
- package/dist/chunk-C3T7QPSO.js.map +1 -0
- package/dist/chunk-FG43GILY.js +46 -0
- package/dist/chunk-FG43GILY.js.map +1 -0
- package/dist/chunk-FS6DCNCA.js +139 -0
- package/dist/chunk-FS6DCNCA.js.map +1 -0
- package/dist/chunk-I6GRD4X7.js +1144 -0
- package/dist/chunk-I6GRD4X7.js.map +1 -0
- package/dist/chunk-IP34URKR.js +621 -0
- package/dist/chunk-IP34URKR.js.map +1 -0
- package/dist/chunk-JFSKOY7Z.js +252 -0
- package/dist/chunk-JFSKOY7Z.js.map +1 -0
- package/dist/chunk-M25KLO7T.js +3272 -0
- package/dist/chunk-M25KLO7T.js.map +1 -0
- package/dist/chunk-M3G2WREL.js +57 -0
- package/dist/chunk-M3G2WREL.js.map +1 -0
- package/dist/chunk-MFFACSBE.js +4266 -0
- package/dist/chunk-MFFACSBE.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/chunk-QZH3XFOQ.js +2636 -0
- package/dist/chunk-QZH3XFOQ.js.map +1 -0
- package/dist/chunk-SPWDMOEU.js +1940 -0
- package/dist/chunk-SPWDMOEU.js.map +1 -0
- package/dist/chunk-TP3BZDVV.js +28 -0
- package/dist/chunk-TP3BZDVV.js.map +1 -0
- package/dist/chunk-UBJUBYSQ.js +18 -0
- package/dist/chunk-UBJUBYSQ.js.map +1 -0
- package/dist/chunk-VNKXGHWY.js +20 -0
- package/dist/chunk-VNKXGHWY.js.map +1 -0
- package/dist/chunk-WKLCPIFB.js +9862 -0
- package/dist/chunk-WKLCPIFB.js.map +1 -0
- package/dist/chunk-YV5XOXRQ.js +7 -0
- package/dist/chunk-YV5XOXRQ.js.map +1 -0
- package/dist/cli-Z3BNNJYQ.js +852 -0
- package/dist/cli-Z3BNNJYQ.js.map +1 -0
- package/dist/client-Y34LNEWN.js +8 -0
- package/dist/client-Y34LNEWN.js.map +1 -0
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -0
- package/dist/configure-XSENK4X5.js +64 -0
- package/dist/configure-XSENK4X5.js.map +1 -0
- package/dist/context.js +10 -0
- package/dist/context.js.map +1 -0
- package/dist/crm-QBNHVBYV.js +86 -0
- package/dist/crm-QBNHVBYV.js.map +1 -0
- package/dist/dfy-X3OXIYRA.js +356 -0
- package/dist/dfy-X3OXIYRA.js.map +1 -0
- package/dist/dist-LGCJKGBS.js +121 -0
- package/dist/dist-LGCJKGBS.js.map +1 -0
- package/dist/engagement-C4U7LPJH.js +463 -0
- package/dist/engagement-C4U7LPJH.js.map +1 -0
- package/dist/enrich-F5GPVZFE.js +226 -0
- package/dist/enrich-F5GPVZFE.js.map +1 -0
- package/dist/extract-DS5N6SSJ.js +155 -0
- package/dist/extract-DS5N6SSJ.js.map +1 -0
- package/dist/feedback-AIXKXNM5.js +51 -0
- package/dist/feedback-AIXKXNM5.js.map +1 -0
- package/dist/fetch-QJDSPI63.js +87 -0
- package/dist/fetch-QJDSPI63.js.map +1 -0
- package/dist/handlers.js +13 -0
- package/dist/handlers.js.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/list-HL7NQQJX.js +236 -0
- package/dist/list-HL7NQQJX.js.map +1 -0
- package/dist/maestro-N7Q2JX22.js +903 -0
- package/dist/maestro-N7Q2JX22.js.map +1 -0
- package/dist/prospect-RUOT43H6.js +532 -0
- package/dist/prospect-RUOT43H6.js.map +1 -0
- package/dist/providers/factory.js +10 -0
- package/dist/providers/factory.js.map +1 -0
- package/dist/providers/registry.js +8 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/provision-FT5NWN77.js +394 -0
- package/dist/provision-FT5NWN77.js.map +1 -0
- package/dist/recipe-JU3SXMZF.js +137 -0
- package/dist/recipe-JU3SXMZF.js.map +1 -0
- package/dist/review-5SB6DYDZ.js +70 -0
- package/dist/review-5SB6DYDZ.js.map +1 -0
- package/dist/sdk-LVBHNQ6T.js +3852 -0
- package/dist/sdk-LVBHNQ6T.js.map +1 -0
- package/dist/server-REKYQZ2E.js +22 -0
- package/dist/server-REKYQZ2E.js.map +1 -0
- package/dist/status-V3EEFS7S.js +114 -0
- package/dist/status-V3EEFS7S.js.map +1 -0
- package/dist/tam-J6NDBP5W.js +682 -0
- package/dist/tam-J6NDBP5W.js.map +1 -0
- package/dist/tools.js +80 -0
- package/dist/tools.js.map +1 -0
- package/dist/validation.js +12 -0
- package/dist/validation.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {
|
|
2
|
+
expandPath,
|
|
3
|
+
runBatch
|
|
4
|
+
} from "./chunk-IP34URKR.js";
|
|
5
|
+
import "./chunk-6GLLK5KO.js";
|
|
6
|
+
import "./chunk-PZ5AY32C.js";
|
|
7
|
+
|
|
8
|
+
// src/recipes/store.ts
|
|
9
|
+
import * as fs from "fs";
|
|
10
|
+
import * as path from "path";
|
|
11
|
+
import YAML from "yaml";
|
|
12
|
+
var RECIPES_DIR = "~/.gtm/recipes";
|
|
13
|
+
function saveRecipe(recipe) {
|
|
14
|
+
const dir = expandPath(RECIPES_DIR);
|
|
15
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
16
|
+
const filePath = recipePath(recipe.name);
|
|
17
|
+
const content = YAML.stringify(recipe, { lineWidth: 120 });
|
|
18
|
+
fs.writeFileSync(filePath, content, "utf-8");
|
|
19
|
+
}
|
|
20
|
+
function loadRecipe(name) {
|
|
21
|
+
const filePath = recipePath(name);
|
|
22
|
+
if (!fs.existsSync(filePath)) return null;
|
|
23
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
24
|
+
return YAML.parse(content);
|
|
25
|
+
}
|
|
26
|
+
function listRecipes() {
|
|
27
|
+
const dir = expandPath(RECIPES_DIR);
|
|
28
|
+
if (!fs.existsSync(dir)) return [];
|
|
29
|
+
const files = fs.readdirSync(dir).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
|
|
30
|
+
return files.map((file) => {
|
|
31
|
+
const content = fs.readFileSync(path.join(dir, file), "utf-8");
|
|
32
|
+
const recipe = YAML.parse(content);
|
|
33
|
+
return {
|
|
34
|
+
name: recipe.name,
|
|
35
|
+
description: recipe.description,
|
|
36
|
+
schedule: recipe.schedule,
|
|
37
|
+
last_run: recipe.state?.last_run,
|
|
38
|
+
run_count: recipe.state?.run_count ?? 0
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function deleteRecipe(name) {
|
|
43
|
+
const filePath = recipePath(name);
|
|
44
|
+
if (!fs.existsSync(filePath)) return false;
|
|
45
|
+
fs.unlinkSync(filePath);
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
function updateRecipeState(name, stats) {
|
|
49
|
+
const recipe = loadRecipe(name);
|
|
50
|
+
if (!recipe) return;
|
|
51
|
+
recipe.state = {
|
|
52
|
+
...recipe.state,
|
|
53
|
+
last_run: (/* @__PURE__ */ new Date()).toISOString(),
|
|
54
|
+
last_run_stats: stats,
|
|
55
|
+
run_count: (recipe.state?.run_count ?? 0) + 1
|
|
56
|
+
};
|
|
57
|
+
recipe.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
58
|
+
saveRecipe(recipe);
|
|
59
|
+
}
|
|
60
|
+
function recipePath(name) {
|
|
61
|
+
const sanitized = name.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
62
|
+
return path.join(expandPath(RECIPES_DIR), `${sanitized}.yaml`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// src/handlers/recipe.ts
|
|
66
|
+
async function handleRecipe(args, ctx, dispatchFn) {
|
|
67
|
+
const action = args.action;
|
|
68
|
+
const dispatch = async (tool, toolArgs) => dispatchFn(tool, toolArgs, ctx);
|
|
69
|
+
switch (action) {
|
|
70
|
+
case "save":
|
|
71
|
+
return handleSave(args);
|
|
72
|
+
case "list":
|
|
73
|
+
return handleList();
|
|
74
|
+
case "run":
|
|
75
|
+
return await handleRun(args, dispatch);
|
|
76
|
+
case "show":
|
|
77
|
+
return handleShow(args);
|
|
78
|
+
case "delete":
|
|
79
|
+
return handleDelete(args);
|
|
80
|
+
default:
|
|
81
|
+
throw new Error(`Unknown recipe action: ${action}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function handleSave(args) {
|
|
85
|
+
const name = args.name;
|
|
86
|
+
const config = args.config;
|
|
87
|
+
if (!name) throw new Error("name is required for save");
|
|
88
|
+
if (!config) throw new Error("config is required for save");
|
|
89
|
+
const existing = loadRecipe(name);
|
|
90
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
91
|
+
const recipe = {
|
|
92
|
+
name,
|
|
93
|
+
description: args.description ?? existing?.description,
|
|
94
|
+
version: (existing?.version ?? 0) + 1,
|
|
95
|
+
created_at: existing?.created_at ?? now,
|
|
96
|
+
updated_at: now,
|
|
97
|
+
config,
|
|
98
|
+
schedule: args.schedule ?? existing?.schedule,
|
|
99
|
+
state: existing?.state
|
|
100
|
+
};
|
|
101
|
+
saveRecipe(recipe);
|
|
102
|
+
return { saved: name, path: `~/.gtm/recipes/${name}.yaml` };
|
|
103
|
+
}
|
|
104
|
+
function handleList() {
|
|
105
|
+
return { recipes: listRecipes() };
|
|
106
|
+
}
|
|
107
|
+
async function handleRun(args, dispatch) {
|
|
108
|
+
const name = args.name;
|
|
109
|
+
if (!name) throw new Error("name is required for run");
|
|
110
|
+
const recipe = loadRecipe(name);
|
|
111
|
+
if (!recipe) throw new Error(`Recipe not found: ${name}`);
|
|
112
|
+
const result = await runBatch(recipe.config, dispatch);
|
|
113
|
+
updateRecipeState(name, {
|
|
114
|
+
total: result.stats.total,
|
|
115
|
+
processed: result.stats.processed,
|
|
116
|
+
errors: result.stats.errors
|
|
117
|
+
});
|
|
118
|
+
return { recipe: name, ...result };
|
|
119
|
+
}
|
|
120
|
+
function handleShow(args) {
|
|
121
|
+
const name = args.name;
|
|
122
|
+
if (!name) throw new Error("name is required for show");
|
|
123
|
+
const recipe = loadRecipe(name);
|
|
124
|
+
if (!recipe) throw new Error(`Recipe not found: ${name}`);
|
|
125
|
+
return recipe;
|
|
126
|
+
}
|
|
127
|
+
function handleDelete(args) {
|
|
128
|
+
const name = args.name;
|
|
129
|
+
if (!name) throw new Error("name is required for delete");
|
|
130
|
+
const deleted = deleteRecipe(name);
|
|
131
|
+
if (!deleted) throw new Error(`Recipe not found: ${name}`);
|
|
132
|
+
return { deleted: true, name };
|
|
133
|
+
}
|
|
134
|
+
export {
|
|
135
|
+
handleRecipe
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=recipe-JU3SXMZF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/recipes/store.ts","../src/handlers/recipe.ts"],"sourcesContent":["/** Recipe persistence. CRUD for named recipe configs stored as YAML in ~/.gtm/recipes/.\n * Constraint: No MCP imports. Pure file I/O. */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport YAML from 'yaml';\n\nimport { expandPath } from '../batch/engine.js';\nimport type { Recipe, RecipeState } from './types.js';\n\n// ─── Constants ──────────────────────────────────────────\n\nconst RECIPES_DIR = '~/.gtm/recipes';\n\n// ─── Public API ─────────────────────────────────────────\n\n/** Save a recipe to disk. Creates or overwrites. */\nexport function saveRecipe(recipe: Recipe): void {\n const dir = expandPath(RECIPES_DIR);\n fs.mkdirSync(dir, { recursive: true });\n const filePath = recipePath(recipe.name);\n const content = YAML.stringify(recipe, { lineWidth: 120 });\n fs.writeFileSync(filePath, content, 'utf-8');\n}\n\n/** Load a recipe by name. Returns null if not found. */\nexport function loadRecipe(name: string): Recipe | null {\n const filePath = recipePath(name);\n if (!fs.existsSync(filePath)) return null;\n const content = fs.readFileSync(filePath, 'utf-8');\n return YAML.parse(content) as Recipe;\n}\n\n/** List all saved recipes. Returns summary info, not full configs. */\nexport function listRecipes(): Array<{\n name: string;\n description?: string;\n schedule?: string;\n last_run?: string;\n run_count: number;\n}> {\n const dir = expandPath(RECIPES_DIR);\n if (!fs.existsSync(dir)) return [];\n\n const files = fs.readdirSync(dir).filter((f) => f.endsWith('.yaml') || f.endsWith('.yml'));\n return files.map((file) => {\n const content = fs.readFileSync(path.join(dir, file), 'utf-8');\n const recipe = YAML.parse(content) as Recipe;\n return {\n name: recipe.name,\n description: recipe.description,\n schedule: recipe.schedule,\n last_run: recipe.state?.last_run,\n run_count: recipe.state?.run_count ?? 0,\n };\n });\n}\n\n/** Delete a recipe by name. Returns true if deleted, false if not found. */\nexport function deleteRecipe(name: string): boolean {\n const filePath = recipePath(name);\n if (!fs.existsSync(filePath)) return false;\n fs.unlinkSync(filePath);\n return true;\n}\n\n/** Update recipe state after a run. */\nexport function updateRecipeState(name: string, stats: RecipeState['last_run_stats']): void {\n const recipe = loadRecipe(name);\n if (!recipe) return;\n\n recipe.state = {\n ...recipe.state,\n last_run: new Date().toISOString(),\n last_run_stats: stats,\n run_count: (recipe.state?.run_count ?? 0) + 1,\n };\n recipe.updated_at = new Date().toISOString();\n saveRecipe(recipe);\n}\n\n// ─── Helpers ────────────────────────────────────────────\n\nfunction recipePath(name: string): string {\n const sanitized = name.replace(/[^a-zA-Z0-9_-]/g, '_');\n return path.join(expandPath(RECIPES_DIR), `${sanitized}.yaml`);\n}\n","/** Handler for gtm_recipe. Routes recipe actions to store functions.\n * Constraint: No direct MCP imports. */\n\nimport {\n saveRecipe,\n loadRecipe,\n listRecipes,\n deleteRecipe,\n updateRecipeState,\n} from '../recipes/index.js';\nimport { runBatch } from '../batch/engine.js';\nimport type { DispatchFn } from '../batch/engine.js';\nimport type { Recipe } from '../recipes/types.js';\nimport type { HandlerContext } from './index.js';\n\n// ─── Types ──────────────────────────────────────────────\n\ntype InternalDispatchFn = (\n tool: string,\n args: Record<string, unknown>,\n ctx: HandlerContext\n) => Promise<unknown>;\n\n// ─── Public API ─────────────────────────────────────────\n\nexport async function handleRecipe(\n args: Record<string, unknown>,\n ctx: HandlerContext,\n dispatchFn: InternalDispatchFn\n): Promise<unknown> {\n const action = args.action as string;\n const dispatch: DispatchFn = async (tool, toolArgs) => dispatchFn(tool, toolArgs, ctx);\n\n switch (action) {\n case 'save':\n return handleSave(args);\n case 'list':\n return handleList();\n case 'run':\n return await handleRun(args, dispatch);\n case 'show':\n return handleShow(args);\n case 'delete':\n return handleDelete(args);\n default:\n throw new Error(`Unknown recipe action: ${action}`);\n }\n}\n\n// ─── Action Handlers ────────────────────────────────────\n\nfunction handleSave(args: Record<string, unknown>): { saved: string; path: string } {\n const name = args.name as string | undefined;\n const config = args.config as Record<string, unknown> | undefined;\n if (!name) throw new Error('name is required for save');\n if (!config) throw new Error('config is required for save');\n\n const existing = loadRecipe(name);\n const now = new Date().toISOString();\n\n const recipe: Recipe = {\n name,\n description: (args.description as string | undefined) ?? existing?.description,\n version: (existing?.version ?? 0) + 1,\n created_at: existing?.created_at ?? now,\n updated_at: now,\n config: config as unknown as Recipe['config'],\n schedule: (args.schedule as string | undefined) ?? existing?.schedule,\n state: existing?.state,\n };\n\n saveRecipe(recipe);\n return { saved: name, path: `~/.gtm/recipes/${name}.yaml` };\n}\n\nfunction handleList(): {\n recipes: Array<{\n name: string;\n description?: string;\n schedule?: string;\n last_run?: string;\n run_count: number;\n }>;\n} {\n return { recipes: listRecipes() };\n}\n\nasync function handleRun(args: Record<string, unknown>, dispatch: DispatchFn): Promise<unknown> {\n const name = args.name as string | undefined;\n if (!name) throw new Error('name is required for run');\n\n const recipe = loadRecipe(name);\n if (!recipe) throw new Error(`Recipe not found: ${name}`);\n\n const result = await runBatch(recipe.config, dispatch);\n\n updateRecipeState(name, {\n total: result.stats.total,\n processed: result.stats.processed,\n errors: result.stats.errors,\n });\n\n return { recipe: name, ...result };\n}\n\nfunction handleShow(args: Record<string, unknown>): Recipe {\n const name = args.name as string | undefined;\n if (!name) throw new Error('name is required for show');\n const recipe = loadRecipe(name);\n if (!recipe) throw new Error(`Recipe not found: ${name}`);\n return recipe;\n}\n\nfunction handleDelete(args: Record<string, unknown>): { deleted: boolean; name: string } {\n const name = args.name as string | undefined;\n if (!name) throw new Error('name is required for delete');\n const deleted = deleteRecipe(name);\n if (!deleted) throw new Error(`Recipe not found: ${name}`);\n return { deleted: true, name };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import "./chunk-PZ5AY32C.js";
|
|
2
|
+
|
|
3
|
+
// src/handlers/review.ts
|
|
4
|
+
var VIEWER_URL = process.env.GTM_VIEWER_URL ?? "https://gtm-viewer-production.up.railway.app";
|
|
5
|
+
async function handleReview(args) {
|
|
6
|
+
const action = args.action;
|
|
7
|
+
switch (action) {
|
|
8
|
+
case "create":
|
|
9
|
+
return createTable(args);
|
|
10
|
+
case "update":
|
|
11
|
+
return updateTable(args);
|
|
12
|
+
case "get_selected":
|
|
13
|
+
return getSelected(args);
|
|
14
|
+
default:
|
|
15
|
+
throw new Error(`Unknown review action: ${action}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async function createTable(args) {
|
|
19
|
+
const data = args.data;
|
|
20
|
+
const title = args.title ?? "Review Table";
|
|
21
|
+
const tableId = args.table_id;
|
|
22
|
+
const ttlSeconds = args.ttl_seconds;
|
|
23
|
+
const rows = data.map((row, i) => ({
|
|
24
|
+
...row,
|
|
25
|
+
_row_id: row._row_id ?? `r${i + 1}`
|
|
26
|
+
}));
|
|
27
|
+
const response = await fetch(`${VIEWER_URL}/api/tables`, {
|
|
28
|
+
method: "POST",
|
|
29
|
+
headers: { "Content-Type": "application/json" },
|
|
30
|
+
body: JSON.stringify({
|
|
31
|
+
title,
|
|
32
|
+
rows,
|
|
33
|
+
...tableId && { table_id: tableId },
|
|
34
|
+
...ttlSeconds && { ttl_seconds: ttlSeconds }
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
if (!response.ok) {
|
|
38
|
+
const body = await response.json().catch(() => ({}));
|
|
39
|
+
throw new Error(`Viewer API error ${response.status}: ${JSON.stringify(body)}`);
|
|
40
|
+
}
|
|
41
|
+
const result = await response.json();
|
|
42
|
+
return { ...result, row_ids: rows.map((r) => r._row_id) };
|
|
43
|
+
}
|
|
44
|
+
async function updateTable(args) {
|
|
45
|
+
const tableId = args.table_id;
|
|
46
|
+
const rows = args.rows;
|
|
47
|
+
const response = await fetch(`${VIEWER_URL}/api/tables/${tableId}`, {
|
|
48
|
+
method: "PATCH",
|
|
49
|
+
headers: { "Content-Type": "application/json" },
|
|
50
|
+
body: JSON.stringify({ rows })
|
|
51
|
+
});
|
|
52
|
+
if (!response.ok) {
|
|
53
|
+
const body = await response.json().catch(() => ({}));
|
|
54
|
+
throw new Error(`Viewer API error ${response.status}: ${JSON.stringify(body)}`);
|
|
55
|
+
}
|
|
56
|
+
return response.json();
|
|
57
|
+
}
|
|
58
|
+
async function getSelected(args) {
|
|
59
|
+
const tableId = args.table_id;
|
|
60
|
+
const response = await fetch(`${VIEWER_URL}/api/tables/${tableId}/selected`);
|
|
61
|
+
if (!response.ok) {
|
|
62
|
+
const body = await response.json().catch(() => ({}));
|
|
63
|
+
throw new Error(`Viewer API error ${response.status}: ${JSON.stringify(body)}`);
|
|
64
|
+
}
|
|
65
|
+
return response.json();
|
|
66
|
+
}
|
|
67
|
+
export {
|
|
68
|
+
handleReview
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=review-5SB6DYDZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/handlers/review.ts"],"sourcesContent":["/** Review handler. Proxies create/update/get_selected to the gtm-viewer API.\n * Constraint: Direct fetch() calls (not handleFetch — avoids SSRF blocking localhost in dev). */\n\n// ─── Config ─────────────────────────────────────────────\n\nconst VIEWER_URL = process.env.GTM_VIEWER_URL ?? 'https://gtm-viewer-production.up.railway.app';\n\n// ─── Handler ────────────────────────────────────────────\n\nexport async function handleReview(args: Record<string, unknown>): Promise<unknown> {\n const action = args.action as string;\n\n switch (action) {\n case 'create':\n return createTable(args);\n case 'update':\n return updateTable(args);\n case 'get_selected':\n return getSelected(args);\n default:\n throw new Error(`Unknown review action: ${action}`);\n }\n}\n\n// ─── Actions ────────────────────────────────────────────\n\nasync function createTable(args: Record<string, unknown>): Promise<unknown> {\n const data = args.data as Array<Record<string, unknown>>;\n const title = (args.title as string) ?? 'Review Table';\n const tableId = args.table_id as string | undefined;\n const ttlSeconds = args.ttl_seconds as number | undefined;\n\n // Assign _row_id to rows that don't have one\n const rows = data.map((row, i) => ({\n ...row,\n _row_id: (row._row_id as string) ?? `r${i + 1}`,\n }));\n\n const response = await fetch(`${VIEWER_URL}/api/tables`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n title,\n rows,\n ...(tableId && { table_id: tableId }),\n ...(ttlSeconds && { ttl_seconds: ttlSeconds }),\n }),\n });\n\n if (!response.ok) {\n const body = await response.json().catch(() => ({}));\n throw new Error(`Viewer API error ${response.status}: ${JSON.stringify(body)}`);\n }\n\n const result = (await response.json()) as Record<string, unknown>;\n\n // Include row_ids so callers can update rows later without recreating the table\n return { ...result, row_ids: rows.map((r) => r._row_id) };\n}\n\nasync function updateTable(args: Record<string, unknown>): Promise<unknown> {\n const tableId = args.table_id as string;\n const rows = args.rows as Array<Record<string, unknown>>;\n\n const response = await fetch(`${VIEWER_URL}/api/tables/${tableId}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ rows }),\n });\n\n if (!response.ok) {\n const body = await response.json().catch(() => ({}));\n throw new Error(`Viewer API error ${response.status}: ${JSON.stringify(body)}`);\n }\n\n return response.json();\n}\n\nasync function getSelected(args: Record<string, unknown>): Promise<unknown> {\n const tableId = args.table_id as string;\n\n const response = await fetch(`${VIEWER_URL}/api/tables/${tableId}/selected`);\n\n if (!response.ok) {\n const body = await response.json().catch(() => ({}));\n throw new Error(`Viewer API error ${response.status}: ${JSON.stringify(body)}`);\n }\n\n return response.json();\n}\n"],"mappings":";;;AAKA,IAAM,aAAa,QAAQ,IAAI,kBAAkB;AAIjD,eAAsB,aAAa,MAAiD;AAClF,QAAM,SAAS,KAAK;AAEpB,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO,YAAY,IAAI;AAAA,IACzB,KAAK;AACH,aAAO,YAAY,IAAI;AAAA,IACzB,KAAK;AACH,aAAO,YAAY,IAAI;AAAA,IACzB;AACE,YAAM,IAAI,MAAM,0BAA0B,MAAM,EAAE;AAAA,EACtD;AACF;AAIA,eAAe,YAAY,MAAiD;AAC1E,QAAM,OAAO,KAAK;AAClB,QAAM,QAAS,KAAK,SAAoB;AACxC,QAAM,UAAU,KAAK;AACrB,QAAM,aAAa,KAAK;AAGxB,QAAM,OAAO,KAAK,IAAI,CAAC,KAAK,OAAO;AAAA,IACjC,GAAG;AAAA,IACH,SAAU,IAAI,WAAsB,IAAI,IAAI,CAAC;AAAA,EAC/C,EAAE;AAEF,QAAM,WAAW,MAAM,MAAM,GAAG,UAAU,eAAe;AAAA,IACvD,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,MAAM,KAAK,UAAU;AAAA,MACnB;AAAA,MACA;AAAA,MACA,GAAI,WAAW,EAAE,UAAU,QAAQ;AAAA,MACnC,GAAI,cAAc,EAAE,aAAa,WAAW;AAAA,IAC9C,CAAC;AAAA,EACH,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,OAAO,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACnD,UAAM,IAAI,MAAM,oBAAoB,SAAS,MAAM,KAAK,KAAK,UAAU,IAAI,CAAC,EAAE;AAAA,EAChF;AAEA,QAAM,SAAU,MAAM,SAAS,KAAK;AAGpC,SAAO,EAAE,GAAG,QAAQ,SAAS,KAAK,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE;AAC1D;AAEA,eAAe,YAAY,MAAiD;AAC1E,QAAM,UAAU,KAAK;AACrB,QAAM,OAAO,KAAK;AAElB,QAAM,WAAW,MAAM,MAAM,GAAG,UAAU,eAAe,OAAO,IAAI;AAAA,IAClE,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,MAAM,KAAK,UAAU,EAAE,KAAK,CAAC;AAAA,EAC/B,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,OAAO,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACnD,UAAM,IAAI,MAAM,oBAAoB,SAAS,MAAM,KAAK,KAAK,UAAU,IAAI,CAAC,EAAE;AAAA,EAChF;AAEA,SAAO,SAAS,KAAK;AACvB;AAEA,eAAe,YAAY,MAAiD;AAC1E,QAAM,UAAU,KAAK;AAErB,QAAM,WAAW,MAAM,MAAM,GAAG,UAAU,eAAe,OAAO,WAAW;AAE3E,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,OAAO,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACnD,UAAM,IAAI,MAAM,oBAAoB,SAAS,MAAM,KAAK,KAAK,UAAU,IAAI,CAAC,EAAE;AAAA,EAChF;AAEA,SAAO,SAAS,KAAK;AACvB;","names":[]}
|