@webround/editor 0.0.0-stage → 0.2.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/blocks.d.ts +90 -0
- package/dist/blocks.js +119 -0
- package/dist/bridge.d.ts +96 -0
- package/dist/bridge.js +970 -0
- package/dist/check/aria.d.ts +19 -0
- package/dist/check/aria.js +106 -0
- package/dist/check/cli.d.ts +3 -0
- package/dist/check/cli.js +30 -0
- package/dist/check/css.d.ts +13 -0
- package/dist/check/css.js +63 -0
- package/dist/check/html.d.ts +8 -0
- package/dist/check/html.js +29 -0
- package/dist/check/index.d.ts +4 -0
- package/dist/check/index.js +5 -0
- package/dist/check/links.d.ts +7 -0
- package/dist/check/links.js +23 -0
- package/dist/check/orphans.d.ts +20 -0
- package/dist/check/orphans.js +57 -0
- package/dist/check/producer-code.d.ts +53 -0
- package/dist/check/producer-code.js +379 -0
- package/dist/check/producer-dom.d.ts +21 -0
- package/dist/check/producer-dom.js +52 -0
- package/dist/check/project.d.ts +20 -0
- package/dist/check/project.js +51 -0
- package/dist/check/rules.d.ts +7 -0
- package/dist/check/rules.js +517 -0
- package/dist/check/types.d.ts +160 -0
- package/dist/check/types.js +22 -0
- package/dist/components/WrAltcha.d.ts +5 -0
- package/dist/components/WrAltcha.js +8 -0
- package/dist/components/WrButton.d.ts +8 -0
- package/dist/components/WrButton.js +34 -0
- package/dist/components/WrForm.d.ts +6 -0
- package/dist/components/WrForm.js +29 -0
- package/dist/components/WrFormPrivacy.d.ts +4 -0
- package/dist/components/WrFormPrivacy.js +7 -0
- package/dist/components/WrFormSuccess.d.ts +4 -0
- package/dist/components/WrFormSuccess.js +12 -0
- package/dist/components/WrIframe.d.ts +12 -0
- package/dist/components/WrIframe.js +30 -0
- package/dist/components/WrImage.d.ts +9 -0
- package/dist/components/WrImage.js +28 -0
- package/dist/components/WrInput.d.ts +8 -0
- package/dist/components/WrInput.js +29 -0
- package/dist/components/WrLink.d.ts +10 -0
- package/dist/components/WrLink.js +38 -0
- package/dist/components/WrNav.d.ts +26 -0
- package/dist/components/WrNav.js +30 -0
- package/dist/components/WrSection.d.ts +11 -0
- package/dist/components/WrSection.js +5 -0
- package/dist/components/WrShared.d.ts +12 -0
- package/dist/components/WrShared.js +20 -0
- package/dist/components/WrText.d.ts +11 -0
- package/dist/components/WrText.js +41 -0
- package/dist/components/WrVideo.d.ts +9 -0
- package/dist/components/WrVideo.js +73 -0
- package/dist/components/text-editor/CodeThemeContext.d.ts +8 -0
- package/dist/components/text-editor/CodeThemeContext.js +10 -0
- package/dist/components/text-editor/ExampleTheme.d.ts +77 -0
- package/dist/components/text-editor/ExampleTheme.js +76 -0
- package/dist/components/text-editor/ToolbarContext.d.ts +17 -0
- package/dist/components/text-editor/ToolbarContext.js +32 -0
- package/dist/components/text-editor/WrTextEditor.d.ts +13 -0
- package/dist/components/text-editor/WrTextEditor.js +48 -0
- package/dist/components/text-editor/common/constants.d.ts +109 -0
- package/dist/components/text-editor/common/constants.js +58 -0
- package/dist/components/text-editor/common/surface.d.ts +3 -0
- package/dist/components/text-editor/common/surface.js +8 -0
- package/dist/components/text-editor/common/utils.d.ts +7 -0
- package/dist/components/text-editor/common/utils.js +78 -0
- package/dist/components/text-editor/hooks/useLexicalCommitOnBlur.d.ts +5 -0
- package/dist/components/text-editor/hooks/useLexicalCommitOnBlur.js +41 -0
- package/dist/components/text-editor/hooks/useLexicalMarkdown.d.ts +33 -0
- package/dist/components/text-editor/hooks/useLexicalMarkdown.js +284 -0
- package/dist/components/text-editor/nodes/CodeBlockNode.d.ts +23 -0
- package/dist/components/text-editor/nodes/CodeBlockNode.js +138 -0
- package/dist/components/text-editor/nodes/HorizontalRuleNode.d.ts +13 -0
- package/dist/components/text-editor/nodes/HorizontalRuleNode.js +22 -0
- package/dist/components/text-editor/plugins/CodeBlockPlugin.d.ts +2 -0
- package/dist/components/text-editor/plugins/CodeBlockPlugin.js +38 -0
- package/dist/components/text-editor/plugins/FontPlugin.d.ts +12 -0
- package/dist/components/text-editor/plugins/FontPlugin.js +114 -0
- package/dist/components/text-editor/plugins/FontSizePlugin.d.ts +7 -0
- package/dist/components/text-editor/plugins/FontSizePlugin.js +105 -0
- package/dist/components/text-editor/plugins/FontWeightPlugin.d.ts +6 -0
- package/dist/components/text-editor/plugins/FontWeightPlugin.js +103 -0
- package/dist/components/text-editor/plugins/HTMLTagPlugin.d.ts +7 -0
- package/dist/components/text-editor/plugins/HTMLTagPlugin.js +82 -0
- package/dist/components/text-editor/plugins/HorizontalRulePlugin.d.ts +2 -0
- package/dist/components/text-editor/plugins/HorizontalRulePlugin.js +35 -0
- package/dist/components/text-editor/plugins/LineSpacingPlugin.d.ts +7 -0
- package/dist/components/text-editor/plugins/LineSpacingPlugin.js +83 -0
- package/dist/components/text-editor/plugins/LinkPlugin.d.ts +8 -0
- package/dist/components/text-editor/plugins/LinkPlugin.js +183 -0
- package/dist/components/text-editor/plugins/ListToolbarPlugin.d.ts +7 -0
- package/dist/components/text-editor/plugins/ListToolbarPlugin.js +40 -0
- package/dist/components/text-editor/plugins/LoadContentPlugin.d.ts +4 -0
- package/dist/components/text-editor/plugins/LoadContentPlugin.js +63 -0
- package/dist/components/text-editor/plugins/MarkdownExportPlugin.d.ts +4 -0
- package/dist/components/text-editor/plugins/MarkdownExportPlugin.js +17 -0
- package/dist/components/text-editor/plugins/MarkdownPastePlugin.d.ts +2 -0
- package/dist/components/text-editor/plugins/MarkdownPastePlugin.js +45 -0
- package/dist/components/text-editor/plugins/SanitizePastePlugin.d.ts +3 -0
- package/dist/components/text-editor/plugins/SanitizePastePlugin.js +40 -0
- package/dist/components/text-editor/plugins/TextAlignPlugin.d.ts +7 -0
- package/dist/components/text-editor/plugins/TextAlignPlugin.js +65 -0
- package/dist/components/text-editor/plugins/TextColorPlugin.d.ts +7 -0
- package/dist/components/text-editor/plugins/TextColorPlugin.js +117 -0
- package/dist/components/text-editor/plugins/ToolbarPlugin.d.ts +10 -0
- package/dist/components/text-editor/plugins/ToolbarPlugin.js +73 -0
- package/dist/components/text-editor/theme-colors.d.ts +11 -0
- package/dist/components/text-editor/theme-colors.js +28 -0
- package/dist/context/WrAppContext.d.ts +35 -0
- package/dist/context/WrAppContext.js +113 -0
- package/dist/context/WrLayout.d.ts +15 -0
- package/dist/context/WrLayout.js +22 -0
- package/dist/context/WrPageContext.d.ts +28 -0
- package/dist/context/WrPageContext.js +282 -0
- package/dist/context/restoreValues.d.ts +2 -0
- package/dist/context/restoreValues.js +6 -0
- package/dist/contrast.d.ts +45 -0
- package/dist/contrast.js +122 -0
- package/dist/drop.d.ts +7 -0
- package/dist/drop.js +51 -0
- package/dist/gaps.d.ts +14 -0
- package/dist/gaps.js +50 -0
- package/dist/hooks/useWrMessage.d.ts +5 -0
- package/dist/hooks/useWrMessage.js +24 -0
- package/dist/hooks/useWrSave.d.ts +2 -0
- package/dist/hooks/useWrSave.js +11 -0
- package/dist/index.css +467 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +20 -0
- package/dist/interactive.d.ts +8 -0
- package/dist/interactive.js +13 -0
- package/dist/measure-rules.d.ts +34 -0
- package/dist/measure-rules.js +54 -0
- package/dist/measure.d.ts +11 -0
- package/dist/measure.js +139 -0
- package/dist/messages.d.ts +860 -0
- package/dist/messages.js +2 -0
- package/dist/nav.d.ts +5 -0
- package/dist/nav.js +10 -0
- package/dist/operations/animations-store.d.ts +6 -0
- package/dist/operations/animations-store.js +63 -0
- package/dist/operations/cli.d.ts +3 -0
- package/dist/operations/cli.js +52 -0
- package/dist/operations/comments-store.d.ts +17 -0
- package/dist/operations/comments-store.js +62 -0
- package/dist/operations/context.d.ts +12 -0
- package/dist/operations/context.js +35 -0
- package/dist/operations/define.d.ts +81 -0
- package/dist/operations/define.js +86 -0
- package/dist/operations/index.d.ts +6 -0
- package/dist/operations/index.js +6 -0
- package/dist/operations/ops/check.d.ts +5 -0
- package/dist/operations/ops/check.js +53 -0
- package/dist/operations/ops/comments.d.ts +6 -0
- package/dist/operations/ops/comments.js +133 -0
- package/dist/operations/ops/content.d.ts +16 -0
- package/dist/operations/ops/content.js +73 -0
- package/dist/operations/ops/json.d.ts +4 -0
- package/dist/operations/ops/json.js +27 -0
- package/dist/operations/ops/langs.d.ts +4 -0
- package/dist/operations/ops/langs.js +32 -0
- package/dist/operations/ops/nodes.d.ts +8 -0
- package/dist/operations/ops/nodes.js +270 -0
- package/dist/operations/ops/pages.d.ts +8 -0
- package/dist/operations/ops/pages.js +154 -0
- package/dist/operations/ops/project.d.ts +36 -0
- package/dist/operations/ops/project.js +97 -0
- package/dist/operations/ops/seo.d.ts +17 -0
- package/dist/operations/ops/seo.js +358 -0
- package/dist/operations/ops/style.d.ts +76 -0
- package/dist/operations/ops/style.js +268 -0
- package/dist/operations/ops/stylesets.d.ts +9 -0
- package/dist/operations/ops/stylesets.js +145 -0
- package/dist/operations/ops/theme.d.ts +6 -0
- package/dist/operations/ops/theme.js +304 -0
- package/dist/operations/registry.d.ts +8 -0
- package/dist/operations/registry.js +19 -0
- package/dist/operations/stylesets-store.d.ts +50 -0
- package/dist/operations/stylesets-store.js +216 -0
- package/dist/registry.d.ts +5 -0
- package/dist/registry.js +24 -0
- package/dist/save.d.ts +65 -0
- package/dist/save.js +86 -0
- package/dist/schema.d.ts +69 -0
- package/dist/schema.js +110 -0
- package/dist/scope.d.ts +41 -0
- package/dist/scope.js +44 -0
- package/dist/vite-plugins/ast.d.ts +3 -0
- package/dist/vite-plugins/ast.js +238 -0
- package/dist/vite-plugins/core-swap.d.ts +3 -0
- package/dist/vite-plugins/core-swap.js +57 -0
- package/dist/vite-plugins/create-page.d.ts +4 -0
- package/dist/vite-plugins/create-page.js +59 -0
- package/dist/vite-plugins/guard.d.ts +15 -0
- package/dist/vite-plugins/guard.js +35 -0
- package/dist/vite-plugins/head.d.ts +13 -0
- package/dist/vite-plugins/head.js +53 -0
- package/dist/vite-plugins/index.d.ts +7 -0
- package/dist/vite-plugins/index.js +7 -0
- package/dist/vite-plugins/jsx-tree.d.ts +118 -0
- package/dist/vite-plugins/jsx-tree.js +686 -0
- package/dist/vite-plugins/langs.d.ts +3 -0
- package/dist/vite-plugins/langs.js +44 -0
- package/dist/vite-plugins/operations.d.ts +10 -0
- package/dist/vite-plugins/operations.js +66 -0
- package/dist/vite-plugins/pages-api.d.ts +3 -0
- package/dist/vite-plugins/pages-api.js +112 -0
- package/dist/vite-plugins/pages.d.ts +3 -0
- package/dist/vite-plugins/pages.js +64 -0
- package/dist/vite-plugins/read.d.ts +3 -0
- package/dist/vite-plugins/read.js +45 -0
- package/dist/vite-plugins/seo-files.d.ts +8 -0
- package/dist/vite-plugins/seo-files.js +42 -0
- package/dist/vite-plugins/theme.d.ts +3 -0
- package/dist/vite-plugins/theme.js +207 -0
- package/dist/vite-plugins/update.d.ts +3 -0
- package/dist/vite-plugins/update.js +46 -0
- package/dist/vite-plugins/wr-plugins.d.ts +15 -0
- package/dist/vite-plugins/wr-plugins.js +34 -0
- package/dist/vite-plugins.d.ts +11 -0
- package/dist/vite-plugins.js +518 -0
- package/package.json +96 -5
- package/README.md +0 -3
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { resolveInSrc, wrRoute } from './guard.js';
|
|
4
|
+
export function wrUpdatePlugin() {
|
|
5
|
+
return {
|
|
6
|
+
name: 'wr-update',
|
|
7
|
+
configureServer(server) {
|
|
8
|
+
wrRoute(server, '/wr/update', (req, res) => {
|
|
9
|
+
if (req.method !== 'PUT') {
|
|
10
|
+
res.statusCode = 405;
|
|
11
|
+
res.end();
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
let body = '';
|
|
15
|
+
req.on('data', chunk => body += chunk);
|
|
16
|
+
req.on('end', () => {
|
|
17
|
+
try {
|
|
18
|
+
const { file, patch } = JSON.parse(body);
|
|
19
|
+
const filePath = resolveInSrc(file);
|
|
20
|
+
if (!filePath) {
|
|
21
|
+
res.statusCode = 400;
|
|
22
|
+
res.end(JSON.stringify({ error: 'invalid file path' }));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const current = fs.existsSync(filePath) ? JSON.parse(fs.readFileSync(filePath, 'utf-8')) : {};
|
|
26
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
27
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
28
|
+
if (value === null)
|
|
29
|
+
delete current[key];
|
|
30
|
+
else
|
|
31
|
+
current[key] = value;
|
|
32
|
+
}
|
|
33
|
+
fs.writeFileSync(filePath, JSON.stringify(current, null, 2));
|
|
34
|
+
res.end('ok');
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
console.error('[wr-update] failed:', err);
|
|
38
|
+
res.statusCode = 500;
|
|
39
|
+
res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
export interface WrPluginsOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Host accettati dal dev server (header Host). Serve dietro a proxy/Worker, dove l'host è
|
|
5
|
+
* pubblico (es. ['.webround.net']). Non impostarlo in locale: lascia attiva la protezione di Vite.
|
|
6
|
+
*/
|
|
7
|
+
allowedHosts?: true | string[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Facade: tutti i plugin dell'editor, nell'ordine giusto. Il vite.config.ts di un progetto
|
|
11
|
+
* deve solo spargere `...wrPlugins()` accanto a react() e tailwindcss(); aggiungere un plugin
|
|
12
|
+
* nuovo qui lo rende disponibile a tutti i progetti con un semplice bump di versione.
|
|
13
|
+
*/
|
|
14
|
+
export declare function wrPlugins(options?: WrPluginsOptions): Plugin[];
|
|
15
|
+
//# sourceMappingURL=wr-plugins.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { wrPagesPlugin } from './pages.js';
|
|
2
|
+
import { wrLangsPlugin } from './langs.js';
|
|
3
|
+
import { wrCoreSwapPlugin } from './core-swap.js';
|
|
4
|
+
import { wrOperationsPlugin } from './operations.js';
|
|
5
|
+
import { wrSeoFilesPlugin } from './seo-files.js';
|
|
6
|
+
import { wrHeadPlugin } from './head.js';
|
|
7
|
+
// Imposta solo ciò che gli viene passato: nessun default che allenti la sicurezza in locale.
|
|
8
|
+
function wrServerConfigPlugin(allowedHosts) {
|
|
9
|
+
return {
|
|
10
|
+
name: 'wr-server-config',
|
|
11
|
+
config: () => ({ server: { allowedHosts } }),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Facade: tutti i plugin dell'editor, nell'ordine giusto. Il vite.config.ts di un progetto
|
|
16
|
+
* deve solo spargere `...wrPlugins()` accanto a react() e tailwindcss(); aggiungere un plugin
|
|
17
|
+
* nuovo qui lo rende disponibile a tutti i progetti con un semplice bump di versione.
|
|
18
|
+
*/
|
|
19
|
+
export function wrPlugins(options = {}) {
|
|
20
|
+
return [
|
|
21
|
+
...(options.allowedHosts ? [wrServerConfigPlugin(options.allowedHosts)] : []),
|
|
22
|
+
// The one door into the project for the editor's page (see operations/)
|
|
23
|
+
wrOperationsPlugin(),
|
|
24
|
+
wrPagesPlugin(),
|
|
25
|
+
wrLangsPlugin(),
|
|
26
|
+
// What a crawler must find in the HTML before any script runs (the Search Console tag): in dev and in the build
|
|
27
|
+
wrHeadPlugin(),
|
|
28
|
+
// robots.txt and the sitemaps, kept in step with the pages, the languages and the SEO data
|
|
29
|
+
{ ...wrSeoFilesPlugin(), apply: 'serve' },
|
|
30
|
+
// sostituisce il vecchio `command === 'serve'` del config: lo switch core/editor è solo dev
|
|
31
|
+
{ ...wrCoreSwapPlugin(), apply: 'serve' },
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=wr-plugins.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
export declare function wrUpdatePlugin(): Plugin;
|
|
3
|
+
export declare function wrReadPlugin(): Plugin;
|
|
4
|
+
export declare function wrCreatePagePlugin(): Plugin;
|
|
5
|
+
export declare function wrPageScaffold(component: string): string;
|
|
6
|
+
export declare function wrCoreSwapPlugin(): Plugin;
|
|
7
|
+
export declare function wrPagesPlugin(): Plugin;
|
|
8
|
+
export declare function wrPagesApiPlugin(): Plugin;
|
|
9
|
+
export declare function wrLangsPlugin(): Plugin;
|
|
10
|
+
export declare function wrAstPlugin(): Plugin;
|
|
11
|
+
//# sourceMappingURL=vite-plugins.d.ts.map
|
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { Project, SyntaxKind } from 'ts-morph';
|
|
4
|
+
import { getFields } from '@webround/editor/schema';
|
|
5
|
+
import { createRequire } from 'module';
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
export function wrUpdatePlugin() {
|
|
8
|
+
return {
|
|
9
|
+
name: 'wr-update',
|
|
10
|
+
configureServer(server) {
|
|
11
|
+
server.middlewares.use('/wr/update', (req, res) => {
|
|
12
|
+
if (req.method !== 'PUT') {
|
|
13
|
+
res.statusCode = 405;
|
|
14
|
+
res.end();
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
let body = '';
|
|
18
|
+
req.on('data', chunk => body += chunk);
|
|
19
|
+
req.on('end', () => {
|
|
20
|
+
try {
|
|
21
|
+
const { file, patch } = JSON.parse(body);
|
|
22
|
+
const filePath = path.resolve(process.cwd(), 'src', file);
|
|
23
|
+
const current = fs.existsSync(filePath) ? JSON.parse(fs.readFileSync(filePath, 'utf-8')) : {};
|
|
24
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
25
|
+
fs.writeFileSync(filePath, JSON.stringify({ ...current, ...patch }, null, 2));
|
|
26
|
+
res.end('ok');
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
console.error('[wr-update] failed:', err);
|
|
30
|
+
res.statusCode = 500;
|
|
31
|
+
res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function wrReadPlugin() {
|
|
39
|
+
return {
|
|
40
|
+
name: 'wr-read',
|
|
41
|
+
configureServer(server) {
|
|
42
|
+
server.middlewares.use('/wr/read', (req, res) => {
|
|
43
|
+
if (req.method !== 'GET') {
|
|
44
|
+
res.statusCode = 405;
|
|
45
|
+
res.end();
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const url = new URL(req.url ?? '', 'http://localhost');
|
|
50
|
+
const file = url.searchParams.get('file');
|
|
51
|
+
if (!file) {
|
|
52
|
+
res.statusCode = 400;
|
|
53
|
+
res.end(JSON.stringify({ error: 'file query param required' }));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const srcRoot = path.resolve(process.cwd(), 'src');
|
|
57
|
+
const filePath = path.resolve(srcRoot, file);
|
|
58
|
+
if (!filePath.startsWith(srcRoot + path.sep)) {
|
|
59
|
+
res.statusCode = 400;
|
|
60
|
+
res.end(JSON.stringify({ error: 'invalid file path' }));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (!fs.existsSync(filePath)) {
|
|
64
|
+
res.setHeader('Content-Type', 'application/json');
|
|
65
|
+
res.end(JSON.stringify(null));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const content = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
69
|
+
res.setHeader('Content-Type', 'application/json');
|
|
70
|
+
res.end(JSON.stringify(content));
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
console.error('[wr-read] failed:', err);
|
|
74
|
+
res.statusCode = 500;
|
|
75
|
+
res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
export function wrCreatePagePlugin() {
|
|
82
|
+
return {
|
|
83
|
+
name: 'wr-create-page',
|
|
84
|
+
configureServer(server) {
|
|
85
|
+
server.middlewares.use('/wr/create-page', (req, res) => {
|
|
86
|
+
if (req.method !== 'POST') {
|
|
87
|
+
res.statusCode = 405;
|
|
88
|
+
res.end();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
let body = '';
|
|
92
|
+
req.on('data', chunk => body += chunk);
|
|
93
|
+
req.on('end', () => {
|
|
94
|
+
try {
|
|
95
|
+
const { pageName, component, lazy } = JSON.parse(body);
|
|
96
|
+
const pagePath = path.resolve(process.cwd(), 'src', 'config', 'pages', `${pageName}.json`);
|
|
97
|
+
const componentPath = path.resolve(process.cwd(), 'src', 'pages', `${component}.tsx`);
|
|
98
|
+
const routesPath = path.resolve(process.cwd(), 'src', 'config', 'routes.json');
|
|
99
|
+
if (fs.existsSync(pagePath) || fs.existsSync(componentPath)) {
|
|
100
|
+
res.statusCode = 409;
|
|
101
|
+
res.end(JSON.stringify({ error: 'page or component already exists' }));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
fs.mkdirSync(path.dirname(pagePath), { recursive: true });
|
|
105
|
+
fs.writeFileSync(pagePath, JSON.stringify({}, null, 2));
|
|
106
|
+
fs.mkdirSync(path.dirname(componentPath), { recursive: true });
|
|
107
|
+
fs.writeFileSync(componentPath, wrPageScaffold(component));
|
|
108
|
+
const routes = JSON.parse(fs.readFileSync(routesPath, 'utf-8'));
|
|
109
|
+
routes[pageName] = { component, ...(lazy ? { lazy: true } : {}) };
|
|
110
|
+
fs.writeFileSync(routesPath, JSON.stringify(routes, null, 2));
|
|
111
|
+
res.end(JSON.stringify({ ok: true }));
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
console.error('[wr-create-page] failed:', err);
|
|
115
|
+
res.statusCode = 500;
|
|
116
|
+
res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
export function wrPageScaffold(component) {
|
|
124
|
+
return `import { WrSection } from '@webround/core';
|
|
125
|
+
|
|
126
|
+
export default function ${component}() {
|
|
127
|
+
return <WrSection id="root" />;
|
|
128
|
+
}
|
|
129
|
+
`;
|
|
130
|
+
}
|
|
131
|
+
export function wrCoreSwapPlugin() {
|
|
132
|
+
let editorPkgDir = null;
|
|
133
|
+
let editorEntry = null;
|
|
134
|
+
try {
|
|
135
|
+
editorEntry = require.resolve('@webround/editor');
|
|
136
|
+
// risali da editorEntry finche' non trovi la root del pacchetto (dove sta il suo package.json)
|
|
137
|
+
let dir = path.dirname(editorEntry);
|
|
138
|
+
while (dir !== path.dirname(dir)) {
|
|
139
|
+
if (fs.existsSync(path.join(dir, 'package.json'))) {
|
|
140
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf-8'));
|
|
141
|
+
if (pkg.name === '@webround/editor') {
|
|
142
|
+
editorPkgDir = dir;
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
dir = path.dirname(dir);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
editorPkgDir = null;
|
|
151
|
+
editorEntry = null;
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
name: 'wr-core-swap',
|
|
155
|
+
enforce: 'pre',
|
|
156
|
+
resolveId(source, importer) {
|
|
157
|
+
if (!editorEntry || !editorPkgDir)
|
|
158
|
+
return null;
|
|
159
|
+
if (source !== '@webround/core')
|
|
160
|
+
return null;
|
|
161
|
+
if (importer) {
|
|
162
|
+
const normalizedImporter = path.resolve(importer);
|
|
163
|
+
const normalizedEditorDir = path.resolve(editorPkgDir);
|
|
164
|
+
if (normalizedImporter.startsWith(normalizedEditorDir + path.sep)) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return editorEntry;
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const WR_PAGES_VIRTUAL_ID = 'virtual:wr-pages';
|
|
173
|
+
const WR_PAGES_RESOLVED_ID = '\0' + WR_PAGES_VIRTUAL_ID;
|
|
174
|
+
export function wrPagesPlugin() {
|
|
175
|
+
const routesPath = path.resolve(process.cwd(), 'src', 'config', 'routes.json');
|
|
176
|
+
function generate() {
|
|
177
|
+
const routes = JSON.parse(fs.readFileSync(routesPath, 'utf-8'));
|
|
178
|
+
const eagerImports = [];
|
|
179
|
+
const eagerEntries = [];
|
|
180
|
+
const lazyEntries = [];
|
|
181
|
+
for (const entry of Object.values(routes)) {
|
|
182
|
+
if (entry.lazy) {
|
|
183
|
+
lazyEntries.push(` ${JSON.stringify(entry.component)}: () => import('/src/pages/${entry.component}.tsx'),`);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
const varName = `Page_${entry.component}`;
|
|
187
|
+
eagerImports.push(`import * as ${varName} from '/src/pages/${entry.component}.tsx';`);
|
|
188
|
+
eagerEntries.push(` ${JSON.stringify(entry.component)}: ${varName},`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return `${eagerImports.join('\n')}
|
|
192
|
+
|
|
193
|
+
export const eagerModules = {
|
|
194
|
+
${eagerEntries.join('\n')}
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
export const lazyModules = {
|
|
198
|
+
${lazyEntries.join('\n')}
|
|
199
|
+
};
|
|
200
|
+
`;
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
name: 'wr-pages',
|
|
204
|
+
resolveId(id) {
|
|
205
|
+
if (id === WR_PAGES_VIRTUAL_ID)
|
|
206
|
+
return WR_PAGES_RESOLVED_ID;
|
|
207
|
+
},
|
|
208
|
+
load(id) {
|
|
209
|
+
if (id !== WR_PAGES_RESOLVED_ID)
|
|
210
|
+
return;
|
|
211
|
+
this.addWatchFile(routesPath);
|
|
212
|
+
return generate();
|
|
213
|
+
},
|
|
214
|
+
configureServer(server) {
|
|
215
|
+
server.watcher.add(routesPath);
|
|
216
|
+
server.watcher.on('change', (file) => {
|
|
217
|
+
if (path.resolve(file) === routesPath) {
|
|
218
|
+
const mod = server.moduleGraph.getModuleById(WR_PAGES_RESOLVED_ID);
|
|
219
|
+
if (mod) {
|
|
220
|
+
server.moduleGraph.invalidateModule(mod);
|
|
221
|
+
server.ws.send({ type: 'full-reload' });
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
export function wrPagesApiPlugin() {
|
|
229
|
+
return {
|
|
230
|
+
name: 'wr-pages-api',
|
|
231
|
+
configureServer(server) {
|
|
232
|
+
server.middlewares.use('/wr/pages', (req, res) => {
|
|
233
|
+
const routesPath = path.resolve(process.cwd(), 'src', 'config', 'routes.json');
|
|
234
|
+
if (req.method === 'GET') {
|
|
235
|
+
const routes = JSON.parse(fs.readFileSync(routesPath, 'utf-8'));
|
|
236
|
+
res.setHeader('Content-Type', 'application/json');
|
|
237
|
+
res.end(JSON.stringify(routes));
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (req.method === 'DELETE' || req.method === 'PATCH') {
|
|
241
|
+
let body = '';
|
|
242
|
+
req.on('data', chunk => body += chunk);
|
|
243
|
+
req.on('end', () => {
|
|
244
|
+
try {
|
|
245
|
+
const payload = body ? JSON.parse(body) : {};
|
|
246
|
+
const { pageName } = payload;
|
|
247
|
+
if (!pageName) {
|
|
248
|
+
res.statusCode = 400;
|
|
249
|
+
res.end(JSON.stringify({ error: 'pageName required' }));
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const routes = JSON.parse(fs.readFileSync(routesPath, 'utf-8'));
|
|
253
|
+
const entry = routes[pageName];
|
|
254
|
+
if (!entry) {
|
|
255
|
+
res.statusCode = 404;
|
|
256
|
+
res.end(JSON.stringify({ error: 'page not found' }));
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
const pagePath = path.resolve(process.cwd(), 'src', 'config', 'pages', `${pageName}.json`);
|
|
260
|
+
const componentPath = path.resolve(process.cwd(), 'src', 'pages', `${entry.component}.tsx`);
|
|
261
|
+
if (req.method === 'DELETE') {
|
|
262
|
+
if (fs.existsSync(pagePath))
|
|
263
|
+
fs.unlinkSync(pagePath);
|
|
264
|
+
if (fs.existsSync(componentPath))
|
|
265
|
+
fs.unlinkSync(componentPath);
|
|
266
|
+
delete routes[pageName];
|
|
267
|
+
fs.writeFileSync(routesPath, JSON.stringify(routes, null, 2));
|
|
268
|
+
res.end(JSON.stringify({ ok: true }));
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
// PATCH: rename route key and/or component
|
|
272
|
+
const { newPageName, newComponent, lazy } = payload;
|
|
273
|
+
const finalPageName = newPageName ?? pageName;
|
|
274
|
+
const finalComponent = newComponent ?? entry.component;
|
|
275
|
+
if (finalPageName !== pageName && routes[finalPageName]) {
|
|
276
|
+
res.statusCode = 409;
|
|
277
|
+
res.end(JSON.stringify({ error: 'target page name already exists' }));
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
const newPagePath = path.resolve(process.cwd(), 'src', 'config', 'pages', `${finalPageName}.json`);
|
|
281
|
+
const newComponentPath = path.resolve(process.cwd(), 'src', 'pages', `${finalComponent}.tsx`);
|
|
282
|
+
if (fs.existsSync(pagePath) && pagePath !== newPagePath) {
|
|
283
|
+
fs.mkdirSync(path.dirname(newPagePath), { recursive: true });
|
|
284
|
+
fs.renameSync(pagePath, newPagePath);
|
|
285
|
+
}
|
|
286
|
+
if (fs.existsSync(componentPath) && componentPath !== newComponentPath) {
|
|
287
|
+
fs.mkdirSync(path.dirname(newComponentPath), { recursive: true });
|
|
288
|
+
fs.renameSync(componentPath, newComponentPath);
|
|
289
|
+
}
|
|
290
|
+
delete routes[pageName];
|
|
291
|
+
routes[finalPageName] = { component: finalComponent, ...(lazy ? { lazy: true } : {}) };
|
|
292
|
+
fs.writeFileSync(routesPath, JSON.stringify(routes, null, 2));
|
|
293
|
+
res.end(JSON.stringify({ ok: true, pageName: finalPageName }));
|
|
294
|
+
}
|
|
295
|
+
catch (err) {
|
|
296
|
+
console.error('[wr-pages-api] failed:', err);
|
|
297
|
+
res.statusCode = 500;
|
|
298
|
+
res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
res.statusCode = 405;
|
|
304
|
+
res.end();
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
const WR_LANGS_VIRTUAL_ID = 'virtual:wr-langs';
|
|
310
|
+
const WR_LANGS_RESOLVED_ID = '\0' + WR_LANGS_VIRTUAL_ID;
|
|
311
|
+
export function wrLangsPlugin() {
|
|
312
|
+
const langsPath = path.resolve(process.cwd(), 'src', 'config', 'langs.json');
|
|
313
|
+
function generate() {
|
|
314
|
+
if (!fs.existsSync(langsPath)) {
|
|
315
|
+
return `export const langs = null;\n`;
|
|
316
|
+
}
|
|
317
|
+
const langs = JSON.parse(fs.readFileSync(langsPath, 'utf-8'));
|
|
318
|
+
return `export const langs = ${JSON.stringify(langs)};\n`;
|
|
319
|
+
}
|
|
320
|
+
function invalidate(server) {
|
|
321
|
+
const mod = server.moduleGraph.getModuleById(WR_LANGS_RESOLVED_ID);
|
|
322
|
+
if (mod) {
|
|
323
|
+
server.moduleGraph.invalidateModule(mod);
|
|
324
|
+
server.ws.send({ type: 'full-reload' });
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return {
|
|
328
|
+
name: 'wr-langs',
|
|
329
|
+
resolveId(id) {
|
|
330
|
+
if (id === WR_LANGS_VIRTUAL_ID)
|
|
331
|
+
return WR_LANGS_RESOLVED_ID;
|
|
332
|
+
},
|
|
333
|
+
load(id) {
|
|
334
|
+
if (id !== WR_LANGS_RESOLVED_ID)
|
|
335
|
+
return;
|
|
336
|
+
this.addWatchFile(langsPath);
|
|
337
|
+
return generate();
|
|
338
|
+
},
|
|
339
|
+
configureServer(server) {
|
|
340
|
+
server.watcher.add(langsPath);
|
|
341
|
+
const onFsEvent = (file) => {
|
|
342
|
+
if (path.resolve(file) === langsPath)
|
|
343
|
+
invalidate(server);
|
|
344
|
+
};
|
|
345
|
+
server.watcher.on('add', onFsEvent);
|
|
346
|
+
server.watcher.on('change', onFsEvent);
|
|
347
|
+
},
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
// Lista chiusa: solo questi tag JSX vengono considerati dal parser.
|
|
351
|
+
// Va tenuta sincronizzata con WR_AST_COMPONENTS in @webround/editor/schema.
|
|
352
|
+
const COMPONENT_TO_KIND = {
|
|
353
|
+
WrVideo: 'video',
|
|
354
|
+
WrImage: 'image',
|
|
355
|
+
WrLink: 'link',
|
|
356
|
+
WrButton: 'button',
|
|
357
|
+
WrNav: 'nav',
|
|
358
|
+
WrText: 'text',
|
|
359
|
+
WrSection: 'section',
|
|
360
|
+
};
|
|
361
|
+
const ROOT = process.cwd();
|
|
362
|
+
function safeResolve(file) {
|
|
363
|
+
const resolved = path.resolve(ROOT, 'src', file);
|
|
364
|
+
if (!resolved.startsWith(path.resolve(ROOT, 'src')))
|
|
365
|
+
return null; // path traversal guard
|
|
366
|
+
return resolved;
|
|
367
|
+
}
|
|
368
|
+
function findNode(project, filePath, id) {
|
|
369
|
+
let sourceFile = project.getSourceFile(filePath);
|
|
370
|
+
if (sourceFile) {
|
|
371
|
+
sourceFile.refreshFromFileSystemSync();
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
sourceFile = project.addSourceFileAtPathIfExists(filePath);
|
|
375
|
+
}
|
|
376
|
+
if (!sourceFile)
|
|
377
|
+
return null;
|
|
378
|
+
const candidates = [
|
|
379
|
+
...sourceFile.getDescendantsOfKind(SyntaxKind.JsxSelfClosingElement),
|
|
380
|
+
...sourceFile.getDescendantsOfKind(SyntaxKind.JsxOpeningElement),
|
|
381
|
+
];
|
|
382
|
+
for (const node of candidates) {
|
|
383
|
+
const tagName = node.getTagNameNode().getText();
|
|
384
|
+
const kind = COMPONENT_TO_KIND[tagName];
|
|
385
|
+
if (!kind)
|
|
386
|
+
continue;
|
|
387
|
+
const idAttr = node.getAttribute('id');
|
|
388
|
+
if (!idAttr || idAttr.getKind() !== SyntaxKind.JsxAttribute)
|
|
389
|
+
continue;
|
|
390
|
+
const init = idAttr.getInitializer?.();
|
|
391
|
+
if (!init || init.getKind() !== SyntaxKind.StringLiteral)
|
|
392
|
+
continue;
|
|
393
|
+
if (init.getLiteralValue() !== id)
|
|
394
|
+
continue;
|
|
395
|
+
return { node, kind };
|
|
396
|
+
}
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
function readLiteral(node, key) {
|
|
400
|
+
const attr = node.getAttribute(key);
|
|
401
|
+
if (!attr || attr.getKind() !== SyntaxKind.JsxAttribute)
|
|
402
|
+
return { present: false };
|
|
403
|
+
const init = attr.getInitializer?.();
|
|
404
|
+
if (!init)
|
|
405
|
+
return { present: true, value: true }; // <WrVideo autoPlay /> senza valore = booleano true
|
|
406
|
+
if (init.getKind() === SyntaxKind.StringLiteral)
|
|
407
|
+
return { present: true, value: init.getLiteralValue() };
|
|
408
|
+
if (init.getKind() === SyntaxKind.JsxExpression) {
|
|
409
|
+
const expr = init.getExpression();
|
|
410
|
+
if (!expr)
|
|
411
|
+
return { present: false };
|
|
412
|
+
if (expr.getKind() === SyntaxKind.TrueKeyword)
|
|
413
|
+
return { present: true, value: true };
|
|
414
|
+
if (expr.getKind() === SyntaxKind.FalseKeyword)
|
|
415
|
+
return { present: true, value: false };
|
|
416
|
+
if (expr.getKind() === SyntaxKind.NumericLiteral)
|
|
417
|
+
return { present: true, value: Number(expr.getText()) };
|
|
418
|
+
if (expr.getKind() === SyntaxKind.StringLiteral)
|
|
419
|
+
return { present: true, value: expr.getLiteralValue() };
|
|
420
|
+
}
|
|
421
|
+
return { present: false }; // espressione non letterale: non editabile da qui, per sicurezza
|
|
422
|
+
}
|
|
423
|
+
function writeLiteral(node, key, value) {
|
|
424
|
+
const existing = node.getAttribute(key);
|
|
425
|
+
if (value === null) {
|
|
426
|
+
if (existing && existing.getKind() === SyntaxKind.JsxAttribute)
|
|
427
|
+
existing.remove();
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
const fieldType = typeof value;
|
|
431
|
+
let text;
|
|
432
|
+
if (fieldType === 'string')
|
|
433
|
+
text = `"${String(value).replace(/"/g, '\\"')}"`;
|
|
434
|
+
else if (fieldType === 'boolean')
|
|
435
|
+
text = `{${value}}`;
|
|
436
|
+
else
|
|
437
|
+
text = `{${value}}`;
|
|
438
|
+
if (existing && existing.getKind() === SyntaxKind.JsxAttribute) {
|
|
439
|
+
existing.setInitializer(text);
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
node.addAttribute({ name: key, initializer: text });
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
export function wrAstPlugin() {
|
|
446
|
+
const project = new Project({ tsConfigFilePath: path.resolve(ROOT, 'tsconfig.json'), skipAddingFilesFromTsConfig: true });
|
|
447
|
+
return {
|
|
448
|
+
name: 'wr-ast-plugin',
|
|
449
|
+
configureServer(server) {
|
|
450
|
+
server.middlewares.use('/wr/node', (req, res, next) => {
|
|
451
|
+
const url = new URL(req.url ?? '', 'http://localhost');
|
|
452
|
+
const file = url.searchParams.get('file');
|
|
453
|
+
const id = url.searchParams.get('id');
|
|
454
|
+
if (req.method === 'GET') {
|
|
455
|
+
if (!file || !id) {
|
|
456
|
+
res.statusCode = 400;
|
|
457
|
+
res.end('missing file/id');
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const resolved = safeResolve(file);
|
|
461
|
+
if (!resolved || !fs.existsSync(resolved)) {
|
|
462
|
+
res.statusCode = 404;
|
|
463
|
+
res.end(JSON.stringify(null));
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
const found = findNode(project, resolved, id);
|
|
467
|
+
if (!found) {
|
|
468
|
+
res.statusCode = 404;
|
|
469
|
+
res.end(JSON.stringify(null));
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
const fields = getFields(found.kind).filter(f => f.backend === 'ast');
|
|
473
|
+
const values = {};
|
|
474
|
+
for (const f of fields) {
|
|
475
|
+
const { present, value } = readLiteral(found.node, f.key);
|
|
476
|
+
if (present && value !== undefined)
|
|
477
|
+
values[f.key] = value;
|
|
478
|
+
}
|
|
479
|
+
res.setHeader('Content-Type', 'application/json');
|
|
480
|
+
res.end(JSON.stringify({ fields: fields.map(f => f.key), values }));
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
if (req.method === 'PUT') {
|
|
484
|
+
let body = '';
|
|
485
|
+
req.on('data', chunk => body += chunk);
|
|
486
|
+
req.on('end', () => {
|
|
487
|
+
try {
|
|
488
|
+
const { file: bodyFile, id: bodyId, key, value } = JSON.parse(body);
|
|
489
|
+
const resolved = safeResolve(bodyFile);
|
|
490
|
+
if (!resolved) {
|
|
491
|
+
res.statusCode = 400;
|
|
492
|
+
res.end(JSON.stringify({ error: 'invalid file' }));
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
const found = findNode(project, resolved, bodyId);
|
|
496
|
+
if (!found) {
|
|
497
|
+
res.statusCode = 404;
|
|
498
|
+
res.end(JSON.stringify({ error: 'node not found' }));
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
writeLiteral(found.node, key, value);
|
|
502
|
+
found.node.getSourceFile().saveSync();
|
|
503
|
+
res.setHeader('Content-Type', 'application/json');
|
|
504
|
+
res.end(JSON.stringify({ ok: true }));
|
|
505
|
+
}
|
|
506
|
+
catch (err) {
|
|
507
|
+
res.statusCode = 500;
|
|
508
|
+
res.end(JSON.stringify({ error: String(err) }));
|
|
509
|
+
}
|
|
510
|
+
});
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
next();
|
|
514
|
+
});
|
|
515
|
+
},
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
//# sourceMappingURL=vite-plugins.js.map
|