@c9up/atlas 0.1.9 → 0.1.11

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 (80) hide show
  1. package/db.darwin-arm64.node +0 -0
  2. package/db.darwin-x64.node +0 -0
  3. package/db.linux-arm64-gnu.node +0 -0
  4. package/db.linux-x64-gnu.node +0 -0
  5. package/db.win32-x64-msvc.node +0 -0
  6. package/dist/AtlasProvider.d.ts +14 -0
  7. package/dist/AtlasProvider.d.ts.map +1 -1
  8. package/dist/AtlasProvider.js +14 -2
  9. package/dist/AtlasProvider.js.map +1 -1
  10. package/dist/BaseEntity.d.ts +3 -12
  11. package/dist/BaseEntity.d.ts.map +1 -1
  12. package/dist/BaseEntity.js +20 -4
  13. package/dist/BaseEntity.js.map +1 -1
  14. package/dist/BaseRepository.d.ts.map +1 -1
  15. package/dist/BaseRepository.js +45 -89
  16. package/dist/BaseRepository.js.map +1 -1
  17. package/dist/ModelQuery.d.ts +2 -2
  18. package/dist/ModelQuery.d.ts.map +1 -1
  19. package/dist/ModelQuery.js +62 -17
  20. package/dist/ModelQuery.js.map +1 -1
  21. package/dist/adapters/NapiDbAdapter.d.ts +14 -1
  22. package/dist/adapters/NapiDbAdapter.d.ts.map +1 -1
  23. package/dist/adapters/NapiDbAdapter.js +9 -7
  24. package/dist/adapters/NapiDbAdapter.js.map +1 -1
  25. package/dist/configure.d.ts.map +1 -1
  26. package/dist/configure.js +5 -6
  27. package/dist/configure.js.map +1 -1
  28. package/dist/decorators/entity.js +1 -1
  29. package/dist/decorators/entity.js.map +1 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/metadata-keys.d.ts +20 -0
  34. package/dist/metadata-keys.d.ts.map +1 -0
  35. package/dist/metadata-keys.js +13 -0
  36. package/dist/metadata-keys.js.map +1 -0
  37. package/dist/query/native.d.ts +7 -0
  38. package/dist/query/native.d.ts.map +1 -1
  39. package/dist/query/native.js +10 -1
  40. package/dist/query/native.js.map +1 -1
  41. package/dist/schema/MigrationRunner.d.ts.map +1 -1
  42. package/dist/schema/MigrationRunner.js +5 -2
  43. package/dist/schema/MigrationRunner.js.map +1 -1
  44. package/dist/schema/Seeder.d.ts +13 -8
  45. package/dist/schema/Seeder.d.ts.map +1 -1
  46. package/dist/schema/Seeder.js +13 -8
  47. package/dist/schema/Seeder.js.map +1 -1
  48. package/dist/services/db.d.ts +7 -0
  49. package/dist/services/db.d.ts.map +1 -1
  50. package/dist/services/db.js +10 -0
  51. package/dist/services/db.js.map +1 -1
  52. package/dist/testing/Factory.d.ts +6 -7
  53. package/dist/testing/Factory.d.ts.map +1 -1
  54. package/dist/testing/Factory.js +3 -5
  55. package/dist/testing/Factory.js.map +1 -1
  56. package/dist/utils/safePath.d.ts +7 -1
  57. package/dist/utils/safePath.d.ts.map +1 -1
  58. package/dist/utils/safePath.js +24 -1
  59. package/dist/utils/safePath.js.map +1 -1
  60. package/index.darwin-arm64.node +0 -0
  61. package/index.darwin-x64.node +0 -0
  62. package/index.linux-arm64-gnu.node +0 -0
  63. package/index.linux-x64-gnu.node +0 -0
  64. package/index.win32-x64-msvc.node +0 -0
  65. package/package.json +1 -1
  66. package/src/AtlasProvider.ts +28 -1
  67. package/src/BaseEntity.ts +27 -12
  68. package/src/BaseRepository.ts +50 -98
  69. package/src/ModelQuery.ts +66 -17
  70. package/src/adapters/NapiDbAdapter.ts +32 -8
  71. package/src/configure.ts +5 -6
  72. package/src/decorators/entity.ts +1 -1
  73. package/src/index.ts +4 -1
  74. package/src/metadata-keys.ts +22 -0
  75. package/src/query/native.ts +12 -1
  76. package/src/schema/MigrationRunner.ts +5 -2
  77. package/src/schema/Seeder.ts +14 -12
  78. package/src/services/db.ts +10 -0
  79. package/src/testing/Factory.ts +9 -12
  80. package/src/utils/safePath.ts +27 -2
@@ -26,16 +26,15 @@ export interface FactoryBuilder<T extends BaseEntity> {
26
26
  /** Override specific fields for the next call (reset after consumption). */
27
27
  merge(overrides: Partial<Record<string, unknown>>): FactoryBuilder<T>;
28
28
 
29
- /**
30
- * Declare a named variation of this factory. States are stored on the
31
- * factory itself and don't mutate the caller — `apply()` returns a child
32
- * builder with the state active.
33
- */
29
+ /** Declare a named variation of this factory, stored on the factory's state map. */
34
30
  state(name: string, fn: StateFn<Record<string, unknown>>): FactoryBuilder<T>;
35
31
 
36
32
  /**
37
- * Activate one or more declared states for the next call. Multiple applies
38
- * compose (all applied states fire, in order).
33
+ * Activate one or more declared states for the NEXT build. Multiple applies
34
+ * compose (all fire, in order). NOTE: this mutates the builder's shared
35
+ * pending state and returns the SAME builder for chaining — there is no
36
+ * isolated child builder. The pending set is reset after each make/create
37
+ * (audit 2026-06-13). `merge()` behaves the same way.
39
38
  */
40
39
  apply(...stateNames: string[]): FactoryBuilder<T>;
41
40
 
@@ -120,13 +119,11 @@ export function factory<T extends BaseEntity>(
120
119
  },
121
120
 
122
121
  makeMany(count) {
123
- // Re-evaluate defaults for each row so `Date.now()` / faker generate distinct values.
122
+ // Re-evaluate defaults for each row so `Date.now()` / faker generate
123
+ // distinct values. `buildData()` reads (never mutates) the pending
124
+ // overrides/states, so they stay stable across iterations on their own.
124
125
  const rows: Record<string, unknown>[] = [];
125
- const capturedOverrides = pendingOverrides;
126
- const capturedStates = pendingStates;
127
126
  for (let i = 0; i < count; i++) {
128
- pendingOverrides = capturedOverrides;
129
- pendingStates = capturedStates;
130
127
  rows.push(buildData());
131
128
  }
132
129
  resetPending();
@@ -40,13 +40,19 @@ export function assertSafeName(
40
40
  * Resolve `fileName` inside `baseDir` and throw if the resulting path escapes
41
41
  * the base — guards against symlink / `../` traversal attacks when loading
42
42
  * migration or seeder files dynamically.
43
+ *
44
+ * Two layers: (1) a logical `path.resolve` check that catches `../` walks, and
45
+ * (2) a `realpath` check that follows symlinks — a symlink FILE sitting inside
46
+ * the base but pointing at `/etc/passwd` passes the logical check yet is caught
47
+ * here. When the file doesn't exist yet (ENOENT), only the logical check
48
+ * applies and the caller's own existence check produces the not-found error.
43
49
  */
44
- export function assertPathInsideBase(
50
+ export async function assertPathInsideBase(
45
51
  baseDir: string,
46
52
  fileName: string,
47
53
  errorCode: string,
48
54
  kind: string,
49
- ): string {
55
+ ): Promise<string> {
50
56
  const resolved = path.resolve(baseDir, fileName);
51
57
  const base = path.resolve(baseDir);
52
58
  if (!resolved.startsWith(base + path.sep) && resolved !== base) {
@@ -55,5 +61,24 @@ export function assertPathInsideBase(
55
61
  `${kind} path escapes directory: ${fileName}`,
56
62
  );
57
63
  }
64
+ // Symlink-aware check: resolve real targets and re-verify containment.
65
+ try {
66
+ const realBase = await fsp.realpath(base);
67
+ const realResolved = await fsp.realpath(resolved);
68
+ if (
69
+ !realResolved.startsWith(realBase + path.sep) &&
70
+ realResolved !== realBase
71
+ ) {
72
+ throw new AtlasError(
73
+ errorCode,
74
+ `${kind} path escapes directory via symlink: ${fileName}`,
75
+ );
76
+ }
77
+ } catch (err) {
78
+ // File not yet created — the logical check above stands; let the caller's
79
+ // existence check report the missing file. Re-throw real traversal errors.
80
+ if (err instanceof AtlasError) throw err;
81
+ if ((err as NodeJS.ErrnoException).code !== "ENOENT") throw err;
82
+ }
58
83
  return resolved;
59
84
  }