@upstart.gg/vite-plugins 0.0.39 → 0.0.40

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 (64) hide show
  1. package/dist/upstart-editor-api.d.ts +79 -0
  2. package/dist/upstart-editor-api.d.ts.map +1 -0
  3. package/dist/upstart-editor-api.js +208 -0
  4. package/dist/upstart-editor-api.js.map +1 -0
  5. package/dist/vite-plugin-upstart-attrs.d.ts +3 -3
  6. package/dist/vite-plugin-upstart-attrs.d.ts.map +1 -1
  7. package/dist/vite-plugin-upstart-attrs.js +227 -25
  8. package/dist/vite-plugin-upstart-attrs.js.map +1 -1
  9. package/dist/vite-plugin-upstart-branding/plugin.d.ts +17 -0
  10. package/dist/vite-plugin-upstart-branding/plugin.d.ts.map +1 -0
  11. package/dist/vite-plugin-upstart-branding/plugin.js +41 -0
  12. package/dist/vite-plugin-upstart-branding/plugin.js.map +1 -0
  13. package/dist/vite-plugin-upstart-branding/runtime.d.ts +10 -0
  14. package/dist/vite-plugin-upstart-branding/runtime.d.ts.map +1 -0
  15. package/dist/vite-plugin-upstart-branding/runtime.js +118 -0
  16. package/dist/vite-plugin-upstart-branding/runtime.js.map +1 -0
  17. package/dist/vite-plugin-upstart-branding/types.d.ts +14 -0
  18. package/dist/vite-plugin-upstart-branding/types.d.ts.map +1 -0
  19. package/dist/vite-plugin-upstart-branding/types.js +1 -0
  20. package/dist/vite-plugin-upstart-editor/plugin.d.ts +3 -3
  21. package/dist/vite-plugin-upstart-editor/plugin.d.ts.map +1 -1
  22. package/dist/vite-plugin-upstart-editor/plugin.js +3 -16
  23. package/dist/vite-plugin-upstart-editor/plugin.js.map +1 -1
  24. package/dist/vite-plugin-upstart-editor/runtime/click-handler.js +25 -11
  25. package/dist/vite-plugin-upstart-editor/runtime/click-handler.js.map +1 -1
  26. package/dist/vite-plugin-upstart-editor/runtime/error-handler.d.ts +5 -0
  27. package/dist/vite-plugin-upstart-editor/runtime/error-handler.d.ts.map +1 -0
  28. package/dist/vite-plugin-upstart-editor/runtime/error-handler.js +16 -0
  29. package/dist/vite-plugin-upstart-editor/runtime/error-handler.js.map +1 -0
  30. package/dist/vite-plugin-upstart-editor/runtime/hover-overlay.js +1 -1
  31. package/dist/vite-plugin-upstart-editor/runtime/hover-overlay.js.map +1 -1
  32. package/dist/vite-plugin-upstart-editor/runtime/index.d.ts +2 -1
  33. package/dist/vite-plugin-upstart-editor/runtime/index.d.ts.map +1 -1
  34. package/dist/vite-plugin-upstart-editor/runtime/index.js +42 -7
  35. package/dist/vite-plugin-upstart-editor/runtime/index.js.map +1 -1
  36. package/dist/vite-plugin-upstart-editor/runtime/text-editor.d.ts +6 -1
  37. package/dist/vite-plugin-upstart-editor/runtime/text-editor.d.ts.map +1 -1
  38. package/dist/vite-plugin-upstart-editor/runtime/text-editor.js +423 -129
  39. package/dist/vite-plugin-upstart-editor/runtime/text-editor.js.map +1 -1
  40. package/dist/vite-plugin-upstart-editor/runtime/types.d.ts +18 -10
  41. package/dist/vite-plugin-upstart-editor/runtime/types.d.ts.map +1 -1
  42. package/dist/vite-plugin-upstart-theme.d.ts +3 -3
  43. package/dist/vite-plugin-upstart-theme.d.ts.map +1 -1
  44. package/dist/vite-plugin-upstart-theme.js +1 -3
  45. package/dist/vite-plugin-upstart-theme.js.map +1 -1
  46. package/package.json +12 -4
  47. package/src/tests/upstart-editor-api.test.ts +98 -174
  48. package/src/tests/vite-plugin-upstart-attrs.test.ts +408 -105
  49. package/src/tests/vite-plugin-upstart-branding.test.ts +90 -0
  50. package/src/tests/vite-plugin-upstart-editor.test.ts +1 -2
  51. package/src/upstart-editor-api.ts +90 -29
  52. package/src/vite-plugin-upstart-attrs.ts +376 -38
  53. package/src/vite-plugin-upstart-branding/plugin.ts +59 -0
  54. package/src/vite-plugin-upstart-branding/runtime.ts +128 -0
  55. package/src/vite-plugin-upstart-branding/types.ts +10 -0
  56. package/src/vite-plugin-upstart-editor/plugin.ts +4 -19
  57. package/src/vite-plugin-upstart-editor/runtime/click-handler.ts +25 -12
  58. package/src/vite-plugin-upstart-editor/runtime/error-handler.ts +12 -0
  59. package/src/vite-plugin-upstart-editor/runtime/hover-overlay.ts +1 -1
  60. package/src/vite-plugin-upstart-editor/runtime/index.ts +39 -5
  61. package/src/vite-plugin-upstart-editor/runtime/text-editor.ts +518 -141
  62. package/src/vite-plugin-upstart-editor/runtime/types.ts +18 -4
  63. package/src/vite-plugin-upstart-theme.ts +0 -3
  64. package/src/vite-plugin-upstart-editor/PLAN.md +0 -1391
@@ -22,201 +22,117 @@ describe("UpstartEditorAPI", () => {
22
22
  });
23
23
 
24
24
  describe("editText", () => {
25
- test("should edit text content at correct offset", async () => {
26
- // Create a test source file
27
- const sourceContent = `<div>Hello World</div>`;
28
- const sourcePath = path.join(tempDir, "test.tsx");
29
- await fs.writeFile(sourcePath, sourceContent);
30
-
31
- // Create registry
32
- const registry: EditableRegistry = {
33
- version: 1,
34
- generatedAt: new Date().toISOString(),
35
- elements: {
36
- "test.tsx:1": {
37
- file: "test.tsx",
38
- type: "text",
39
- startOffset: 5,
40
- endOffset: 16,
41
- originalContent: "Hello World",
42
- context: { parentTag: "div" },
43
- },
44
- },
45
- };
46
- await fs.writeFile(registryPath, JSON.stringify(registry));
47
-
48
- // Edit the text
49
- const result = await api.editText("test.tsx:1", "Hello Universe");
25
+ async function writeLocaleFile(language: string, namespace: string, data: Record<string, unknown>) {
26
+ const dir = path.join(tempDir, "app", "locales", language);
27
+ await fs.mkdir(dir, { recursive: true });
28
+ await fs.writeFile(path.join(dir, `${namespace}.json`), JSON.stringify(data, null, 2) + "\n");
29
+ }
30
+
31
+ async function readLocaleFile(language: string, namespace: string) {
32
+ const content = await fs.readFile(
33
+ path.join(tempDir, "app", "locales", language, `${namespace}.json`),
34
+ "utf-8",
35
+ );
36
+ return JSON.parse(content);
37
+ }
38
+
39
+ test("should update a flat key in a locale file", async () => {
40
+ await writeLocaleFile("en", "translation", { greeting: "Hello" });
41
+
42
+ const result = await api.editText({
43
+ action: "editText",
44
+ language: "en",
45
+ namespace: "translation",
46
+ key: "greeting",
47
+ content: "Hi",
48
+ });
50
49
 
51
50
  expect(result.success).toBe(true);
52
-
53
- // Verify file was updated
54
- const updatedContent = await fs.readFile(sourcePath, "utf-8");
55
- expect(updatedContent).toBe("<div>Hello Universe</div>");
51
+ const data = await readLocaleFile("en", "translation");
52
+ expect(data.greeting).toBe("Hi");
56
53
  });
57
54
 
58
- test("should update registry after edit", async () => {
59
- const sourceContent = `<div>Original</div>`;
60
- const sourcePath = path.join(tempDir, "test.tsx");
61
- await fs.writeFile(sourcePath, sourceContent);
55
+ test("should update a flat dotted key when it exists", async () => {
56
+ await writeLocaleFile("en", "translation", { "nav.home": "Home" });
62
57
 
63
- const registry: EditableRegistry = {
64
- version: 1,
65
- generatedAt: new Date().toISOString(),
66
- elements: {
67
- "test.tsx:1": {
68
- file: "test.tsx",
69
- type: "text",
70
- startOffset: 5,
71
- endOffset: 13,
72
- originalContent: "Original",
73
- context: { parentTag: "div" },
74
- },
75
- },
76
- };
77
- await fs.writeFile(registryPath, JSON.stringify(registry));
78
-
79
- await api.editText("test.tsx:1", "Modified");
58
+ const result = await api.editText({
59
+ action: "editText",
60
+ language: "en",
61
+ namespace: "translation",
62
+ key: "nav.home",
63
+ content: "Dashboard",
64
+ });
80
65
 
81
- // Read updated registry
82
- const updatedRegistry = JSON.parse(await fs.readFile(registryPath, "utf-8"));
83
- expect(updatedRegistry.elements["test.tsx:1"].originalContent).toBe("Modified");
66
+ expect(result.success).toBe(true);
67
+ const data = await readLocaleFile("en", "translation");
68
+ expect(data["nav.home"]).toBe("Dashboard");
84
69
  });
85
70
 
86
- test("should shift subsequent offsets after edit", async () => {
87
- const sourceContent = `<div>First</div><span>Second</span>`;
88
- const sourcePath = path.join(tempDir, "test.tsx");
89
- await fs.writeFile(sourcePath, sourceContent);
90
-
91
- const registry: EditableRegistry = {
92
- version: 1,
93
- generatedAt: new Date().toISOString(),
94
- elements: {
95
- "test.tsx:1": {
96
- file: "test.tsx",
97
- type: "text",
98
- startOffset: 5,
99
- endOffset: 10,
100
- originalContent: "First",
101
- context: { parentTag: "div" },
102
- },
103
- "test.tsx:2": {
104
- file: "test.tsx",
105
- type: "text",
106
- startOffset: 22,
107
- endOffset: 28,
108
- originalContent: "Second",
109
- context: { parentTag: "span" },
110
- },
111
- },
112
- };
113
- await fs.writeFile(registryPath, JSON.stringify(registry));
114
-
115
- // Edit first element (adding 5 characters: "First" -> "First!!!!!")
116
- await api.editText("test.tsx:1", "First!!!!!");
71
+ test("should update a nested key via dot notation", async () => {
72
+ await writeLocaleFile("en", "translation", { nav: { home: "Home", about: "About" } });
117
73
 
118
- // Read updated registry
119
- const updatedRegistry = JSON.parse(await fs.readFile(registryPath, "utf-8"));
74
+ const result = await api.editText({
75
+ action: "editText",
76
+ language: "en",
77
+ namespace: "translation",
78
+ key: "nav.home",
79
+ content: "Dashboard",
80
+ });
120
81
 
121
- // Second element offset should have shifted by 5
122
- expect(updatedRegistry.elements["test.tsx:2"].startOffset).toBe(27);
123
- expect(updatedRegistry.elements["test.tsx:2"].endOffset).toBe(33);
82
+ expect(result.success).toBe(true);
83
+ const data = await readLocaleFile("en", "translation");
84
+ expect(data.nav.home).toBe("Dashboard");
85
+ expect(data.nav.about).toBe("About");
124
86
  });
125
87
 
126
- test("should fail if element not found", async () => {
127
- const registry: EditableRegistry = {
128
- version: 1,
129
- generatedAt: new Date().toISOString(),
130
- elements: {},
131
- };
132
- await fs.writeFile(registryPath, JSON.stringify(registry));
133
-
134
- const result = await api.editText("nonexistent:1", "New text");
88
+ test("should fail if locale file does not exist", async () => {
89
+ const result = await api.editText({
90
+ action: "editText",
91
+ language: "fr",
92
+ namespace: "translation",
93
+ key: "greeting",
94
+ content: "Bonjour",
95
+ });
135
96
 
136
97
  expect(result.success).toBe(false);
137
- expect(result.error).toContain("not found");
98
+ expect(result.error).toContain("Failed to read locale file");
138
99
  });
139
100
 
140
- test("should fail if element is not text type", async () => {
141
- const registry: EditableRegistry = {
142
- version: 1,
143
- generatedAt: new Date().toISOString(),
144
- elements: {
145
- "test.tsx:1": {
146
- file: "test.tsx",
147
- type: "className",
148
- startOffset: 5,
149
- endOffset: 10,
150
- originalContent: "px-4",
151
- context: { parentTag: "div" },
152
- },
153
- },
154
- };
155
- await fs.writeFile(registryPath, JSON.stringify(registry));
101
+ test("should fail if key does not exist", async () => {
102
+ await writeLocaleFile("en", "translation", { greeting: "Hello" });
156
103
 
157
- const result = await api.editText("test.tsx:1", "New text");
104
+ const result = await api.editText({
105
+ action: "editText",
106
+ language: "en",
107
+ namespace: "translation",
108
+ key: "farewell",
109
+ content: "Bye",
110
+ });
158
111
 
159
112
  expect(result.success).toBe(false);
160
- expect(result.error).toContain("not a text element");
113
+ expect(result.error).toContain("not found");
161
114
  });
162
115
 
163
- test("should find content by search if offset has shifted", async () => {
164
- // Simulate a file where content has shifted (e.g., due to manual edit)
165
- const sourceContent = `\n\n<div>Hello World</div>`;
166
- const sourcePath = path.join(tempDir, "test.tsx");
167
- await fs.writeFile(sourcePath, sourceContent);
168
-
169
- // Registry has old offsets (before the newlines were added)
170
- const registry: EditableRegistry = {
171
- version: 1,
172
- generatedAt: new Date().toISOString(),
173
- elements: {
174
- "test.tsx:1": {
175
- file: "test.tsx",
176
- type: "text",
177
- startOffset: 5, // Old offset (now content is at offset 7)
178
- endOffset: 16,
179
- originalContent: "Hello World",
180
- context: { parentTag: "div" },
181
- },
182
- },
183
- };
184
- await fs.writeFile(registryPath, JSON.stringify(registry));
185
-
186
- // Should still find and edit the content
187
- const result = await api.editText("test.tsx:1", "Hello Universe");
116
+ test("should preserve other keys in the file", async () => {
117
+ await writeLocaleFile("en", "translation", {
118
+ greeting: "Hello",
119
+ farewell: "Goodbye",
120
+ title: "Welcome",
121
+ });
122
+
123
+ const result = await api.editText({
124
+ action: "editText",
125
+ language: "en",
126
+ namespace: "translation",
127
+ key: "greeting",
128
+ content: "Hi",
129
+ });
188
130
 
189
131
  expect(result.success).toBe(true);
190
-
191
- const updatedContent = await fs.readFile(sourcePath, "utf-8");
192
- expect(updatedContent).toBe("\n\n<div>Hello Universe</div>");
193
- });
194
-
195
- test("should fail if original content no longer exists", async () => {
196
- const sourceContent = `<div>Completely Different</div>`;
197
- const sourcePath = path.join(tempDir, "test.tsx");
198
- await fs.writeFile(sourcePath, sourceContent);
199
-
200
- const registry: EditableRegistry = {
201
- version: 1,
202
- generatedAt: new Date().toISOString(),
203
- elements: {
204
- "test.tsx:1": {
205
- file: "test.tsx",
206
- type: "text",
207
- startOffset: 5,
208
- endOffset: 16,
209
- originalContent: "Hello World",
210
- context: { parentTag: "div" },
211
- },
212
- },
213
- };
214
- await fs.writeFile(registryPath, JSON.stringify(registry));
215
-
216
- const result = await api.editText("test.tsx:1", "New content");
217
-
218
- expect(result.success).toBe(false);
219
- expect(result.error).toContain("not found in file");
132
+ const data = await readLocaleFile("en", "translation");
133
+ expect(data.greeting).toBe("Hi");
134
+ expect(data.farewell).toBe("Goodbye");
135
+ expect(data.title).toBe("Welcome");
220
136
  });
221
137
  });
222
138
 
@@ -242,7 +158,11 @@ describe("UpstartEditorAPI", () => {
242
158
  };
243
159
  await fs.writeFile(registryPath, JSON.stringify(registry));
244
160
 
245
- const result = await api.editClassName("test.tsx:1", "px-8 py-4 bg-blue-500");
161
+ const result = await api.editClassName({
162
+ action: "editClassName",
163
+ id: "test.tsx:1",
164
+ className: "px-8 py-4 bg-blue-500",
165
+ });
246
166
 
247
167
  expect(result.success).toBe(true);
248
168
 
@@ -267,7 +187,11 @@ describe("UpstartEditorAPI", () => {
267
187
  };
268
188
  await fs.writeFile(registryPath, JSON.stringify(registry));
269
189
 
270
- const result = await api.editClassName("test.tsx:1", "new-class");
190
+ const result = await api.editClassName({
191
+ action: "editClassName",
192
+ id: "test.tsx:1",
193
+ className: "new-class",
194
+ });
271
195
 
272
196
  expect(result.success).toBe(false);
273
197
  expect(result.error).toContain("not a className element");