vite-plugin-semi-d2c-code-saver 1.0.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/README.md +63 -0
- package/dist/bundle.js +2 -0
- package/dist/bundle.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/modifyFiles.d.ts +4 -0
- package/dist/vitePlugin.cjs +2 -0
- package/dist/vitePlugin.cjs.map +1 -0
- package/dist/vitePlugin.d.ts +1 -0
- package/dist/vitePlugin.mjs +2 -0
- package/dist/vitePlugin.mjs.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# semi-d2c-code-saver
|
|
2
|
+
|
|
3
|
+
把 Semi D2C 的导出结果保存到本地,并在 Vite 本地开发时提供两个固定入口:
|
|
4
|
+
|
|
5
|
+
- `http://localhost:5173/bundle.js` 访问 `dist/bundle.js`
|
|
6
|
+
- `http://localhost:5173/save-file` 接收保存请求
|
|
7
|
+
|
|
8
|
+
该包以 Vite 插件形式接入,插件只接受一个参数:`d2c` 导出的代码存储目录名。
|
|
9
|
+
|
|
10
|
+
## 使用方式
|
|
11
|
+
|
|
12
|
+
1. 安装
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm i vite-plugin-semi-d2c-code-saver
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
2. 在 `vite.config.ts` 中接入
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { defineConfig } from 'vite';
|
|
22
|
+
import { viteD2CCodeSaver } from 'semi-d2c-code-saver';
|
|
23
|
+
|
|
24
|
+
export default defineConfig({
|
|
25
|
+
plugins: [viteD2CCodeSaver('semi-d2c-code')],
|
|
26
|
+
server: {
|
|
27
|
+
port: 5173,
|
|
28
|
+
strictPort: true,
|
|
29
|
+
cors: true,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
3. 在 Semi D2C 插件侧发送保存请求
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
await fetch('/save-file', {
|
|
38
|
+
method: 'POST',
|
|
39
|
+
headers: { 'Content-Type': 'application/json' },
|
|
40
|
+
body: JSON.stringify({
|
|
41
|
+
content: file.content,
|
|
42
|
+
fileName: file.path,
|
|
43
|
+
}),
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 约定与行为
|
|
48
|
+
|
|
49
|
+
- 插件只接受一个参数:`d2c` 导出代码存储目录名
|
|
50
|
+
- 保存目录相对 Vite 项目根目录
|
|
51
|
+
- 保存时会自动创建目录
|
|
52
|
+
- 同名文件会被覆盖
|
|
53
|
+
|
|
54
|
+
## 本地访问
|
|
55
|
+
|
|
56
|
+
- 访问插件打包文件:`http://localhost:5173/bundle.js`
|
|
57
|
+
- 保存文件接口:`http://localhost:5173/save-file`
|
|
58
|
+
|
|
59
|
+
## 构建
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npm run build
|
|
63
|
+
```
|
package/dist/bundle.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var plugin=function(e){"use strict";return e.semiD2CPlugin=()=>({name:"Semi D2C Code Saver",options:[{name:"port",type:"input",defaultValue:"5173"}],setup(e,t){const o=t.port||5173;e.modifyFiles(e=>(async({files:e},t)=>{for(const o of e)try{await fetch(`http://localhost:${t}/save-file`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:o.content,fileName:o.path})}),console.log(`File ${o.path} sent to local server successfully`)}catch(e){console.error(`Failed to send file ${o.path} to local server:`,e)}return e})(e,Number(o)))}}),e}({});
|
|
2
|
+
//# sourceMappingURL=bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.js","sources":["../src/index.ts","../src/modifyFiles.ts"],"sourcesContent":["import { modifyFiles } from './modifyFiles';\nimport type { SemiD2CPlugin } from '@douyinfe/semi-d2c-typings';\n\nexport const semiD2CPlugin: SemiD2CPlugin = () => ({\n name: 'Semi D2C Code Saver',\n options: [\n {\n name: 'port',\n type: 'input',\n defaultValue: '5173',\n },\n ],\n\n setup(api, pluginOptions) {\n const port = pluginOptions.port || 5173;\n\n api.modifyFiles((p) => modifyFiles(p, Number(port)));\n },\n});\n","import { D2CFilesResult, PluginHooks } from '@douyinfe/semi-d2c-typings';\r\n\r\nexport const modifyFiles: (\r\n args: { files: D2CFilesResult },\r\n port: number\r\n) => Promise<D2CFilesResult> = async (\r\n {\r\n files,\r\n }: {\r\n files: D2CFilesResult;\r\n },\r\n port: number\r\n) => {\r\n for (const file of files) {\r\n try {\r\n // 发送文件内容到本地服务器\r\n await fetch(`http://localhost:${port}/save-file`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify({\r\n content: file.content,\r\n fileName: file.path,\r\n }),\r\n });\r\n console.log(`File ${file.path} sent to local server successfully`);\r\n } catch (error) {\r\n console.error(`Failed to send file ${file.path} to local server:`, error);\r\n }\r\n }\r\n return files;\r\n};\r\n"],"names":["name","options","type","defaultValue","setup","api","pluginOptions","port","modifyFiles","p","async","files","file","fetch","method","headers","body","JSON","stringify","content","fileName","path","console","log","error","Number"],"mappings":"2DAG4C,KAAO,CACjDA,KAAM,sBACNC,QAAS,CACP,CACED,KAAM,OACNE,KAAM,QACNC,aAAc,SAIlB,KAAAC,CAAMC,EAAKC,GACT,MAAMC,EAAOD,EAAcC,MAAQ,KAEnCF,EAAIG,YAAaC,GCXUC,QAE3BC,SAIFJ,KAEA,IAAK,MAAMK,KAAQD,EACjB,UAEQE,MAAM,oBAAoBN,cAAkB,CAChDO,OAAQ,OACRC,QAAS,CACP,eAAgB,oBAElBC,KAAMC,KAAKC,UAAU,CACnBC,QAASP,EAAKO,QACdC,SAAUR,EAAKS,SAGnBC,QAAQC,IAAI,QAAQX,EAAKS,yCAC1B,CAAC,MAAOG,GACPF,QAAQE,MAAM,uBAAuBZ,EAAKS,wBAAyBG,EACpE,CAEH,OAAOb,GDfkBH,CAAYC,EAAGgB,OAAOlB,IAC9C"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("fs"),t=require("path"),s=require("url"),r="undefined"!=typeof document?document.currentScript:null;exports.viteD2CCodeSaver=(o="semi-d2c-code")=>({name:"vite-semi-d2c-code-saver",configureServer(n){n.middlewares.use("/bundle.js",(o,n)=>{if(n.setHeader("Access-Control-Allow-Origin","*"),n.setHeader("Access-Control-Allow-Methods","GET, HEAD, OPTIONS"),n.setHeader("Access-Control-Allow-Headers","Content-Type"),"OPTIONS"===o.method)return n.statusCode=204,void n.end();if("GET"!==o.method&&"HEAD"!==o.method)return n.statusCode=404,void n.end();try{const o=t.resolve(t.dirname(s.fileURLToPath("undefined"==typeof document?require("url").pathToFileURL(__filename).href:r&&"SCRIPT"===r.tagName.toUpperCase()&&r.src||new URL("vitePlugin.cjs",document.baseURI).href)),"..","dist/bundle.js");if(console.log(o,"absPath"),!e.existsSync(o))return n.statusCode=404,void n.end();const d=e.readFileSync(o);n.statusCode=200,n.setHeader("Content-Type","application/javascript; charset=utf-8"),n.end(d)}catch{n.statusCode=500,n.end()}}),n.middlewares.use("/save-file",(s,r)=>{if(r.setHeader("Access-Control-Allow-Origin","*"),r.setHeader("Access-Control-Allow-Methods","POST, OPTIONS"),r.setHeader("Access-Control-Allow-Headers","Content-Type"),"OPTIONS"===s.method)return r.statusCode=204,void r.end();if("POST"!==s.method)return r.statusCode=404,void r.end();let d="";s.on("data",e=>{d+=e.toString()}),s.on("end",()=>{try{if(!d)throw new Error("Empty request body");const{content:s,fileName:i}=JSON.parse(d);if("string"!=typeof s||"string"!=typeof i)throw new Error("Invalid payload");const a=t.resolve(n.config.root,o),c=t.normalize(i).replace(/^([/\\])+/,""),l=t.resolve(a,c),u=a.endsWith(t.sep)?a:a+t.sep;if(!l.startsWith(u))throw new Error("Invalid file path");e.existsSync(a)||e.mkdirSync(a,{recursive:!0});const f=t.dirname(l);e.existsSync(f)||e.mkdirSync(f,{recursive:!0}),e.writeFileSync(l,s,"utf8"),console.log(`[semi-d2c-code-saver] saved ${i} -> ${l}`),r.statusCode=200,r.setHeader("Content-Type","application/json"),r.end(JSON.stringify({message:"File saved successfully"}))}catch(e){r.statusCode=500,r.setHeader("Content-Type","application/json"),r.end(JSON.stringify({error:"Failed to save file"}))}})})}});
|
|
2
|
+
//# sourceMappingURL=vitePlugin.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitePlugin.cjs","sources":["../src/vitePlugin.ts"],"sourcesContent":["import type { Plugin } from 'vite';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport { fileURLToPath } from 'url';\r\n\r\nexport const viteD2CCodeSaver = (outputDirName = 'semi-d2c-code'): Plugin => {\r\n const route = '/save-file';\r\n const bundlePath = 'dist/bundle.js';\r\n const bundleRoute = '/bundle.js';\r\n\r\n return {\r\n name: 'vite-semi-d2c-code-saver',\r\n configureServer(server) {\r\n server.middlewares.use(bundleRoute, (req, res) => {\r\n res.setHeader('Access-Control-Allow-Origin', '*');\r\n res.setHeader('Access-Control-Allow-Methods', 'GET, HEAD, OPTIONS');\r\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\r\n\r\n if (req.method === 'OPTIONS') {\r\n res.statusCode = 204;\r\n res.end();\r\n return;\r\n }\r\n\r\n if (req.method !== 'GET' && req.method !== 'HEAD') {\r\n res.statusCode = 404;\r\n res.end();\r\n return;\r\n }\r\n\r\n try {\r\n const absPath = path.resolve(\r\n path.dirname(fileURLToPath(import.meta.url)),\r\n '..',\r\n bundlePath\r\n );\r\n console.log(absPath, 'absPath');\r\n if (!fs.existsSync(absPath)) {\r\n res.statusCode = 404;\r\n res.end();\r\n return;\r\n }\r\n\r\n const content = fs.readFileSync(absPath);\r\n res.statusCode = 200;\r\n res.setHeader(\r\n 'Content-Type',\r\n 'application/javascript; charset=utf-8'\r\n );\r\n res.end(content);\r\n } catch {\r\n res.statusCode = 500;\r\n res.end();\r\n }\r\n });\r\n\r\n server.middlewares.use(route, (req, res) => {\r\n res.setHeader('Access-Control-Allow-Origin', '*');\r\n res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');\r\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\r\n\r\n if (req.method === 'OPTIONS') {\r\n res.statusCode = 204;\r\n res.end();\r\n return;\r\n }\r\n\r\n if (req.method !== 'POST') {\r\n res.statusCode = 404;\r\n res.end();\r\n return;\r\n }\r\n\r\n let body = '';\r\n req.on('data', (chunk) => {\r\n body += chunk.toString();\r\n });\r\n\r\n req.on('end', () => {\r\n try {\r\n if (!body) {\r\n throw new Error('Empty request body');\r\n }\r\n\r\n const { content, fileName } = JSON.parse(body);\r\n if (typeof content !== 'string' || typeof fileName !== 'string') {\r\n throw new Error('Invalid payload');\r\n }\r\n\r\n const baseDir = path.resolve(server.config.root, outputDirName);\r\n const normalized = path\r\n .normalize(fileName)\r\n .replace(/^([/\\\\])+/, '');\r\n const targetPath = path.resolve(baseDir, normalized);\r\n const baseDirWithSep = baseDir.endsWith(path.sep)\r\n ? baseDir\r\n : baseDir + path.sep;\r\n\r\n if (!targetPath.startsWith(baseDirWithSep)) {\r\n throw new Error('Invalid file path');\r\n }\r\n\r\n if (!fs.existsSync(baseDir)) {\r\n fs.mkdirSync(baseDir, { recursive: true });\r\n }\r\n\r\n const targetDir = path.dirname(targetPath);\r\n if (!fs.existsSync(targetDir)) {\r\n fs.mkdirSync(targetDir, { recursive: true });\r\n }\r\n\r\n fs.writeFileSync(targetPath, content, 'utf8');\r\n\r\n console.log(\r\n `[semi-d2c-code-saver] saved ${fileName} -> ${targetPath}`\r\n );\r\n\r\n res.statusCode = 200;\r\n res.setHeader('Content-Type', 'application/json');\r\n res.end(JSON.stringify({ message: 'File saved successfully' }));\r\n } catch (error) {\r\n res.statusCode = 500;\r\n res.setHeader('Content-Type', 'application/json');\r\n res.end(JSON.stringify({ error: 'Failed to save file' }));\r\n }\r\n });\r\n });\r\n },\r\n };\r\n};\r\n"],"names":["outputDirName","name","configureServer","server","middlewares","use","req","res","setHeader","method","statusCode","end","absPath","path","resolve","dirname","fileURLToPath","console","log","fs","existsSync","content","readFileSync","body","on","chunk","toString","Error","fileName","JSON","parse","baseDir","config","root","normalized","normalize","replace","targetPath","baseDirWithSep","endsWith","sep","startsWith","mkdirSync","recursive","targetDir","writeFileSync","stringify","message","error"],"mappings":"wJAKgC,CAACA,EAAgB,mBAKxC,CACLC,KAAM,2BACN,eAAAC,CAAgBC,GACdA,EAAOC,YAAYC,IALH,aAKoB,CAACC,EAAKC,KAKxC,GAJAA,EAAIC,UAAU,8BAA+B,KAC7CD,EAAIC,UAAU,+BAAgC,sBAC9CD,EAAIC,UAAU,+BAAgC,gBAE3B,YAAfF,EAAIG,OAGN,OAFAF,EAAIG,WAAa,SACjBH,EAAII,MAIN,GAAmB,QAAfL,EAAIG,QAAmC,SAAfH,EAAIG,OAG9B,OAFAF,EAAIG,WAAa,SACjBH,EAAII,MAIN,IACE,MAAMC,EAAUC,EAAKC,QACnBD,EAAKE,QAAQC,EAAaA,yLAC1B,KA1BS,kBA8BX,GADAC,QAAQC,IAAIN,EAAS,YAChBO,EAAGC,WAAWR,GAGjB,OAFAL,EAAIG,WAAa,SACjBH,EAAII,MAIN,MAAMU,EAAUF,EAAGG,aAAaV,GAChCL,EAAIG,WAAa,IACjBH,EAAIC,UACF,eACA,yCAEFD,EAAII,IAAIU,EACT,CAAC,MACAd,EAAIG,WAAa,IACjBH,EAAII,KACL,IAGHR,EAAOC,YAAYC,IAlDT,aAkDoB,CAACC,EAAKC,KAKlC,GAJAA,EAAIC,UAAU,8BAA+B,KAC7CD,EAAIC,UAAU,+BAAgC,iBAC9CD,EAAIC,UAAU,+BAAgC,gBAE3B,YAAfF,EAAIG,OAGN,OAFAF,EAAIG,WAAa,SACjBH,EAAII,MAIN,GAAmB,SAAfL,EAAIG,OAGN,OAFAF,EAAIG,WAAa,SACjBH,EAAII,MAIN,IAAIY,EAAO,GACXjB,EAAIkB,GAAG,OAASC,IACdF,GAAQE,EAAMC,aAGhBpB,EAAIkB,GAAG,MAAO,KACZ,IACE,IAAKD,EACH,MAAM,IAAII,MAAM,sBAGlB,MAAMN,QAAEA,EAAOO,SAAEA,GAAaC,KAAKC,MAAMP,GACzC,GAAuB,iBAAZF,GAA4C,iBAAbO,EACxC,MAAM,IAAID,MAAM,mBAGlB,MAAMI,EAAUlB,EAAKC,QAAQX,EAAO6B,OAAOC,KAAMjC,GAC3CkC,EAAarB,EAChBsB,UAAUP,GACVQ,QAAQ,YAAa,IAClBC,EAAaxB,EAAKC,QAAQiB,EAASG,GACnCI,EAAiBP,EAAQQ,SAAS1B,EAAK2B,KACzCT,EACAA,EAAUlB,EAAK2B,IAEnB,IAAKH,EAAWI,WAAWH,GACzB,MAAM,IAAIX,MAAM,qBAGbR,EAAGC,WAAWW,IACjBZ,EAAGuB,UAAUX,EAAS,CAAEY,WAAW,IAGrC,MAAMC,EAAY/B,EAAKE,QAAQsB,GAC1BlB,EAAGC,WAAWwB,IACjBzB,EAAGuB,UAAUE,EAAW,CAAED,WAAW,IAGvCxB,EAAG0B,cAAcR,EAAYhB,EAAS,QAEtCJ,QAAQC,IACN,+BAA+BU,QAAeS,KAGhD9B,EAAIG,WAAa,IACjBH,EAAIC,UAAU,eAAgB,oBAC9BD,EAAII,IAAIkB,KAAKiB,UAAU,CAAEC,QAAS,4BACnC,CAAC,MAAOC,GACPzC,EAAIG,WAAa,IACjBH,EAAIC,UAAU,eAAgB,oBAC9BD,EAAII,IAAIkB,KAAKiB,UAAU,CAAEE,MAAO,wBACjC,KAGN"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const viteD2CCodeSaver: (outputDirName?: string) => any;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import e from"fs";import t from"path";import{fileURLToPath as s}from"url";const o=(o="semi-d2c-code")=>({name:"vite-semi-d2c-code-saver",configureServer(r){r.middlewares.use("/bundle.js",(o,r)=>{if(r.setHeader("Access-Control-Allow-Origin","*"),r.setHeader("Access-Control-Allow-Methods","GET, HEAD, OPTIONS"),r.setHeader("Access-Control-Allow-Headers","Content-Type"),"OPTIONS"===o.method)return r.statusCode=204,void r.end();if("GET"!==o.method&&"HEAD"!==o.method)return r.statusCode=404,void r.end();try{const o=t.resolve(t.dirname(s(import.meta.url)),"..","dist/bundle.js");if(console.log(o,"absPath"),!e.existsSync(o))return r.statusCode=404,void r.end();const n=e.readFileSync(o);r.statusCode=200,r.setHeader("Content-Type","application/javascript; charset=utf-8"),r.end(n)}catch{r.statusCode=500,r.end()}}),r.middlewares.use("/save-file",(s,n)=>{if(n.setHeader("Access-Control-Allow-Origin","*"),n.setHeader("Access-Control-Allow-Methods","POST, OPTIONS"),n.setHeader("Access-Control-Allow-Headers","Content-Type"),"OPTIONS"===s.method)return n.statusCode=204,void n.end();if("POST"!==s.method)return n.statusCode=404,void n.end();let d="";s.on("data",e=>{d+=e.toString()}),s.on("end",()=>{try{if(!d)throw new Error("Empty request body");const{content:s,fileName:i}=JSON.parse(d);if("string"!=typeof s||"string"!=typeof i)throw new Error("Invalid payload");const a=t.resolve(r.config.root,o),c=t.normalize(i).replace(/^([/\\])+/,""),l=t.resolve(a,c),u=a.endsWith(t.sep)?a:a+t.sep;if(!l.startsWith(u))throw new Error("Invalid file path");e.existsSync(a)||e.mkdirSync(a,{recursive:!0});const m=t.dirname(l);e.existsSync(m)||e.mkdirSync(m,{recursive:!0}),e.writeFileSync(l,s,"utf8"),console.log(`[semi-d2c-code-saver] saved ${i} -> ${l}`),n.statusCode=200,n.setHeader("Content-Type","application/json"),n.end(JSON.stringify({message:"File saved successfully"}))}catch(e){n.statusCode=500,n.setHeader("Content-Type","application/json"),n.end(JSON.stringify({error:"Failed to save file"}))}})})}});export{o as viteD2CCodeSaver};
|
|
2
|
+
//# sourceMappingURL=vitePlugin.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitePlugin.mjs","sources":["../src/vitePlugin.ts"],"sourcesContent":["import type { Plugin } from 'vite';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport { fileURLToPath } from 'url';\r\n\r\nexport const viteD2CCodeSaver = (outputDirName = 'semi-d2c-code'): Plugin => {\r\n const route = '/save-file';\r\n const bundlePath = 'dist/bundle.js';\r\n const bundleRoute = '/bundle.js';\r\n\r\n return {\r\n name: 'vite-semi-d2c-code-saver',\r\n configureServer(server) {\r\n server.middlewares.use(bundleRoute, (req, res) => {\r\n res.setHeader('Access-Control-Allow-Origin', '*');\r\n res.setHeader('Access-Control-Allow-Methods', 'GET, HEAD, OPTIONS');\r\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\r\n\r\n if (req.method === 'OPTIONS') {\r\n res.statusCode = 204;\r\n res.end();\r\n return;\r\n }\r\n\r\n if (req.method !== 'GET' && req.method !== 'HEAD') {\r\n res.statusCode = 404;\r\n res.end();\r\n return;\r\n }\r\n\r\n try {\r\n const absPath = path.resolve(\r\n path.dirname(fileURLToPath(import.meta.url)),\r\n '..',\r\n bundlePath\r\n );\r\n console.log(absPath, 'absPath');\r\n if (!fs.existsSync(absPath)) {\r\n res.statusCode = 404;\r\n res.end();\r\n return;\r\n }\r\n\r\n const content = fs.readFileSync(absPath);\r\n res.statusCode = 200;\r\n res.setHeader(\r\n 'Content-Type',\r\n 'application/javascript; charset=utf-8'\r\n );\r\n res.end(content);\r\n } catch {\r\n res.statusCode = 500;\r\n res.end();\r\n }\r\n });\r\n\r\n server.middlewares.use(route, (req, res) => {\r\n res.setHeader('Access-Control-Allow-Origin', '*');\r\n res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');\r\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\r\n\r\n if (req.method === 'OPTIONS') {\r\n res.statusCode = 204;\r\n res.end();\r\n return;\r\n }\r\n\r\n if (req.method !== 'POST') {\r\n res.statusCode = 404;\r\n res.end();\r\n return;\r\n }\r\n\r\n let body = '';\r\n req.on('data', (chunk) => {\r\n body += chunk.toString();\r\n });\r\n\r\n req.on('end', () => {\r\n try {\r\n if (!body) {\r\n throw new Error('Empty request body');\r\n }\r\n\r\n const { content, fileName } = JSON.parse(body);\r\n if (typeof content !== 'string' || typeof fileName !== 'string') {\r\n throw new Error('Invalid payload');\r\n }\r\n\r\n const baseDir = path.resolve(server.config.root, outputDirName);\r\n const normalized = path\r\n .normalize(fileName)\r\n .replace(/^([/\\\\])+/, '');\r\n const targetPath = path.resolve(baseDir, normalized);\r\n const baseDirWithSep = baseDir.endsWith(path.sep)\r\n ? baseDir\r\n : baseDir + path.sep;\r\n\r\n if (!targetPath.startsWith(baseDirWithSep)) {\r\n throw new Error('Invalid file path');\r\n }\r\n\r\n if (!fs.existsSync(baseDir)) {\r\n fs.mkdirSync(baseDir, { recursive: true });\r\n }\r\n\r\n const targetDir = path.dirname(targetPath);\r\n if (!fs.existsSync(targetDir)) {\r\n fs.mkdirSync(targetDir, { recursive: true });\r\n }\r\n\r\n fs.writeFileSync(targetPath, content, 'utf8');\r\n\r\n console.log(\r\n `[semi-d2c-code-saver] saved ${fileName} -> ${targetPath}`\r\n );\r\n\r\n res.statusCode = 200;\r\n res.setHeader('Content-Type', 'application/json');\r\n res.end(JSON.stringify({ message: 'File saved successfully' }));\r\n } catch (error) {\r\n res.statusCode = 500;\r\n res.setHeader('Content-Type', 'application/json');\r\n res.end(JSON.stringify({ error: 'Failed to save file' }));\r\n }\r\n });\r\n });\r\n },\r\n };\r\n};\r\n"],"names":["viteD2CCodeSaver","outputDirName","name","configureServer","server","middlewares","use","req","res","setHeader","method","statusCode","end","absPath","path","resolve","dirname","fileURLToPath","url","console","log","fs","existsSync","content","readFileSync","body","on","chunk","toString","Error","fileName","JSON","parse","baseDir","config","root","normalized","normalize","replace","targetPath","baseDirWithSep","endsWith","sep","startsWith","mkdirSync","recursive","targetDir","writeFileSync","stringify","message","error"],"mappings":"gFAKaA,EAAmB,CAACC,EAAgB,mBAKxC,CACLC,KAAM,2BACN,eAAAC,CAAgBC,GACdA,EAAOC,YAAYC,IALH,aAKoB,CAACC,EAAKC,KAKxC,GAJAA,EAAIC,UAAU,8BAA+B,KAC7CD,EAAIC,UAAU,+BAAgC,sBAC9CD,EAAIC,UAAU,+BAAgC,gBAE3B,YAAfF,EAAIG,OAGN,OAFAF,EAAIG,WAAa,SACjBH,EAAII,MAIN,GAAmB,QAAfL,EAAIG,QAAmC,SAAfH,EAAIG,OAG9B,OAFAF,EAAIG,WAAa,SACjBH,EAAII,MAIN,IACE,MAAMC,EAAUC,EAAKC,QACnBD,EAAKE,QAAQC,cAA0BC,MACvC,KA1BS,kBA8BX,GADAC,QAAQC,IAAIP,EAAS,YAChBQ,EAAGC,WAAWT,GAGjB,OAFAL,EAAIG,WAAa,SACjBH,EAAII,MAIN,MAAMW,EAAUF,EAAGG,aAAaX,GAChCL,EAAIG,WAAa,IACjBH,EAAIC,UACF,eACA,yCAEFD,EAAII,IAAIW,EACT,CAAC,MACAf,EAAIG,WAAa,IACjBH,EAAII,KACL,IAGHR,EAAOC,YAAYC,IAlDT,aAkDoB,CAACC,EAAKC,KAKlC,GAJAA,EAAIC,UAAU,8BAA+B,KAC7CD,EAAIC,UAAU,+BAAgC,iBAC9CD,EAAIC,UAAU,+BAAgC,gBAE3B,YAAfF,EAAIG,OAGN,OAFAF,EAAIG,WAAa,SACjBH,EAAII,MAIN,GAAmB,SAAfL,EAAIG,OAGN,OAFAF,EAAIG,WAAa,SACjBH,EAAII,MAIN,IAAIa,EAAO,GACXlB,EAAImB,GAAG,OAASC,IACdF,GAAQE,EAAMC,aAGhBrB,EAAImB,GAAG,MAAO,KACZ,IACE,IAAKD,EACH,MAAM,IAAII,MAAM,sBAGlB,MAAMN,QAAEA,EAAOO,SAAEA,GAAaC,KAAKC,MAAMP,GACzC,GAAuB,iBAAZF,GAA4C,iBAAbO,EACxC,MAAM,IAAID,MAAM,mBAGlB,MAAMI,EAAUnB,EAAKC,QAAQX,EAAO8B,OAAOC,KAAMlC,GAC3CmC,EAAatB,EAChBuB,UAAUP,GACVQ,QAAQ,YAAa,IAClBC,EAAazB,EAAKC,QAAQkB,EAASG,GACnCI,EAAiBP,EAAQQ,SAAS3B,EAAK4B,KACzCT,EACAA,EAAUnB,EAAK4B,IAEnB,IAAKH,EAAWI,WAAWH,GACzB,MAAM,IAAIX,MAAM,qBAGbR,EAAGC,WAAWW,IACjBZ,EAAGuB,UAAUX,EAAS,CAAEY,WAAW,IAGrC,MAAMC,EAAYhC,EAAKE,QAAQuB,GAC1BlB,EAAGC,WAAWwB,IACjBzB,EAAGuB,UAAUE,EAAW,CAAED,WAAW,IAGvCxB,EAAG0B,cAAcR,EAAYhB,EAAS,QAEtCJ,QAAQC,IACN,+BAA+BU,QAAeS,KAGhD/B,EAAIG,WAAa,IACjBH,EAAIC,UAAU,eAAgB,oBAC9BD,EAAII,IAAImB,KAAKiB,UAAU,CAAEC,QAAS,4BACnC,CAAC,MAAOC,GACP1C,EAAIG,WAAa,IACjBH,EAAIC,UAAU,eAAgB,oBAC9BD,EAAII,IAAImB,KAAKiB,UAAU,CAAEE,MAAO,wBACjC,KAGN"}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vite-plugin-semi-d2c-code-saver",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Save Semi D2C output files locally, with a Vite dev-server middleware",
|
|
5
|
+
"author": "renpeng <renpeng1111@gmail.com>",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/renpeng11/semi-d2c-code-saver.git"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"main": "dist/vitePlugin.cjs",
|
|
12
|
+
"module": "dist/vitePlugin.mjs",
|
|
13
|
+
"types": "dist/vitePlugin.d.ts",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/vitePlugin.d.ts",
|
|
18
|
+
"import": "./dist/vitePlugin.mjs",
|
|
19
|
+
"require": "./dist/vitePlugin.cjs"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"dev": "concurrently \"npm:build -- -w\" \"npm:start:server\"",
|
|
27
|
+
"build": "cross-env NODE_ENV=production rollup -c --logLevel=silent"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"semi-d2c",
|
|
31
|
+
"plugin",
|
|
32
|
+
"code-saver"
|
|
33
|
+
],
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@babel/core": "^7.22.10",
|
|
36
|
+
"@babel/eslint-parser": "^7.22.10",
|
|
37
|
+
"@douyinfe/semi-d2c-typings": "latest",
|
|
38
|
+
"@rollup/plugin-commonjs": "^25.0.4",
|
|
39
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
40
|
+
"@rollup/plugin-node-resolve": "^15.2.0",
|
|
41
|
+
"@rollup/plugin-terser": "^0.4.3",
|
|
42
|
+
"@rollup/plugin-typescript": "^11.1.6",
|
|
43
|
+
"concurrently": "^9.2.1",
|
|
44
|
+
"cross-env": "^10.1.0",
|
|
45
|
+
"eslint": "^8.47.0",
|
|
46
|
+
"eslint-config-prettier": "^9.0.0",
|
|
47
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
48
|
+
"prettier": "^3.0.2",
|
|
49
|
+
"rollup": "^3.28.0",
|
|
50
|
+
"tslib": "^2.6.2",
|
|
51
|
+
"typescript": "^3.7.0"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"tslib": "^2.6.2",
|
|
55
|
+
"typescript": "^3.7.0",
|
|
56
|
+
"vite": "^8.0.1"
|
|
57
|
+
}
|
|
58
|
+
}
|