@vedangiitb/qwintly-core 1.4.3 → 1.4.5
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/tools/helpers/pageConfigJson.helpers.d.ts +3 -0
- package/dist/ai/tools/helpers/pageConfigJson.helpers.d.ts.map +1 -1
- package/dist/ai/tools/helpers/pageConfigJson.helpers.js +61 -0
- package/dist/ai/tools/helpers/pageConfigJson.helpers.js.map +1 -1
- package/dist/ai/tools/implementations/deleteElement.impl.js +2 -2
- package/dist/ai/tools/implementations/deleteElement.impl.js.map +1 -1
- package/dist/ai/tools/implementations/insertElement.impl.js +2 -2
- package/dist/ai/tools/implementations/insertElement.impl.js.map +1 -1
- package/dist/ai/tools/implementations/updateClassName.impl.js +2 -2
- package/dist/ai/tools/implementations/updateClassName.impl.js.map +1 -1
- package/dist/ai/tools/implementations/updateProps.impl.js +2 -2
- package/dist/ai/tools/implementations/updateProps.impl.js.map +1 -1
- package/dist/ai/tools/schemas/createNewRoute.schema.js +1 -1
- package/dist/ai/tools/schemas/createNewRoute.schema.js.map +1 -1
- package/dist/ai/tools/schemas/deleteElement.schema.js +1 -1
- package/dist/ai/tools/schemas/deleteElement.schema.js.map +1 -1
- package/dist/ai/tools/schemas/insertElement.schema.js +1 -1
- package/dist/ai/tools/schemas/insertElement.schema.js.map +1 -1
- package/dist/ai/tools/schemas/updateClassName.schema.js +1 -1
- package/dist/ai/tools/schemas/updateClassName.schema.js.map +1 -1
- package/dist/ai/tools/schemas/updateProps.schema.js +1 -1
- package/dist/ai/tools/schemas/updateProps.schema.js.map +1 -1
- package/dist/ai/tools/validators/builderElement.zod.js +2 -2
- package/dist/ai/tools/validators/builderElement.zod.js.map +1 -1
- package/dist/image/unsplash.service.js +1 -1
- package/dist/image/unsplash.service.js.map +1 -1
- package/dist/indexer/projectInfoIndex.d.ts.map +1 -1
- package/dist/indexer/projectInfoIndex.js +70 -203
- package/dist/indexer/projectInfoIndex.js.map +1 -1
- package/dist/tests/insertUpdate.impl.test.js +93 -0
- package/dist/tests/insertUpdate.impl.test.js.map +1 -1
- package/dist/tests/projectInfoIndex.test.d.ts +2 -0
- package/dist/tests/projectInfoIndex.test.d.ts.map +1 -0
- package/dist/tests/projectInfoIndex.test.js +75 -0
- package/dist/tests/projectInfoIndex.test.js.map +1 -0
- package/dist/tests/unsplash.service.test.d.ts +2 -0
- package/dist/tests/unsplash.service.test.d.ts.map +1 -0
- package/dist/tests/unsplash.service.test.js +94 -0
- package/dist/tests/unsplash.service.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BuilderElement } from "../../../types/elements.js";
|
|
2
|
+
import type { CoreFs } from "../implementations/workspaceDeps.js";
|
|
2
3
|
export type PageConfigJson = {
|
|
3
4
|
elements: BuilderElement[];
|
|
4
5
|
};
|
|
@@ -22,4 +23,6 @@ export declare const getAvailableRoutes: (deps: {
|
|
|
22
23
|
}>>;
|
|
23
24
|
};
|
|
24
25
|
}) => Promise<string[]>;
|
|
26
|
+
export declare const matchRoute: (physicalRoute: string, requestedRoute: string) => boolean;
|
|
27
|
+
export declare const resolvePageConfigJsonPath: (workspaceRoot: string, route: string, fs: CoreFs) => Promise<string>;
|
|
25
28
|
//# sourceMappingURL=pageConfigJson.helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageConfigJson.helpers.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/pageConfigJson.helpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"pageConfigJson.helpers.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/pageConfigJson.helpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAGjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAElE,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,OAAO,MAAM,KAAG,MAAM,EAQ5D,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,YAM5C,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,eAAe,MAAM,EAAE,OAAO,MAAM,WAOzE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,KAAG,cAkBrD,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,QAAQ,cAAc,WACO,CAAC;AAEtE,eAAO,MAAM,iBAAiB,GAAI,UAAU,cAAc,EAAE,gBAa3D,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,UAAU,cAAc,EAAE,EAC1B,aAAa,GAAG,CAAC,MAAM,CAAC,SA0BzB,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,UAAU,cAAc,EAAE,EAC1B,WAAW,MAAM,KAChB,cAAc,GAAG,IAkBnB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,UAAU,cAAc,EAAE,EAC1B,IAAI,MAAM,KACT,OAkBF,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,UAAU,MAAM,EAAE,SAAS,MAAM,kBAkDtE,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,MAAM;IAC7C,aAAa,EAAE,MAAM,CAAC;IACtB,EAAE,EAAE;QACF,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC;YAClD,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,OAAO,CAAC;YAC3B,MAAM,EAAE,MAAM,OAAO,CAAC;SACvB,CAAC,CAAC,CAAC;KACL,CAAC;CACH,KAAG,OAAO,CAAC,MAAM,EAAE,CAoCnB,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,eAAe,MAAM,EAAE,gBAAgB,MAAM,KAAG,OA+C1E,CAAC;AAEF,eAAO,MAAM,yBAAyB,GACpC,eAAe,MAAM,EACrB,OAAO,MAAM,EACb,IAAI,MAAM,KACT,OAAO,CAAC,MAAM,CAsBhB,CAAC"}
|
|
@@ -214,4 +214,65 @@ export const getAvailableRoutes = async (deps) => {
|
|
|
214
214
|
await scan(appDir);
|
|
215
215
|
return routes.sort();
|
|
216
216
|
};
|
|
217
|
+
export const matchRoute = (physicalRoute, requestedRoute) => {
|
|
218
|
+
const physSegs = normalizeRouteSegments(physicalRoute);
|
|
219
|
+
const reqSegs = normalizeRouteSegments(requestedRoute);
|
|
220
|
+
let pIdx = 0;
|
|
221
|
+
let rIdx = 0;
|
|
222
|
+
while (pIdx < physSegs.length && rIdx < reqSegs.length) {
|
|
223
|
+
const phys = physSegs[pIdx];
|
|
224
|
+
const req = reqSegs[rIdx];
|
|
225
|
+
// Catch-all (e.g. [...slug] or [[...slug]])
|
|
226
|
+
if (phys.startsWith("[") && phys.endsWith("]") && phys.includes("...")) {
|
|
227
|
+
return true;
|
|
228
|
+
}
|
|
229
|
+
// Regular dynamic segment (e.g. [id])
|
|
230
|
+
if (phys.startsWith("[") && phys.endsWith("]")) {
|
|
231
|
+
pIdx++;
|
|
232
|
+
rIdx++;
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
// Exact match
|
|
236
|
+
if (phys.toLowerCase() === req.toLowerCase()) {
|
|
237
|
+
pIdx++;
|
|
238
|
+
rIdx++;
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
// Handle case where we ran out of requested segments but have remaining physical segments
|
|
244
|
+
// e.g. physical is /blog/[[...slug]] (optional catch-all) and request is /blog
|
|
245
|
+
if (rIdx === reqSegs.length && pIdx < physSegs.length) {
|
|
246
|
+
// All remaining physical segments must be optional catch-alls (e.g., [[...slug]])
|
|
247
|
+
for (let i = pIdx; i < physSegs.length; i++) {
|
|
248
|
+
const phys = physSegs[i];
|
|
249
|
+
if (!(phys.startsWith("[[") && phys.endsWith("]]") && phys.includes("..."))) {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return true;
|
|
254
|
+
}
|
|
255
|
+
return pIdx === physSegs.length && rIdx === reqSegs.length;
|
|
256
|
+
};
|
|
257
|
+
export const resolvePageConfigJsonPath = async (workspaceRoot, route, fs) => {
|
|
258
|
+
// 1. Try exact match first
|
|
259
|
+
const exactPath = getPageConfigJsonPath(workspaceRoot, route);
|
|
260
|
+
try {
|
|
261
|
+
await fs.stat(exactPath);
|
|
262
|
+
return exactPath;
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
// Exact file does not exist, let's resolve dynamically
|
|
266
|
+
}
|
|
267
|
+
// 2. Fetch all available routes in the workspace
|
|
268
|
+
const available = await getAvailableRoutes({ workspaceRoot, fs });
|
|
269
|
+
// 3. Find first matching route
|
|
270
|
+
for (const physRoute of available) {
|
|
271
|
+
if (matchRoute(physRoute, route)) {
|
|
272
|
+
return getPageConfigJsonPath(workspaceRoot, physRoute);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
// 4. Fallback: if no match, just return the exact path
|
|
276
|
+
return exactPath;
|
|
277
|
+
};
|
|
217
278
|
//# sourceMappingURL=pageConfigJson.helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageConfigJson.helpers.js","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/pageConfigJson.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { BuilderElement } from \"../../../types/elements.js\";\nimport { createElementId } from \"./elementid.helpers.js\";\nimport { toWorkspacePath } from \"./fileSystem.helpers.js\";\n\nexport type PageConfigJson = {\n elements: BuilderElement[];\n};\n\nexport const normalizeRouteSegments = (route: string): string[] => {\n const raw = String(route ?? \"\").trim();\n if (!raw || raw === \"/\") return [];\n return raw\n .replace(/\\\\/g, \"/\")\n .split(\"/\")\n .map((s) => s.trim())\n .filter(Boolean);\n};\n\nexport const isSafeSegment = (segment: string) => {\n const s = String(segment ?? \"\").trim();\n if (!s) return false;\n if (s === \".\" || s === \"..\") return false;\n if (s.includes(\"/\") || s.includes(\"\\\\\")) return false;\n return true;\n};\n\nexport const getPageConfigJsonPath = (workspaceRoot: string, route: string) => {\n const segments = normalizeRouteSegments(route);\n if (segments.some((s) => !isSafeSegment(s))) {\n throw new Error(\"invalid route\");\n }\n const rel = path.posix.join(\"app\", ...segments, \"pageConfig.json\");\n return toWorkspacePath(workspaceRoot, rel);\n};\n\nexport const parsePageConfigJson = (content: string): PageConfigJson => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(String(content ?? \"\"));\n } catch {\n throw new Error(\"pageConfig.json is not valid JSON\");\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"pageConfig.json must be an object\");\n }\n\n const elements = (parsed as any).elements;\n if (!Array.isArray(elements)) {\n throw new Error('pageConfig.json must contain \"elements\" array');\n }\n\n return { elements: elements as BuilderElement[] };\n};\n\nexport const stringifyPageConfigJson = (config: PageConfigJson) =>\n JSON.stringify({ elements: config.elements ?? [] }, null, 2) + \"\\n\";\n\nexport const extractAllIdsDeep = (elements: BuilderElement[]) => {\n const ids = new Set<string>();\n const walk = (arr: BuilderElement[]) => {\n for (const el of arr) {\n if (!el || typeof el !== \"object\") continue;\n const id = (el as any).id;\n if (typeof id === \"string\" && id.trim()) ids.add(id.trim());\n const children = (el as any).children;\n if (Array.isArray(children)) walk(children as BuilderElement[]);\n }\n };\n walk(Array.isArray(elements) ? elements : []);\n return ids;\n};\n\nexport const ensureElementIds = (\n elements: BuilderElement[],\n existingIds: Set<string>,\n) => {\n const seen = new Set<string>();\n const walk = (arr: BuilderElement[]) => {\n for (const el of arr) {\n if (!el || typeof el !== \"object\") continue;\n\n const anyEl = el as any;\n const currentId = typeof anyEl.id === \"string\" ? anyEl.id.trim() : \"\";\n if (!currentId || seen.has(currentId)) {\n const newId = createElementId(existingIds);\n anyEl.id = newId;\n existingIds.add(newId);\n seen.add(newId);\n } else {\n anyEl.id = currentId;\n existingIds.add(currentId);\n seen.add(currentId);\n }\n\n if (Array.isArray(anyEl.children)) {\n walk(anyEl.children as BuilderElement[]);\n }\n }\n };\n walk(elements);\n};\n\nexport const findElementById = (\n elements: BuilderElement[],\n elementId: string,\n): BuilderElement | null => {\n const id = String(elementId ?? \"\").trim();\n if (!id) return null;\n\n const walk = (arr: BuilderElement[]): BuilderElement | null => {\n for (const el of arr) {\n if (!el || typeof el !== \"object\") continue;\n if ((el as any).id === id) return el;\n const children = (el as any).children;\n if (Array.isArray(children)) {\n const found = walk(children as BuilderElement[]);\n if (found) return found;\n }\n }\n return null;\n };\n\n return walk(elements);\n};\n\nexport const deleteElementById = (\n elements: BuilderElement[],\n id: string,\n): boolean => {\n const target = String(id ?? \"\").trim();\n if (!target) return false;\n\n let deleted = false;\n const walk = (arr: BuilderElement[]) => {\n for (let idx = arr.length - 1; idx >= 0; idx--) {\n const el = arr[idx] as any;\n if (el?.id === target) {\n arr.splice(idx, 1);\n deleted = true;\n continue;\n }\n if (Array.isArray(el?.children)) walk(el.children as BuilderElement[]);\n }\n };\n walk(elements);\n return deleted;\n};\n\nexport const writeFileAtomic = async (filePath: string, content: string) => {\n const dir = path.dirname(filePath);\n const base = path.basename(filePath);\n const tmp = path.join(\n dir,\n `.qwintly_tmp_${base}_${Date.now()}_${Math.random().toString(16).slice(2)}`,\n );\n const bak = path.join(\n dir,\n `.qwintly_bak_${base}_${Date.now()}_${Math.random().toString(16).slice(2)}`,\n );\n\n try {\n await fs.mkdir(dir, { recursive: true });\n await fs.writeFile(tmp, content ?? \"\", \"utf-8\");\n\n // Windows rename doesn't overwrite; do a 2-step swap.\n try {\n await fs.rename(filePath, bak);\n await fs.rename(tmp, filePath);\n await fs.rm(bak, { force: true });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code === \"ENOENT\") {\n // No previous file; just put the temp file in place.\n await fs.rename(tmp, filePath);\n } else {\n throw err;\n }\n }\n } catch (err) {\n // rollback best-effort\n try {\n await fs.rm(tmp, { force: true });\n } catch {\n // ignore\n }\n try {\n await fs.stat(bak);\n try {\n await fs.rm(filePath, { force: true });\n } catch {\n // ignore\n }\n await fs.rename(bak, filePath);\n } catch {\n // ignore\n }\n throw err;\n }\n};\n\nexport const getAvailableRoutes = async (deps: {\n workspaceRoot: string;\n fs: {\n safeReadDir: (absoluteDir: string) => Promise<Array<{\n name: string;\n isDirectory: () => boolean;\n isFile: () => boolean;\n }>>;\n };\n}): Promise<string[]> => {\n const { workspaceRoot, fs } = deps;\n const appDir = toWorkspacePath(workspaceRoot, \"app\");\n const routes: string[] = [];\n\n const scan = async (dirPath: string) => {\n let entries;\n try {\n entries = await fs.safeReadDir(dirPath);\n } catch {\n return;\n }\n\n let hasPageConfig = false;\n for (const entry of entries) {\n if (entry.isFile() && entry.name === \"pageConfig.json\") {\n hasPageConfig = true;\n break;\n }\n }\n\n if (hasPageConfig) {\n const rel = path.relative(appDir, dirPath);\n const routeStr = \"/\" + rel.replace(/\\\\/g, \"/\");\n routes.push(routeStr === \"/\" ? \"/\" : routeStr.replace(/\\/$/, \"\"));\n }\n\n for (const entry of entries) {\n if (entry.isDirectory() && entry.name !== \"node_modules\" && !entry.name.startsWith(\".\")) {\n await scan(path.join(dirPath, entry.name));\n }\n }\n };\n\n await scan(appDir);\n return routes.sort();\n};\n\n"]}
|
|
1
|
+
{"version":3,"file":"pageConfigJson.helpers.js","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/pageConfigJson.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { BuilderElement } from \"../../../types/elements.js\";\nimport { createElementId } from \"./elementid.helpers.js\";\nimport { toWorkspacePath } from \"./fileSystem.helpers.js\";\nimport type { CoreFs } from \"../implementations/workspaceDeps.js\";\n\nexport type PageConfigJson = {\n elements: BuilderElement[];\n};\n\nexport const normalizeRouteSegments = (route: string): string[] => {\n const raw = String(route ?? \"\").trim();\n if (!raw || raw === \"/\") return [];\n return raw\n .replace(/\\\\/g, \"/\")\n .split(\"/\")\n .map((s) => s.trim())\n .filter(Boolean);\n};\n\nexport const isSafeSegment = (segment: string) => {\n const s = String(segment ?? \"\").trim();\n if (!s) return false;\n if (s === \".\" || s === \"..\") return false;\n if (s.includes(\"/\") || s.includes(\"\\\\\")) return false;\n return true;\n};\n\nexport const getPageConfigJsonPath = (workspaceRoot: string, route: string) => {\n const segments = normalizeRouteSegments(route);\n if (segments.some((s) => !isSafeSegment(s))) {\n throw new Error(\"invalid route\");\n }\n const rel = path.posix.join(\"app\", ...segments, \"pageConfig.json\");\n return toWorkspacePath(workspaceRoot, rel);\n};\n\nexport const parsePageConfigJson = (content: string): PageConfigJson => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(String(content ?? \"\"));\n } catch {\n throw new Error(\"pageConfig.json is not valid JSON\");\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(\"pageConfig.json must be an object\");\n }\n\n const elements = (parsed as any).elements;\n if (!Array.isArray(elements)) {\n throw new Error('pageConfig.json must contain \"elements\" array');\n }\n\n return { elements: elements as BuilderElement[] };\n};\n\nexport const stringifyPageConfigJson = (config: PageConfigJson) =>\n JSON.stringify({ elements: config.elements ?? [] }, null, 2) + \"\\n\";\n\nexport const extractAllIdsDeep = (elements: BuilderElement[]) => {\n const ids = new Set<string>();\n const walk = (arr: BuilderElement[]) => {\n for (const el of arr) {\n if (!el || typeof el !== \"object\") continue;\n const id = (el as any).id;\n if (typeof id === \"string\" && id.trim()) ids.add(id.trim());\n const children = (el as any).children;\n if (Array.isArray(children)) walk(children as BuilderElement[]);\n }\n };\n walk(Array.isArray(elements) ? elements : []);\n return ids;\n};\n\nexport const ensureElementIds = (\n elements: BuilderElement[],\n existingIds: Set<string>,\n) => {\n const seen = new Set<string>();\n const walk = (arr: BuilderElement[]) => {\n for (const el of arr) {\n if (!el || typeof el !== \"object\") continue;\n\n const anyEl = el as any;\n const currentId = typeof anyEl.id === \"string\" ? anyEl.id.trim() : \"\";\n if (!currentId || seen.has(currentId)) {\n const newId = createElementId(existingIds);\n anyEl.id = newId;\n existingIds.add(newId);\n seen.add(newId);\n } else {\n anyEl.id = currentId;\n existingIds.add(currentId);\n seen.add(currentId);\n }\n\n if (Array.isArray(anyEl.children)) {\n walk(anyEl.children as BuilderElement[]);\n }\n }\n };\n walk(elements);\n};\n\nexport const findElementById = (\n elements: BuilderElement[],\n elementId: string,\n): BuilderElement | null => {\n const id = String(elementId ?? \"\").trim();\n if (!id) return null;\n\n const walk = (arr: BuilderElement[]): BuilderElement | null => {\n for (const el of arr) {\n if (!el || typeof el !== \"object\") continue;\n if ((el as any).id === id) return el;\n const children = (el as any).children;\n if (Array.isArray(children)) {\n const found = walk(children as BuilderElement[]);\n if (found) return found;\n }\n }\n return null;\n };\n\n return walk(elements);\n};\n\nexport const deleteElementById = (\n elements: BuilderElement[],\n id: string,\n): boolean => {\n const target = String(id ?? \"\").trim();\n if (!target) return false;\n\n let deleted = false;\n const walk = (arr: BuilderElement[]) => {\n for (let idx = arr.length - 1; idx >= 0; idx--) {\n const el = arr[idx] as any;\n if (el?.id === target) {\n arr.splice(idx, 1);\n deleted = true;\n continue;\n }\n if (Array.isArray(el?.children)) walk(el.children as BuilderElement[]);\n }\n };\n walk(elements);\n return deleted;\n};\n\nexport const writeFileAtomic = async (filePath: string, content: string) => {\n const dir = path.dirname(filePath);\n const base = path.basename(filePath);\n const tmp = path.join(\n dir,\n `.qwintly_tmp_${base}_${Date.now()}_${Math.random().toString(16).slice(2)}`,\n );\n const bak = path.join(\n dir,\n `.qwintly_bak_${base}_${Date.now()}_${Math.random().toString(16).slice(2)}`,\n );\n\n try {\n await fs.mkdir(dir, { recursive: true });\n await fs.writeFile(tmp, content ?? \"\", \"utf-8\");\n\n // Windows rename doesn't overwrite; do a 2-step swap.\n try {\n await fs.rename(filePath, bak);\n await fs.rename(tmp, filePath);\n await fs.rm(bak, { force: true });\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code === \"ENOENT\") {\n // No previous file; just put the temp file in place.\n await fs.rename(tmp, filePath);\n } else {\n throw err;\n }\n }\n } catch (err) {\n // rollback best-effort\n try {\n await fs.rm(tmp, { force: true });\n } catch {\n // ignore\n }\n try {\n await fs.stat(bak);\n try {\n await fs.rm(filePath, { force: true });\n } catch {\n // ignore\n }\n await fs.rename(bak, filePath);\n } catch {\n // ignore\n }\n throw err;\n }\n};\n\nexport const getAvailableRoutes = async (deps: {\n workspaceRoot: string;\n fs: {\n safeReadDir: (absoluteDir: string) => Promise<Array<{\n name: string;\n isDirectory: () => boolean;\n isFile: () => boolean;\n }>>;\n };\n}): Promise<string[]> => {\n const { workspaceRoot, fs } = deps;\n const appDir = toWorkspacePath(workspaceRoot, \"app\");\n const routes: string[] = [];\n\n const scan = async (dirPath: string) => {\n let entries;\n try {\n entries = await fs.safeReadDir(dirPath);\n } catch {\n return;\n }\n\n let hasPageConfig = false;\n for (const entry of entries) {\n if (entry.isFile() && entry.name === \"pageConfig.json\") {\n hasPageConfig = true;\n break;\n }\n }\n\n if (hasPageConfig) {\n const rel = path.relative(appDir, dirPath);\n const routeStr = \"/\" + rel.replace(/\\\\/g, \"/\");\n routes.push(routeStr === \"/\" ? \"/\" : routeStr.replace(/\\/$/, \"\"));\n }\n\n for (const entry of entries) {\n if (entry.isDirectory() && entry.name !== \"node_modules\" && !entry.name.startsWith(\".\")) {\n await scan(path.join(dirPath, entry.name));\n }\n }\n };\n\n await scan(appDir);\n return routes.sort();\n};\n\nexport const matchRoute = (physicalRoute: string, requestedRoute: string): boolean => {\n const physSegs = normalizeRouteSegments(physicalRoute);\n const reqSegs = normalizeRouteSegments(requestedRoute);\n\n let pIdx = 0;\n let rIdx = 0;\n\n while (pIdx < physSegs.length && rIdx < reqSegs.length) {\n const phys = physSegs[pIdx];\n const req = reqSegs[rIdx];\n\n // Catch-all (e.g. [...slug] or [[...slug]])\n if (phys.startsWith(\"[\") && phys.endsWith(\"]\") && phys.includes(\"...\")) {\n return true;\n }\n\n // Regular dynamic segment (e.g. [id])\n if (phys.startsWith(\"[\") && phys.endsWith(\"]\")) {\n pIdx++;\n rIdx++;\n continue;\n }\n\n // Exact match\n if (phys.toLowerCase() === req.toLowerCase()) {\n pIdx++;\n rIdx++;\n continue;\n }\n\n return false;\n }\n\n // Handle case where we ran out of requested segments but have remaining physical segments\n // e.g. physical is /blog/[[...slug]] (optional catch-all) and request is /blog\n if (rIdx === reqSegs.length && pIdx < physSegs.length) {\n // All remaining physical segments must be optional catch-alls (e.g., [[...slug]])\n for (let i = pIdx; i < physSegs.length; i++) {\n const phys = physSegs[i];\n if (!(phys.startsWith(\"[[\") && phys.endsWith(\"]]\") && phys.includes(\"...\"))) {\n return false;\n }\n }\n return true;\n }\n\n return pIdx === physSegs.length && rIdx === reqSegs.length;\n};\n\nexport const resolvePageConfigJsonPath = async (\n workspaceRoot: string,\n route: string,\n fs: CoreFs,\n): Promise<string> => {\n // 1. Try exact match first\n const exactPath = getPageConfigJsonPath(workspaceRoot, route);\n try {\n await fs.stat(exactPath);\n return exactPath;\n } catch {\n // Exact file does not exist, let's resolve dynamically\n }\n\n // 2. Fetch all available routes in the workspace\n const available = await getAvailableRoutes({ workspaceRoot, fs });\n\n // 3. Find first matching route\n for (const physRoute of available) {\n if (matchRoute(physRoute, route)) {\n return getPageConfigJsonPath(workspaceRoot, physRoute);\n }\n }\n\n // 4. Fallback: if no match, just return the exact path\n return exactPath;\n};\n\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { deleteElementById, ensureElementIds, extractAllIdsDeep,
|
|
1
|
+
import { deleteElementById, ensureElementIds, extractAllIdsDeep, resolvePageConfigJsonPath, parsePageConfigJson, stringifyPageConfigJson, writeFileAtomic, } from "../helpers/pageConfigJson.helpers.js";
|
|
2
2
|
export const createDeleteElementImpl = (deps) => {
|
|
3
3
|
const { workspaceRoot, fs } = deps;
|
|
4
4
|
return async (route, elementId) => {
|
|
@@ -7,7 +7,7 @@ export const createDeleteElementImpl = (deps) => {
|
|
|
7
7
|
return { success: false, error: "invalid element_id" };
|
|
8
8
|
let configPath;
|
|
9
9
|
try {
|
|
10
|
-
configPath =
|
|
10
|
+
configPath = await resolvePageConfigJsonPath(workspaceRoot, route, fs);
|
|
11
11
|
}
|
|
12
12
|
catch (err) {
|
|
13
13
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deleteElement.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/deleteElement.impl.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,
|
|
1
|
+
{"version":3,"file":"deleteElement.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/deleteElement.impl.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n deleteElementById,\n ensureElementIds,\n extractAllIdsDeep,\n resolvePageConfigJsonPath,\n parsePageConfigJson,\n stringifyPageConfigJson,\n writeFileAtomic,\n} from \"../helpers/pageConfigJson.helpers.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\n\nexport const createDeleteElementImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs } = deps;\n\n return async (route: string, elementId: string) => {\n const id = String(elementId ?? \"\").trim();\n if (!id) return { success: false, error: \"invalid element_id\" };\n\n let configPath: string;\n try {\n configPath = await resolvePageConfigJsonPath(workspaceRoot, route, fs);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n let before = \"\";\n try {\n before = await fs.readFile(configPath);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code === \"ENOENT\") return { success: false, error: \"not found\" };\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n let parsed: ReturnType<typeof parsePageConfigJson>;\n try {\n parsed = parsePageConfigJson(before);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n const elements = parsed.elements ?? [];\n const existingIds = extractAllIdsDeep(elements);\n ensureElementIds(elements, existingIds);\n\n const deleted = deleteElementById(elements, id);\n if (!deleted) return { success: true, changed: false };\n\n const after = stringifyPageConfigJson({ elements });\n\n try {\n await writeFileAtomic(configPath, after);\n return { success: true, changed: true, deleted_id: id };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n };\n};\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolveUnsplashImagesDeep } from "../../../image/unsplash.service.js";
|
|
2
|
-
import { ensureElementIds, extractAllIdsDeep, findElementById,
|
|
2
|
+
import { ensureElementIds, extractAllIdsDeep, findElementById, resolvePageConfigJsonPath, parsePageConfigJson, stringifyPageConfigJson, writeFileAtomic, } from "../helpers/pageConfigJson.helpers.js";
|
|
3
3
|
import { InsertElementArgsZod } from "../validators/builderElement.zod.js";
|
|
4
4
|
export const createInsertElementImpl = (deps) => {
|
|
5
5
|
const { workspaceRoot, fs } = deps;
|
|
@@ -26,7 +26,7 @@ export const createInsertElementImpl = (deps) => {
|
|
|
26
26
|
const before_id = String(parsedArgs.data.before_id ?? "").trim();
|
|
27
27
|
let configPath;
|
|
28
28
|
try {
|
|
29
|
-
configPath =
|
|
29
|
+
configPath = await resolvePageConfigJsonPath(workspaceRoot, parsedArgs.data.route, fs);
|
|
30
30
|
}
|
|
31
31
|
catch (err) {
|
|
32
32
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"insertElement.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/insertElement.impl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAE/E,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,
|
|
1
|
+
{"version":3,"file":"insertElement.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/insertElement.impl.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveUnsplashImagesDeep } from \"../../../image/unsplash.service.js\";\nimport type { BuilderElement } from \"../../../types/elements.js\";\nimport {\n ensureElementIds,\n extractAllIdsDeep,\n findElementById,\n resolvePageConfigJsonPath,\n parsePageConfigJson,\n stringifyPageConfigJson,\n writeFileAtomic,\n} from \"../helpers/pageConfigJson.helpers.js\";\nimport { InsertElementArgsZod } from \"../validators/builderElement.zod.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\n\nexport const createInsertElementImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs } = deps;\n\n return async (\n routeOrArgs: string | Record<string, unknown>,\n parentId?: string,\n element?: BuilderElement,\n beforeId?: string,\n ) => {\n const rawArgs =\n typeof routeOrArgs === \"object\" && routeOrArgs !== null\n ? (routeOrArgs as Record<string, unknown>)\n : {\n route: routeOrArgs,\n parent_id: parentId,\n before_id: beforeId,\n element,\n };\n\n const parsedArgs = InsertElementArgsZod.safeParse(rawArgs);\n if (!parsedArgs.success) {\n return {\n success: false,\n error: \"invalid args\",\n error_detail: parsedArgs.error.flatten(),\n };\n }\n\n const parent_id = String(parsedArgs.data.parent_id ?? \"\").trim();\n if (!parent_id) return { success: false, error: \"invalid parent_id\" };\n\n const before_id = String(parsedArgs.data.before_id ?? \"\").trim();\n\n let configPath: string;\n try {\n configPath = await resolvePageConfigJsonPath(workspaceRoot, parsedArgs.data.route, fs);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n let before = \"\";\n try {\n before = await fs.readFile(configPath);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code === \"ENOENT\") return { success: false, error: \"not found\" };\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n let parsed: ReturnType<typeof parsePageConfigJson>;\n try {\n parsed = parsePageConfigJson(before);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n const elements = parsed.elements ?? [];\n const existingIds = extractAllIdsDeep(elements);\n ensureElementIds(elements, existingIds);\n\n // Clone + inject ids for the inserted element subtree.\n const toInsert = JSON.parse(\n JSON.stringify(parsedArgs.data.element ?? null),\n ) as BuilderElement;\n await resolveUnsplashImagesDeep(toInsert);\n ensureElementIds([toInsert], existingIds);\n\n const parent = findElementById(elements, parent_id);\n if (!parent) return { success: false, error: \"parent not found\" };\n\n const anyParent = parent as any;\n if (!anyParent.children || !Array.isArray(anyParent.children))\n anyParent.children = [];\n\n const children = anyParent.children as BuilderElement[];\n if (before_id) {\n const idx = children.findIndex((c: any) => String(c?.id ?? \"\") === before_id);\n if (idx >= 0) {\n children.splice(idx, 0, toInsert);\n } else {\n children.push(toInsert);\n }\n } else {\n children.push(toInsert);\n }\n\n const after = stringifyPageConfigJson({ elements });\n try {\n await writeFileAtomic(configPath, after);\n return {\n success: true,\n changed: true,\n inserted_id: (toInsert as any).id,\n };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n };\n};\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ensureElementIds, extractAllIdsDeep, findElementById,
|
|
1
|
+
import { ensureElementIds, extractAllIdsDeep, findElementById, resolvePageConfigJsonPath, parsePageConfigJson, stringifyPageConfigJson, writeFileAtomic, } from "../helpers/pageConfigJson.helpers.js";
|
|
2
2
|
export const createUpdateClassNameImpl = (deps) => {
|
|
3
3
|
const { workspaceRoot, fs } = deps;
|
|
4
4
|
return async (route, elementId, className) => {
|
|
@@ -7,7 +7,7 @@ export const createUpdateClassNameImpl = (deps) => {
|
|
|
7
7
|
return { success: false, error: "invalid element_id" };
|
|
8
8
|
let configPath;
|
|
9
9
|
try {
|
|
10
|
-
configPath =
|
|
10
|
+
configPath = await resolvePageConfigJsonPath(workspaceRoot, route, fs);
|
|
11
11
|
}
|
|
12
12
|
catch (err) {
|
|
13
13
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updateClassName.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/updateClassName.impl.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,
|
|
1
|
+
{"version":3,"file":"updateClassName.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/updateClassName.impl.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,yBAAyB,EACzB,mBAAmB,EACnB,uBAAuB,EACvB,eAAe,GAChB,MAAM,sCAAsC,CAAC;AAG9C,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,IAAmB,EAAE,EAAE;IAC/D,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;IAEnC,OAAO,KAAK,EAAE,KAAa,EAAE,SAAiB,EAAE,SAAiB,EAAE,EAAE;QACnE,MAAM,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1C,IAAI,CAAC,EAAE;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC;QAEhE,IAAI,UAAkB,CAAC;QACvB,IAAI,CAAC;YACH,UAAU,GAAG,MAAM,yBAAyB,CAAC,aAAa,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACzE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,GAAI,GAAoC,EAAE,IAAI,CAAC;YACzD,IAAI,IAAI,KAAK,QAAQ;gBAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;YACrE,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC;QACJ,CAAC;QAED,IAAI,MAA8C,CAAC;QACnD,IAAI,CAAC;YACH,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;QACvC,MAAM,WAAW,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAChD,gBAAgB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAExC,MAAM,EAAE,GAAG,eAAe,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,EAAE;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;QAE9D,EAAU,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QAEhD,MAAM,KAAK,GAAG,uBAAuB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QACpD,IAAI,CAAC;YACH,MAAM,eAAe,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {\n ensureElementIds,\n extractAllIdsDeep,\n findElementById,\n resolvePageConfigJsonPath,\n parsePageConfigJson,\n stringifyPageConfigJson,\n writeFileAtomic,\n} from \"../helpers/pageConfigJson.helpers.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\n\nexport const createUpdateClassNameImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs } = deps;\n\n return async (route: string, elementId: string, className: string) => {\n const id = String(elementId ?? \"\").trim();\n if (!id) return { success: false, error: \"invalid element_id\" };\n\n let configPath: string;\n try {\n configPath = await resolvePageConfigJsonPath(workspaceRoot, route, fs);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n let before = \"\";\n try {\n before = await fs.readFile(configPath);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code === \"ENOENT\") return { success: false, error: \"not found\" };\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n let parsed: ReturnType<typeof parsePageConfigJson>;\n try {\n parsed = parsePageConfigJson(before);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n const elements = parsed.elements ?? [];\n const existingIds = extractAllIdsDeep(elements);\n ensureElementIds(elements, existingIds);\n\n const el = findElementById(elements, id);\n if (!el) return { success: false, error: \"element not found\" };\n\n (el as any).className = String(className ?? \"\");\n\n const after = stringifyPageConfigJson({ elements });\n try {\n await writeFileAtomic(configPath, after);\n return { success: true, changed: true, updated_id: id };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n };\n};\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolveUnsplashImageForElement } from "../../../image/unsplash.service.js";
|
|
2
|
-
import { ensureElementIds, extractAllIdsDeep, findElementById,
|
|
2
|
+
import { ensureElementIds, extractAllIdsDeep, findElementById, resolvePageConfigJsonPath, parsePageConfigJson, stringifyPageConfigJson, writeFileAtomic, } from "../helpers/pageConfigJson.helpers.js";
|
|
3
3
|
const applyPropsPatch = (el, patch) => {
|
|
4
4
|
const anyEl = el;
|
|
5
5
|
if (!anyEl.props || typeof anyEl.props !== "object")
|
|
@@ -31,7 +31,7 @@ export const createUpdatePropsImpl = (deps) => {
|
|
|
31
31
|
return { success: false, error: "invalid element_id" };
|
|
32
32
|
let configPath;
|
|
33
33
|
try {
|
|
34
|
-
configPath =
|
|
34
|
+
configPath = await resolvePageConfigJsonPath(workspaceRoot, args.route, fs);
|
|
35
35
|
}
|
|
36
36
|
catch (err) {
|
|
37
37
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updateProps.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/updateProps.impl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,oCAAoC,CAAC;AAEpF,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,
|
|
1
|
+
{"version":3,"file":"updateProps.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/updateProps.impl.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveUnsplashImageForElement } from \"../../../image/unsplash.service.js\";\nimport type { BuilderElement, OnClickAction } from \"../../../types/elements.js\";\nimport {\n ensureElementIds,\n extractAllIdsDeep,\n findElementById,\n resolvePageConfigJsonPath,\n parsePageConfigJson,\n stringifyPageConfigJson,\n writeFileAtomic,\n} from \"../helpers/pageConfigJson.helpers.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\n\ntype UpdatePropsArgs = {\n route: string;\n element_id: string;\n} & Partial<{\n onClick: OnClickAction;\n text: string;\n href: string;\n placeholder: string;\n alt: string;\n target: string;\n rel: string;\n value: string;\n type: string;\n name: string;\n size: number;\n color: string;\n strokeWidth: number;\n}>;\n\nconst applyPropsPatch = (el: BuilderElement, patch: UpdatePropsArgs) => {\n const anyEl = el as any;\n if (!anyEl.props || typeof anyEl.props !== \"object\") anyEl.props = {};\n\n const apply = (key: string, value: unknown) => {\n if (value === undefined || value === null) return;\n anyEl.props[key] = value;\n };\n\n apply(\"onClick\", patch.onClick);\n apply(\"text\", patch.text);\n apply(\"href\", patch.href);\n apply(\"placeholder\", patch.placeholder);\n apply(\"alt\", patch.alt);\n apply(\"target\", patch.target);\n apply(\"rel\", patch.rel);\n apply(\"value\", patch.value);\n apply(\"type\", patch.type);\n\n apply(\"name\", patch.name);\n apply(\"size\", patch.size);\n apply(\"color\", patch.color);\n apply(\"strokeWidth\", patch.strokeWidth);\n};\n\nexport const createUpdatePropsImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs } = deps;\n\n return async (args: UpdatePropsArgs) => {\n const id = String(args?.element_id ?? \"\").trim();\n if (!id) return { success: false, error: \"invalid element_id\" };\n\n let configPath: string;\n try {\n configPath = await resolvePageConfigJsonPath(workspaceRoot, args.route, fs);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n let before = \"\";\n try {\n before = await fs.readFile(configPath);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code === \"ENOENT\") return { success: false, error: \"not found\" };\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n let parsed: ReturnType<typeof parsePageConfigJson>;\n try {\n parsed = parsePageConfigJson(before);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n const elements = parsed.elements ?? [];\n const existingIds = extractAllIdsDeep(elements);\n ensureElementIds(elements, existingIds);\n\n const el = findElementById(elements, id);\n if (!el) return { success: false, error: \"element not found\" };\n\n applyPropsPatch(el, args);\n\n if (el.type === \"image\") {\n const anyEl = el as any;\n const alt = String(args.alt ?? anyEl?.props?.alt ?? \"\").trim();\n await resolveUnsplashImageForElement(el, alt);\n }\n\n const after = stringifyPageConfigJson({ elements });\n try {\n await writeFileAtomic(configPath, after);\n return { success: true, changed: true, updated_id: id };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n };\n};\n"]}
|
|
@@ -8,7 +8,7 @@ export const CreateNewRouteSchema = {
|
|
|
8
8
|
parent_route: {
|
|
9
9
|
type: Type.STRING,
|
|
10
10
|
// Accept both "/dashboard" and "dashboard" (caller might omit the leading slash).
|
|
11
|
-
pattern: "^(?:/|/(?:[A-Za-z0-9_-]+(?:/[A-Za-z0-9_-]+)*)?|[A-Za-z0-9_-]+(?:/[A-Za-z0-9_-]+)*)$",
|
|
11
|
+
pattern: "^(?:/|/(?:[A-Za-z0-9_.[\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\]-]+)*)?|[A-Za-z0-9_.[\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\]-]+)*)$",
|
|
12
12
|
description: 'The parent route ("/" for app root). Example: "/" or "/dashboard". If you forget the leading "/", it will be assumed (e.g. "dashboard" -> "/dashboard"). NEVER pass empty string, use "/" if not sure about parent route.',
|
|
13
13
|
},
|
|
14
14
|
route_name: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNewRoute.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/createNewRoute.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,IAAI,EAAE,kBAAkB;IACxB,WAAW,EACT,2HAA2H;IAC7H,UAAU,EAAE;QACV,IAAI,EAAE,IAAI,CAAC,MAAM;QACjB,UAAU,EAAE;YACV,YAAY,EAAE;gBACZ,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,kFAAkF;gBAClF,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"createNewRoute.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/createNewRoute.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,IAAI,EAAE,kBAAkB;IACxB,WAAW,EACT,2HAA2H;IAC7H,UAAU,EAAE;QACV,IAAI,EAAE,IAAI,CAAC,MAAM;QACjB,UAAU,EAAE;YACV,YAAY,EAAE;gBACZ,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,kFAAkF;gBAClF,OAAO,EACL,qHAAqH;gBACvH,WAAW,EACT,2NAA2N;aAC9N;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,WAAW,EACT,yFAAyF;aAC5F;SACF;QACD,QAAQ,EAAE,CAAC,cAAc,EAAE,YAAY,CAAC;KACzC;CACF,CAAC","sourcesContent":["import { Type } from \"@google/genai\";\n\nexport const CreateNewRouteSchema = {\n name: \"create_new_route\",\n description:\n \"Creates a new Next.js App Router route folder under /app/<parent_route>/<route_name> with a page.tsx and pageConfig.json.\",\n parameters: {\n type: Type.OBJECT,\n properties: {\n parent_route: {\n type: Type.STRING,\n // Accept both \"/dashboard\" and \"dashboard\" (caller might omit the leading slash).\n pattern:\n \"^(?:/|/(?:[A-Za-z0-9_.[\\\\\\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\\\\\\]-]+)*)?|[A-Za-z0-9_.[\\\\\\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\\\\\\]-]+)*)$\",\n description:\n 'The parent route (\"/\" for app root). Example: \"/\" or \"/dashboard\". If you forget the leading \"/\", it will be assumed (e.g. \"dashboard\" -> \"/dashboard\"). NEVER pass empty string, use \"/\" if not sure about parent route.',\n },\n route_name: {\n type: Type.STRING,\n description:\n 'The new route segment to create under the parent route. Example: \"about\" or \"settings\".',\n },\n },\n required: [\"parent_route\", \"route_name\"],\n },\n};\n"]}
|
|
@@ -8,7 +8,7 @@ export const DeleteElementSchema = {
|
|
|
8
8
|
route: {
|
|
9
9
|
type: Type.STRING,
|
|
10
10
|
// Accept both "/about" and "about" (caller might omit the leading slash).
|
|
11
|
-
pattern: "^(?:/(?:[A-Za-z0-9_-]+(?:/[A-Za-z0-9_-]+)*)
|
|
11
|
+
pattern: "^(?:/(?:[A-Za-z0-9_.[\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\]-]+)*)?|[A-Za-z0-9_.[\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\]-]+)*)$",
|
|
12
12
|
description: "The route to delete the element at. Example: '/' or '/about'. If you forget the leading '/', it will be assumed (e.g. 'about' -> '/about').",
|
|
13
13
|
},
|
|
14
14
|
element_id: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deleteElement.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/deleteElement.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE,uBAAuB;IACpC,UAAU,EAAE;QACV,IAAI,EAAE,IAAI,CAAC,MAAM;QACjB,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,0EAA0E;gBAC1E,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"deleteElement.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/deleteElement.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE,uBAAuB;IACpC,UAAU,EAAE;QACV,IAAI,EAAE,IAAI,CAAC,MAAM;QACjB,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,0EAA0E;gBAC1E,OAAO,EACL,mHAAmH;gBACrH,WAAW,EACT,6IAA6I;aAChJ;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,WAAW,EAAE,sCAAsC;aACpD;SACF;QACD,QAAQ,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC;KAClC;CACF,CAAC","sourcesContent":["import { Type } from \"@google/genai\";\r\n\r\nexport const DeleteElementSchema = {\n name: \"delete_element\",\n description: \"Deletes element code.\",\n parameters: {\n type: Type.OBJECT,\n properties: {\n route: {\n type: Type.STRING,\n // Accept both \"/about\" and \"about\" (caller might omit the leading slash).\n pattern:\n \"^(?:/(?:[A-Za-z0-9_.[\\\\\\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\\\\\\]-]+)*)?|[A-Za-z0-9_.[\\\\\\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\\\\\\]-]+)*)$\",\n description:\n \"The route to delete the element at. Example: '/' or '/about'. If you forget the leading '/', it will be assumed (e.g. 'about' -> '/about').\",\n },\n element_id: {\n type: Type.STRING,\n description: \"The id of the element to be deleted.\",\n },\n },\r\n required: [\"route\", \"element_id\"],\r\n },\r\n};\r\n"]}
|
|
@@ -126,7 +126,7 @@ export const InsertElementSchema = {
|
|
|
126
126
|
route: {
|
|
127
127
|
type: Type.STRING,
|
|
128
128
|
// Accept both "/about" and "about" (caller might omit the leading slash).
|
|
129
|
-
pattern: "^(?:/(?:[A-Za-z0-9_-]+(?:/[A-Za-z0-9_-]+)*)
|
|
129
|
+
pattern: "^(?:/(?:[A-Za-z0-9_.[\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\]-]+)*)?|[A-Za-z0-9_.[\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\]-]+)*)$",
|
|
130
130
|
description: "The route to insert the element at. Use URL paths with forward slashes only. Examples: '/', '/about', '/pricing'. If you forget the leading '/', it will be assumed (e.g. 'about' -> '/about'). Never send Windows-style backslashes (e.g. '\\\\') or filesystem paths like 'app/pricing'. Never send empty string.",
|
|
131
131
|
},
|
|
132
132
|
parent_id: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"insertElement.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/insertElement.schema.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"insertElement.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/insertElement.schema.ts"],"names":[],"mappings":"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","sourcesContent":["import { Type } from \"@google/genai\";\r\n\r\nexport const ELEMENT_TYPES = [\r\n \"fragment\",\r\n \"div\",\r\n \"text\",\r\n \"image\",\r\n \"button\",\r\n \"input\",\r\n \"textarea\",\r\n \"link\",\r\n \"icon\",\r\n] as const;\r\n\r\nconst OnClickActionSchema = {\r\n type: Type.OBJECT,\r\n properties: {\r\n kind: {\r\n type: Type.STRING,\r\n enum: [\"route\", \"back\", \"reload\", \"external\"],\r\n description:\r\n \"What happens when the element is clicked. 'route' navigates within the app, 'external' opens a URL, 'back' goes back, 'reload' refreshes.\",\r\n },\r\n href: {\r\n type: Type.STRING,\r\n description:\r\n \"URL to navigate to (used for kind='route' and kind='external').\",\r\n },\r\n replace: {\r\n type: Type.BOOLEAN,\r\n description: \"For kind='route': replace history instead of pushing.\",\r\n },\r\n newTab: {\r\n type: Type.BOOLEAN,\r\n description: \"For kind='external': open link in a new tab.\",\r\n },\r\n },\r\n required: [\"kind\"],\r\n};\r\n\r\nconst BuilderElementPropsSchema = {\r\n type: Type.OBJECT,\r\n properties: {\r\n onClick: OnClickActionSchema,\r\n text: {\r\n type: Type.STRING,\r\n description:\r\n \"Text content used by 'text' (<p>), 'button' (label), and as a fallback for 'link' when it has no children.\",\r\n },\r\n href: {\r\n type: Type.STRING,\r\n description: \"For 'link': the href attribute (defaults to '#').\",\r\n },\r\n placeholder: {\r\n type: Type.STRING,\r\n description: \"For 'input' and 'textarea': placeholder shown when empty.\",\r\n },\r\n alt: {\r\n type: Type.STRING,\r\n description:\r\n \"For 'image': alt text for accessibility AND the query used to fetch a suitable Unsplash image (src is auto-resolved from alt).\",\r\n },\r\n target: {\r\n type: Type.STRING,\r\n description: \"For 'link': target attribute (e.g. '_blank').\",\r\n },\r\n rel: {\r\n type: Type.STRING,\r\n description: \"For 'link': rel attribute (e.g. 'noreferrer').\",\r\n },\r\n value: {\r\n type: Type.STRING,\r\n description:\r\n \"For 'input' and 'textarea': default value (maps to defaultValue).\",\r\n },\r\n type: {\r\n type: Type.STRING,\r\n description:\r\n \"For 'input': input type (e.g. 'text', 'email', 'password'). Defaults to 'text'.\",\r\n },\r\n\r\n // icon\r\n name: {\r\n type: Type.STRING,\r\n description: \"For 'icon': Lucide icon name (e.g. 'ArrowRight', 'Menu').\",\r\n },\r\n size: { type: Type.NUMBER, description: \"For 'icon': size in px.\" },\r\n color: { type: Type.STRING, description: \"For 'icon': stroke color.\" },\r\n strokeWidth: {\r\n type: Type.NUMBER,\r\n description: \"For 'icon': stroke width.\",\r\n },\r\n },\r\n};\r\n\r\n// NOTE: Gemini tool `parameters` schemas reject `$ref`, so true recursion isn't available here.\r\n// We unroll nesting to a reasonable max depth; for deeper trees, insert in multiple steps.\r\nconst buildBuilderElementSchema = (depth: number): any => {\r\n return {\r\n type: Type.OBJECT,\r\n properties: {\r\n type: {\r\n type: Type.STRING,\r\n enum: ELEMENT_TYPES,\r\n description:\r\n \"Element type to render. Use 'text' for <p>, 'image' forn <img>, 'link' for <a>, 'icon' for Lucide icon, 'fragment' renders children only\",\r\n },\r\n className: {\r\n type: Type.STRING,\r\n description: \"Tailwind CSS className (Tailwind only)\",\r\n },\r\n visible: {\r\n type: Type.BOOLEAN,\r\n description: \"Visibility flag\",\r\n },\r\n props: BuilderElementPropsSchema,\r\n children: {\r\n type: Type.ARRAY,\r\n description:\r\n \"Child elements. Each child can itself have children (children[].children[]...)\",\r\n items:\r\n depth > 0\r\n ? buildBuilderElementSchema(depth - 1)\r\n : {\r\n type: Type.OBJECT,\r\n description:\r\n \"Max depth reached. Insert deeper children separately using the returned inserted_id as parent_id\",\r\n },\r\n },\r\n },\r\n required: [\"type\"],\r\n };\r\n};\r\n\r\nexport const BuilderElementSchema: any = buildBuilderElementSchema(4);\r\n\r\nexport const InsertElementSchema = {\n name: \"insert_element\",\n description:\n \"Inserts element code. Use element.children to create nested UI. Each child is another BuilderElement and can itself have children.\",\n parameters: {\n type: Type.OBJECT,\n properties: {\n route: {\n type: Type.STRING,\n // Accept both \"/about\" and \"about\" (caller might omit the leading slash).\n pattern:\n \"^(?:/(?:[A-Za-z0-9_.[\\\\\\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\\\\\\]-]+)*)?|[A-Za-z0-9_.[\\\\\\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\\\\\\]-]+)*)$\",\n description:\n \"The route to insert the element at. Use URL paths with forward slashes only. Examples: '/', '/about', '/pricing'. If you forget the leading '/', it will be assumed (e.g. 'about' -> '/about'). Never send Windows-style backslashes (e.g. '\\\\\\\\') or filesystem paths like 'app/pricing'. Never send empty string.\",\n },\n parent_id: {\n type: Type.STRING,\n description: \"The parent id to insert the element at.\",\n },\n before_id: {\n type: Type.STRING,\n description:\n \"Optional. If provided, inserts the new element before the existing child element with this id (within parent_id's children list). If not found, appends at the end.\",\n },\n element: {\n ...BuilderElementSchema,\n description: \"The element to insert.\",\n },\n },\n required: [\"route\", \"parent_id\", \"element\"],\r\n },\r\n};\r\n"]}
|
|
@@ -8,7 +8,7 @@ export const UpdateClassNameSchema = {
|
|
|
8
8
|
route: {
|
|
9
9
|
type: Type.STRING,
|
|
10
10
|
// Accept both "/about" and "about" (caller might omit the leading slash).
|
|
11
|
-
pattern: "^(?:/(?:[A-Za-z0-9_-]+(?:/[A-Za-z0-9_-]+)*)
|
|
11
|
+
pattern: "^(?:/(?:[A-Za-z0-9_.[\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\]-]+)*)?|[A-Za-z0-9_.[\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\]-]+)*)$",
|
|
12
12
|
description: "The route to update the element at. Example: '/' or '/about'. If you forget the leading '/', it will be assumed (e.g. 'about' -> '/about').",
|
|
13
13
|
},
|
|
14
14
|
element_id: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updateClassName.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/updateClassName.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,IAAI,EAAE,kBAAkB;IACxB,WAAW,EACT,+NAA+N;IACjO,UAAU,EAAE;QACV,IAAI,EAAE,IAAI,CAAC,MAAM;QACjB,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,0EAA0E;gBAC1E,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"updateClassName.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/updateClassName.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,IAAI,EAAE,kBAAkB;IACxB,WAAW,EACT,+NAA+N;IACjO,UAAU,EAAE;QACV,IAAI,EAAE,IAAI,CAAC,MAAM;QACjB,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,0EAA0E;gBAC1E,OAAO,EACL,mHAAmH;gBACrH,WAAW,EACT,6IAA6I;aAChJ;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,WAAW,EAAE,sCAAsC;aACpD;YACD,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE;SACjC;QACD,QAAQ,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,WAAW,CAAC;KAC/C;CACF,CAAC","sourcesContent":["import { Type } from \"@google/genai\";\r\n\r\nexport const UpdateClassNameSchema = {\n name: \"update_classname\",\n description:\n \"Updates className (only tailwind classes allowed). Give complete className. Prefer semantic token classes (bg-background, text-foreground, border-border, ring-ring, etc.); use update_global_styles to change global tokens.\",\n parameters: {\n type: Type.OBJECT,\n properties: {\n route: {\n type: Type.STRING,\n // Accept both \"/about\" and \"about\" (caller might omit the leading slash).\n pattern:\n \"^(?:/(?:[A-Za-z0-9_.[\\\\\\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\\\\\\]-]+)*)?|[A-Za-z0-9_.[\\\\\\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\\\\\\]-]+)*)$\",\n description:\n \"The route to update the element at. Example: '/' or '/about'. If you forget the leading '/', it will be assumed (e.g. 'about' -> '/about').\",\n },\n element_id: {\n type: Type.STRING,\n description: \"The id of the element to be updated.\",\n },\n className: { type: Type.STRING },\r\n },\r\n required: [\"route\", \"element_id\", \"className\"],\r\n },\r\n};\r\n"]}
|
|
@@ -31,7 +31,7 @@ export const UpdatePropsSchema = {
|
|
|
31
31
|
route: {
|
|
32
32
|
type: Type.STRING,
|
|
33
33
|
// Accept both "/about" and "about" (caller might omit the leading slash).
|
|
34
|
-
pattern: "^(?:/(?:[A-Za-z0-9_-]+(?:/[A-Za-z0-9_-]+)*)
|
|
34
|
+
pattern: "^(?:/(?:[A-Za-z0-9_.[\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\]-]+)*)?|[A-Za-z0-9_.[\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\]-]+)*)$",
|
|
35
35
|
description: "The route to update the element at. Example: '/' or '/about'. If you forget the leading '/', it will be assumed (e.g. 'about' -> '/about').",
|
|
36
36
|
},
|
|
37
37
|
element_id: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updateProps.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/updateProps.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,mBAAmB,GAAG;IAC1B,IAAI,EAAE,IAAI,CAAC,MAAM;IACjB,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,IAAI,EAAE,IAAI,CAAC,MAAM;YACjB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC;YAC7C,WAAW,EACT,2IAA2I;SAC9I;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,IAAI,CAAC,MAAM;YACjB,WAAW,EACT,iEAAiE;SACpE;QACD,OAAO,EAAE;YACP,IAAI,EAAE,IAAI,CAAC,OAAO;YAClB,WAAW,EAAE,uDAAuD;SACrE;QACD,MAAM,EAAE;YACN,IAAI,EAAE,IAAI,CAAC,OAAO;YAClB,WAAW,EAAE,8CAA8C;SAC5D;KACF;IACD,QAAQ,EAAE,CAAC,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,uBAAuB;IACpC,UAAU,EAAE;QACV,IAAI,EAAE,IAAI,CAAC,MAAM;QACjB,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,0EAA0E;gBAC1E,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"updateProps.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/updateProps.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,mBAAmB,GAAG;IAC1B,IAAI,EAAE,IAAI,CAAC,MAAM;IACjB,UAAU,EAAE;QACV,IAAI,EAAE;YACJ,IAAI,EAAE,IAAI,CAAC,MAAM;YACjB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC;YAC7C,WAAW,EACT,2IAA2I;SAC9I;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,IAAI,CAAC,MAAM;YACjB,WAAW,EACT,iEAAiE;SACpE;QACD,OAAO,EAAE;YACP,IAAI,EAAE,IAAI,CAAC,OAAO;YAClB,WAAW,EAAE,uDAAuD;SACrE;QACD,MAAM,EAAE;YACN,IAAI,EAAE,IAAI,CAAC,OAAO;YAClB,WAAW,EAAE,8CAA8C;SAC5D;KACF;IACD,QAAQ,EAAE,CAAC,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,uBAAuB;IACpC,UAAU,EAAE;QACV,IAAI,EAAE,IAAI,CAAC,MAAM;QACjB,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,0EAA0E;gBAC1E,OAAO,EACL,mHAAmH;gBACrH,WAAW,EACT,6IAA6I;aAChJ;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,WAAW,EAAE,sCAAsC;aACpD;YACD,OAAO,EAAE,mBAAmB;YAC5B,IAAI,EAAE;gBACJ,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,WAAW,EACT,4GAA4G;aAC/G;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,WAAW,EAAE,mDAAmD;aACjE;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,WAAW,EAAE,2DAA2D;aACzE;YACD,GAAG,EAAE;gBACH,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,WAAW,EACT,gIAAgI;aACnI;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,WAAW,EAAE,+CAA+C;aAC7D;YACD,GAAG,EAAE;gBACH,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,WAAW,EAAE,gDAAgD;aAC9D;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,WAAW,EACT,mEAAmE;aACtE;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,WAAW,EACT,iFAAiF;aACpF;YAED,OAAO;YACP,IAAI,EAAE;gBACJ,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,WAAW,EAAE,2DAA2D;aACzE;YACD,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,yBAAyB,EAAE;YACnE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,2BAA2B,EAAE;YACtE,WAAW,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,WAAW,EAAE,2BAA2B;aACzC;SACF;QACD,QAAQ,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC;KAClC;CACF,CAAC","sourcesContent":["import { Type } from \"@google/genai\";\n\nconst OnClickActionSchema = {\n type: Type.OBJECT,\n properties: {\n kind: {\n type: Type.STRING,\n enum: [\"route\", \"back\", \"reload\", \"external\"],\n description:\n \"What happens when the element is clicked. 'route' navigates within the app, 'external' opens a URL, 'back' goes back, 'reload' refreshes.\",\n },\n href: {\n type: Type.STRING,\n description:\n \"URL to navigate to (used for kind='route' and kind='external').\",\n },\n replace: {\n type: Type.BOOLEAN,\n description: \"For kind='route': replace history instead of pushing.\",\n },\n newTab: {\n type: Type.BOOLEAN,\n description: \"For kind='external': open link in a new tab.\",\n },\n },\n required: [\"kind\"],\n};\n\nexport const UpdatePropsSchema = {\n name: \"update_props\",\n description: \"Updates element code.\",\n parameters: {\n type: Type.OBJECT,\n properties: {\n route: {\n type: Type.STRING,\n // Accept both \"/about\" and \"about\" (caller might omit the leading slash).\n pattern:\n \"^(?:/(?:[A-Za-z0-9_.[\\\\\\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\\\\\\]-]+)*)?|[A-Za-z0-9_.[\\\\\\\\\\]-]+(?:/[A-Za-z0-9_.[\\\\\\\\\\]-]+)*)$\",\n description:\n \"The route to update the element at. Example: '/' or '/about'. If you forget the leading '/', it will be assumed (e.g. 'about' -> '/about').\",\n },\n element_id: {\n type: Type.STRING,\n description: \"The id of the element to be updated.\",\n },\n onClick: OnClickActionSchema,\n text: {\n type: Type.STRING,\n description:\n \"Text content used by 'text' (<p>), 'button' (label), and as a fallback for 'link' when it has no children.\",\n },\n href: {\n type: Type.STRING,\n description: \"For 'link': the href attribute (defaults to '#').\",\n },\n placeholder: {\n type: Type.STRING,\n description: \"For 'input' and 'textarea': placeholder shown when empty.\",\n },\n alt: {\n type: Type.STRING,\n description:\n \"For 'image': alt text for accessibility AND the query used to fetch a suitable Unsplash image (src is auto-resolved from alt).\",\n },\n target: {\n type: Type.STRING,\n description: \"For 'link': target attribute (e.g. '_blank').\",\n },\n rel: {\n type: Type.STRING,\n description: \"For 'link': rel attribute (e.g. 'noreferrer').\",\n },\n value: {\n type: Type.STRING,\n description:\n \"For 'input' and 'textarea': default value (maps to defaultValue).\",\n },\n type: {\n type: Type.STRING,\n description:\n \"For 'input': input type (e.g. 'text', 'email', 'password'). Defaults to 'text'.\",\n },\n\n // icon\n name: {\n type: Type.STRING,\n description: \"For 'icon': Lucide icon name (e.g. 'ArrowRight', 'Menu').\",\n },\n size: { type: Type.NUMBER, description: \"For 'icon': size in px.\" },\n color: { type: Type.STRING, description: \"For 'icon': stroke color.\" },\n strokeWidth: {\n type: Type.NUMBER,\n description: \"For 'icon': stroke width.\",\n },\n },\n required: [\"route\", \"element_id\"],\n },\n};\n"]}
|
|
@@ -28,8 +28,8 @@ const isInternalRoutePath = (value) => {
|
|
|
28
28
|
return false;
|
|
29
29
|
if (s.includes("\\"))
|
|
30
30
|
return false;
|
|
31
|
-
// Allow "/" or "/a" or "/a/b-c_d"
|
|
32
|
-
return /^\/(?:[A-Za-z0-9_-]+(?:\/[A-Za-z0-9_-]+)*)?$/.test(s);
|
|
31
|
+
// Allow "/" or "/a" or "/a/b-c_d" or "/product/[id]" or "/blog/[...slug]" or "/blog/[[...slug]]"
|
|
32
|
+
return /^\/(?:[A-Za-z0-9_.[\]-]+(?:\/[A-Za-z0-9_.[\]-]+)*)?$/.test(s);
|
|
33
33
|
};
|
|
34
34
|
export const OnClickActionZod = z.discriminatedUnion("kind", [
|
|
35
35
|
z.object({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builderElement.zod.js","sourceRoot":"","sources":["../../../../src/ai/tools/validators/builderElement.zod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,UAAU;IACV,KAAK;IACL,MAAM;IACN,OAAO;IACP,QAAQ;IACR,OAAO;IACP,UAAU;IACV,MAAM;IACN,MAAM;CACE,CAAC;AAEX,MAAM,0BAA0B,GAAG,CAAC,KAAc,EAAE,EAAE;IACpD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACvC,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC5C,IAAI,WAAW,KAAK,GAAG;QAAE,OAAO,GAAG,CAAC;IACpC,IAAI,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,WAAW,CAAC;IACpD,gFAAgF;IAChF,OAAO,IAAI,WAAW,EAAE,CAAC;AAC3B,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,KAAa,EAAE,EAAE;IAC5C,MAAM,CAAC,GAAG,0BAA0B,CAAC,KAAK,CAAC,CAAC;IAC5C,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,
|
|
1
|
+
{"version":3,"file":"builderElement.zod.js","sourceRoot":"","sources":["../../../../src/ai/tools/validators/builderElement.zod.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nexport const ELEMENT_TYPES = [\n \"fragment\",\n \"div\",\n \"text\",\n \"image\",\n \"button\",\n \"input\",\n \"textarea\",\n \"link\",\n \"icon\",\n] as const;\n\nconst normalizeInternalRoutePath = (value: unknown) => {\n const raw = String(value ?? \"\").trim();\n if (!raw) return \"\";\n const forwardOnly = raw.replace(/\\\\/g, \"/\");\n if (forwardOnly === \"/\") return \"/\";\n if (forwardOnly.startsWith(\"/\")) return forwardOnly;\n // Fallback: if caller forgot the leading slash, assume they meant an app route.\n return `/${forwardOnly}`;\n};\n\nconst isInternalRoutePath = (value: string) => {\n const s = normalizeInternalRoutePath(value);\n if (!s) return false;\n if (s.includes(\"\\\\\")) return false;\n // Allow \"/\" or \"/a\" or \"/a/b-c_d\" or \"/product/[id]\" or \"/blog/[...slug]\" or \"/blog/[[...slug]]\"\n return /^\\/(?:[A-Za-z0-9_.[\\]-]+(?:\\/[A-Za-z0-9_.[\\]-]+)*)?$/.test(s);\n};\n\nexport const OnClickActionZod = z.discriminatedUnion(\"kind\", [\n z.object({\n kind: z.literal(\"route\"),\n href: z.preprocess(\n normalizeInternalRoutePath,\n z\n .string()\n .min(1)\n .refine(isInternalRoutePath, {\n message:\n \"href must be an internal route path like '/' or '/pricing' (forward slashes only; no backslashes)\",\n }),\n ),\n replace: z.boolean().optional(),\n }),\n z.object({ kind: z.literal(\"back\") }),\n z.object({ kind: z.literal(\"reload\") }),\n z.object({\n kind: z.literal(\"external\"),\n href: z.string().min(1),\n newTab: z.boolean().optional(),\n }),\n]);\n\nexport const BuilderElementZod: z.ZodType<any> = z.object({\n type: z.enum(ELEMENT_TYPES),\n className: z.string().optional(),\n visible: z.boolean().optional(),\n props: z\n .object({\n onClick: OnClickActionZod.optional(),\n text: z.string().optional(),\n href: z.string().optional(),\n placeholder: z.string().optional(),\n alt: z.string().optional(),\n target: z.string().optional(),\n rel: z.string().optional(),\n value: z.string().optional(),\n type: z.string().optional(),\n name: z.string().optional(),\n size: z.number().optional(),\n color: z.string().optional(),\n strokeWidth: z.number().optional(),\n })\n .passthrough()\n .optional(),\n children: z.array(z.lazy(() => BuilderElementZod)).optional(),\n});\n\nexport const InsertElementArgsZod = z.object({\n route: z.preprocess(\n normalizeInternalRoutePath,\n z\n .string()\n .min(1)\n .refine(isInternalRoutePath, {\n message:\n \"route must be like '/' or '/about' (forward slashes only; no backslashes)\",\n }),\n ),\n parent_id: z.string().min(1),\n before_id: z.string().min(1).optional(),\n element: BuilderElementZod,\n});\n"]}
|