@aprovan/patchwork-editor 0.1.2-dev.ba8f277 → 0.1.2-dev.f456953
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/.turbo/turbo-build.log +2 -2
- package/dist/components/edit/api.d.ts +1 -1
- package/dist/components/edit/fileTypes.d.ts +1 -1
- package/dist/index.js +23 -3
- package/package.json +3 -3
- package/src/components/ServicesInspector.tsx +1 -1
- package/src/components/edit/api.ts +8 -8
- package/src/components/edit/fileTypes.ts +75 -55
package/.turbo/turbo-build.log
CHANGED
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
[34mCLI[39m Target: es2022
|
|
10
10
|
[34mCLI[39m Cleaning output folder
|
|
11
11
|
[34mESM[39m Build start
|
|
12
|
-
[32mESM[39m [1mdist/index.js [22m[32m104.
|
|
13
|
-
[32mESM[39m ⚡️ Build success in
|
|
12
|
+
[32mESM[39m [1mdist/index.js [22m[32m104.93 KB[39m
|
|
13
|
+
[32mESM[39m ⚡️ Build success in 252ms
|
package/dist/index.js
CHANGED
|
@@ -1013,8 +1013,28 @@ function SaveStatusButton({
|
|
|
1013
1013
|
|
|
1014
1014
|
// src/components/edit/fileTypes.ts
|
|
1015
1015
|
var COMPILABLE_EXTENSIONS = [".tsx", ".jsx", ".ts", ".js"];
|
|
1016
|
-
var MEDIA_EXTENSIONS = [
|
|
1017
|
-
|
|
1016
|
+
var MEDIA_EXTENSIONS = [
|
|
1017
|
+
".svg",
|
|
1018
|
+
".png",
|
|
1019
|
+
".jpg",
|
|
1020
|
+
".jpeg",
|
|
1021
|
+
".gif",
|
|
1022
|
+
".webp",
|
|
1023
|
+
".mp4",
|
|
1024
|
+
".mov",
|
|
1025
|
+
".webm"
|
|
1026
|
+
];
|
|
1027
|
+
var TEXT_EXTENSIONS = [
|
|
1028
|
+
".json",
|
|
1029
|
+
".yaml",
|
|
1030
|
+
".yml",
|
|
1031
|
+
".md",
|
|
1032
|
+
".txt",
|
|
1033
|
+
".css",
|
|
1034
|
+
".html",
|
|
1035
|
+
".xml",
|
|
1036
|
+
".toml"
|
|
1037
|
+
];
|
|
1018
1038
|
var EXTENSION_TO_LANGUAGE = {
|
|
1019
1039
|
".tsx": "tsx",
|
|
1020
1040
|
".jsx": "jsx",
|
|
@@ -2841,7 +2861,7 @@ function ServicesInspector({
|
|
|
2841
2861
|
),
|
|
2842
2862
|
/* @__PURE__ */ jsxs(DialogComponent, { open, onOpenChange: setOpen, children: [
|
|
2843
2863
|
/* @__PURE__ */ jsxs(DialogHeaderComponent, { children: [
|
|
2844
|
-
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: "
|
|
2864
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: "Services" }),
|
|
2845
2865
|
/* @__PURE__ */ jsx(DialogCloseComponent, { onClose: () => setOpen(false) })
|
|
2846
2866
|
] }),
|
|
2847
2867
|
/* @__PURE__ */ jsx(DialogContentComponent, { className: "space-y-3 max-h-96 overflow-auto", children: namespaces.map((ns) => /* @__PURE__ */ jsxs("details", { open: namespaces.length === 1, children: [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aprovan/patchwork-editor",
|
|
3
|
-
"version": "0.1.2-dev.
|
|
3
|
+
"version": "0.1.2-dev.f456953",
|
|
4
4
|
"description": "Components for facilitating widget generation and editing",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"shiki": "^3.22.0",
|
|
26
26
|
"tailwind-merge": "^3.4.0",
|
|
27
27
|
"tiptap-markdown": "^0.9.0",
|
|
28
|
-
"@aprovan/
|
|
29
|
-
"@aprovan/
|
|
28
|
+
"@aprovan/bobbin": "0.1.0-dev.f456953",
|
|
29
|
+
"@aprovan/patchwork-compiler": "0.1.2-dev.f456953"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -133,7 +133,7 @@ export function ServicesInspector({
|
|
|
133
133
|
|
|
134
134
|
<DialogComponent open={open} onOpenChange={setOpen}>
|
|
135
135
|
<DialogHeaderComponent>
|
|
136
|
-
<h2 className="text-lg font-semibold">
|
|
136
|
+
<h2 className="text-lg font-semibold">Services</h2>
|
|
137
137
|
<DialogCloseComponent onClose={() => setOpen(false)} />
|
|
138
138
|
</DialogHeaderComponent>
|
|
139
139
|
<DialogContentComponent className="space-y-3 max-h-96 overflow-auto">
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { applyDiffs, hasDiffBlocks, parseEditResponse } from
|
|
2
|
-
import type { EditRequest, EditResponse } from
|
|
1
|
+
import { applyDiffs, hasDiffBlocks, parseEditResponse } from "../../lib/diff";
|
|
2
|
+
import type { EditRequest, EditResponse } from "./types";
|
|
3
3
|
|
|
4
4
|
export interface EditApiOptions {
|
|
5
5
|
endpoint?: string;
|
|
@@ -12,16 +12,16 @@ export async function sendEditRequest(
|
|
|
12
12
|
request: EditRequest,
|
|
13
13
|
options: EditApiOptions = {},
|
|
14
14
|
): Promise<EditResponse> {
|
|
15
|
-
const { endpoint =
|
|
15
|
+
const { endpoint = "/api/edit", onProgress, sanitize = true } = options;
|
|
16
16
|
|
|
17
17
|
const response = await fetch(endpoint, {
|
|
18
|
-
method:
|
|
19
|
-
headers: {
|
|
18
|
+
method: "POST",
|
|
19
|
+
headers: { "Content-Type": "application/json" },
|
|
20
20
|
body: JSON.stringify(request),
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
if (!response.ok) {
|
|
24
|
-
throw new Error(
|
|
24
|
+
throw new Error("Edit request failed");
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const text = await streamResponse(response, onProgress);
|
|
@@ -42,7 +42,7 @@ export async function sendEditRequest(
|
|
|
42
42
|
// Provide detailed context about failed diffs for better error feedback
|
|
43
43
|
const failedDetails = result.failed
|
|
44
44
|
.map((f, i) => `[${i + 1}] "${f}"`)
|
|
45
|
-
.join(
|
|
45
|
+
.join("\n");
|
|
46
46
|
throw new Error(
|
|
47
47
|
`Failed to apply ${parsed.diffs.length} diff(s). None of the SEARCH blocks matched the code.\n\nFailed searches:\n${failedDetails}\n\nThis usually means the code has changed or the SEARCH text doesn't match exactly.`,
|
|
48
48
|
);
|
|
@@ -71,7 +71,7 @@ async function streamResponse(
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
const decoder = new TextDecoder();
|
|
74
|
-
let fullText =
|
|
74
|
+
let fullText = "";
|
|
75
75
|
const emittedNotes = new Set<string>();
|
|
76
76
|
|
|
77
77
|
let done = false;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type FileCategory =
|
|
1
|
+
export type FileCategory = "compilable" | "text" | "media" | "binary";
|
|
2
2
|
|
|
3
3
|
export interface FileTypeInfo {
|
|
4
4
|
category: FileCategory;
|
|
@@ -6,55 +6,75 @@ export interface FileTypeInfo {
|
|
|
6
6
|
mimeType: string;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
const COMPILABLE_EXTENSIONS = [
|
|
10
|
-
const MEDIA_EXTENSIONS = [
|
|
11
|
-
|
|
9
|
+
const COMPILABLE_EXTENSIONS = [".tsx", ".jsx", ".ts", ".js"];
|
|
10
|
+
const MEDIA_EXTENSIONS = [
|
|
11
|
+
".svg",
|
|
12
|
+
".png",
|
|
13
|
+
".jpg",
|
|
14
|
+
".jpeg",
|
|
15
|
+
".gif",
|
|
16
|
+
".webp",
|
|
17
|
+
".mp4",
|
|
18
|
+
".mov",
|
|
19
|
+
".webm",
|
|
20
|
+
];
|
|
21
|
+
const TEXT_EXTENSIONS = [
|
|
22
|
+
".json",
|
|
23
|
+
".yaml",
|
|
24
|
+
".yml",
|
|
25
|
+
".md",
|
|
26
|
+
".txt",
|
|
27
|
+
".css",
|
|
28
|
+
".html",
|
|
29
|
+
".xml",
|
|
30
|
+
".toml",
|
|
31
|
+
];
|
|
12
32
|
|
|
13
33
|
const EXTENSION_TO_LANGUAGE: Record<string, string> = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
".tsx": "tsx",
|
|
35
|
+
".jsx": "jsx",
|
|
36
|
+
".ts": "typescript",
|
|
37
|
+
".js": "javascript",
|
|
38
|
+
".json": "json",
|
|
39
|
+
".yaml": "yaml",
|
|
40
|
+
".yml": "yaml",
|
|
41
|
+
".md": "markdown",
|
|
42
|
+
".txt": "text",
|
|
43
|
+
".css": "css",
|
|
44
|
+
".html": "html",
|
|
45
|
+
".xml": "xml",
|
|
46
|
+
".toml": "toml",
|
|
47
|
+
".svg": "xml",
|
|
28
48
|
};
|
|
29
49
|
|
|
30
50
|
const EXTENSION_TO_MIME: Record<string, string> = {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
".tsx": "text/typescript-jsx",
|
|
52
|
+
".jsx": "text/javascript-jsx",
|
|
53
|
+
".ts": "text/typescript",
|
|
54
|
+
".js": "text/javascript",
|
|
55
|
+
".json": "application/json",
|
|
56
|
+
".yaml": "text/yaml",
|
|
57
|
+
".yml": "text/yaml",
|
|
58
|
+
".md": "text/markdown",
|
|
59
|
+
".txt": "text/plain",
|
|
60
|
+
".css": "text/css",
|
|
61
|
+
".html": "text/html",
|
|
62
|
+
".xml": "application/xml",
|
|
63
|
+
".toml": "text/toml",
|
|
64
|
+
".svg": "image/svg+xml",
|
|
65
|
+
".png": "image/png",
|
|
66
|
+
".jpg": "image/jpeg",
|
|
67
|
+
".jpeg": "image/jpeg",
|
|
68
|
+
".gif": "image/gif",
|
|
69
|
+
".webp": "image/webp",
|
|
70
|
+
".mp4": "video/mp4",
|
|
71
|
+
".mov": "video/quicktime",
|
|
72
|
+
".webm": "video/webm",
|
|
53
73
|
};
|
|
54
74
|
|
|
55
75
|
function getExtension(path: string): string {
|
|
56
|
-
const lastDot = path.lastIndexOf(
|
|
57
|
-
if (lastDot === -1) return
|
|
76
|
+
const lastDot = path.lastIndexOf(".");
|
|
77
|
+
if (lastDot === -1) return "";
|
|
58
78
|
return path.slice(lastDot).toLowerCase();
|
|
59
79
|
}
|
|
60
80
|
|
|
@@ -63,32 +83,32 @@ export function getFileType(path: string): FileTypeInfo {
|
|
|
63
83
|
|
|
64
84
|
if (COMPILABLE_EXTENSIONS.includes(ext)) {
|
|
65
85
|
return {
|
|
66
|
-
category:
|
|
86
|
+
category: "compilable",
|
|
67
87
|
language: EXTENSION_TO_LANGUAGE[ext] ?? null,
|
|
68
|
-
mimeType: EXTENSION_TO_MIME[ext] ??
|
|
88
|
+
mimeType: EXTENSION_TO_MIME[ext] ?? "text/plain",
|
|
69
89
|
};
|
|
70
90
|
}
|
|
71
91
|
|
|
72
92
|
if (TEXT_EXTENSIONS.includes(ext)) {
|
|
73
93
|
return {
|
|
74
|
-
category:
|
|
94
|
+
category: "text",
|
|
75
95
|
language: EXTENSION_TO_LANGUAGE[ext] ?? null,
|
|
76
|
-
mimeType: EXTENSION_TO_MIME[ext] ??
|
|
96
|
+
mimeType: EXTENSION_TO_MIME[ext] ?? "text/plain",
|
|
77
97
|
};
|
|
78
98
|
}
|
|
79
99
|
|
|
80
100
|
if (MEDIA_EXTENSIONS.includes(ext)) {
|
|
81
101
|
return {
|
|
82
|
-
category:
|
|
83
|
-
language: ext ===
|
|
84
|
-
mimeType: EXTENSION_TO_MIME[ext] ??
|
|
102
|
+
category: "media",
|
|
103
|
+
language: ext === ".svg" ? "xml" : null,
|
|
104
|
+
mimeType: EXTENSION_TO_MIME[ext] ?? "application/octet-stream",
|
|
85
105
|
};
|
|
86
106
|
}
|
|
87
107
|
|
|
88
108
|
return {
|
|
89
|
-
category:
|
|
109
|
+
category: "binary",
|
|
90
110
|
language: null,
|
|
91
|
-
mimeType:
|
|
111
|
+
mimeType: "application/octet-stream",
|
|
92
112
|
};
|
|
93
113
|
}
|
|
94
114
|
|
|
@@ -105,7 +125,7 @@ export function isTextFile(path: string): boolean {
|
|
|
105
125
|
}
|
|
106
126
|
|
|
107
127
|
export function isMarkdownFile(path: string): boolean {
|
|
108
|
-
return getExtension(path) ===
|
|
128
|
+
return getExtension(path) === ".md";
|
|
109
129
|
}
|
|
110
130
|
|
|
111
131
|
export function isPreviewable(path: string): boolean {
|
|
@@ -119,15 +139,15 @@ export function getLanguageFromExt(path: string): string | null {
|
|
|
119
139
|
|
|
120
140
|
export function getMimeType(path: string): string {
|
|
121
141
|
const ext = getExtension(path);
|
|
122
|
-
return EXTENSION_TO_MIME[ext] ??
|
|
142
|
+
return EXTENSION_TO_MIME[ext] ?? "application/octet-stream";
|
|
123
143
|
}
|
|
124
144
|
|
|
125
145
|
export function isImageFile(path: string): boolean {
|
|
126
146
|
const ext = getExtension(path);
|
|
127
|
-
return [
|
|
147
|
+
return [".svg", ".png", ".jpg", ".jpeg", ".gif", ".webp"].includes(ext);
|
|
128
148
|
}
|
|
129
149
|
|
|
130
150
|
export function isVideoFile(path: string): boolean {
|
|
131
151
|
const ext = getExtension(path);
|
|
132
|
-
return [
|
|
152
|
+
return [".mp4", ".mov", ".webm"].includes(ext);
|
|
133
153
|
}
|