@gravito/constellation 1.0.0-beta.1 → 2.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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  DiskSitemapStorage
3
- } from "./chunk-OGZECOH5.js";
3
+ } from "./chunk-7WHLC3OJ.js";
4
4
  export {
5
5
  DiskSitemapStorage
6
6
  };
@@ -0,0 +1,56 @@
1
+ // src/storage/DiskSitemapStorage.ts
2
+ import fs from "fs/promises";
3
+ import path from "path";
4
+ function sanitizeFilename(filename) {
5
+ if (!filename) {
6
+ throw new Error("Invalid sitemap filename.");
7
+ }
8
+ if (filename.includes("\0")) {
9
+ throw new Error("Invalid sitemap filename.");
10
+ }
11
+ if (filename.includes("/") || filename.includes("\\")) {
12
+ throw new Error("Invalid sitemap filename.");
13
+ }
14
+ if (filename.includes("..")) {
15
+ throw new Error("Invalid sitemap filename.");
16
+ }
17
+ return filename;
18
+ }
19
+ var DiskSitemapStorage = class {
20
+ constructor(outDir, baseUrl) {
21
+ this.outDir = outDir;
22
+ this.baseUrl = baseUrl;
23
+ }
24
+ async write(filename, content) {
25
+ const safeName = sanitizeFilename(filename);
26
+ await fs.mkdir(this.outDir, { recursive: true });
27
+ await fs.writeFile(path.join(this.outDir, safeName), content);
28
+ }
29
+ async read(filename) {
30
+ try {
31
+ const safeName = sanitizeFilename(filename);
32
+ return await fs.readFile(path.join(this.outDir, safeName), "utf-8");
33
+ } catch {
34
+ return null;
35
+ }
36
+ }
37
+ async exists(filename) {
38
+ try {
39
+ const safeName = sanitizeFilename(filename);
40
+ await fs.access(path.join(this.outDir, safeName));
41
+ return true;
42
+ } catch {
43
+ return false;
44
+ }
45
+ }
46
+ getUrl(filename) {
47
+ const safeName = sanitizeFilename(filename);
48
+ const base = this.baseUrl.endsWith("/") ? this.baseUrl.slice(0, -1) : this.baseUrl;
49
+ const file = safeName.startsWith("/") ? safeName.slice(1) : safeName;
50
+ return `${base}/${file}`;
51
+ }
52
+ };
53
+
54
+ export {
55
+ DiskSitemapStorage
56
+ };
package/dist/index.cjs CHANGED
@@ -35,6 +35,21 @@ var DiskSitemapStorage_exports = {};
35
35
  __export(DiskSitemapStorage_exports, {
36
36
  DiskSitemapStorage: () => DiskSitemapStorage
37
37
  });
38
+ function sanitizeFilename(filename) {
39
+ if (!filename) {
40
+ throw new Error("Invalid sitemap filename.");
41
+ }
42
+ if (filename.includes("\0")) {
43
+ throw new Error("Invalid sitemap filename.");
44
+ }
45
+ if (filename.includes("/") || filename.includes("\\")) {
46
+ throw new Error("Invalid sitemap filename.");
47
+ }
48
+ if (filename.includes("..")) {
49
+ throw new Error("Invalid sitemap filename.");
50
+ }
51
+ return filename;
52
+ }
38
53
  var import_promises, import_node_path, DiskSitemapStorage;
39
54
  var init_DiskSitemapStorage = __esm({
40
55
  "src/storage/DiskSitemapStorage.ts"() {
@@ -47,27 +62,31 @@ var init_DiskSitemapStorage = __esm({
47
62
  this.baseUrl = baseUrl;
48
63
  }
49
64
  async write(filename, content) {
65
+ const safeName = sanitizeFilename(filename);
50
66
  await import_promises.default.mkdir(this.outDir, { recursive: true });
51
- await import_promises.default.writeFile(import_node_path.default.join(this.outDir, filename), content);
67
+ await import_promises.default.writeFile(import_node_path.default.join(this.outDir, safeName), content);
52
68
  }
53
69
  async read(filename) {
54
70
  try {
55
- return await import_promises.default.readFile(import_node_path.default.join(this.outDir, filename), "utf-8");
71
+ const safeName = sanitizeFilename(filename);
72
+ return await import_promises.default.readFile(import_node_path.default.join(this.outDir, safeName), "utf-8");
56
73
  } catch {
57
74
  return null;
58
75
  }
59
76
  }
60
77
  async exists(filename) {
61
78
  try {
62
- await import_promises.default.access(import_node_path.default.join(this.outDir, filename));
79
+ const safeName = sanitizeFilename(filename);
80
+ await import_promises.default.access(import_node_path.default.join(this.outDir, safeName));
63
81
  return true;
64
82
  } catch {
65
83
  return false;
66
84
  }
67
85
  }
68
86
  getUrl(filename) {
87
+ const safeName = sanitizeFilename(filename);
69
88
  const base = this.baseUrl.endsWith("/") ? this.baseUrl.slice(0, -1) : this.baseUrl;
70
- const file = filename.startsWith("/") ? filename.slice(1) : filename;
89
+ const file = safeName.startsWith("/") ? safeName.slice(1) : safeName;
71
90
  return `${base}/${file}`;
72
91
  }
73
92
  };
@@ -1185,6 +1204,21 @@ var MemorySitemapStorage = class {
1185
1204
  };
1186
1205
 
1187
1206
  // src/OrbitSitemap.ts
1207
+ function sanitizeFilename2(value) {
1208
+ if (!value) {
1209
+ return null;
1210
+ }
1211
+ if (value.includes("\0")) {
1212
+ return null;
1213
+ }
1214
+ if (value.includes("/") || value.includes("\\")) {
1215
+ return null;
1216
+ }
1217
+ if (value.includes("..")) {
1218
+ return null;
1219
+ }
1220
+ return value;
1221
+ }
1188
1222
  var OrbitSitemap = class _OrbitSitemap {
1189
1223
  options;
1190
1224
  mode;
@@ -1235,7 +1269,11 @@ var OrbitSitemap = class _OrbitSitemap {
1235
1269
  const baseDir = opts.path ? opts.path.substring(0, opts.path.lastIndexOf("/")) : void 0;
1236
1270
  const handler = async (ctx) => {
1237
1271
  const reqPath = ctx.req.path;
1238
- const filename = reqPath.split("/").pop() || indexFilename;
1272
+ const rawName = reqPath.split("/").pop() || indexFilename;
1273
+ const filename = sanitizeFilename2(rawName);
1274
+ if (!filename) {
1275
+ return ctx.text("Not Found", 404);
1276
+ }
1239
1277
  const isIndex = filename === indexFilename;
1240
1278
  let content = await storage.read(filename);
1241
1279
  if (!content && isIndex) {
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Job } from '@gravito/stream';
2
- import { PlanetCore } from 'gravito-core';
2
+ import { PlanetCore } from '@gravito/core';
3
3
 
4
4
  type ChangeFreq = 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
5
5
  interface AlternateUrl {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Job } from '@gravito/stream';
2
- import { PlanetCore } from 'gravito-core';
2
+ import { PlanetCore } from '@gravito/core';
3
3
 
4
4
  type ChangeFreq = 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
5
5
  interface AlternateUrl {
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  DiskSitemapStorage
3
- } from "./chunk-OGZECOH5.js";
3
+ } from "./chunk-7WHLC3OJ.js";
4
4
 
5
5
  // src/core/ChangeTracker.ts
6
6
  var MemoryChangeTracker = class {
@@ -1083,6 +1083,21 @@ var MemorySitemapStorage = class {
1083
1083
  };
1084
1084
 
1085
1085
  // src/OrbitSitemap.ts
1086
+ function sanitizeFilename(value) {
1087
+ if (!value) {
1088
+ return null;
1089
+ }
1090
+ if (value.includes("\0")) {
1091
+ return null;
1092
+ }
1093
+ if (value.includes("/") || value.includes("\\")) {
1094
+ return null;
1095
+ }
1096
+ if (value.includes("..")) {
1097
+ return null;
1098
+ }
1099
+ return value;
1100
+ }
1086
1101
  var OrbitSitemap = class _OrbitSitemap {
1087
1102
  options;
1088
1103
  mode;
@@ -1133,7 +1148,11 @@ var OrbitSitemap = class _OrbitSitemap {
1133
1148
  const baseDir = opts.path ? opts.path.substring(0, opts.path.lastIndexOf("/")) : void 0;
1134
1149
  const handler = async (ctx) => {
1135
1150
  const reqPath = ctx.req.path;
1136
- const filename = reqPath.split("/").pop() || indexFilename;
1151
+ const rawName = reqPath.split("/").pop() || indexFilename;
1152
+ const filename = sanitizeFilename(rawName);
1153
+ if (!filename) {
1154
+ return ctx.text("Not Found", 404);
1155
+ }
1137
1156
  const isIndex = filename === indexFilename;
1138
1157
  let content = await storage.read(filename);
1139
1158
  if (!content && isIndex) {
@@ -1191,7 +1210,7 @@ var OrbitSitemap = class _OrbitSitemap {
1191
1210
  const opts = this.options;
1192
1211
  let storage = opts.storage;
1193
1212
  if (!storage) {
1194
- const { DiskSitemapStorage: DiskSitemapStorage2 } = await import("./DiskSitemapStorage-EKADBB2W.js");
1213
+ const { DiskSitemapStorage: DiskSitemapStorage2 } = await import("./DiskSitemapStorage-7ZZMGC4K.js");
1195
1214
  storage = new DiskSitemapStorage2(opts.outDir, opts.baseUrl);
1196
1215
  }
1197
1216
  let providers = opts.providers;
@@ -1237,7 +1256,7 @@ var OrbitSitemap = class _OrbitSitemap {
1237
1256
  }
1238
1257
  let storage = opts.storage;
1239
1258
  if (!storage) {
1240
- const { DiskSitemapStorage: DiskSitemapStorage2 } = await import("./DiskSitemapStorage-EKADBB2W.js");
1259
+ const { DiskSitemapStorage: DiskSitemapStorage2 } = await import("./DiskSitemapStorage-7ZZMGC4K.js");
1241
1260
  storage = new DiskSitemapStorage2(opts.outDir, opts.baseUrl);
1242
1261
  }
1243
1262
  const incrementalGenerator = new IncrementalGenerator({
@@ -1266,7 +1285,7 @@ var OrbitSitemap = class _OrbitSitemap {
1266
1285
  const jobId = randomUUID();
1267
1286
  let storage = opts.storage;
1268
1287
  if (!storage) {
1269
- const { DiskSitemapStorage: DiskSitemapStorage2 } = await import("./DiskSitemapStorage-EKADBB2W.js");
1288
+ const { DiskSitemapStorage: DiskSitemapStorage2 } = await import("./DiskSitemapStorage-7ZZMGC4K.js");
1270
1289
  storage = new DiskSitemapStorage2(opts.outDir, opts.baseUrl);
1271
1290
  }
1272
1291
  let providers = opts.providers;
package/package.json CHANGED
@@ -1,11 +1,18 @@
1
1
  {
2
2
  "name": "@gravito/constellation",
3
- "version": "1.0.0-beta.1",
3
+ "version": "2.0.0",
4
4
  "description": "Powerful sitemap generation for Gravito applications with dynamic/static support, sharding, and caching.",
5
- "type": "module",
6
5
  "main": "./dist/index.cjs",
7
- "module": "./dist/index.mjs",
6
+ "module": "./dist/index.js",
7
+ "type": "module",
8
8
  "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
9
16
  "files": [
10
17
  "dist",
11
18
  "README.md",
@@ -13,22 +20,24 @@
13
20
  ],
14
21
  "scripts": {
15
22
  "build": "bun run build.ts",
16
- "typecheck": "tsc --noEmit",
17
- "test": "bun test"
23
+ "typecheck": "bun tsc -p tsconfig.json --noEmit --skipLibCheck",
24
+ "test": "bun test",
25
+ "test:coverage": "bun test --coverage --coverage-threshold=80",
26
+ "test:ci": "bun test --coverage --coverage-threshold=80"
18
27
  },
19
28
  "peerDependencies": {
20
- "gravito-core": "1.0.0-beta.6"
29
+ "@gravito/core": "workspace:*"
21
30
  },
22
31
  "dependencies": {
23
32
  "@aws-sdk/client-s3": "^3.956.0",
24
33
  "@google-cloud/storage": "^7.18.0",
25
- "@gravito/stream": "1.0.0-beta.1",
26
- "@gravito/photon": "1.0.0-beta.1"
34
+ "@gravito/stream": "workspace:*",
35
+ "@gravito/photon": "workspace:*"
27
36
  },
28
37
  "devDependencies": {
29
38
  "bun-plugin-dts": "^0.3.0",
30
39
  "bun-types": "latest",
31
- "gravito-core": "1.0.0-beta.6",
40
+ "@gravito/core": "workspace:*",
32
41
  "tsup": "^8.5.1",
33
42
  "typescript": "^5.9.3"
34
43
  },
@@ -47,4 +56,4 @@
47
56
  "license": "MIT",
48
57
  "author": "Carl Lee <carllee0520@gmail.com>",
49
58
  "homepage": "https://github.com/gravito-framework/gravito#readme"
50
- }
59
+ }
@@ -1,37 +0,0 @@
1
- // src/storage/DiskSitemapStorage.ts
2
- import fs from "fs/promises";
3
- import path from "path";
4
- var DiskSitemapStorage = class {
5
- constructor(outDir, baseUrl) {
6
- this.outDir = outDir;
7
- this.baseUrl = baseUrl;
8
- }
9
- async write(filename, content) {
10
- await fs.mkdir(this.outDir, { recursive: true });
11
- await fs.writeFile(path.join(this.outDir, filename), content);
12
- }
13
- async read(filename) {
14
- try {
15
- return await fs.readFile(path.join(this.outDir, filename), "utf-8");
16
- } catch {
17
- return null;
18
- }
19
- }
20
- async exists(filename) {
21
- try {
22
- await fs.access(path.join(this.outDir, filename));
23
- return true;
24
- } catch {
25
- return false;
26
- }
27
- }
28
- getUrl(filename) {
29
- const base = this.baseUrl.endsWith("/") ? this.baseUrl.slice(0, -1) : this.baseUrl;
30
- const file = filename.startsWith("/") ? filename.slice(1) : filename;
31
- return `${base}/${file}`;
32
- }
33
- };
34
-
35
- export {
36
- DiskSitemapStorage
37
- };