@standardagents/builder 0.20.0 → 0.21.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.
- package/dist/built-in-routes.js +139 -1
- package/dist/built-in-routes.js.map +1 -1
- package/dist/{index-Bug9ATQX.d.ts → index-CpuS9hHJ.d.ts} +12 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +207 -3
- package/dist/index.js.map +1 -1
- package/dist/plugin.js +16 -1
- package/dist/plugin.js.map +1 -1
- package/dist/runtime.d.ts +64 -3
- package/dist/runtime.js +191 -2
- package/dist/runtime.js.map +1 -1
- package/dist/test.d.ts +1 -1
- package/package.json +4 -4
package/dist/built-in-routes.js
CHANGED
|
@@ -2521,7 +2521,9 @@ __export(files_exports, {
|
|
|
2521
2521
|
dirname: () => dirname,
|
|
2522
2522
|
isTextMimeType: () => isTextMimeType,
|
|
2523
2523
|
normalizePath: () => normalizePath,
|
|
2524
|
-
|
|
2524
|
+
resolveRenameDestination: () => resolveRenameDestination,
|
|
2525
|
+
rowToFileRecord: () => rowToFileRecord,
|
|
2526
|
+
validateMovePaths: () => validateMovePaths
|
|
2525
2527
|
});
|
|
2526
2528
|
function isTextMimeType(mimeType) {
|
|
2527
2529
|
if (mimeType.startsWith("text/")) return true;
|
|
@@ -2554,6 +2556,33 @@ function dirname(path9) {
|
|
|
2554
2556
|
if (lastSlash <= 0) return "/";
|
|
2555
2557
|
return normalized.slice(0, lastSlash);
|
|
2556
2558
|
}
|
|
2559
|
+
function validateMovePaths(source, destination, isDirectory) {
|
|
2560
|
+
if (source === "/") {
|
|
2561
|
+
throw new Error("Cannot move the root directory");
|
|
2562
|
+
}
|
|
2563
|
+
if (destination === "/") {
|
|
2564
|
+
throw new Error("Cannot move over the root directory");
|
|
2565
|
+
}
|
|
2566
|
+
if (isDirectory && destination.startsWith(source + "/")) {
|
|
2567
|
+
throw new Error(
|
|
2568
|
+
"Cannot move a directory into itself or one of its descendants"
|
|
2569
|
+
);
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
function resolveRenameDestination(path9, newName) {
|
|
2573
|
+
if (typeof newName !== "string" || newName.length === 0) {
|
|
2574
|
+
throw new Error("New name must be a non-empty string");
|
|
2575
|
+
}
|
|
2576
|
+
if (newName.includes("/")) {
|
|
2577
|
+
throw new Error("New name must not contain path separators");
|
|
2578
|
+
}
|
|
2579
|
+
if (newName === "." || newName === "..") {
|
|
2580
|
+
throw new Error("New name must not be '.' or '..'");
|
|
2581
|
+
}
|
|
2582
|
+
const normalized = normalizePath(path9);
|
|
2583
|
+
const parent = dirname(normalized);
|
|
2584
|
+
return parent === "/" ? `/${newName}` : `${parent}/${newName}`;
|
|
2585
|
+
}
|
|
2557
2586
|
function rowToFileRecord(row) {
|
|
2558
2587
|
return {
|
|
2559
2588
|
path: row.path,
|
|
@@ -3030,6 +3059,94 @@ var init_files = __esm({
|
|
|
3030
3059
|
normalizedPath
|
|
3031
3060
|
);
|
|
3032
3061
|
}
|
|
3062
|
+
/**
|
|
3063
|
+
* Move (or rename) a file or directory from one path to another.
|
|
3064
|
+
*
|
|
3065
|
+
* Works for inline files, chunked files, and directories. Moving a
|
|
3066
|
+
* directory relocates the directory marker and every descendant entry,
|
|
3067
|
+
* preserving their relative layout. The destination must not already
|
|
3068
|
+
* exist, and a directory cannot be moved into itself or one of its own
|
|
3069
|
+
* descendants.
|
|
3070
|
+
*
|
|
3071
|
+
* Implementation note: the `file_chunks` table has a foreign key on
|
|
3072
|
+
* `files(path)` with `ON DELETE CASCADE`, and there is no `ON UPDATE`
|
|
3073
|
+
* action. To keep referential integrity intact (foreign key enforcement
|
|
3074
|
+
* is on in Durable Object SQLite), we copy the affected rows to their new
|
|
3075
|
+
* paths first, then delete the originals — the cascade removes the old
|
|
3076
|
+
* chunks, while the freshly copied chunks already point at the new file
|
|
3077
|
+
* rows. This never leaves an orphaned chunk mid-operation.
|
|
3078
|
+
*/
|
|
3079
|
+
async move(sourcePath, destinationPath) {
|
|
3080
|
+
const source = normalizePath(sourcePath);
|
|
3081
|
+
const destination = normalizePath(destinationPath);
|
|
3082
|
+
if (source === destination) {
|
|
3083
|
+
const existing = await this.stat(source);
|
|
3084
|
+
if (!existing) {
|
|
3085
|
+
throw new Error(`Source path does not exist: ${source}`);
|
|
3086
|
+
}
|
|
3087
|
+
return existing;
|
|
3088
|
+
}
|
|
3089
|
+
const record24 = await this.stat(source);
|
|
3090
|
+
if (!record24) {
|
|
3091
|
+
throw new Error(`Source path does not exist: ${source}`);
|
|
3092
|
+
}
|
|
3093
|
+
validateMovePaths(source, destination, record24.isDirectory);
|
|
3094
|
+
const destPrefix = destination + "/";
|
|
3095
|
+
const collision = await this.sql.exec(
|
|
3096
|
+
`SELECT COUNT(*) as count FROM files WHERE path = ? OR path LIKE ? || '%'`,
|
|
3097
|
+
destination,
|
|
3098
|
+
destPrefix
|
|
3099
|
+
);
|
|
3100
|
+
if (collision.one().count > 0) {
|
|
3101
|
+
throw new Error(`Destination already exists: ${destination}`);
|
|
3102
|
+
}
|
|
3103
|
+
const sourcePrefix = source + "/";
|
|
3104
|
+
const sourceLen = source.length;
|
|
3105
|
+
const destName = basename(destination);
|
|
3106
|
+
await this.sql.exec(
|
|
3107
|
+
`INSERT INTO files (path, name, mime_type, storage, location, data, content, size, metadata, thumbnail, is_directory, created_at, width, height, is_chunked, chunk_count)
|
|
3108
|
+
SELECT ? || SUBSTR(path, ? + 1), name, mime_type, storage, location, data, content, size, metadata, thumbnail, is_directory, created_at, width, height, is_chunked, chunk_count
|
|
3109
|
+
FROM files
|
|
3110
|
+
WHERE path = ? OR path LIKE ? || '%'`,
|
|
3111
|
+
destination,
|
|
3112
|
+
sourceLen,
|
|
3113
|
+
source,
|
|
3114
|
+
sourcePrefix
|
|
3115
|
+
);
|
|
3116
|
+
await this.sql.exec(
|
|
3117
|
+
`INSERT INTO file_chunks (file_path, chunk_index, data)
|
|
3118
|
+
SELECT ? || SUBSTR(file_path, ? + 1), chunk_index, data
|
|
3119
|
+
FROM file_chunks
|
|
3120
|
+
WHERE file_path = ? OR file_path LIKE ? || '%'`,
|
|
3121
|
+
destination,
|
|
3122
|
+
sourceLen,
|
|
3123
|
+
source,
|
|
3124
|
+
sourcePrefix
|
|
3125
|
+
);
|
|
3126
|
+
await this.sql.exec(
|
|
3127
|
+
`DELETE FROM files WHERE path = ? OR path LIKE ? || '%'`,
|
|
3128
|
+
source,
|
|
3129
|
+
sourcePrefix
|
|
3130
|
+
);
|
|
3131
|
+
await this.sql.exec(
|
|
3132
|
+
`UPDATE files SET name = ? WHERE path = ?`,
|
|
3133
|
+
destName,
|
|
3134
|
+
destination
|
|
3135
|
+
);
|
|
3136
|
+
const moved = await this.stat(destination);
|
|
3137
|
+
if (!moved) {
|
|
3138
|
+
throw new Error(`Failed to move ${source} to ${destination}`);
|
|
3139
|
+
}
|
|
3140
|
+
return moved;
|
|
3141
|
+
}
|
|
3142
|
+
/**
|
|
3143
|
+
* Rename a file or directory in place, keeping it in the same parent
|
|
3144
|
+
* directory. `newName` must be a bare file name with no path separators.
|
|
3145
|
+
*/
|
|
3146
|
+
async rename(path9, newName) {
|
|
3147
|
+
const destination = resolveRenameDestination(path9, newName);
|
|
3148
|
+
return this.move(normalizePath(path9), destination);
|
|
3149
|
+
}
|
|
3033
3150
|
/**
|
|
3034
3151
|
* Get storage statistics
|
|
3035
3152
|
*/
|
|
@@ -12127,6 +12244,20 @@ var init_ThreadStateImpl = __esm({
|
|
|
12127
12244
|
async rmdirFile(path9) {
|
|
12128
12245
|
await this._threadInstance.rmdirFile(path9);
|
|
12129
12246
|
}
|
|
12247
|
+
async moveFile(sourcePath, destinationPath) {
|
|
12248
|
+
const result = await this._threadInstance.moveFile(sourcePath, destinationPath);
|
|
12249
|
+
if (!result.success || !result.file) {
|
|
12250
|
+
throw new Error(result.error || "Failed to move file");
|
|
12251
|
+
}
|
|
12252
|
+
return this._mapFileRecord(result.file);
|
|
12253
|
+
}
|
|
12254
|
+
async renameFile(path9, newName) {
|
|
12255
|
+
const result = await this._threadInstance.renameFile(path9, newName);
|
|
12256
|
+
if (!result.success || !result.file) {
|
|
12257
|
+
throw new Error(result.error || "Failed to rename file");
|
|
12258
|
+
}
|
|
12259
|
+
return this._mapFileRecord(result.file);
|
|
12260
|
+
}
|
|
12130
12261
|
async getFileStats() {
|
|
12131
12262
|
const stats = await this._threadInstance.getFileStats();
|
|
12132
12263
|
return {
|
|
@@ -69648,6 +69779,13 @@ async function handlePost2(stub, path9, req) {
|
|
|
69648
69779
|
const contentType = req.headers.get("Content-Type") || "";
|
|
69649
69780
|
if (contentType.includes("application/json")) {
|
|
69650
69781
|
const body = await req.json();
|
|
69782
|
+
if (body.action === "move" || body.action === "rename") {
|
|
69783
|
+
const result2 = body.action === "move" ? await stub.moveFile(path9, body.destination) : await stub.renameFile(path9, body.newName);
|
|
69784
|
+
if (!result2.success) {
|
|
69785
|
+
return Response.json({ error: result2.error }, { status: 400 });
|
|
69786
|
+
}
|
|
69787
|
+
return Response.json(toAttachmentRef(result2.file), { status: 200 });
|
|
69788
|
+
}
|
|
69651
69789
|
if (body.type === "directory") {
|
|
69652
69790
|
const result2 = await stub.mkdirFile(path9);
|
|
69653
69791
|
if (!result2.success) {
|