Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@open-editor/server

Package Overview
Dependencies
Maintainers
1
Versions
55
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@open-editor/server - npm Package Compare versions

Comparing version
1.0.0-beta.2
to
1.0.0-beta.3
+4
-20
dist/index.d.ts

@@ -5,3 +5,2 @@ import connect from 'connect';

* 服务器核心配置选项
*
* @remarks

@@ -14,5 +13,3 @@ * 本配置定义了服务器启动的基础参数,支持 HTTP/HTTPS 双协议模式,

* 项目源码根目录路径
*
* @default `process.cwd()` 进程当前工作目录
*
* @securityNote 需确保该路径具备可读权限

@@ -22,6 +19,8 @@ */

/**
* 自定义端口号
*/
port?: number;
/**
* HTTPS 安全传输层配置
*
* @see [TLS Context Options](https://nodejs.org/api/tls.html#tlscreatesecurecontextoptions)
*
* @example

@@ -36,3 +35,2 @@ * {

* PEM 格式的 SSL 私钥文件路径
*
* @fileMustExist 文件必须存在且可读

@@ -43,3 +41,2 @@ */

* PEM 格式的 SSL 证书文件路径
*
* @fileMustExist 文件必须存在且可读

@@ -51,5 +48,3 @@ */

* 自定义编辑器打开处理器
*
* @default 使用内置的 `launch-editor` 实现
*
* @param file - 需要打开的目标文件路径

@@ -61,11 +56,4 @@ */

* 创建并启动应用服务器
*
* @param options - 服务器配置参数集
* @returns 返回包含实际监听端口的 Promise
*
* @technicalProcess
* 1. 初始化应用实例
* 2. 根据配置创建 HTTP/HTTPS 服务器
* 3. 动态分配可用端口并启动监听
*
* @example

@@ -88,5 +76,3 @@ * ```typescript

* 项目根目录路径
*
* @default process.cwd()
*
* @remarks

@@ -98,3 +84,2 @@ * 用于解析文件相对路径的基础目录

* 自定义编辑器打开处理器
*
* @remarks

@@ -108,3 +93,2 @@ * 默认使用 launch-editor 库实现

* 创建编辑器中间件
*
* @param options - 中间件配置选项

@@ -111,0 +95,0 @@ * @returns connect 中间件处理函数

+1
-1

@@ -1,1 +0,1 @@

"use strict";var e=require("node:http"),r=require("node:https"),t=require("node:fs"),n=require("connect"),o=require("cors"),i=require("@open-editor/shared"),s=require("node:path"),a=require("node:url"),c=require("launch-editor"),u=require("node:net");const DEFAULE_OPEN_DDITOR=(e,r)=>{c(e,(e,t)=>r(t))};function openEditorMiddleware(e={}){let{rootDir:r=process.cwd(),onOpenEditor:t=DEFAULE_OPEN_DDITOR}=e;return(e,n)=>{try{var o;let{query:i}=a.parse(null!=(o=e.url)?o:"/",!0),{f:c="unknown",l:u="1",c:l="1"}=i;if(!c)return void sendErrorResponse(n,400,"缺少文件路径参数");let d=s.resolve(r,decodeURIComponent(c));if(!validateFile(d,n))return;e.headers.referer&&t(`${d}:${u}:${l}`,e=>{throw Error(e||"可能原因有编辑器未启动/编辑器未响应")}),sendFileContent(n,d)}catch(r){let e=r instanceof Error?r.message:"未知错误";sendErrorResponse(n,500,`服务器内部错误: ${e}`)}}}function validateFile(e,r){return t.existsSync(e)?!!t.statSync(e).isFile()||(sendErrorResponse(r,400,`'${e}' 不是有效文件`),!1):(sendErrorResponse(r,404,`文件 '${e}' 不存在`),!1)}function sendFileContent(e,r){e.setHeader("Content-Type","application/javascript;charset=UTF-8"),e.end(t.readFileSync(r,"utf-8"))}function sendErrorResponse(e,r,t){e.statusCode=r,e.setHeader("Content-Type","text/plain;charset=UTF-8"),e.end(`[@open-editor/server] ${t}`)}function createApp(e){let{rootDir:r,onOpenEditor:t}=e,s=n();return s.use(o({methods:"GET"})),s.use(i.ServerApis.OPEN_EDITOR,openEditorMiddleware({rootDir:r,onOpenEditor:t})),s}function asyncGeneratorStep(e,r,t,n,o,i,s){try{var a=e[i](s),c=a.value}catch(e){t(e);return}a.done?r(c):Promise.resolve(c).then(n,o)}function _async_to_generator(e){return function(){var r=this,t=arguments;return new Promise(function(n,o){var i=e.apply(r,t);function _next(e){asyncGeneratorStep(i,n,o,_next,_throw,"next",e)}function _throw(e){asyncGeneratorStep(i,n,o,_next,_throw,"throw",e)}_next(void 0)})}}function getAvailablePort(){return _async_to_generator(function*({concurrency:e=5,retries:r=10}={}){for(let t=0;t<r;t++){let r=Array.from({length:e},generatePort).map(e=>checkPortNumber(e).then(r=>r?e:null)),t=yield Promise.race([...r,new Promise(e=>{setTimeout(()=>e(null),100)})]);if(t)return t}throw Error(`port detection failed, please check system resources. number of attempts: ${r}`)}).apply(this,arguments)}function checkPortNumber(e){return new Promise(r=>{let t=u.createServer();t.unref(),t.on("error",()=>{r(!1)}),t.listen(e,()=>{t.close(()=>{r(!0)})})})}function generatePort(){return Math.floor(6e3*Math.random()+3e3)}function setupServer(e={}){let{rootDir:r,https:t}=e;return startServer(createHttpServer(createApp({rootDir:r}),t))}function createHttpServer(n,o){if(!o)return e.createServer(n);let i={key:t.readFileSync(o.key),cert:t.readFileSync(o.cert)};return r.createServer(i,n)}function startServer(e){return new Promise((r,t)=>{getAvailablePort().then(n=>{e.listen(n).once("listening",()=>r(n)).once("error",t)}).catch(t)})}exports.openEditorMiddleware=openEditorMiddleware,exports.setupServer=setupServer;
"use strict";var e=require("node:http"),r=require("node:https"),t=require("node:fs"),n=require("connect"),o=require("cors"),i=require("@open-editor/shared"),s=require("node:path"),a=require("node:url"),c=require("launch-editor"),u=require("node:net");const DEFAULE_OPEN_DDITOR=(e,r)=>{c(e,(e,t)=>r(t))};function openEditorMiddleware(e={}){let{rootDir:r=process.cwd(),onOpenEditor:t=DEFAULE_OPEN_DDITOR}=e;return(e,n)=>{try{var o;let{query:i}=a.parse(null!=(o=e.url)?o:"/",!0),{f:c="unknown",l:u="1",c:l="1"}=i;if(!c)return void sendErrorResponse(n,400,"缺少文件路径参数");let d=s.resolve(r,decodeURIComponent(c));if(!validateFile(d,n))return;e.headers.referer&&t(`${d}:${u}:${l}`,e=>{throw Error(e||"可能原因有编辑器未启动/编辑器未响应")}),sendFileContent(n,d)}catch(r){let e=r instanceof Error?r.message:"未知错误";sendErrorResponse(n,500,`服务器内部错误: ${e}`)}}}function validateFile(e,r){return t.existsSync(e)?!!t.statSync(e).isFile()||(sendErrorResponse(r,400,`'${e}' 不是有效文件`),!1):(sendErrorResponse(r,404,`文件 '${e}' 不存在`),!1)}function sendFileContent(e,r){e.setHeader("Content-Type","application/javascript;charset=UTF-8"),e.end(t.readFileSync(r,"utf-8"))}function sendErrorResponse(e,r,t){e.statusCode=r,e.setHeader("Content-Type","text/plain;charset=UTF-8"),e.end(`[@open-editor/server] ${t}`)}function createApp(e){let{rootDir:r,onOpenEditor:t}=e,s=n();return s.use(o({methods:"GET"})),s.use(i.ServerApis.OPEN_EDITOR,openEditorMiddleware({rootDir:r,onOpenEditor:t})),s}function asyncGeneratorStep(e,r,t,n,o,i,s){try{var a=e[i](s),c=a.value}catch(e){t(e);return}a.done?r(c):Promise.resolve(c).then(n,o)}function _async_to_generator(e){return function(){var r=this,t=arguments;return new Promise(function(n,o){var i=e.apply(r,t);function _next(e){asyncGeneratorStep(i,n,o,_next,_throw,"next",e)}function _throw(e){asyncGeneratorStep(i,n,o,_next,_throw,"throw",e)}_next(void 0)})}}function getAvailablePort(e){return _async_to_generator(function*(){if(e)return Promise.resolve(e);for(let e=0;e<10;e++){let e=Array.from({length:5},generatePort).map(e=>checkPortNumber(e).then(r=>r?e:null)),r=yield Promise.race([...e,new Promise(e=>{setTimeout(()=>e(null),100)})]);if(r)return r}throw Error("port detection failed, please check system resources. number of attempts: 10")})()}function checkPortNumber(e){return new Promise(r=>{let t=u.createServer();t.unref(),t.on("error",()=>{r(!1)}),t.listen(e,()=>{t.close(()=>{r(!0)})})})}function generatePort(){return Math.floor(6e3*Math.random()+3e3)}function setupServer(e={}){let{rootDir:r,port:t,https:n}=e;return startServer(createHttpServer(createApp({rootDir:r}),n),t)}function createHttpServer(n,o){if(!o)return e.createServer(n);let i={key:t.readFileSync(o.key),cert:t.readFileSync(o.cert)};return r.createServer(i,n)}function startServer(e,r){return new Promise((t,n)=>{getAvailablePort(r).then(r=>{e.listen(r).once("listening",()=>t(r)).once("error",n)}).catch(n)})}exports.openEditorMiddleware=openEditorMiddleware,exports.setupServer=setupServer;

@@ -1,1 +0,1 @@

import e from"node:http";import r from"node:https";import{existsSync as t,statSync as n,readFileSync as o}from"node:fs";import i from"connect";import s from"cors";import{ServerApis as a}from"@open-editor/shared";import{resolve as c}from"node:path";import{parse as u}from"node:url";import p from"launch-editor";import l from"node:net";let DEFAULE_OPEN_DDITOR=(e,r)=>{p(e,(e,t)=>r(t))};function openEditorMiddleware(e={}){let{rootDir:r=process.cwd(),onOpenEditor:t=DEFAULE_OPEN_DDITOR}=e;return(e,n)=>{try{var o;let{query:i}=u(null!=(o=e.url)?o:"/",!0),{f:s="unknown",l:a="1",c:p="1"}=i;if(!s)return void sendErrorResponse(n,400,"缺少文件路径参数");let l=c(r,decodeURIComponent(s));if(!validateFile(l,n))return;e.headers.referer&&t(`${l}:${a}:${p}`,e=>{throw Error(e||"可能原因有编辑器未启动/编辑器未响应")}),sendFileContent(n,l)}catch(r){let e=r instanceof Error?r.message:"未知错误";sendErrorResponse(n,500,`服务器内部错误: ${e}`)}}}function validateFile(e,r){return t(e)?!!n(e).isFile()||(sendErrorResponse(r,400,`'${e}' 不是有效文件`),!1):(sendErrorResponse(r,404,`文件 '${e}' 不存在`),!1)}function sendFileContent(e,r){e.setHeader("Content-Type","application/javascript;charset=UTF-8"),e.end(o(r,"utf-8"))}function sendErrorResponse(e,r,t){e.statusCode=r,e.setHeader("Content-Type","text/plain;charset=UTF-8"),e.end(`[@open-editor/server] ${t}`)}function createApp(e){let{rootDir:r,onOpenEditor:t}=e,n=i();return n.use(s({methods:"GET"})),n.use(a.OPEN_EDITOR,openEditorMiddleware({rootDir:r,onOpenEditor:t})),n}function asyncGeneratorStep(e,r,t,n,o,i,s){try{var a=e[i](s),c=a.value}catch(e){t(e);return}a.done?r(c):Promise.resolve(c).then(n,o)}function _async_to_generator(e){return function(){var r=this,t=arguments;return new Promise(function(n,o){var i=e.apply(r,t);function _next(e){asyncGeneratorStep(i,n,o,_next,_throw,"next",e)}function _throw(e){asyncGeneratorStep(i,n,o,_next,_throw,"throw",e)}_next(void 0)})}}function getAvailablePort(){return _async_to_generator(function*({concurrency:e=5,retries:r=10}={}){for(let t=0;t<r;t++){let r=Array.from({length:e},generatePort).map(e=>checkPortNumber(e).then(r=>r?e:null)),t=yield Promise.race([...r,new Promise(e=>{setTimeout(()=>e(null),100)})]);if(t)return t}throw Error(`port detection failed, please check system resources. number of attempts: ${r}`)}).apply(this,arguments)}function checkPortNumber(e){return new Promise(r=>{let t=l.createServer();t.unref(),t.on("error",()=>{r(!1)}),t.listen(e,()=>{t.close(()=>{r(!0)})})})}function generatePort(){return Math.floor(6e3*Math.random()+3e3)}function setupServer(e={}){let{rootDir:r,https:t}=e;return startServer(createHttpServer(createApp({rootDir:r}),t))}function createHttpServer(t,n){if(!n)return e.createServer(t);let i={key:o(n.key),cert:o(n.cert)};return r.createServer(i,t)}function startServer(e){return new Promise((r,t)=>{getAvailablePort().then(n=>{e.listen(n).once("listening",()=>r(n)).once("error",t)}).catch(t)})}export{openEditorMiddleware,setupServer};
import e from"node:http";import r from"node:https";import{existsSync as t,statSync as n,readFileSync as o}from"node:fs";import i from"connect";import s from"cors";import{ServerApis as a}from"@open-editor/shared";import{resolve as c}from"node:path";import{parse as u}from"node:url";import l from"launch-editor";import p from"node:net";let DEFAULE_OPEN_DDITOR=(e,r)=>{l(e,(e,t)=>r(t))};function openEditorMiddleware(e={}){let{rootDir:r=process.cwd(),onOpenEditor:t=DEFAULE_OPEN_DDITOR}=e;return(e,n)=>{try{var o;let{query:i}=u(null!=(o=e.url)?o:"/",!0),{f:s="unknown",l:a="1",c:l="1"}=i;if(!s)return void sendErrorResponse(n,400,"缺少文件路径参数");let p=c(r,decodeURIComponent(s));if(!validateFile(p,n))return;e.headers.referer&&t(`${p}:${a}:${l}`,e=>{throw Error(e||"可能原因有编辑器未启动/编辑器未响应")}),sendFileContent(n,p)}catch(r){let e=r instanceof Error?r.message:"未知错误";sendErrorResponse(n,500,`服务器内部错误: ${e}`)}}}function validateFile(e,r){return t(e)?!!n(e).isFile()||(sendErrorResponse(r,400,`'${e}' 不是有效文件`),!1):(sendErrorResponse(r,404,`文件 '${e}' 不存在`),!1)}function sendFileContent(e,r){e.setHeader("Content-Type","application/javascript;charset=UTF-8"),e.end(o(r,"utf-8"))}function sendErrorResponse(e,r,t){e.statusCode=r,e.setHeader("Content-Type","text/plain;charset=UTF-8"),e.end(`[@open-editor/server] ${t}`)}function createApp(e){let{rootDir:r,onOpenEditor:t}=e,n=i();return n.use(s({methods:"GET"})),n.use(a.OPEN_EDITOR,openEditorMiddleware({rootDir:r,onOpenEditor:t})),n}function asyncGeneratorStep(e,r,t,n,o,i,s){try{var a=e[i](s),c=a.value}catch(e){t(e);return}a.done?r(c):Promise.resolve(c).then(n,o)}function _async_to_generator(e){return function(){var r=this,t=arguments;return new Promise(function(n,o){var i=e.apply(r,t);function _next(e){asyncGeneratorStep(i,n,o,_next,_throw,"next",e)}function _throw(e){asyncGeneratorStep(i,n,o,_next,_throw,"throw",e)}_next(void 0)})}}function getAvailablePort(e){return _async_to_generator(function*(){if(e)return Promise.resolve(e);for(let e=0;e<10;e++){let e=Array.from({length:5},generatePort).map(e=>checkPortNumber(e).then(r=>r?e:null)),r=yield Promise.race([...e,new Promise(e=>{setTimeout(()=>e(null),100)})]);if(r)return r}throw Error("port detection failed, please check system resources. number of attempts: 10")})()}function checkPortNumber(e){return new Promise(r=>{let t=p.createServer();t.unref(),t.on("error",()=>{r(!1)}),t.listen(e,()=>{t.close(()=>{r(!0)})})})}function generatePort(){return Math.floor(6e3*Math.random()+3e3)}function setupServer(e={}){let{rootDir:r,port:t,https:n}=e;return startServer(createHttpServer(createApp({rootDir:r}),n),t)}function createHttpServer(t,n){if(!n)return e.createServer(t);let i={key:o(n.key),cert:o(n.cert)};return r.createServer(i,t)}function startServer(e,r){return new Promise((t,n)=>{getAvailablePort(r).then(r=>{e.listen(r).once("listening",()=>t(r)).once("error",n)}).catch(n)})}export{openEditorMiddleware,setupServer};
{
"name": "@open-editor/server",
"version": "1.0.0-beta.2",
"version": "1.0.0-beta.3",
"description": "internal utils shared across @open-editor packages",

@@ -34,3 +34,3 @@ "main": "./dist/index.js",

"launch-editor": "^2.6.0",
"@open-editor/shared": "1.0.0-beta.2"
"@open-editor/shared": "1.0.0-beta.3"
},

@@ -37,0 +37,0 @@ "devDependencies": {