@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.
- package/db.darwin-arm64.node +0 -0
- package/db.darwin-x64.node +0 -0
- package/db.linux-arm64-gnu.node +0 -0
- package/db.linux-x64-gnu.node +0 -0
- package/db.win32-x64-msvc.node +0 -0
- package/dist/AtlasProvider.d.ts +14 -0
- package/dist/AtlasProvider.d.ts.map +1 -1
- package/dist/AtlasProvider.js +14 -2
- package/dist/AtlasProvider.js.map +1 -1
- package/dist/BaseEntity.d.ts +3 -12
- package/dist/BaseEntity.d.ts.map +1 -1
- package/dist/BaseEntity.js +20 -4
- package/dist/BaseEntity.js.map +1 -1
- package/dist/BaseRepository.d.ts.map +1 -1
- package/dist/BaseRepository.js +45 -89
- package/dist/BaseRepository.js.map +1 -1
- package/dist/ModelQuery.d.ts +2 -2
- package/dist/ModelQuery.d.ts.map +1 -1
- package/dist/ModelQuery.js +62 -17
- package/dist/ModelQuery.js.map +1 -1
- package/dist/adapters/NapiDbAdapter.d.ts +14 -1
- package/dist/adapters/NapiDbAdapter.d.ts.map +1 -1
- package/dist/adapters/NapiDbAdapter.js +9 -7
- package/dist/adapters/NapiDbAdapter.js.map +1 -1
- package/dist/configure.d.ts.map +1 -1
- package/dist/configure.js +5 -6
- package/dist/configure.js.map +1 -1
- package/dist/decorators/entity.js +1 -1
- package/dist/decorators/entity.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metadata-keys.d.ts +20 -0
- package/dist/metadata-keys.d.ts.map +1 -0
- package/dist/metadata-keys.js +13 -0
- package/dist/metadata-keys.js.map +1 -0
- package/dist/query/native.d.ts +7 -0
- package/dist/query/native.d.ts.map +1 -1
- package/dist/query/native.js +10 -1
- package/dist/query/native.js.map +1 -1
- package/dist/schema/MigrationRunner.d.ts.map +1 -1
- package/dist/schema/MigrationRunner.js +5 -2
- package/dist/schema/MigrationRunner.js.map +1 -1
- package/dist/schema/Seeder.d.ts +13 -8
- package/dist/schema/Seeder.d.ts.map +1 -1
- package/dist/schema/Seeder.js +13 -8
- package/dist/schema/Seeder.js.map +1 -1
- package/dist/services/db.d.ts +7 -0
- package/dist/services/db.d.ts.map +1 -1
- package/dist/services/db.js +10 -0
- package/dist/services/db.js.map +1 -1
- package/dist/testing/Factory.d.ts +6 -7
- package/dist/testing/Factory.d.ts.map +1 -1
- package/dist/testing/Factory.js +3 -5
- package/dist/testing/Factory.js.map +1 -1
- package/dist/utils/safePath.d.ts +7 -1
- package/dist/utils/safePath.d.ts.map +1 -1
- package/dist/utils/safePath.js +24 -1
- package/dist/utils/safePath.js.map +1 -1
- package/index.darwin-arm64.node +0 -0
- package/index.darwin-x64.node +0 -0
- package/index.linux-arm64-gnu.node +0 -0
- package/index.linux-x64-gnu.node +0 -0
- package/index.win32-x64-msvc.node +0 -0
- package/package.json +1 -1
- package/src/AtlasProvider.ts +28 -1
- package/src/BaseEntity.ts +27 -12
- package/src/BaseRepository.ts +50 -98
- package/src/ModelQuery.ts +66 -17
- package/src/adapters/NapiDbAdapter.ts +32 -8
- package/src/configure.ts +5 -6
- package/src/decorators/entity.ts +1 -1
- package/src/index.ts +4 -1
- package/src/metadata-keys.ts +22 -0
- package/src/query/native.ts +12 -1
- package/src/schema/MigrationRunner.ts +5 -2
- package/src/schema/Seeder.ts +14 -12
- package/src/services/db.ts +10 -0
- package/src/testing/Factory.ts +9 -12
- package/src/utils/safePath.ts +27 -2
package/src/testing/Factory.ts
CHANGED
|
@@ -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
|
|
38
|
-
* compose (all
|
|
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
|
|
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();
|
package/src/utils/safePath.ts
CHANGED
|
@@ -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
|
}
|