@hyperfrontend/project-scope 0.2.2 → 0.2.3

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/_shared/core/fs/guard/index.cjs.js +7 -0
  3. package/_shared/core/fs/guard/index.esm.js +5 -0
  4. package/_shared/core/fs/stat/index.cjs.js +3 -2
  5. package/_shared/core/fs/stat/index.esm.js +3 -2
  6. package/_shared/core/path/confine/index.cjs.js +22 -0
  7. package/_shared/core/path/confine/index.esm.js +19 -0
  8. package/cli/index.cjs.js +5 -1
  9. package/cli/index.esm.js +5 -1
  10. package/core/fs/index.cjs.js +12 -2
  11. package/core/fs/index.esm.js +12 -2
  12. package/core/index.cjs.js +13 -3
  13. package/core/index.esm.js +14 -4
  14. package/core/path/index.cjs.js +4 -2
  15. package/core/path/index.d.ts +22 -1
  16. package/core/path/index.d.ts.map +1 -1
  17. package/core/path/index.esm.js +4 -3
  18. package/heuristics/dependencies/index.cjs.js +10 -1
  19. package/heuristics/dependencies/index.esm.js +12 -3
  20. package/heuristics/entry-points/index.cjs.js +2 -1
  21. package/heuristics/entry-points/index.esm.js +2 -1
  22. package/heuristics/framework/index.cjs.js +2 -1
  23. package/heuristics/framework/index.esm.js +2 -1
  24. package/heuristics/index.cjs.js +10 -1
  25. package/heuristics/index.esm.js +12 -3
  26. package/heuristics/project-type/index.cjs.js +2 -1
  27. package/heuristics/project-type/index.esm.js +2 -1
  28. package/index.cjs.js +18 -3
  29. package/index.esm.js +19 -4
  30. package/nx/index.cjs.js +3 -2
  31. package/nx/index.esm.js +3 -2
  32. package/package.json +1 -1
  33. package/project/config/index.cjs.js +5 -1
  34. package/project/config/index.esm.js +5 -1
  35. package/project/index.cjs.js +5 -1
  36. package/project/index.esm.js +5 -1
  37. package/project/package/index.cjs.js +5 -1
  38. package/project/package/index.esm.js +5 -1
  39. package/project/root/index.cjs.js +2 -1
  40. package/project/root/index.esm.js +2 -1
  41. package/project/traversal/index.cjs.js +2 -1
  42. package/project/traversal/index.esm.js +2 -1
  43. package/tech/backend/index.cjs.js +2 -1
  44. package/tech/backend/index.esm.js +2 -1
  45. package/tech/build/index.cjs.js +2 -1
  46. package/tech/build/index.esm.js +2 -1
  47. package/tech/frontend/index.cjs.js +2 -1
  48. package/tech/frontend/index.esm.js +2 -1
  49. package/tech/index.cjs.js +2 -1
  50. package/tech/index.esm.js +2 -1
  51. package/tech/legacy/index.cjs.js +2 -1
  52. package/tech/legacy/index.esm.js +2 -1
  53. package/tech/linting/index.cjs.js +2 -1
  54. package/tech/linting/index.esm.js +2 -1
  55. package/tech/monorepo/index.cjs.js +2 -1
  56. package/tech/monorepo/index.esm.js +2 -1
  57. package/tech/testing/index.cjs.js +2 -1
  58. package/tech/testing/index.esm.js +2 -1
  59. package/tech/types/index.cjs.js +2 -1
  60. package/tech/types/index.esm.js +2 -1
@@ -9,6 +9,7 @@ import { join as join$1 } from 'node:path';
9
9
  import { createError } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.esm.js';
10
10
  import { existsSync, readFileSync, statSync, lstatSync, readdirSync } from 'node:fs';
11
11
  import { min } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/math/index.esm.js';
12
+ import { isSafePath } from '../../_shared/core/fs/guard/index.esm.js';
12
13
  import { isDirectory, exists } from '../../_shared/core/fs/stat/index.esm.js';
13
14
  import { join } from '../../_shared/core/path/join/index.esm.js';
14
15
  import { createCache } from '../../_shared/core/cache/index.esm.js';
@@ -199,7 +200,7 @@ function createFileSystemError(message, code, context) {
199
200
  * ```
200
201
  */
201
202
  function readFileIfExists(filePath, encoding = 'utf-8') {
202
- if (!existsSync(filePath)) {
203
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
203
204
  return null;
204
205
  }
205
206
  try {
@@ -11,7 +11,9 @@ const index_cjs_js$5 = require('../_dependencies/@hyperfrontend/immutable-api-ut
11
11
  const index_cjs_js$1 = require('../_dependencies/@hyperfrontend/logging/index.cjs.js');
12
12
  const index_cjs_js$6 = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs.js');
13
13
  const index_cjs_js$8 = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/math/index.cjs.js');
14
+ const { isSafePath } = require('../_shared/core/fs/guard/index.cjs.js');
14
15
  const { isFile, isDirectory, exists } = require('../_shared/core/fs/stat/index.cjs.js');
16
+ const { isWithinRoot } = require('../_shared/core/path/confine/index.cjs.js');
15
17
  const { join } = require('../_shared/core/path/join/index.cjs.js');
16
18
  const { createCache } = require('../_shared/core/cache/index.cjs.js');
17
19
  const { matchGlobPattern } = require('../_shared/core/patterns/glob/index.cjs.js');
@@ -203,6 +205,9 @@ function createFileSystemError(message, code, context) {
203
205
  * ```
204
206
  */
205
207
  function readFileContent(filePath, encoding = 'utf-8') {
208
+ if (!isSafePath(filePath)) {
209
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
210
+ }
206
211
  if (!node_fs.existsSync(filePath)) {
207
212
  fsLogger.debug('File not found', { path: filePath });
208
213
  throw createFileSystemError(`File not found: ${filePath}`, 'FS_NOT_FOUND', { path: filePath, operation: 'read' });
@@ -231,7 +236,7 @@ function readFileContent(filePath, encoding = 'utf-8') {
231
236
  * ```
232
237
  */
233
238
  function readFileIfExists(filePath, encoding = 'utf-8') {
234
- if (!node_fs.existsSync(filePath)) {
239
+ if (!isSafePath(filePath) || !node_fs.existsSync(filePath)) {
235
240
  return null;
236
241
  }
237
242
  try {
@@ -440,6 +445,10 @@ function resolveImportPath(importPath, fromFile, projectPath, extensions) {
440
445
  }
441
446
  const fromDir = node_path.dirname(fromFile);
442
447
  const absolutePath = node_path.resolve(fromDir, importPath);
448
+ // why: An import string comes from untrusted source code; reject targets that escape the project root before any stat, so a hostile `../../etc/passwd` can't probe the filesystem.
449
+ if (!isWithinRoot(projectPath, absolutePath)) {
450
+ return null;
451
+ }
443
452
  if (exists(absolutePath)) {
444
453
  if (isFile(absolutePath)) {
445
454
  return node_path.relative(projectPath, absolutePath);
@@ -1,15 +1,17 @@
1
- import { join as join$1, relative, dirname, resolve } from 'node:path';
1
+ import { join as join$1, normalize, sep, resolve, relative, dirname } from 'node:path';
2
2
  import { createMap } from '../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/map/index.esm.js';
3
3
  import { freeze, entries, keys, defineProperties, values } from '../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/object/index.esm.js';
4
4
  import { createSet } from '../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.esm.js';
5
- import { existsSync, readFileSync, statSync, lstatSync, readdirSync } from 'node:fs';
5
+ import { existsSync, readFileSync, statSync, lstatSync, readdirSync, realpathSync } from 'node:fs';
6
6
  import { isArray } from '../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.esm.js';
7
7
  import { error, warn, log, info, debug } from '../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/console/index.esm.js';
8
8
  import { stringify, parse } from '../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/json/index.esm.js';
9
9
  import { createLogger } from '../_dependencies/@hyperfrontend/logging/index.esm.js';
10
10
  import { createError } from '../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.esm.js';
11
11
  import { min, round } from '../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/math/index.esm.js';
12
+ import { isSafePath } from '../_shared/core/fs/guard/index.esm.js';
12
13
  import { isFile, isDirectory, exists } from '../_shared/core/fs/stat/index.esm.js';
14
+ import { isWithinRoot } from '../_shared/core/path/confine/index.esm.js';
13
15
  import { join } from '../_shared/core/path/join/index.esm.js';
14
16
  import { createCache } from '../_shared/core/cache/index.esm.js';
15
17
  import { matchGlobPattern } from '../_shared/core/patterns/glob/index.esm.js';
@@ -201,6 +203,9 @@ function createFileSystemError(message, code, context) {
201
203
  * ```
202
204
  */
203
205
  function readFileContent(filePath, encoding = 'utf-8') {
206
+ if (!isSafePath(filePath)) {
207
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
208
+ }
204
209
  if (!existsSync(filePath)) {
205
210
  fsLogger.debug('File not found', { path: filePath });
206
211
  throw createFileSystemError(`File not found: ${filePath}`, 'FS_NOT_FOUND', { path: filePath, operation: 'read' });
@@ -229,7 +234,7 @@ function readFileContent(filePath, encoding = 'utf-8') {
229
234
  * ```
230
235
  */
231
236
  function readFileIfExists(filePath, encoding = 'utf-8') {
232
- if (!existsSync(filePath)) {
237
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
233
238
  return null;
234
239
  }
235
240
  try {
@@ -438,6 +443,10 @@ function resolveImportPath(importPath, fromFile, projectPath, extensions) {
438
443
  }
439
444
  const fromDir = dirname(fromFile);
440
445
  const absolutePath = resolve(fromDir, importPath);
446
+ // why: An import string comes from untrusted source code; reject targets that escape the project root before any stat, so a hostile `../../etc/passwd` can't probe the filesystem.
447
+ if (!isWithinRoot(projectPath, absolutePath)) {
448
+ return null;
449
+ }
441
450
  if (exists(absolutePath)) {
442
451
  if (isFile(absolutePath)) {
443
452
  return relative(projectPath, absolutePath);
@@ -11,6 +11,7 @@ const index_cjs_js = require('../../_dependencies/@hyperfrontend/immutable-api-u
11
11
  const index_cjs_js$1 = require('../../_dependencies/@hyperfrontend/logging/index.cjs.js');
12
12
  const index_cjs_js$6 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs.js');
13
13
  const index_cjs_js$7 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/map/index.cjs.js');
14
+ const { isSafePath } = require('../../_shared/core/fs/guard/index.cjs.js');
14
15
  const { isDirectory, exists } = require('../../_shared/core/fs/stat/index.cjs.js');
15
16
  const { join } = require('../../_shared/core/path/join/index.cjs.js');
16
17
  const { createCache } = require('../../_shared/core/cache/index.cjs.js');
@@ -201,7 +202,7 @@ function createFileSystemError(message, code, context) {
201
202
  * ```
202
203
  */
203
204
  function readFileIfExists(filePath, encoding = 'utf-8') {
204
- if (!node_fs.existsSync(filePath)) {
205
+ if (!isSafePath(filePath) || !node_fs.existsSync(filePath)) {
205
206
  return null;
206
207
  }
207
208
  try {
@@ -9,6 +9,7 @@ import { createSet } from '../../_dependencies/@hyperfrontend/immutable-api-util
9
9
  import { createLogger } from '../../_dependencies/@hyperfrontend/logging/index.esm.js';
10
10
  import { createError } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.esm.js';
11
11
  import { createMap } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/map/index.esm.js';
12
+ import { isSafePath } from '../../_shared/core/fs/guard/index.esm.js';
12
13
  import { isDirectory, exists } from '../../_shared/core/fs/stat/index.esm.js';
13
14
  import { join } from '../../_shared/core/path/join/index.esm.js';
14
15
  import { createCache } from '../../_shared/core/cache/index.esm.js';
@@ -199,7 +200,7 @@ function createFileSystemError(message, code, context) {
199
200
  * ```
200
201
  */
201
202
  function readFileIfExists(filePath, encoding = 'utf-8') {
202
- if (!existsSync(filePath)) {
203
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
203
204
  return null;
204
205
  }
205
206
  try {
package/index.cjs.js CHANGED
@@ -15,9 +15,11 @@ const index_cjs_js$8 = require('./_dependencies/@hyperfrontend/immutable-api-uti
15
15
  const index_cjs_js$9 = require('./_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/number/index.cjs.js');
16
16
  const node_util = require('node:util');
17
17
  const node_os = require('node:os');
18
+ const { isSafePath } = require('./_shared/core/fs/guard/index.cjs.js');
18
19
  const { getFileStat, isFile, isDirectory, isSymlink, exists } = require('./_shared/core/fs/stat/index.cjs.js');
19
- const { join, joinPosix } = require('./_shared/core/path/join/index.cjs.js');
20
20
  const { normalizePath, normalizeToForwardSlashes, normalizeToNative, removeTrailingSlash, ensureTrailingSlash } = require('./_shared/core/path/normalize/index.cjs.js');
21
+ const { isWithinRoot } = require('./_shared/core/path/confine/index.cjs.js');
22
+ const { join, joinPosix } = require('./_shared/core/path/join/index.cjs.js');
21
23
  const { resolvePath, resolveFromWorkspace, resolveRealPath, relativePath, joinPath, isAbsolute, offsetFromRoot } = require('./_shared/core/path/resolve/index.cjs.js');
22
24
  const { pathSegments, getBasename, getDirname, getExtension, getFileNameWithoutExtension, parsePath } = require('./_shared/core/path/segments/index.cjs.js');
23
25
  const { createStructuredError, createConfigError, createFsError, createParseError, createValidationError } = require('./_shared/core/errors/structured-errors/index.cjs.js');
@@ -270,6 +272,9 @@ function createFileSystemError(message, code, context) {
270
272
  * ```
271
273
  */
272
274
  function readFileContent(filePath, encoding = 'utf-8') {
275
+ if (!isSafePath(filePath)) {
276
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
277
+ }
273
278
  if (!node_fs.existsSync(filePath)) {
274
279
  fsLogger.debug('File not found', { path: filePath });
275
280
  throw createFileSystemError(`File not found: ${filePath}`, 'FS_NOT_FOUND', { path: filePath, operation: 'read' });
@@ -296,6 +301,9 @@ function readFileContent(filePath, encoding = 'utf-8') {
296
301
  * ```
297
302
  */
298
303
  function readFileBuffer(filePath) {
304
+ if (!isSafePath(filePath)) {
305
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
306
+ }
299
307
  if (!node_fs.existsSync(filePath)) {
300
308
  throw createFileSystemError(`File not found: ${filePath}`, 'FS_NOT_FOUND', { path: filePath, operation: 'read' });
301
309
  }
@@ -322,7 +330,7 @@ function readFileBuffer(filePath) {
322
330
  * ```
323
331
  */
324
332
  function readFileIfExists(filePath, encoding = 'utf-8') {
325
- if (!node_fs.existsSync(filePath)) {
333
+ if (!isSafePath(filePath) || !node_fs.existsSync(filePath)) {
326
334
  return null;
327
335
  }
328
336
  try {
@@ -354,6 +362,9 @@ function readFileIfExists(filePath, encoding = 'utf-8') {
354
362
  * ```
355
363
  */
356
364
  function readJsonFile(filePath, options) {
365
+ if (!isSafePath(filePath)) {
366
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
367
+ }
357
368
  if (!node_fs.existsSync(filePath)) {
358
369
  if (options && 'default' in options) {
359
370
  fsLogger.debug('JSON file not found, using default', { path: filePath });
@@ -393,7 +404,7 @@ function readJsonFile(filePath, options) {
393
404
  * ```
394
405
  */
395
406
  function readJsonFileIfExists(filePath) {
396
- if (!node_fs.existsSync(filePath)) {
407
+ if (!isSafePath(filePath) || !node_fs.existsSync(filePath)) {
397
408
  return null;
398
409
  }
399
410
  try {
@@ -1172,6 +1183,10 @@ function resolveImportPath(importPath, fromFile, projectPath, extensions) {
1172
1183
  }
1173
1184
  const fromDir = node_path.dirname(fromFile);
1174
1185
  const absolutePath = node_path.resolve(fromDir, importPath);
1186
+ // why: An import string comes from untrusted source code; reject targets that escape the project root before any stat, so a hostile `../../etc/passwd` can't probe the filesystem.
1187
+ if (!isWithinRoot(projectPath, absolutePath)) {
1188
+ return null;
1189
+ }
1175
1190
  if (exists(absolutePath)) {
1176
1191
  if (isFile(absolutePath)) {
1177
1192
  return node_path.relative(projectPath, absolutePath);
package/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import { join as join$1, posix, normalize, sep, isAbsolute as isAbsolute$1, relative, resolve, basename, dirname, extname, parse as parse$1 } from 'node:path';
1
+ import { join as join$1, normalize, sep, resolve, posix, isAbsolute as isAbsolute$1, relative, basename, dirname, extname, parse as parse$1 } from 'node:path';
2
2
  import { dateNow, createDate } from './_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/date/index.esm.js';
3
3
  import { existsSync, readFileSync, statSync, lstatSync, mkdirSync, readdirSync, rmSync, realpathSync, writeFileSync, mkdtempSync, unlinkSync, rmdirSync, chmodSync, readlinkSync } from 'node:fs';
4
4
  import { isArray, from } from './_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/array/index.esm.js';
@@ -13,9 +13,11 @@ import { min, round, max } from './_dependencies/@hyperfrontend/immutable-api-ut
13
13
  import { parseInt, parseFloat } from './_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/number/index.esm.js';
14
14
  import { parseArgs } from 'node:util';
15
15
  import { tmpdir, platform, arch } from 'node:os';
16
+ import { isSafePath } from './_shared/core/fs/guard/index.esm.js';
16
17
  import { getFileStat, isFile, isDirectory, isSymlink, exists } from './_shared/core/fs/stat/index.esm.js';
17
- import { join, joinPosix } from './_shared/core/path/join/index.esm.js';
18
18
  import { normalizePath, normalizeToForwardSlashes, normalizeToNative, removeTrailingSlash, ensureTrailingSlash } from './_shared/core/path/normalize/index.esm.js';
19
+ import { isWithinRoot } from './_shared/core/path/confine/index.esm.js';
20
+ import { join, joinPosix } from './_shared/core/path/join/index.esm.js';
19
21
  import { resolvePath, resolveFromWorkspace, resolveRealPath, relativePath, joinPath, isAbsolute, offsetFromRoot } from './_shared/core/path/resolve/index.esm.js';
20
22
  import { pathSegments, getBasename, getDirname, getExtension, getFileNameWithoutExtension, parsePath } from './_shared/core/path/segments/index.esm.js';
21
23
  import { createStructuredError, createConfigError, createFsError, createParseError, createValidationError } from './_shared/core/errors/structured-errors/index.esm.js';
@@ -268,6 +270,9 @@ function createFileSystemError(message, code, context) {
268
270
  * ```
269
271
  */
270
272
  function readFileContent(filePath, encoding = 'utf-8') {
273
+ if (!isSafePath(filePath)) {
274
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
275
+ }
271
276
  if (!existsSync(filePath)) {
272
277
  fsLogger.debug('File not found', { path: filePath });
273
278
  throw createFileSystemError(`File not found: ${filePath}`, 'FS_NOT_FOUND', { path: filePath, operation: 'read' });
@@ -294,6 +299,9 @@ function readFileContent(filePath, encoding = 'utf-8') {
294
299
  * ```
295
300
  */
296
301
  function readFileBuffer(filePath) {
302
+ if (!isSafePath(filePath)) {
303
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
304
+ }
297
305
  if (!existsSync(filePath)) {
298
306
  throw createFileSystemError(`File not found: ${filePath}`, 'FS_NOT_FOUND', { path: filePath, operation: 'read' });
299
307
  }
@@ -320,7 +328,7 @@ function readFileBuffer(filePath) {
320
328
  * ```
321
329
  */
322
330
  function readFileIfExists(filePath, encoding = 'utf-8') {
323
- if (!existsSync(filePath)) {
331
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
324
332
  return null;
325
333
  }
326
334
  try {
@@ -352,6 +360,9 @@ function readFileIfExists(filePath, encoding = 'utf-8') {
352
360
  * ```
353
361
  */
354
362
  function readJsonFile(filePath, options) {
363
+ if (!isSafePath(filePath)) {
364
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
365
+ }
355
366
  if (!existsSync(filePath)) {
356
367
  if (options && 'default' in options) {
357
368
  fsLogger.debug('JSON file not found, using default', { path: filePath });
@@ -391,7 +402,7 @@ function readJsonFile(filePath, options) {
391
402
  * ```
392
403
  */
393
404
  function readJsonFileIfExists(filePath) {
394
- if (!existsSync(filePath)) {
405
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
395
406
  return null;
396
407
  }
397
408
  try {
@@ -1170,6 +1181,10 @@ function resolveImportPath(importPath, fromFile, projectPath, extensions) {
1170
1181
  }
1171
1182
  const fromDir = dirname(fromFile);
1172
1183
  const absolutePath = resolve(fromDir, importPath);
1184
+ // why: An import string comes from untrusted source code; reject targets that escape the project root before any stat, so a hostile `../../etc/passwd` can't probe the filesystem.
1185
+ if (!isWithinRoot(projectPath, absolutePath)) {
1186
+ return null;
1187
+ }
1173
1188
  if (exists(absolutePath)) {
1174
1189
  if (isFile(absolutePath)) {
1175
1190
  return relative(projectPath, absolutePath);
package/nx/index.cjs.js CHANGED
@@ -10,6 +10,7 @@ const index_cjs_js = require('../_dependencies/@hyperfrontend/immutable-api-util
10
10
  const index_cjs_js$1 = require('../_dependencies/@hyperfrontend/logging/index.cjs.js');
11
11
  const index_cjs_js$6 = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs.js');
12
12
  const index_cjs_js$7 = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/map/index.cjs.js');
13
+ const { isSafePath } = require('../_shared/core/fs/guard/index.cjs.js');
13
14
  const { isDirectory, exists } = require('../_shared/core/fs/stat/index.cjs.js');
14
15
  const { join } = require('../_shared/core/path/join/index.cjs.js');
15
16
 
@@ -197,7 +198,7 @@ function createFileSystemError(message, code, context) {
197
198
  * ```
198
199
  */
199
200
  function readFileIfExists(filePath, encoding = 'utf-8') {
200
- if (!node_fs.existsSync(filePath)) {
201
+ if (!isSafePath(filePath) || !node_fs.existsSync(filePath)) {
201
202
  return null;
202
203
  }
203
204
  try {
@@ -221,7 +222,7 @@ function readFileIfExists(filePath, encoding = 'utf-8') {
221
222
  * ```
222
223
  */
223
224
  function readJsonFileIfExists(filePath) {
224
- if (!node_fs.existsSync(filePath)) {
225
+ if (!isSafePath(filePath) || !node_fs.existsSync(filePath)) {
225
226
  return null;
226
227
  }
227
228
  try {
package/nx/index.esm.js CHANGED
@@ -8,6 +8,7 @@ import { createSet } from '../_dependencies/@hyperfrontend/immutable-api-utils/b
8
8
  import { createLogger } from '../_dependencies/@hyperfrontend/logging/index.esm.js';
9
9
  import { createError } from '../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.esm.js';
10
10
  import { createMap } from '../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/map/index.esm.js';
11
+ import { isSafePath } from '../_shared/core/fs/guard/index.esm.js';
11
12
  import { isDirectory, exists } from '../_shared/core/fs/stat/index.esm.js';
12
13
  import { join } from '../_shared/core/path/join/index.esm.js';
13
14
 
@@ -195,7 +196,7 @@ function createFileSystemError(message, code, context) {
195
196
  * ```
196
197
  */
197
198
  function readFileIfExists(filePath, encoding = 'utf-8') {
198
- if (!existsSync(filePath)) {
199
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
199
200
  return null;
200
201
  }
201
202
  try {
@@ -219,7 +220,7 @@ function readFileIfExists(filePath, encoding = 'utf-8') {
219
220
  * ```
220
221
  */
221
222
  function readJsonFileIfExists(filePath) {
222
- if (!existsSync(filePath)) {
223
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
223
224
  return null;
224
225
  }
225
226
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperfrontend/project-scope",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Codebase analysis, project topology detection, and virtual file system utilities for Node.js projects.",
5
5
  "exports": {
6
6
  "./package.json": "./package.json",
@@ -11,6 +11,7 @@ const index_cjs_js$6 = require('../../_dependencies/@hyperfrontend/immutable-api
11
11
  const index_cjs_js$3 = require('../../_dependencies/@hyperfrontend/logging/index.cjs.js');
12
12
  const index_cjs_js$7 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs.js');
13
13
  const index_cjs_js$8 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/number/index.cjs.js');
14
+ const { isSafePath } = require('../../_shared/core/fs/guard/index.cjs.js');
14
15
  const { isDirectory, exists } = require('../../_shared/core/fs/stat/index.cjs.js');
15
16
  const { createConfigError } = require('../../_shared/core/errors/structured-errors/index.cjs.js');
16
17
  const { createCache } = require('../../_shared/core/cache/index.cjs.js');
@@ -202,6 +203,9 @@ function createFileSystemError(message, code, context) {
202
203
  * ```
203
204
  */
204
205
  function readFileContent(filePath, encoding = 'utf-8') {
206
+ if (!isSafePath(filePath)) {
207
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
208
+ }
205
209
  if (!node_fs.existsSync(filePath)) {
206
210
  fsLogger.debug('File not found', { path: filePath });
207
211
  throw createFileSystemError(`File not found: ${filePath}`, 'FS_NOT_FOUND', { path: filePath, operation: 'read' });
@@ -230,7 +234,7 @@ function readFileContent(filePath, encoding = 'utf-8') {
230
234
  * ```
231
235
  */
232
236
  function readFileIfExists(filePath, encoding = 'utf-8') {
233
- if (!node_fs.existsSync(filePath)) {
237
+ if (!isSafePath(filePath) || !node_fs.existsSync(filePath)) {
234
238
  return null;
235
239
  }
236
240
  try {
@@ -9,6 +9,7 @@ import { stringify, parse } from '../../_dependencies/@hyperfrontend/immutable-a
9
9
  import { createLogger } from '../../_dependencies/@hyperfrontend/logging/index.esm.js';
10
10
  import { createError } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.esm.js';
11
11
  import { parseInt, parseFloat } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/number/index.esm.js';
12
+ import { isSafePath } from '../../_shared/core/fs/guard/index.esm.js';
12
13
  import { isDirectory, exists } from '../../_shared/core/fs/stat/index.esm.js';
13
14
  import { createConfigError } from '../../_shared/core/errors/structured-errors/index.esm.js';
14
15
  import { createCache } from '../../_shared/core/cache/index.esm.js';
@@ -200,6 +201,9 @@ function createFileSystemError(message, code, context) {
200
201
  * ```
201
202
  */
202
203
  function readFileContent(filePath, encoding = 'utf-8') {
204
+ if (!isSafePath(filePath)) {
205
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
206
+ }
203
207
  if (!existsSync(filePath)) {
204
208
  fsLogger.debug('File not found', { path: filePath });
205
209
  throw createFileSystemError(`File not found: ${filePath}`, 'FS_NOT_FOUND', { path: filePath, operation: 'read' });
@@ -228,7 +232,7 @@ function readFileContent(filePath, encoding = 'utf-8') {
228
232
  * ```
229
233
  */
230
234
  function readFileIfExists(filePath, encoding = 'utf-8') {
231
- if (!existsSync(filePath)) {
235
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
232
236
  return null;
233
237
  }
234
238
  try {
@@ -11,6 +11,7 @@ const index_cjs_js$6 = require('../_dependencies/@hyperfrontend/immutable-api-ut
11
11
  const index_cjs_js$3 = require('../_dependencies/@hyperfrontend/logging/index.cjs.js');
12
12
  const index_cjs_js$7 = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs.js');
13
13
  const index_cjs_js$8 = require('../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/number/index.cjs.js');
14
+ const { isSafePath } = require('../_shared/core/fs/guard/index.cjs.js');
14
15
  const { isDirectory, exists } = require('../_shared/core/fs/stat/index.cjs.js');
15
16
  const { join } = require('../_shared/core/path/join/index.cjs.js');
16
17
  const { createConfigError } = require('../_shared/core/errors/structured-errors/index.cjs.js');
@@ -203,6 +204,9 @@ function createFileSystemError(message, code, context) {
203
204
  * ```
204
205
  */
205
206
  function readFileContent(filePath, encoding = 'utf-8') {
207
+ if (!isSafePath(filePath)) {
208
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
209
+ }
206
210
  if (!node_fs.existsSync(filePath)) {
207
211
  fsLogger.debug('File not found', { path: filePath });
208
212
  throw createFileSystemError(`File not found: ${filePath}`, 'FS_NOT_FOUND', { path: filePath, operation: 'read' });
@@ -231,7 +235,7 @@ function readFileContent(filePath, encoding = 'utf-8') {
231
235
  * ```
232
236
  */
233
237
  function readFileIfExists(filePath, encoding = 'utf-8') {
234
- if (!node_fs.existsSync(filePath)) {
238
+ if (!isSafePath(filePath) || !node_fs.existsSync(filePath)) {
235
239
  return null;
236
240
  }
237
241
  try {
@@ -9,6 +9,7 @@ import { stringify, parse as parse$1 } from '../_dependencies/@hyperfrontend/imm
9
9
  import { createLogger } from '../_dependencies/@hyperfrontend/logging/index.esm.js';
10
10
  import { createError } from '../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.esm.js';
11
11
  import { parseInt, parseFloat } from '../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/number/index.esm.js';
12
+ import { isSafePath } from '../_shared/core/fs/guard/index.esm.js';
12
13
  import { isDirectory, exists } from '../_shared/core/fs/stat/index.esm.js';
13
14
  import { join } from '../_shared/core/path/join/index.esm.js';
14
15
  import { createConfigError } from '../_shared/core/errors/structured-errors/index.esm.js';
@@ -201,6 +202,9 @@ function createFileSystemError(message, code, context) {
201
202
  * ```
202
203
  */
203
204
  function readFileContent(filePath, encoding = 'utf-8') {
205
+ if (!isSafePath(filePath)) {
206
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
207
+ }
204
208
  if (!existsSync(filePath)) {
205
209
  fsLogger.debug('File not found', { path: filePath });
206
210
  throw createFileSystemError(`File not found: ${filePath}`, 'FS_NOT_FOUND', { path: filePath, operation: 'read' });
@@ -229,7 +233,7 @@ function readFileContent(filePath, encoding = 'utf-8') {
229
233
  * ```
230
234
  */
231
235
  function readFileIfExists(filePath, encoding = 'utf-8') {
232
- if (!existsSync(filePath)) {
236
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
233
237
  return null;
234
238
  }
235
239
  try {
@@ -9,6 +9,7 @@ const node_fs = require('node:fs');
9
9
  const index_cjs_js$4 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/console/index.cjs.js');
10
10
  const index_cjs_js$1 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.cjs.js');
11
11
  const index_cjs_js$2 = require('../../_dependencies/@hyperfrontend/logging/index.cjs.js');
12
+ const { isSafePath } = require('../../_shared/core/fs/guard/index.cjs.js');
12
13
  const { exists } = require('../../_shared/core/fs/stat/index.cjs.js');
13
14
  const { join } = require('../../_shared/core/path/join/index.cjs.js');
14
15
  const { createConfigError } = require('../../_shared/core/errors/structured-errors/index.cjs.js');
@@ -198,6 +199,9 @@ function createFileSystemError(message, code, context) {
198
199
  * ```
199
200
  */
200
201
  function readFileContent(filePath, encoding = 'utf-8') {
202
+ if (!isSafePath(filePath)) {
203
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
204
+ }
201
205
  if (!node_fs.existsSync(filePath)) {
202
206
  fsLogger.debug('File not found', { path: filePath });
203
207
  throw createFileSystemError(`File not found: ${filePath}`, 'FS_NOT_FOUND', { path: filePath, operation: 'read' });
@@ -226,7 +230,7 @@ function readFileContent(filePath, encoding = 'utf-8') {
226
230
  * ```
227
231
  */
228
232
  function readFileIfExists(filePath, encoding = 'utf-8') {
229
- if (!node_fs.existsSync(filePath)) {
233
+ if (!isSafePath(filePath) || !node_fs.existsSync(filePath)) {
230
234
  return null;
231
235
  }
232
236
  try {
@@ -7,6 +7,7 @@ import { existsSync, readFileSync } from 'node:fs';
7
7
  import { error, warn, log, info, debug } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/console/index.esm.js';
8
8
  import { createSet } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.esm.js';
9
9
  import { createLogger } from '../../_dependencies/@hyperfrontend/logging/index.esm.js';
10
+ import { isSafePath } from '../../_shared/core/fs/guard/index.esm.js';
10
11
  import { exists } from '../../_shared/core/fs/stat/index.esm.js';
11
12
  import { join } from '../../_shared/core/path/join/index.esm.js';
12
13
  import { createConfigError } from '../../_shared/core/errors/structured-errors/index.esm.js';
@@ -196,6 +197,9 @@ function createFileSystemError(message, code, context) {
196
197
  * ```
197
198
  */
198
199
  function readFileContent(filePath, encoding = 'utf-8') {
200
+ if (!isSafePath(filePath)) {
201
+ throw createFileSystemError(`Unsafe file path: ${filePath}`, 'FS_READ_ERROR', { path: filePath, operation: 'read' });
202
+ }
199
203
  if (!existsSync(filePath)) {
200
204
  fsLogger.debug('File not found', { path: filePath });
201
205
  throw createFileSystemError(`File not found: ${filePath}`, 'FS_NOT_FOUND', { path: filePath, operation: 'read' });
@@ -224,7 +228,7 @@ function readFileContent(filePath, encoding = 'utf-8') {
224
228
  * ```
225
229
  */
226
230
  function readFileIfExists(filePath, encoding = 'utf-8') {
227
- if (!existsSync(filePath)) {
231
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
228
232
  return null;
229
233
  }
230
234
  try {
@@ -9,6 +9,7 @@ const index_cjs_js$2 = require('../../_dependencies/@hyperfrontend/immutable-api
9
9
  const index_cjs_js = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.cjs.js');
10
10
  const index_cjs_js$1 = require('../../_dependencies/@hyperfrontend/logging/index.cjs.js');
11
11
  const index_cjs_js$6 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs.js');
12
+ const { isSafePath } = require('../../_shared/core/fs/guard/index.cjs.js');
12
13
  const { exists } = require('../../_shared/core/fs/stat/index.cjs.js');
13
14
  const { join } = require('../../_shared/core/path/join/index.cjs.js');
14
15
 
@@ -171,7 +172,7 @@ createScopedLogger('project-scope:fs');
171
172
  * ```
172
173
  */
173
174
  function readFileIfExists(filePath, encoding = 'utf-8') {
174
- if (!node_fs.existsSync(filePath)) {
175
+ if (!isSafePath(filePath) || !node_fs.existsSync(filePath)) {
175
176
  return null;
176
177
  }
177
178
  try {
@@ -7,6 +7,7 @@ import { freeze, entries, keys, values } from '../../_dependencies/@hyperfronten
7
7
  import { createSet } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.esm.js';
8
8
  import { createLogger } from '../../_dependencies/@hyperfrontend/logging/index.esm.js';
9
9
  import { createError } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.esm.js';
10
+ import { isSafePath } from '../../_shared/core/fs/guard/index.esm.js';
10
11
  import { exists } from '../../_shared/core/fs/stat/index.esm.js';
11
12
  import { join } from '../../_shared/core/path/join/index.esm.js';
12
13
 
@@ -169,7 +170,7 @@ createScopedLogger('project-scope:fs');
169
170
  * ```
170
171
  */
171
172
  function readFileIfExists(filePath, encoding = 'utf-8') {
172
- if (!existsSync(filePath)) {
173
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
173
174
  return null;
174
175
  }
175
176
  try {
@@ -9,6 +9,7 @@ const index_cjs_js$1 = require('../../_dependencies/@hyperfrontend/logging/index
9
9
  const node_path = require('node:path');
10
10
  const node_fs = require('node:fs');
11
11
  const index_cjs_js$6 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.cjs.js');
12
+ const { isSafePath } = require('../../_shared/core/fs/guard/index.cjs.js');
12
13
  const { isDirectory } = require('../../_shared/core/fs/stat/index.cjs.js');
13
14
  const { matchGlobPattern } = require('../../_shared/core/patterns/glob/index.cjs.js');
14
15
 
@@ -196,7 +197,7 @@ function createFileSystemError(message, code, context) {
196
197
  * ```
197
198
  */
198
199
  function readFileIfExists(filePath, encoding = 'utf-8') {
199
- if (!node_fs.existsSync(filePath)) {
200
+ if (!isSafePath(filePath) || !node_fs.existsSync(filePath)) {
200
201
  return null;
201
202
  }
202
203
  try {
@@ -7,6 +7,7 @@ import { createLogger } from '../../_dependencies/@hyperfrontend/logging/index.e
7
7
  import { join } from 'node:path';
8
8
  import { existsSync, readFileSync, statSync, lstatSync, readdirSync } from 'node:fs';
9
9
  import { createError } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/error/index.esm.js';
10
+ import { isSafePath } from '../../_shared/core/fs/guard/index.esm.js';
10
11
  import { isDirectory } from '../../_shared/core/fs/stat/index.esm.js';
11
12
  import { matchGlobPattern } from '../../_shared/core/patterns/glob/index.esm.js';
12
13
 
@@ -194,7 +195,7 @@ function createFileSystemError(message, code, context) {
194
195
  * ```
195
196
  */
196
197
  function readFileIfExists(filePath, encoding = 'utf-8') {
197
- if (!existsSync(filePath)) {
198
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
198
199
  return null;
199
200
  }
200
201
  try {
@@ -10,6 +10,7 @@ const index_cjs_js$3 = require('../../_dependencies/@hyperfrontend/immutable-api
10
10
  const index_cjs_js = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.cjs.js');
11
11
  const index_cjs_js$1 = require('../../_dependencies/@hyperfrontend/logging/index.cjs.js');
12
12
  const index_cjs_js$7 = require('../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/math/index.cjs.js');
13
+ const { isSafePath } = require('../../_shared/core/fs/guard/index.cjs.js');
13
14
  const { exists } = require('../../_shared/core/fs/stat/index.cjs.js');
14
15
  const { collectAllDependencies, parseVersionString } = require('../../_shared/tech/shared-utils/detector-helpers/index.cjs.js');
15
16
 
@@ -172,7 +173,7 @@ createScopedLogger('project-scope:fs');
172
173
  * ```
173
174
  */
174
175
  function readFileIfExists(filePath, encoding = 'utf-8') {
175
- if (!node_fs.existsSync(filePath)) {
176
+ if (!isSafePath(filePath) || !node_fs.existsSync(filePath)) {
176
177
  return null;
177
178
  }
178
179
  try {
@@ -8,6 +8,7 @@ import { error, warn, log, info, debug } from '../../_dependencies/@hyperfronten
8
8
  import { createSet } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/set/index.esm.js';
9
9
  import { createLogger } from '../../_dependencies/@hyperfrontend/logging/index.esm.js';
10
10
  import { min } from '../../_dependencies/@hyperfrontend/immutable-api-utils/built-in-copy/math/index.esm.js';
11
+ import { isSafePath } from '../../_shared/core/fs/guard/index.esm.js';
11
12
  import { exists } from '../../_shared/core/fs/stat/index.esm.js';
12
13
  import { collectAllDependencies, parseVersionString } from '../../_shared/tech/shared-utils/detector-helpers/index.esm.js';
13
14
 
@@ -170,7 +171,7 @@ createScopedLogger('project-scope:fs');
170
171
  * ```
171
172
  */
172
173
  function readFileIfExists(filePath, encoding = 'utf-8') {
173
- if (!existsSync(filePath)) {
174
+ if (!isSafePath(filePath) || !existsSync(filePath)) {
174
175
  return null;
175
176
  }
176
177
  try {