@lovable.dev/mcp-js 0.22.1 → 0.22.2-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/authorize-CumVyk7p.d.cts +27 -0
  2. package/dist/authorize-D6p4-9_D.d.ts +27 -0
  3. package/dist/base-DCe0kP79.d.cts +29 -0
  4. package/dist/base-DCe0kP79.d.ts +29 -0
  5. package/dist/cli/extract-manifest.cjs +116 -201
  6. package/dist/cli/extract-manifest.d.cts +1 -1
  7. package/dist/cli/extract-manifest.d.ts +1 -1
  8. package/dist/cli/extract-manifest.js +117 -156
  9. package/dist/content-D5LJAHyM.js +12 -0
  10. package/dist/content-NCYIGgOb.cjs +17 -0
  11. package/dist/context-BweeEcoA.cjs +56 -0
  12. package/dist/context-CIpPzN7P.js +51 -0
  13. package/dist/cors-CSDhBjFd.cjs +913 -0
  14. package/dist/cors-rWp_tbLZ.js +830 -0
  15. package/dist/forwarded--h4efJy-.js +43 -0
  16. package/dist/forwarded-Pi8Hs5Ps.cjs +48 -0
  17. package/dist/fs-errors-CWNzOV75.cjs +11 -0
  18. package/dist/fs-errors-PA2t1TIp.js +6 -0
  19. package/dist/index.cjs +129 -329
  20. package/dist/index.d.cts +26 -26
  21. package/dist/index.d.ts +26 -26
  22. package/dist/index.js +118 -177
  23. package/dist/{io-D4srzRKc.d.ts → io-CfSPxeBN.d.ts} +6 -4
  24. package/dist/io-DPYvBqET.d.cts +15 -0
  25. package/dist/list-tools-B4TTPEl1.d.cts +8 -0
  26. package/dist/list-tools-CFUX-uo-.cjs +57 -0
  27. package/dist/list-tools-DVJrjtmH.js +46 -0
  28. package/dist/list-tools-bh6-eqZM.d.ts +8 -0
  29. package/dist/logger-2OXtfiIW.js +141 -0
  30. package/dist/logger-BqPOa_E1.cjs +194 -0
  31. package/dist/mcp-BNcpj8o7.cjs +128 -0
  32. package/dist/mcp-Bx3bJHzH.js +123 -0
  33. package/dist/metadata-path-CAkNcfyY.js +12 -0
  34. package/dist/metadata-path-zd7NSNoa.cjs +17 -0
  35. package/dist/package-CgwD4Ywz.js +4 -0
  36. package/dist/package-DzstF8Ih.cjs +9 -0
  37. package/dist/paths-IS65L6TA.js +7 -0
  38. package/dist/paths-OP318a6c.cjs +18 -0
  39. package/dist/protocols/mcp/index.cjs +3 -750
  40. package/dist/protocols/mcp/index.d.cts +6 -7
  41. package/dist/protocols/mcp/index.d.ts +6 -7
  42. package/dist/protocols/mcp/index.js +2 -12
  43. package/dist/protocols/oauth-metadata.cjs +48 -539
  44. package/dist/protocols/oauth-metadata.d.cts +5 -6
  45. package/dist/protocols/oauth-metadata.d.ts +5 -6
  46. package/dist/protocols/oauth-metadata.js +52 -10
  47. package/dist/protocols/rest/index.cjs +5 -843
  48. package/dist/protocols/rest/index.d.cts +7 -10
  49. package/dist/protocols/rest/index.d.ts +7 -10
  50. package/dist/protocols/rest/index.js +3 -16
  51. package/dist/rest-BRshnow2.js +117 -0
  52. package/dist/rest-C4ZEGSIV.cjs +122 -0
  53. package/dist/stacks/supabase/index.cjs +76 -1318
  54. package/dist/stacks/supabase/index.d.cts +29 -30
  55. package/dist/stacks/supabase/index.d.ts +29 -30
  56. package/dist/stacks/supabase/index.js +73 -89
  57. package/dist/stacks/supabase/vite.cjs +258 -287
  58. package/dist/stacks/supabase/vite.d.cts +24 -24
  59. package/dist/stacks/supabase/vite.d.ts +24 -24
  60. package/dist/stacks/supabase/vite.js +252 -252
  61. package/dist/stacks/tanstack/index.cjs +42 -1272
  62. package/dist/stacks/tanstack/index.d.cts +8 -9
  63. package/dist/stacks/tanstack/index.d.ts +8 -9
  64. package/dist/stacks/tanstack/index.js +36 -41
  65. package/dist/stacks/tanstack/vite.cjs +223 -312
  66. package/dist/stacks/tanstack/vite.d.cts +80 -81
  67. package/dist/stacks/tanstack/vite.d.ts +80 -81
  68. package/dist/stacks/tanstack/vite.js +216 -282
  69. package/dist/types-BYdYYTjk.d.cts +321 -0
  70. package/dist/types-BYdYYTjk.d.ts +321 -0
  71. package/package.json +4 -4
  72. package/dist/authorize-BMeXd_Sh.d.ts +0 -25
  73. package/dist/base-CM-KCpp6.d.ts +0 -28
  74. package/dist/chunk-5HVSJCKE.js +0 -114
  75. package/dist/chunk-6DXGZZA4.js +0 -6
  76. package/dist/chunk-6QFZYYUV.js +0 -11
  77. package/dist/chunk-6SZOFKGH.js +0 -58
  78. package/dist/chunk-H37EB22A.js +0 -125
  79. package/dist/chunk-IFDWUM7L.js +0 -741
  80. package/dist/chunk-IXZIFYO6.js +0 -79
  81. package/dist/chunk-MA5H6PSF.js +0 -46
  82. package/dist/chunk-TJN33K5U.js +0 -141
  83. package/dist/chunk-UQK5UO6C.js +0 -26
  84. package/dist/chunk-XQWJN6DC.js +0 -14
  85. package/dist/chunk-Y3ZFPEQH.js +0 -8
  86. package/dist/chunk-ZQXSWTPU.js +0 -6
  87. package/dist/types-qqrmJ736.d.ts +0 -321
@@ -1,318 +1,289 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/stacks/supabase/vite.ts
21
- var vite_exports = {};
22
- __export(vite_exports, {
23
- default: () => vite_default,
24
- mcpPlugin: () => mcpPlugin
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
25
4
  });
26
- module.exports = __toCommonJS(vite_exports);
27
- var import_node_path2 = require("path");
28
- var import_vite = require("vite");
29
-
30
- // src/stacks/supabase/emit.ts
31
- var import_esbuild = require("esbuild");
32
- var import_node_fs = require("fs");
33
- var import_node_path = require("path");
34
-
35
- // package.json
36
- var version = "0.22.1";
37
-
38
- // src/core/fs-errors.ts
39
- function isFileMissing(err) {
40
- return typeof err === "object" && err !== null && "code" in err && err.code === "ENOENT";
41
- }
42
-
43
- // src/stacks/supabase/paths.ts
44
- var FUNCTIONS_MOUNT_PREFIX = "/functions/v1/";
45
- function assertFunctionName(value, label = "functionName") {
46
- if (!/^[a-zA-Z0-9_-]+$/.test(value)) {
47
- throw new Error(
48
- `@lovable.dev/mcp-js: ${label} must be a single path segment matching [A-Za-z0-9_-], got ${JSON.stringify(value)}`
49
- );
50
- }
51
- }
52
-
53
- // src/stacks/supabase/emit.ts
54
- var DEFAULT_MCP_ENTRY = "src/lib/mcp/index.ts";
55
- var DEFAULT_FUNCTIONS_DIR = "supabase/functions";
56
- var DEFAULT_FUNCTION_NAME = "mcp";
57
- var GENERATED_BANNER = "// AUTO-GENERATED by @lovable.dev/mcp-js \u2014 do not edit. Regenerated by the Vite plugin.\n// To take ownership, delete this banner line; the plugin then leaves the file alone.";
58
- var GENERATED_JSON_MARKER_KEY = "_lovableMcpGenerated";
5
+ const require_package = require("../../package-DzstF8Ih.cjs");
6
+ const require_fs_errors = require("../../fs-errors-CWNzOV75.cjs");
7
+ const require_paths = require("../../paths-OP318a6c.cjs");
8
+ let node_fs = require("node:fs");
9
+ let node_path = require("node:path");
10
+ let vite = require("vite");
11
+ let esbuild = require("esbuild");
12
+ const GENERATED_BANNER = "// AUTO-GENERATED by @lovable.dev/mcp-js — do not edit. Regenerated by the Vite plugin.\n// To take ownership, delete this banner line; the plugin then leaves the file alone.";
13
+ const GENERATED_JSON_MARKER_KEY = "_lovableMcpGenerated";
59
14
  function fileExists(path) {
60
- try {
61
- (0, import_node_fs.lstatSync)(path);
62
- return true;
63
- } catch (err) {
64
- if (isFileMissing(err))
65
- return false;
66
- throw err;
67
- }
15
+ try {
16
+ (0, node_fs.lstatSync)(path);
17
+ return true;
18
+ } catch (err) {
19
+ if (require_fs_errors.isFileMissing(err)) return false;
20
+ throw err;
21
+ }
68
22
  }
69
23
  function hasGeneratedBanner(content) {
70
- return content.replace(/\r\n/g, "\n").startsWith(GENERATED_BANNER);
24
+ return content.replace(/\r\n/g, "\n").startsWith(GENERATED_BANNER);
71
25
  }
72
26
  function hasGeneratedJsonMarker(content) {
73
- try {
74
- const parsed = JSON.parse(content);
75
- return typeof parsed === "object" && parsed !== null && GENERATED_JSON_MARKER_KEY in parsed;
76
- } catch {
77
- return false;
78
- }
27
+ try {
28
+ const parsed = JSON.parse(content);
29
+ return typeof parsed === "object" && parsed !== null && GENERATED_JSON_MARKER_KEY in parsed;
30
+ } catch {
31
+ return false;
32
+ }
79
33
  }
80
34
  function writeIfChanged(file, content, ownershipCheck) {
81
- let existing;
82
- try {
83
- existing = (0, import_node_fs.readFileSync)(file, "utf8");
84
- } catch (err) {
85
- if (!isFileMissing(err))
86
- throw err;
87
- }
88
- if (existing !== void 0) {
89
- if (!ownershipCheck(existing)) {
90
- throw new Error(
91
- `@lovable.dev/mcp-js: refusing to overwrite user-authored file at ${file}. Delete it or move it first.`
92
- );
93
- }
94
- if (existing === content)
95
- return false;
96
- }
97
- (0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(file), { recursive: true });
98
- (0, import_node_fs.writeFileSync)(file, content, "utf8");
99
- return true;
35
+ let existing;
36
+ try {
37
+ existing = (0, node_fs.readFileSync)(file, "utf8");
38
+ } catch (err) {
39
+ if (!require_fs_errors.isFileMissing(err)) throw err;
40
+ }
41
+ if (existing !== void 0) {
42
+ if (!ownershipCheck(existing)) throw new Error(`@lovable.dev/mcp-js: refusing to overwrite user-authored file at ${file}. Delete it or move it first.`);
43
+ if (existing === content) return false;
44
+ }
45
+ (0, node_fs.mkdirSync)((0, node_path.dirname)(file), { recursive: true });
46
+ (0, node_fs.writeFileSync)(file, content, "utf8");
47
+ return true;
100
48
  }
101
49
  function readProjectDependencyVersions(projectRoot) {
102
- try {
103
- const pkg = JSON.parse((0, import_node_fs.readFileSync)((0, import_node_path.join)(projectRoot, "package.json"), "utf8"));
104
- return { ...pkg.peerDependencies, ...pkg.devDependencies, ...pkg.dependencies };
105
- } catch {
106
- return {};
107
- }
50
+ try {
51
+ const pkg = JSON.parse((0, node_fs.readFileSync)((0, node_path.join)(projectRoot, "package.json"), "utf8"));
52
+ return {
53
+ ...pkg.peerDependencies,
54
+ ...pkg.devDependencies,
55
+ ...pkg.dependencies
56
+ };
57
+ } catch {
58
+ return {};
59
+ }
108
60
  }
109
61
  function npmSpecifierFor(bare, versions) {
110
- const pkg = bare.startsWith("@") ? bare.split("/").slice(0, 2).join("/") : bare.split("/")[0];
111
- const subpath = bare.slice(pkg.length);
112
- if (pkg === "@lovable.dev/mcp-js")
113
- return `npm:${pkg}@${version}${subpath}`;
114
- const range = versions[pkg];
115
- const version2 = range && /^[\dv^~>=]|^latest$/.test(range) ? range : void 0;
116
- return version2 ? `npm:${pkg}@${version2}${subpath}` : `npm:${pkg}${subpath}`;
62
+ const pkg = bare.startsWith("@") ? bare.split("/").slice(0, 2).join("/") : bare.split("/")[0];
63
+ const subpath = bare.slice(pkg.length);
64
+ if (pkg === "@lovable.dev/mcp-js") return `npm:${pkg}@${require_package.version}${subpath}`;
65
+ const range = versions[pkg];
66
+ const version$1 = range && /^[\dv^~>=]|^latest$/.test(range) ? range : void 0;
67
+ return version$1 ? `npm:${pkg}@${version$1}${subpath}` : `npm:${pkg}${subpath}`;
117
68
  }
118
69
  function externalizeBareAsNpm(versions) {
119
- return {
120
- name: "lovable-mcp-externalize-bare-as-npm",
121
- setup(pluginBuild) {
122
- pluginBuild.onResolve({ filter: /.*/ }, (args) => {
123
- const p = args.path;
124
- if (p.startsWith(".") || p.startsWith("/"))
125
- return null;
126
- if (/^(npm|node|jsr|https?|data):/.test(p))
127
- return { path: p, external: true };
128
- return { path: npmSpecifierFor(p, versions), external: true };
129
- });
130
- }
131
- };
70
+ return {
71
+ name: "lovable-mcp-externalize-bare-as-npm",
72
+ setup(pluginBuild) {
73
+ pluginBuild.onResolve({ filter: /.*/ }, (args) => {
74
+ const p = args.path;
75
+ if (p.startsWith(".") || p.startsWith("/")) return null;
76
+ if (/^(npm|node|jsr|https?|data):/.test(p)) return {
77
+ path: p,
78
+ external: true
79
+ };
80
+ return {
81
+ path: npmSpecifierFor(p, versions),
82
+ external: true
83
+ };
84
+ });
85
+ }
86
+ };
132
87
  }
133
88
  function importMetaEnvDefines(inlineEnv) {
134
- const env = inlineEnv ?? {};
135
- const defines = { "import.meta.env": JSON.stringify(env) };
136
- for (const [key, value] of Object.entries(env)) {
137
- if (/^[A-Za-z_$][\w$]*$/.test(key))
138
- defines[`import.meta.env.${key}`] = JSON.stringify(value);
139
- }
140
- return defines;
89
+ const env = inlineEnv ?? {};
90
+ const defines = { "import.meta.env": JSON.stringify(env) };
91
+ for (const [key, value] of Object.entries(env)) if (/^[A-Za-z_$][\w$]*$/.test(key)) defines[`import.meta.env.${key}`] = JSON.stringify(value);
92
+ return defines;
141
93
  }
142
94
  async function bundleFunctionEntry(projectRoot, mcpEntryAbs, functionName, inlineEnv) {
143
- const versions = readProjectDependencyVersions(projectRoot);
144
- const wrapper = `import mcp from ${JSON.stringify(mcpEntryAbs)};
145
- import { createSupabaseHandler } from "@lovable.dev/mcp-js/stacks/supabase";
146
- Deno.serve(createSupabaseHandler(mcp, { functionName: ${JSON.stringify(functionName)} }));
147
- `;
148
- const result = await (0, import_esbuild.build)({
149
- stdin: { contents: wrapper, resolveDir: projectRoot, sourcefile: "lovable-mcp-supabase-entry.ts", loader: "ts" },
150
- bundle: true,
151
- write: false,
152
- metafile: true,
153
- format: "esm",
154
- platform: "neutral",
155
- target: "esnext",
156
- absWorkingDir: projectRoot,
157
- logLevel: "silent",
158
- define: importMetaEnvDefines(inlineEnv),
159
- plugins: [externalizeBareAsNpm(versions)]
160
- });
161
- const out = result.outputFiles[0]?.text ?? "";
162
- const inputs = Object.keys(result.metafile?.inputs ?? {}).filter((p) => !p.startsWith("<") && !p.startsWith("npm:")).map((p) => (0, import_node_path.resolve)(projectRoot, p));
163
- const code = `${GENERATED_BANNER}
164
- // supabase function: ${functionName}
165
- // Bundled from ${(0, import_node_path.relative)(projectRoot, mcpEntryAbs).split(import_node_path.sep).join("/")} by @lovable.dev/mcp-js.
166
- ` + out;
167
- return { code, inputs };
95
+ const versions = readProjectDependencyVersions(projectRoot);
96
+ const result = await (0, esbuild.build)({
97
+ stdin: {
98
+ contents: `import mcp from ${JSON.stringify(mcpEntryAbs)};\nimport { createSupabaseHandler } from "@lovable.dev/mcp-js/stacks/supabase";\nDeno.serve(createSupabaseHandler(mcp, { functionName: ${JSON.stringify(functionName)} }));\n`,
99
+ resolveDir: projectRoot,
100
+ sourcefile: "lovable-mcp-supabase-entry.ts",
101
+ loader: "ts"
102
+ },
103
+ bundle: true,
104
+ write: false,
105
+ metafile: true,
106
+ format: "esm",
107
+ platform: "neutral",
108
+ target: "esnext",
109
+ absWorkingDir: projectRoot,
110
+ logLevel: "silent",
111
+ define: importMetaEnvDefines(inlineEnv),
112
+ plugins: [externalizeBareAsNpm(versions)]
113
+ });
114
+ const out = result.outputFiles[0]?.text ?? "";
115
+ const inputs = Object.keys(result.metafile?.inputs ?? {}).filter((p) => !p.startsWith("<") && !p.startsWith("npm:")).map((p) => (0, node_path.resolve)(projectRoot, p));
116
+ return {
117
+ code: `${GENERATED_BANNER}\n// supabase function: ${functionName}\n// Bundled from ${(0, node_path.relative)(projectRoot, mcpEntryAbs).split(node_path.sep).join("/")} by @lovable.dev/mcp-js.\n` + out,
118
+ inputs
119
+ };
168
120
  }
169
121
  function resolvePaths(options) {
170
- const projectRoot = (0, import_node_path.resolve)(options.projectRoot);
171
- const mcpEntry = options.mcpEntry ?? DEFAULT_MCP_ENTRY;
172
- const functionsDir = options.functionsDir ?? DEFAULT_FUNCTIONS_DIR;
173
- const functionName = options.functionName ?? DEFAULT_FUNCTION_NAME;
174
- assertFunctionName(functionName);
175
- const functionDir = (0, import_node_path.resolve)(projectRoot, functionsDir, functionName);
176
- if (functionDir !== projectRoot && !functionDir.startsWith(projectRoot + import_node_path.sep)) {
177
- throw new Error(
178
- `@lovable.dev/mcp-js: functionsDir must resolve within the project root, got ${JSON.stringify(functionsDir)}`
179
- );
180
- }
181
- return {
182
- functionDir,
183
- functionEntry: (0, import_node_path.join)(functionDir, "index.ts"),
184
- mcpEntryAbs: (0, import_node_path.resolve)(projectRoot, mcpEntry)
185
- };
122
+ const projectRoot = (0, node_path.resolve)(options.projectRoot);
123
+ const mcpEntry = options.mcpEntry ?? "src/lib/mcp/index.ts";
124
+ const functionsDir = options.functionsDir ?? "supabase/functions";
125
+ const functionName = options.functionName ?? "mcp";
126
+ require_paths.assertFunctionName(functionName);
127
+ const functionDir = (0, node_path.resolve)(projectRoot, functionsDir, functionName);
128
+ if (functionDir !== projectRoot && !functionDir.startsWith(projectRoot + node_path.sep)) throw new Error(`@lovable.dev/mcp-js: functionsDir must resolve within the project root, got ${JSON.stringify(functionsDir)}`);
129
+ return {
130
+ functionDir,
131
+ functionEntry: (0, node_path.join)(functionDir, "index.ts"),
132
+ mcpEntryAbs: (0, node_path.resolve)(projectRoot, mcpEntry)
133
+ };
186
134
  }
135
+ /**
136
+ * Sync the Supabase function for an MCP entry. Bundles the entry (and its local
137
+ * import graph) into a self-contained `supabase/functions/<name>/index.ts` with
138
+ * direct `npm:` specifiers, and removes the SDK-owned files when the entry
139
+ * disappears so deleting it leaves no stale boilerplate behind. No `deno.json`
140
+ * is emitted — the bundle carries no bare imports, so an import map is moot, and
141
+ * a legacy generated `deno.json` is cleaned up below.
142
+ */
187
143
  async function syncSupabaseFunction(options) {
188
- const projectRoot = (0, import_node_path.resolve)(options.projectRoot);
189
- const paths = resolvePaths(options);
190
- const functionName = options.functionName ?? DEFAULT_FUNCTION_NAME;
191
- const written = [];
192
- const removed = [];
193
- if (!fileExists(paths.mcpEntryAbs)) {
194
- cleanupOrphans(paths.functionDir, /* @__PURE__ */ new Set(), removed);
195
- return { written, removed, inputs: [] };
196
- }
197
- const { code, inputs } = await bundleFunctionEntry(projectRoot, paths.mcpEntryAbs, functionName, options.inlineEnv);
198
- if (writeIfChanged(paths.functionEntry, code, hasGeneratedBanner)) {
199
- written.push(paths.functionEntry);
200
- }
201
- cleanupOrphans(paths.functionDir, /* @__PURE__ */ new Set([paths.functionEntry]), removed);
202
- return { written, removed, inputs };
144
+ const projectRoot = (0, node_path.resolve)(options.projectRoot);
145
+ const paths = resolvePaths(options);
146
+ const functionName = options.functionName ?? "mcp";
147
+ const written = [];
148
+ const removed = [];
149
+ if (!fileExists(paths.mcpEntryAbs)) {
150
+ cleanupOrphans(paths.functionDir, /* @__PURE__ */ new Set(), removed);
151
+ return {
152
+ written,
153
+ removed,
154
+ inputs: []
155
+ };
156
+ }
157
+ const { code, inputs } = await bundleFunctionEntry(projectRoot, paths.mcpEntryAbs, functionName, options.inlineEnv);
158
+ if (writeIfChanged(paths.functionEntry, code, hasGeneratedBanner)) written.push(paths.functionEntry);
159
+ cleanupOrphans(paths.functionDir, /* @__PURE__ */ new Set([paths.functionEntry]), removed);
160
+ return {
161
+ written,
162
+ removed,
163
+ inputs
164
+ };
203
165
  }
204
166
  function cleanupOrphans(functionDir, expected, removed) {
205
- let entries;
206
- try {
207
- entries = (0, import_node_fs.readdirSync)(functionDir);
208
- } catch (err) {
209
- if (isFileMissing(err))
210
- return;
211
- throw err;
212
- }
213
- for (const entry of entries) {
214
- const full = (0, import_node_path.join)(functionDir, entry);
215
- if (expected.has(full))
216
- continue;
217
- let content;
218
- try {
219
- content = (0, import_node_fs.readFileSync)(full, "utf8");
220
- } catch (err) {
221
- if (isFileMissing(err) || err.code === "EISDIR")
222
- continue;
223
- throw err;
224
- }
225
- if (hasGeneratedBanner(content) || hasGeneratedJsonMarker(content)) {
226
- try {
227
- (0, import_node_fs.unlinkSync)(full);
228
- removed.push(full);
229
- } catch (err) {
230
- if (!isFileMissing(err))
231
- throw err;
232
- }
233
- }
234
- }
167
+ let entries;
168
+ try {
169
+ entries = (0, node_fs.readdirSync)(functionDir);
170
+ } catch (err) {
171
+ if (require_fs_errors.isFileMissing(err)) return;
172
+ throw err;
173
+ }
174
+ for (const entry of entries) {
175
+ const full = (0, node_path.join)(functionDir, entry);
176
+ if (expected.has(full)) continue;
177
+ let content;
178
+ try {
179
+ content = (0, node_fs.readFileSync)(full, "utf8");
180
+ } catch (err) {
181
+ if (require_fs_errors.isFileMissing(err) || err.code === "EISDIR") continue;
182
+ throw err;
183
+ }
184
+ if (hasGeneratedBanner(content) || hasGeneratedJsonMarker(content)) try {
185
+ (0, node_fs.unlinkSync)(full);
186
+ removed.push(full);
187
+ } catch (err) {
188
+ if (!require_fs_errors.isFileMissing(err)) throw err;
189
+ }
190
+ }
235
191
  }
236
-
237
- // src/stacks/supabase/vite.ts
192
+ //#endregion
193
+ //#region src/stacks/supabase/vite.ts
238
194
  function normalizePath(p) {
239
- return p.split(import_node_path2.sep).join("/");
195
+ return p.split(node_path.sep).join("/");
240
196
  }
241
197
  function productionImportMetaEnv(config) {
242
- return {
243
- ...(0, import_vite.loadEnv)("production", config.envDir, config.envPrefix),
244
- MODE: "production",
245
- BASE_URL: config.base ?? "/",
246
- DEV: false,
247
- PROD: true,
248
- SSR: false
249
- };
198
+ return {
199
+ ...(0, vite.loadEnv)("production", config.envDir, config.envPrefix),
200
+ MODE: "production",
201
+ BASE_URL: config.base ?? "/",
202
+ DEV: false,
203
+ PROD: true,
204
+ SSR: false
205
+ };
250
206
  }
207
+ /**
208
+ * Vite plugin that emits the Supabase Edge Function entry (and its
209
+ * `deno.json` import map) for an `@lovable.dev/mcp-js` MCP server.
210
+ *
211
+ * Place this in your `vite.config.ts` plugins array. It uses Vite as the
212
+ * trigger for codegen even though the emitted output (Deno function) is
213
+ * not part of the Vite bundle — Classic Lovable stacks already run Vite
214
+ * for the frontend, so it's the natural authoring surface.
215
+ *
216
+ * Lifecycle, mirroring `stacks/tanstack/vite`:
217
+ * - `configResolved` finalizes the project root and runs the first emit.
218
+ * - `buildStart` re-runs the emit so a `vite build` always picks up the
219
+ * latest source.
220
+ * - `configureServer` re-emits when the entry or any bundled source file
221
+ * (tools, local helpers) changes during `vite dev`, so editing a tool
222
+ * regenerates the function without restarting the server.
223
+ *
224
+ * The entry and its local import graph are bundled by esbuild into one
225
+ * self-contained Deno module (deps left as `npm:` specifiers), so the deployed
226
+ * function carries no cross-project imports the Supabase deploy can't upload.
227
+ * Idempotent: `syncSupabaseFunction` writes only on byte-level change and
228
+ * cleans up SDK-owned files when the entry is deleted.
229
+ */
251
230
  function mcpPlugin(options = {}) {
252
- const mcpEntryOption = options.mcpEntry ?? DEFAULT_MCP_ENTRY;
253
- const functionsDirOption = options.functionsDir ?? DEFAULT_FUNCTIONS_DIR;
254
- const functionName = options.functionName ?? DEFAULT_FUNCTION_NAME;
255
- const urlPath = `${FUNCTIONS_MOUNT_PREFIX}${functionName}`;
256
- let projectRoot = process.cwd();
257
- let mcpEntryAbs = (0, import_node_path2.resolve)(projectRoot, mcpEntryOption);
258
- let inlineEnv = {};
259
- let watchedInputs = /* @__PURE__ */ new Set();
260
- const regenerate = async () => {
261
- const { inputs } = await syncSupabaseFunction({
262
- projectRoot,
263
- mcpEntry: mcpEntryOption,
264
- functionsDir: functionsDirOption,
265
- functionName,
266
- inlineEnv
267
- });
268
- watchedInputs = new Set(inputs.map(normalizePath));
269
- };
270
- return {
271
- name: "@lovable.dev/mcp-js/supabase",
272
- // The extract CLI reads these back via `resolveConfig().plugins`. Getter
273
- // for `mcpEntry` because the absolute path is finalized in `configResolved`;
274
- // `urlPath` is config-time-final so it's a plain field.
275
- api: {
276
- get mcpEntry() {
277
- return mcpEntryAbs;
278
- },
279
- urlPath
280
- },
281
- async configResolved(config) {
282
- projectRoot = config.root;
283
- mcpEntryAbs = (0, import_node_path2.resolve)(projectRoot, mcpEntryOption);
284
- inlineEnv = productionImportMetaEnv(config);
285
- await regenerate();
286
- },
287
- configureServer(server) {
288
- const onChange = (file) => {
289
- const norm = normalizePath(file);
290
- if (norm !== normalizePath(mcpEntryAbs) && !watchedInputs.has(norm))
291
- return;
292
- regenerate().catch((err) => {
293
- const message = `[@lovable.dev/mcp-js] failed to regenerate the Supabase function: ${err instanceof Error ? err.message : String(err)}`;
294
- if (server.config?.logger?.error)
295
- server.config.logger.error(message);
296
- else
297
- console.error(message);
298
- });
299
- };
300
- server.watcher.on("add", onChange);
301
- server.watcher.on("change", onChange);
302
- server.watcher.on("unlink", onChange);
303
- server.watcher.once("close", () => {
304
- server.watcher.off("add", onChange);
305
- server.watcher.off("change", onChange);
306
- server.watcher.off("unlink", onChange);
307
- });
308
- },
309
- async buildStart() {
310
- await regenerate();
311
- }
312
- };
231
+ const mcpEntryOption = options.mcpEntry ?? "src/lib/mcp/index.ts";
232
+ const functionsDirOption = options.functionsDir ?? "supabase/functions";
233
+ const functionName = options.functionName ?? "mcp";
234
+ const urlPath = `${require_paths.FUNCTIONS_MOUNT_PREFIX}${functionName}`;
235
+ let projectRoot = process.cwd();
236
+ let mcpEntryAbs = (0, node_path.resolve)(projectRoot, mcpEntryOption);
237
+ let inlineEnv = {};
238
+ let watchedInputs = /* @__PURE__ */ new Set();
239
+ const regenerate = async () => {
240
+ const { inputs } = await syncSupabaseFunction({
241
+ projectRoot,
242
+ mcpEntry: mcpEntryOption,
243
+ functionsDir: functionsDirOption,
244
+ functionName,
245
+ inlineEnv
246
+ });
247
+ watchedInputs = new Set(inputs.map(normalizePath));
248
+ };
249
+ return {
250
+ name: "@lovable.dev/mcp-js/supabase",
251
+ api: {
252
+ get mcpEntry() {
253
+ return mcpEntryAbs;
254
+ },
255
+ urlPath
256
+ },
257
+ async configResolved(config) {
258
+ projectRoot = config.root;
259
+ mcpEntryAbs = (0, node_path.resolve)(projectRoot, mcpEntryOption);
260
+ inlineEnv = productionImportMetaEnv(config);
261
+ await regenerate();
262
+ },
263
+ configureServer(server) {
264
+ const onChange = (file) => {
265
+ const norm = normalizePath(file);
266
+ if (norm !== normalizePath(mcpEntryAbs) && !watchedInputs.has(norm)) return;
267
+ regenerate().catch((err) => {
268
+ const message = `[@lovable.dev/mcp-js] failed to regenerate the Supabase function: ${err instanceof Error ? err.message : String(err)}`;
269
+ if (server.config?.logger?.error) server.config.logger.error(message);
270
+ else console.error(message);
271
+ });
272
+ };
273
+ server.watcher.on("add", onChange);
274
+ server.watcher.on("change", onChange);
275
+ server.watcher.on("unlink", onChange);
276
+ server.watcher.once("close", () => {
277
+ server.watcher.off("add", onChange);
278
+ server.watcher.off("change", onChange);
279
+ server.watcher.off("unlink", onChange);
280
+ });
281
+ },
282
+ async buildStart() {
283
+ await regenerate();
284
+ }
285
+ };
313
286
  }
314
- var vite_default = mcpPlugin;
315
- // Annotate the CommonJS export names for ESM import in node:
316
- 0 && (module.exports = {
317
- mcpPlugin
318
- });
287
+ //#endregion
288
+ exports.default = mcpPlugin;
289
+ exports.mcpPlugin = mcpPlugin;
@@ -1,26 +1,26 @@
1
- import { Plugin } from 'vite';
2
- export { M as McpPluginApi } from '../../io-D4srzRKc.js';
3
-
1
+ import { t as McpPluginApi } from "../../io-DPYvBqET.cjs";
2
+ import { Plugin } from "vite";
3
+ //#region src/stacks/supabase/vite.d.ts
4
4
  interface McpPluginOptions {
5
- /**
6
- * Path to the MCP entry file (default export = `defineMcp(...)` result),
7
- * relative to the project root.
8
- * @default "src/lib/mcp/index.ts"
9
- */
10
- mcpEntry?: string;
11
- /**
12
- * Directory holding Supabase function folders (one per function), relative
13
- * to the project root.
14
- * @default "supabase/functions"
15
- */
16
- functionsDir?: string;
17
- /**
18
- * Name of the function directory under `functionsDir`. Becomes the public
19
- * URL segment (`/functions/v1/<functionName>`) the dispatcher binds OAuth
20
- * metadata to via `resourcePath`.
21
- * @default "mcp"
22
- */
23
- functionName?: string;
5
+ /**
6
+ * Path to the MCP entry file (default export = `defineMcp(...)` result),
7
+ * relative to the project root.
8
+ * @default "src/lib/mcp/index.ts"
9
+ */
10
+ mcpEntry?: string;
11
+ /**
12
+ * Directory holding Supabase function folders (one per function), relative
13
+ * to the project root.
14
+ * @default "supabase/functions"
15
+ */
16
+ functionsDir?: string;
17
+ /**
18
+ * Name of the function directory under `functionsDir`. Becomes the public
19
+ * URL segment (`/functions/v1/<functionName>`) the dispatcher binds OAuth
20
+ * metadata to via `resourcePath`.
21
+ * @default "mcp"
22
+ */
23
+ functionName?: string;
24
24
  }
25
25
  /**
26
26
  * Vite plugin that emits the Supabase Edge Function entry (and its
@@ -46,5 +46,5 @@ interface McpPluginOptions {
46
46
  * cleans up SDK-owned files when the entry is deleted.
47
47
  */
48
48
  declare function mcpPlugin(options?: McpPluginOptions): Plugin;
49
-
50
- export { type McpPluginOptions, mcpPlugin as default, mcpPlugin };
49
+ //#endregion
50
+ export { type McpPluginApi, McpPluginOptions, mcpPlugin as default, mcpPlugin };