@zuplo/editor 1.0.18282606817-dev → 1.0.18288423685-dev
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/client/{local-editor.html → local.html} +5 -5
- package/dist/client/static/css/App-DH9HRCOf.css +1 -0
- package/dist/client/static/css/main-DB0Klj1W.css +1 -0
- package/dist/client/static/js/App-B6G4730z.js +2162 -0
- package/dist/client/static/js/App-B6G4730z.js.map +1 -0
- package/dist/client/static/js/local-worker-Cd_QJYDp.js +2 -0
- package/dist/client/static/js/local-worker-Cd_QJYDp.js.map +1 -0
- package/dist/client/static/js/main-BKLfe0Z9.js +52 -0
- package/dist/client/static/js/main-BKLfe0Z9.js.map +1 -0
- package/dist/config.d.ts +54 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +54 -0
- package/dist/config.js.map +1 -0
- package/dist/error-handler.d.ts +3 -0
- package/dist/error-handler.d.ts.map +1 -0
- package/dist/error-handler.js +135 -0
- package/dist/error-handler.js.map +1 -0
- package/dist/interfaces.d.ts +24 -0
- package/dist/interfaces.d.ts.map +1 -0
- package/dist/interfaces.js +13 -0
- package/dist/interfaces.js.map +1 -0
- package/dist/routes/api.d.ts +2 -1
- package/dist/routes/api.d.ts.map +1 -1
- package/dist/routes/api.js +23 -21
- package/dist/routes/api.js.map +1 -1
- package/dist/routes/editor.d.ts.map +1 -1
- package/dist/routes/editor.js +37 -51
- package/dist/routes/editor.js.map +1 -1
- package/dist/routes/fs.d.ts.map +1 -1
- package/dist/routes/fs.js +219 -238
- package/dist/routes/fs.js.map +1 -1
- package/dist/routes/test.js +1 -1
- package/dist/routes/test.js.map +1 -1
- package/dist/routes/types.d.ts.map +1 -1
- package/dist/routes/types.js +30 -22
- package/dist/routes/types.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +38 -29
- package/dist/server.js.map +1 -1
- package/dist/utils/path.d.ts +33 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +42 -0
- package/dist/utils/path.js.map +1 -0
- package/package.json +2 -1
- package/dist/client/static/css/main-D3M2tKfG.css +0 -1
- package/dist/client/static/js/local-worker-BVQSFGzz.js +0 -2
- package/dist/client/static/js/local-worker-BVQSFGzz.js.map +0 -1
- package/dist/client/static/js/main-CIyp_ifb.js +0 -2074
- package/dist/client/static/js/main-CIyp_ifb.js.map +0 -1
package/dist/routes/types.js
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import { ApiError, Problems } from "@zuplo/errors";
|
1
2
|
import fs from "node:fs/promises";
|
2
3
|
import path from "node:path";
|
3
4
|
export async function createTypesRoutes(fastify, options) {
|
@@ -5,33 +6,40 @@ export async function createTypesRoutes(fastify, options) {
|
|
5
6
|
// Serve TypeScript definition files from node_modules
|
6
7
|
// GET /api/types/node_modules/@types/node/index.d.ts
|
7
8
|
fastify.get("/node_modules/*", async (request, reply) => {
|
9
|
+
// Get the path after /node_modules/
|
10
|
+
const requestedPath = request.params["*"];
|
11
|
+
const fullPath = path.join(portalRoot, "node_modules", requestedPath);
|
12
|
+
// Security: ensure the path is within node_modules
|
13
|
+
const resolvedPath = path.resolve(fullPath);
|
14
|
+
const node_modules_path = path.resolve(portalRoot, "node_modules");
|
15
|
+
if (!resolvedPath.startsWith(node_modules_path)) {
|
16
|
+
throw new ApiError({
|
17
|
+
...Problems.FORBIDDEN,
|
18
|
+
detail: "Access denied",
|
19
|
+
});
|
20
|
+
}
|
21
|
+
// Check if file exists
|
8
22
|
try {
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
if (!resolvedPath.startsWith(node_modules_path)) {
|
16
|
-
return reply.status(403).send("Access denied");
|
17
|
-
}
|
18
|
-
// Check if file exists
|
19
|
-
try {
|
20
|
-
const stat = await fs.stat(resolvedPath);
|
21
|
-
if (!stat.isFile()) {
|
22
|
-
return reply.status(404).send("Not found");
|
23
|
-
}
|
23
|
+
const stat = await fs.stat(resolvedPath);
|
24
|
+
if (!stat.isFile()) {
|
25
|
+
throw new ApiError({
|
26
|
+
...Problems.NOT_FOUND,
|
27
|
+
detail: "Type definition file not found",
|
28
|
+
});
|
24
29
|
}
|
25
|
-
catch {
|
26
|
-
return reply.status(404).send("Not found");
|
27
|
-
}
|
28
|
-
// Read and return the file
|
29
|
-
const content = await fs.readFile(resolvedPath, "utf-8");
|
30
|
-
reply.type("application/typescript").send(content);
|
31
30
|
}
|
32
31
|
catch (err) {
|
33
|
-
|
32
|
+
if (err instanceof ApiError) {
|
33
|
+
throw err;
|
34
|
+
}
|
35
|
+
throw new ApiError({
|
36
|
+
...Problems.NOT_FOUND,
|
37
|
+
detail: "Type definition file not found",
|
38
|
+
});
|
34
39
|
}
|
40
|
+
// Read and return the file
|
41
|
+
const content = await fs.readFile(resolvedPath, "utf-8");
|
42
|
+
reply.type("application/typescript").send(content);
|
35
43
|
});
|
36
44
|
}
|
37
45
|
//# sourceMappingURL=types.js.map
|
package/dist/routes/types.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/routes/types.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/routes/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAM7B,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAwB,EACxB,OAA2B;IAE3B,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAE/B,sDAAsD;IACtD,qDAAqD;IACrD,OAAO,CAAC,GAAG,CACT,iBAAiB,EACjB,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACvB,oCAAoC;QACpC,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,EAAE,aAAa,CAAC,CAAC;QAEtE,mDAAmD;QACnD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QACnE,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,QAAQ,CAAC;gBACjB,GAAG,QAAQ,CAAC,SAAS;gBACrB,MAAM,EAAE,eAAe;aACxB,CAAC,CAAC;QACL,CAAC;QAED,uBAAuB;QACvB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACzC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;gBACnB,MAAM,IAAI,QAAQ,CAAC;oBACjB,GAAG,QAAQ,CAAC,SAAS;oBACrB,MAAM,EAAE,gCAAgC;iBACzC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;gBAC5B,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,MAAM,IAAI,QAAQ,CAAC;gBACjB,GAAG,QAAQ,CAAC,SAAS;gBACrB,MAAM,EAAE,gCAAgC;aACzC,CAAC,CAAC;QACL,CAAC;QAED,2BAA2B;QAC3B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACzD,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrD,CAAC,CACF,CAAC;AACJ,CAAC"}
|
package/dist/server.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAOA,OAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,SAAS,CAAC;AAGxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAQnC,UAAU,aAAa;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,iBAAiB;IACrB,GAAG,EAAE,eAAe,CAAC;IAC5B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,OAAO,CAAY;IAC3B,OAAO,CAAC,UAAU,CAA6B;IAC/C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;gBAElB,OAAO,EAAE,aAAa;IAwBlC,IAAI,QAAa,OAAO,CAAC,IAAI,CAAC,CAoJ5B;IAEF,KAAK,QAAa,OAAO,CAAC,IAAI,CAAC,CAM7B;IAEF,IAAI,QAAa,OAAO,CAAC,IAAI,CAAC,CAkB5B;CACH"}
|
package/dist/server.js
CHANGED
@@ -2,18 +2,17 @@ import fastifyCors from "@fastify/cors";
|
|
2
2
|
import middie from "@fastify/middie";
|
3
3
|
import fastifyMultipart from "@fastify/multipart";
|
4
4
|
import fastifyStatic from "@fastify/static";
|
5
|
+
import { ApiError, ApiNotFoundError, Problems } from "@zuplo/errors";
|
5
6
|
import autoprefixer from "autoprefixer";
|
6
7
|
import { watch } from "chokidar";
|
7
8
|
import Fastify from "fastify";
|
8
9
|
import fs from "node:fs/promises";
|
9
10
|
import path from "node:path";
|
10
|
-
import { fileURLToPath } from "node:url";
|
11
11
|
import tailwindcss from "tailwindcss";
|
12
12
|
import { createServer as createViteServer } from "vite";
|
13
|
+
import { editorConfig } from "./config.js";
|
14
|
+
import { errorHandler } from "./error-handler.js";
|
13
15
|
import { createApiRoutes } from "./routes/api.js";
|
14
|
-
const __filename = fileURLToPath(import.meta.url);
|
15
|
-
const __dirname = path.dirname(__filename);
|
16
|
-
const WATCHED_DIRS = ["config", "modules", "schemas"];
|
17
16
|
export class LocalEditorServer {
|
18
17
|
app;
|
19
18
|
listenerHost;
|
@@ -30,19 +29,21 @@ export class LocalEditorServer {
|
|
30
29
|
this.listenerPort = options.port;
|
31
30
|
this.logger = options.logger;
|
32
31
|
this.deploymentUrl = options.deploymentUrl;
|
33
|
-
this.listenerHost =
|
32
|
+
this.listenerHost = editorConfig.server.host;
|
34
33
|
// Watch all project directories
|
35
|
-
this.watcher = watch(
|
34
|
+
this.watcher = watch(editorConfig.watch.watchedDirs.map((dir) => path.join(this.workingDir, dir)), { ignoreInitial: true });
|
36
35
|
// Determine portal root (go up from packages/editor/src to portal root)
|
37
|
-
this.portalRoot =
|
36
|
+
this.portalRoot = new URL("../../..", import.meta.url).pathname;
|
38
37
|
this.app = Fastify({
|
39
38
|
// logger: this.logger,
|
40
|
-
bodyLimit:
|
39
|
+
bodyLimit: editorConfig.server.bodyLimit,
|
41
40
|
trustProxy: true,
|
42
41
|
});
|
43
42
|
}
|
44
43
|
init = async () => {
|
45
44
|
// Register CORS
|
45
|
+
// Note: origin "*" is acceptable for local development only
|
46
|
+
// This allows the editor UI to make requests from any origin
|
46
47
|
await this.app.register(fastifyCors, {
|
47
48
|
origin: "*",
|
48
49
|
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
@@ -51,7 +52,7 @@ export class LocalEditorServer {
|
|
51
52
|
// Register multipart for file uploads
|
52
53
|
await this.app.register(fastifyMultipart, {
|
53
54
|
limits: {
|
54
|
-
fileSize:
|
55
|
+
fileSize: editorConfig.file.maxFileSize,
|
55
56
|
},
|
56
57
|
});
|
57
58
|
// Serve Monaco editor files from node_modules
|
@@ -78,15 +79,12 @@ export class LocalEditorServer {
|
|
78
79
|
const tailwindConfigWithAbsolutePaths = {
|
79
80
|
...tailwindConfig,
|
80
81
|
content: tailwindConfig.content.map((contentPath) => {
|
81
|
-
// If it's already absolute or a glob pattern with absolute path, leave it
|
82
82
|
if (path.isAbsolute(contentPath)) {
|
83
83
|
return contentPath;
|
84
84
|
}
|
85
|
-
// Convert relative paths to absolute based on portal root
|
86
85
|
return path.join(this.portalRoot, contentPath);
|
87
86
|
}),
|
88
87
|
};
|
89
|
-
this.logger.info(`Tailwind config loaded. Content: ${JSON.stringify(tailwindConfigWithAbsolutePaths.content)}`);
|
90
88
|
// Create Vite server in middleware mode
|
91
89
|
// Explicitly configure PostCSS since it doesn't load automatically in middleware mode
|
92
90
|
this.vite = await createViteServer({
|
@@ -105,6 +103,8 @@ export class LocalEditorServer {
|
|
105
103
|
});
|
106
104
|
// Use Vite's connect instance as middleware
|
107
105
|
this.app.use(this.vite.middlewares);
|
106
|
+
// Set up custom error handler
|
107
|
+
this.app.setErrorHandler(errorHandler);
|
108
108
|
// Add support for text/plain and application/* content types
|
109
109
|
this.app.addContentTypeParser("text/plain", { parseAs: "string" }, (_req, body, done) => {
|
110
110
|
done(null, body);
|
@@ -138,27 +138,24 @@ export class LocalEditorServer {
|
|
138
138
|
this.app.get("/", async (_request, reply) => {
|
139
139
|
reply.redirect("/dev/project/local/edit", 301);
|
140
140
|
});
|
141
|
-
|
141
|
+
const htmlPath = path.join(this.portalRoot, "local.html");
|
142
|
+
let template = await fs.readFile(htmlPath, "utf-8");
|
143
|
+
// SPA fallback - serve local.html for all unmatched routes
|
142
144
|
this.app.setNotFoundHandler(async (request, reply) => {
|
143
145
|
if (!this.vite) {
|
144
|
-
|
146
|
+
throw new ApiError({
|
147
|
+
...Problems.INTERNAL_SERVER_ERROR,
|
148
|
+
detail: "Vite server not initialized",
|
149
|
+
});
|
145
150
|
}
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
// Read the local-editor.html file
|
152
|
-
const htmlPath = path.join(this.portalRoot, "local-editor.html");
|
153
|
-
let template = await fs.readFile(htmlPath, "utf-8");
|
154
|
-
// Apply Vite HTML transforms
|
155
|
-
template = await this.vite.transformIndexHtml(url, template);
|
156
|
-
reply.status(200).type("text/html").send(template);
|
157
|
-
}
|
158
|
-
catch (err) {
|
159
|
-
this.logger.error(err);
|
160
|
-
reply.status(500).send(`Error loading page: ${err.message}`);
|
151
|
+
// Only handle GET requests that accept HTML
|
152
|
+
if (request.method !== "GET" ||
|
153
|
+
(request.headers.accept &&
|
154
|
+
!request.headers.accept.includes("text/html"))) {
|
155
|
+
throw new ApiNotFoundError();
|
161
156
|
}
|
157
|
+
template = await this.vite.transformIndexHtml(request.url, template);
|
158
|
+
reply.status(200).type("text/html").send(template);
|
162
159
|
});
|
163
160
|
};
|
164
161
|
start = async () => {
|
@@ -169,6 +166,18 @@ export class LocalEditorServer {
|
|
169
166
|
});
|
170
167
|
};
|
171
168
|
stop = async () => {
|
169
|
+
// Close all SSE connections
|
170
|
+
for (const client of this.sseClients) {
|
171
|
+
try {
|
172
|
+
if (client.writable) {
|
173
|
+
client.end();
|
174
|
+
}
|
175
|
+
}
|
176
|
+
catch (err) {
|
177
|
+
this.logger.warn({ err }, "Error closing SSE client");
|
178
|
+
}
|
179
|
+
}
|
180
|
+
this.sseClients.clear();
|
172
181
|
await this.watcher.close();
|
173
182
|
if (this.vite) {
|
174
183
|
await this.vite.close();
|
package/dist/server.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,gBAAgB,MAAM,oBAAoB,CAAC;AAClD,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,YAAY,MAAM,cAAc,CAAC;AACxC,OAAO,EAAa,KAAK,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,OAAiC,MAAM,SAAS,CAAC;AACxD,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
/**
|
2
|
+
* Normalizes a file path by removing leading slashes.
|
3
|
+
* This is necessary because path.join() treats leading slashes as absolute paths.
|
4
|
+
*
|
5
|
+
* @param filePath - The file path to normalize
|
6
|
+
* @returns The normalized path without leading slash
|
7
|
+
*
|
8
|
+
* @example
|
9
|
+
* normalizeRelativePath("/config/routes.json") // => "config/routes.json"
|
10
|
+
* normalizeRelativePath("config/routes.json") // => "config/routes.json"
|
11
|
+
*/
|
12
|
+
export declare function normalizeRelativePath(filePath: string): string;
|
13
|
+
/**
|
14
|
+
* Validates that a resolved path is within the allowed base directory.
|
15
|
+
* This prevents path traversal attacks.
|
16
|
+
*
|
17
|
+
* @param resolvedPath - The absolute resolved path
|
18
|
+
* @param baseDir - The base directory that the path must be within
|
19
|
+
* @returns true if the path is safe, false otherwise
|
20
|
+
*
|
21
|
+
* @example
|
22
|
+
* isPathSafe("/home/user/project/config", "/home/user/project") // => true
|
23
|
+
* isPathSafe("/etc/passwd", "/home/user/project") // => false
|
24
|
+
*/
|
25
|
+
export declare function isPathSafe(resolvedPath: string, baseDir: string): boolean;
|
26
|
+
/**
|
27
|
+
* Normalizes a path for consistent display (always start with /)
|
28
|
+
*
|
29
|
+
* @param filePath - The file path to normalize
|
30
|
+
* @returns The normalized path with leading slash
|
31
|
+
*/
|
32
|
+
export declare function normalizeDisplayPath(filePath: string): string;
|
33
|
+
//# sourceMappingURL=path.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAIzE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE7D"}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import path from "node:path";
|
2
|
+
/**
|
3
|
+
* Normalizes a file path by removing leading slashes.
|
4
|
+
* This is necessary because path.join() treats leading slashes as absolute paths.
|
5
|
+
*
|
6
|
+
* @param filePath - The file path to normalize
|
7
|
+
* @returns The normalized path without leading slash
|
8
|
+
*
|
9
|
+
* @example
|
10
|
+
* normalizeRelativePath("/config/routes.json") // => "config/routes.json"
|
11
|
+
* normalizeRelativePath("config/routes.json") // => "config/routes.json"
|
12
|
+
*/
|
13
|
+
export function normalizeRelativePath(filePath) {
|
14
|
+
return filePath.startsWith("/") ? filePath.slice(1) : filePath;
|
15
|
+
}
|
16
|
+
/**
|
17
|
+
* Validates that a resolved path is within the allowed base directory.
|
18
|
+
* This prevents path traversal attacks.
|
19
|
+
*
|
20
|
+
* @param resolvedPath - The absolute resolved path
|
21
|
+
* @param baseDir - The base directory that the path must be within
|
22
|
+
* @returns true if the path is safe, false otherwise
|
23
|
+
*
|
24
|
+
* @example
|
25
|
+
* isPathSafe("/home/user/project/config", "/home/user/project") // => true
|
26
|
+
* isPathSafe("/etc/passwd", "/home/user/project") // => false
|
27
|
+
*/
|
28
|
+
export function isPathSafe(resolvedPath, baseDir) {
|
29
|
+
const normalizedResolved = path.resolve(resolvedPath);
|
30
|
+
const normalizedBase = path.resolve(baseDir);
|
31
|
+
return normalizedResolved.startsWith(normalizedBase);
|
32
|
+
}
|
33
|
+
/**
|
34
|
+
* Normalizes a path for consistent display (always start with /)
|
35
|
+
*
|
36
|
+
* @param filePath - The file path to normalize
|
37
|
+
* @returns The normalized path with leading slash
|
38
|
+
*/
|
39
|
+
export function normalizeDisplayPath(filePath) {
|
40
|
+
return filePath.startsWith("/") ? filePath : `/${filePath}`;
|
41
|
+
}
|
42
|
+
//# sourceMappingURL=path.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;;;GAUG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,OAAO,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AACjE,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CAAC,YAAoB,EAAE,OAAe;IAC9D,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACtD,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,kBAAkB,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;AACvD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACnD,OAAO,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC;AAC9D,CAAC"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@zuplo/editor",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.18288423685-dev",
|
4
4
|
"description": "Local development server for Zuplo API Gateway projects",
|
5
5
|
"type": "module",
|
6
6
|
"main": "./dist/index.js",
|
@@ -35,6 +35,7 @@
|
|
35
35
|
"@fastify/multipart": "^9.2.1",
|
36
36
|
"@fastify/static": "^8.2.0",
|
37
37
|
"@fastify/vite": "^8.2.0",
|
38
|
+
"@zuplo/errors": "^6.59.52",
|
38
39
|
"chokidar": "^4.0.3",
|
39
40
|
"fastify": "^5.6.1",
|
40
41
|
"pino": "^10.0.0",
|