@ghostry/fabricator 0.0.2 → 0.0.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 (37) hide show
  1. package/README.md +18 -6
  2. package/dist/esm/Adapter/Core.js +3 -3
  3. package/dist/esm/Enumeration/Enumerate.js +16 -13
  4. package/dist/esm/Error/index.js +8 -8
  5. package/dist/esm/Fabricator/Constructor.js +12 -14
  6. package/dist/esm/Harnessing/Core.js +30 -0
  7. package/dist/esm/Harnessing/Salt.js +12 -0
  8. package/dist/esm/Harnessing/Types.js +1 -0
  9. package/dist/esm/Instance/Core.js +17 -24
  10. package/dist/esm/Primitive/recursive/Fabricator.js +1 -1
  11. package/dist/esm/Random/index.js +24 -79
  12. package/dist/esm/adapting.js +2 -0
  13. package/dist/esm/harnessing.js +1 -0
  14. package/dist/esm/index.js +1 -2
  15. package/dist/esm/internal.js +1 -2
  16. package/dist/types/Adapter/Core.d.ts +1 -1
  17. package/dist/types/Adapter/Types.d.ts +1 -1
  18. package/dist/types/Enumeration/Enumerate.d.ts +17 -15
  19. package/dist/types/Error/index.d.ts +15 -19
  20. package/dist/types/Fabricator/Constructor.d.ts +4 -4
  21. package/dist/types/Harnessing/Core.d.ts +43 -0
  22. package/dist/types/Harnessing/Salt.d.ts +31 -0
  23. package/dist/types/Harnessing/Types.d.ts +79 -0
  24. package/dist/types/Instance/Core.d.ts +14 -31
  25. package/dist/types/Instance/Types.d.ts +35 -41
  26. package/dist/types/Primitive/opaque/Registry.d.ts +1 -1
  27. package/dist/types/Primitive/recursive/Fabricator.d.ts +8 -8
  28. package/dist/types/Random/Types.d.ts +97 -217
  29. package/dist/types/Random/index.d.ts +30 -48
  30. package/dist/types/Types.d.ts +3 -3
  31. package/dist/types/adapting.d.ts +32 -0
  32. package/dist/types/harnessing.d.ts +30 -0
  33. package/dist/types/index.d.ts +40 -75
  34. package/dist/types/internal.d.ts +5 -23
  35. package/package.json +23 -3
  36. package/dist/esm/Random/CallSite.js +0 -70
  37. package/dist/types/Random/CallSite.d.ts +0 -78
@@ -1,46 +1,31 @@
1
1
  import type { Limits } from "./Enumeration/Types";
2
2
  import type { Instance, Stack } from "./Instance/Types";
3
- import type { Algorithm, Attribution, Seed } from "./Random/Types";
3
+ import type { Algorithm, Salt } from "./Random/Types";
4
4
  import { registry } from "./Schema/Registry";
5
5
  import type { PlainObject } from "./Utility/Types";
6
6
  export declare function initialize<const $Registry extends PlainObject = typeof registry>(config?: Partial<{
7
7
  /** The registry of type definers to use — `registry` itself. */
8
8
  types: $Registry;
9
9
  /**
10
- * Optional mixer composed into every stream beside `clock`. Accepts a
11
- * single string, or several several lets a seed be composed out of
12
- * independent, meaningful parts (a user id, a scenario label) without
13
- * hand-joining them first. If omitted, the seed is empty (unless
14
- * `FABRICATOR_SEED` / `SEED` / `RANDOM_SEED` supplies one): wall-clock
15
- * `clock` is the default entropy, so an unconfigured instance varies by run
16
- * and replays from `context.clock` alone. Pass a seed when two instances
17
- * should share a clock but draw different universes, or when `clock:
18
- * "seeded"` should make the seed itself the reproducibility unit.
10
+ * Optional differentiator composed into every stream beside `clock` it
11
+ * distinguishes runs, it does not generate them. Accepts a single string,
12
+ * or several several lets a salt be composed out of independent,
13
+ * meaningful parts (a user id, a scenario label) without hand-joining them
14
+ * first. If omitted, the salt is empty (unless `FABRICATOR_SALT` supplies
15
+ * one): wall-clock `clock` is the default entropy, so an unconfigured
16
+ * instance varies by run and replays from `context.clock` alone. Pass a
17
+ * salt when two instances should share a clock but draw different
18
+ * universes, or when `clock: "derived"` should make the salt itself the
19
+ * reproducibility unit.
19
20
  */
20
- seed?: Seed;
21
+ salt?: Salt;
21
22
  /**
22
23
  * Bring your own PRNG: a factory that, given a seed, returns a source of
23
24
  * randomness — a `() => number` in `[0, 1)`, a drop-in for `Math.random`.
24
- * Defaults to the built-in `sfc32` generator.
25
+ * The seed is a whole encoded trace, of which `salt` is one slot, not the
26
+ * `salt` itself. Defaults to the built-in `sfc32` generator.
25
27
  */
26
28
  algorithm?: Algorithm;
27
- /**
28
- * How this instance attributes a construction's randomness to the file it
29
- * was written in:
30
- *
31
- * - `{ kind: "rooted", root }` expresses every file relative to `root` (an
32
- * absolute path or a `file://` URL), so the same seed reproduces the same
33
- * data on a checkout at a different absolute path.
34
- * - `{ kind: "call site" }`, the default, is `"rooted"` at the directory of
35
- * whichever file called `initialize()`.
36
- * - `{ kind: "none" }` attributes nothing: every construction of a given kind
37
- * anywhere in the instance shares one stream, keyed by kind alone.
38
- *
39
- * See
40
- * [Reproducibility](https://docs.ghostry.dev/fabricator/guides/reproducibility)
41
- * for the trade-offs between the three.
42
- */
43
- attribution?: Attribution;
44
29
  /**
45
30
  * Instance-wide numeric ceilings. `combinatorial` bounds how many instances
46
31
  * `combinatorial(...)` may enumerate — the check is eager, it throws at
@@ -55,14 +40,14 @@ export declare function initialize<const $Registry extends PlainObject = typeof
55
40
  * every leaf's trace, the default entropy for the instance. Defaults to the
56
41
  * wall-clock instant of this `initialize()` call, so an unconfigured run
57
42
  * has realistic dates and varies by process, and replays from
58
- * `context.clock` (with the same empty or supplied `seed`). Pass a fixed
59
- * `Date` to freeze "now" (and the rest of the run, unless `seed` also
60
- * differs). Pass `"seeded"` to derive "now" from the instance seed instead
43
+ * `context.clock` (with the same empty or supplied `salt`). Pass a fixed
44
+ * `Date` to freeze "now" (and the rest of the run, unless `salt` also
45
+ * differs). Pass `"derived"` to derive "now" from the instance salt instead
61
46
  * — an instant drawn across the whole representable `Date` span, so an
62
47
  * implausible date is the expected outcome of that policy, not a bug.
63
- * `"seeded"` is what makes `seed` alone the reproducibility unit.
48
+ * `"derived"` is what makes `salt` alone the reproducibility unit.
64
49
  */
65
- clock?: Date | "seeded";
50
+ clock?: Date | "derived";
66
51
  /**
67
52
  * The ambient carrier backing `wrap` for this lineage — override only to
68
53
  * force a specific one.
@@ -79,14 +64,14 @@ export declare function initialize<const $Registry extends PlainObject = typeof
79
64
  }>): Instance<$Registry>;
80
65
  export { Omitted } from "./Types";
81
66
  /**
82
- * Tags a `Seed` — for `new Fabricator(schema, { seed })`, or `fork`'s own
83
- * `Overlay.seed` — as composing onto whatever base is in effect, rather than
67
+ * Tags a `Salt` — for `new Fabricator(schema, { salt })`, or `fork`'s own
68
+ * `Overlay.salt` — as composing onto whatever base is in effect, rather than
84
69
  * replacing it outright.
85
70
  */
86
71
  export { layer } from "./Random";
87
72
  /**
88
73
  * `layer(...)`'s return type, so a caller building one programmatically can
89
- * name it — the same rationale as the existing `Seed`/`Attribution` exports.
74
+ * name it — the same rationale as the existing `Salt` export.
90
75
  */
91
76
  export type { Layered } from "./Random/Types";
92
77
  /**
@@ -95,25 +80,6 @@ export type { Layered } from "./Random/Types";
95
80
  * subclasses are distinguished by `.name`.
96
81
  */
97
82
  export { FabricatorError } from "./Error";
98
- /**
99
- * The adapter contract, exported because an adapter is a separate package
100
- * rather than something registered here: `Adapter`/`Recurse` are what one
101
- * declares, `drive` is what its conversion entry point calls, and
102
- * `Adaptation`/`AdaptationsOf` are how it reads what a Schema declared —
103
- * `[Adaptation]` at runtime, `AdaptationsOf` at the type level, keyed by its
104
- * own `key` in both cases.
105
- *
106
- * This package names no external schema library and depends on none: every
107
- * mapping, and every dependency it needs, belongs to the adapter.
108
- *
109
- * `Adapting` is the odd one out, facing whoever _writes_ an adaptation rather
110
- * than whoever implements an adapter: it is the parameter type of every kind's
111
- * `.adapt(adapter, produce)` producer, so a caller writing that producer as a
112
- * named function can name it — the same reason `Stream` is exported below.
113
- */
114
- export { drive } from "./Adapter/Core";
115
- export type { Adaptations, AdaptationsOf, Adapter, Adapting, Recurse, } from "./Adapter/Types";
116
- export { Adaptation } from "./Types";
117
83
  /**
118
84
  * The default registry of type definers, exported so it can be extended via
119
85
  * `registry.extend(({ T }) => ({ ... }))` before being passed to `initialize({
@@ -142,17 +108,23 @@ export type { Stream } from "./Random/Types";
142
108
  */
143
109
  export type { ProduceContext } from "./Random/Types";
144
110
  /**
145
- * The shape `initialize({ seed })` and `new Fabricator(schema, { seed })` both
146
- * accepta single string, or several so a caller building one
147
- * programmatically (rather than as an inline literal) can name the type.
111
+ * What every kind's `.adapt(adapter, produce)` producer is called with `{
112
+ * schema, meta }` the same rationale as `Stream`/`ProduceContext` above: a
113
+ * caller writing the producer as a named function can name its parameter.
114
+ * `meta` is the kind's own config, reachable here without importing the `Meta`
115
+ * well-known symbol from `@ghostry/fabricator/internal` — that symbol stays off
116
+ * the path an ordinary caller writing an `.adapt()` call has to walk. The rest
117
+ * of the adapter contract (`walk`, `Adapter`, `Adaptation`, `Adaptations`,
118
+ * `AdaptationsOf`, `Recurse`) is exported from `@ghostry/fabricator/adapting`
119
+ * instead — surface for implementing an adapter, not for calling `.adapt()`.
148
120
  */
149
- export type { Seed } from "./Random/Types";
121
+ export type { Adapting } from "./Adapter/Types";
150
122
  /**
151
- * The shape `initialize({ attribution })` accepts, so a caller building one
152
- * programmatically — a rooted policy derived from an env var, say can name
153
- * the type.
123
+ * The shape `initialize({ salt })` and `new Fabricator(schema, { salt })` both
124
+ * accept — a single string, or several so a caller building one
125
+ * programmatically (rather than as an inline literal) can name the type.
154
126
  */
155
- export type { Attribution } from "./Random/Types";
127
+ export type { Salt } from "./Random/Types";
156
128
  /**
157
129
  * Reads the value type a built Fabricator produces straight off its `fabricate`
158
130
  * signature — `Fabrication<typeof Product>` instead of `ReturnType<typeof
@@ -170,19 +142,12 @@ export type { ValueOf } from "./Schema/Types";
170
142
  * onto one, the same reason `Stream` is exported above.
171
143
  */
172
144
  export type { Trace } from "./Random/Types";
173
- /**
174
- * How `file` and `ordinal` on a {@link Trace} were resolved — recorded so a
175
- * captured trace is self-describing, including `"counted"` (replayed for a node
176
- * taken from inside a `T.recursive` expansion; not a variant you choose when
177
- * building).
178
- */
179
- export type { RootKind } from "./Random/Types";
180
145
  /**
181
146
  * `fork`/`wrap`'s own config shapes, so a caller building an overlay
182
147
  * programmatically (rather than as an inline literal) can name them — the same
183
- * rationale as the existing `Seed`/`Attribution` exports. `Config` is what
184
- * `initialize`'s own parameter is a `Partial` of; `Overlay` is what
185
- * `fork`/`wrap` accept; `Context` is `instance.context`'s own type, so a caller
186
- * writing a helper that reads it can name the parameter.
148
+ * rationale as the existing `Salt` export. `Config` is what `initialize`'s own
149
+ * parameter is a `Partial` of; `Overlay` is what `fork`/`wrap` accept;
150
+ * `Context` is `instance.context`'s own type, so a caller writing a helper that
151
+ * reads it can name the parameter.
187
152
  */
188
153
  export type { Config, Context, Overlay, Stack } from "./Instance/Types";
@@ -58,30 +58,12 @@ export type { Constructor } from "./Fabricator/Constructor";
58
58
  export { plan, resolve } from "./Enumeration/Plan";
59
59
  export type { Axis, Enumerable, Pin, Resolvable } from "./Enumeration/Types";
60
60
  /**
61
- * The randomness layer underneath `initialize({ seed, algorithm, attribution
62
- * })` and a Fabricator's `.trace` — needed by tests exercising stream
63
- * attribution and construction directly, beneath the level `initialize()`
64
- * itself exposes.
61
+ * The randomness layer underneath `initialize({ clock, salt, algorithm })` and
62
+ * a Fabricator's `.trace` — needed by tests exercising stream construction
63
+ * directly, beneath the level `initialize()` itself exposes.
65
64
  */
66
- export { defaultAlgorithm, encode, randomSeed, toRandomSource, toStream, toStreamFromTrace, } from "./Random";
67
- export type { Algorithm, ConstructionTrace, ConstructorOptions, ResolvedAttribution, RootKind, RootPins, Seed, Trace, } from "./Random/Types";
68
- /**
69
- * `Random/CallSite.ts`'s pure string helpers. Exported for this package's own
70
- * tests: the percent-encoded, `file://`-prefixed, and backslashed spellings
71
- * they exist to fold together cannot be produced by running the suite from an
72
- * ordinary POSIX checkout, so they have to be driven with synthetic frame
73
- * strings instead of real stack frames.
74
- */
75
- export { directoryOf, normalizeLocation, relativize } from "./Random/CallSite";
76
- /**
77
- * Resolves the file that triggered the current call. Exported here for a
78
- * library that wraps fabricator (e.g. `@ghostry/extern`'s testing scope) and
79
- * wants a construction attributed to _its own_ caller rather than to itself,
80
- * which is what the `skip` option is for. See `Random/CallSite.ts`'s doc
81
- * comment for the full contract, including why `skip` is a list of roots that
82
- * composes onto this library's own root rather than replacing it.
83
- */
84
- export { resolveCallerFile } from "./Random/CallSite";
65
+ export { defaultAlgorithm, encode, randomSalt, toRandomSource, toStream, toStreamFromTrace, } from "./Random";
66
+ export type { Algorithm, ConstructionTrace, ConstructorOptions, RootPins, Salt, Trace, } from "./Random/Types";
85
67
  /**
86
68
  * The synchronous ambient carrier. `#stack` (`package.json`) selects it only
87
69
  * where there is no `node:async_hooks` — in practice a browser bundle — so on
package/package.json CHANGED
@@ -1,10 +1,16 @@
1
1
  {
2
2
  "name": "@ghostry/fabricator",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "license": "MIT",
5
5
  "description": "Fabricate typed data from composable schemas.",
6
6
  "keywords": [
7
- "factory"
7
+ "factory",
8
+ "reproducible",
9
+ "fixtures",
10
+ "testing",
11
+ "mock",
12
+ "schema",
13
+ "typescript"
8
14
  ],
9
15
  "author": {
10
16
  "name": "Patrick Rebsch"
@@ -14,9 +20,13 @@
14
20
  "url": "git+https://github.com/ghostry-dev/fabricator",
15
21
  "directory": "pkg/fabricator"
16
22
  },
17
- "homepage": "https://github.com/ghostry-dev/fabricator",
23
+ "homepage": "https://docs.ghostry.dev/fabricator/",
18
24
  "bugs": "https://github.com/ghostry-dev/fabricator/issues",
19
25
  "type": "module",
26
+ "sideEffects": false,
27
+ "engines": {
28
+ "node": ">=20.0.0"
29
+ },
20
30
  "types": "./dist/types/index.d.ts",
21
31
  "module": "./dist/esm/index.js",
22
32
  "imports": {
@@ -38,6 +48,16 @@
38
48
  "types": "./dist/types/internal.d.ts",
39
49
  "import": "./dist/esm/internal.js",
40
50
  "default": "./dist/esm/internal.js"
51
+ },
52
+ "./adapting": {
53
+ "types": "./dist/types/adapting.d.ts",
54
+ "import": "./dist/esm/adapting.js",
55
+ "default": "./dist/esm/adapting.js"
56
+ },
57
+ "./harnessing": {
58
+ "types": "./dist/types/harnessing.d.ts",
59
+ "import": "./dist/esm/harnessing.js",
60
+ "default": "./dist/esm/harnessing.js"
41
61
  }
42
62
  },
43
63
  "publishConfig": {
@@ -1,70 +0,0 @@
1
- const OWN_ROOT = normalizeLocation(new URL("..", import.meta.url).href);
2
- function stripPosition(text) {
3
- return text.replace(/:\d+:\d+/g, "");
4
- }
5
- function extractLocation(frameLine) {
6
- const trimmed = frameLine.trim().replace(/^at\s+/, "");
7
- const parenthesized = trimmed.match(/\(([^()]*)\)$/);
8
- return parenthesized ? parenthesized[1] : trimmed;
9
- }
10
- function decode(text) {
11
- try {
12
- return decodeURIComponent(text);
13
- } catch {
14
- return text;
15
- }
16
- }
17
- function normalizeLocation(location) {
18
- const isUrl = location.startsWith("file://");
19
- const path = isUrl ? decode(location.slice(7)) : location;
20
- return path.replace(/\\/g, "/").replace(/^\/?([A-Za-z]):\//, (_, letter)=>`/${letter.toUpperCase()}:/`);
21
- }
22
- function directoryOf(location) {
23
- const cut = location.lastIndexOf("/");
24
- return -1 === cut ? location : location.slice(0, cut + 1);
25
- }
26
- function relativize(root, file) {
27
- if (!file.startsWith("/")) return file;
28
- const from = root.split("/").filter(Boolean);
29
- const to = file.split("/").filter(Boolean);
30
- let shared = 0;
31
- while(shared < from.length && shared < to.length && from[shared] === to[shared])shared++;
32
- const traversals = Array(from.length - shared).fill("..");
33
- return [
34
- ...traversals,
35
- ...to.slice(shared)
36
- ].join("/");
37
- }
38
- function isInternalFrame(location, otherInternals = []) {
39
- if (location.startsWith(OWN_ROOT)) return true;
40
- return otherInternals.some((skip)=>location.startsWith(skip));
41
- }
42
- function firstExternalFrame(stack, otherInternals = []) {
43
- var _ref, _locations_find;
44
- const locations = stack.split("\n").filter((line)=>line.trim().startsWith("at ")).map(extractLocation).map(normalizeLocation);
45
- return null != (_ref = null != (_locations_find = locations.find((location)=>!isInternalFrame(location, otherInternals))) ? _locations_find : locations[locations.length - 1]) ? _ref : stack;
46
- }
47
- function resolveCallerFile(options) {
48
- var _options_skip;
49
- const skip = null == options ? void 0 : null == (_options_skip = options.skip) ? void 0 : _options_skip.map(normalizeLocation);
50
- const stack = captureRawStack();
51
- const location = stripPosition(stack.walkable ? firstExternalFrame(stack.text, skip) : stack.text);
52
- return (null == options ? void 0 : options.root) === void 0 ? location : relativize(normalizeLocation(options.root), location);
53
- }
54
- function captureRawStack() {
55
- var _captured_stack;
56
- if ("function" != typeof Error.captureStackTrace) {
57
- var _stack;
58
- return {
59
- text: null != (_stack = new Error().stack) ? _stack : "",
60
- walkable: false
61
- };
62
- }
63
- const captured = {};
64
- Error.captureStackTrace(captured);
65
- return {
66
- text: null != (_captured_stack = captured.stack) ? _captured_stack : "",
67
- walkable: true
68
- };
69
- }
70
- export { directoryOf, normalizeLocation, relativize, resolveCallerFile };
@@ -1,78 +0,0 @@
1
- /**
2
- * One canonical form for a location, whatever produced it: Node ESM emits
3
- * `file:///…` URLs, Bun emits bare absolute paths, and this module's own
4
- * `import.meta.url` is percent-encoded — three spellings of one file that must
5
- * compare equal, or `isInternalFrame`/`relativize` silently stop matching. A
6
- * bare path is trusted as-is and never decoded, since it may contain a literal
7
- * `%20`; only the `file://` form's escaping is guaranteed well-formed. Forward
8
- * slashes and an uppercased leading `/X:/` drive fold Windows' `C:\a\b` and
9
- * `file:///c:/a/b` together — the drive is the one component two sources
10
- * disagree on, so it's the only thing case-folded: doing more would break
11
- * case-sensitive filesystems and change what ends up hashed.
12
- */
13
- export declare function normalizeLocation(location: string): string;
14
- /**
15
- * The directory a location sits in, trailing separator included — without it, a
16
- * root of `/a/b/` would match the unrelated sibling `/a/bcd/x.ts`, since
17
- * `startsWith`/prefix-stripping only sees character runs, not path segments.
18
- */
19
- export declare function directoryOf(location: string): string;
20
- /**
21
- * `file` expressed relative to `root`, ascending with `..` where `file` sits
22
- * outside `root` rather than falling back to `file` unchanged. An ascending
23
- * path stays identical across machines whose checkouts hold both locations at
24
- * the same relative position, the common case for anything under the same
25
- * repository — passing an escaping file through as absolute would defeat the
26
- * default `"call site"` policy for every schema helper that isn't a sibling of
27
- * wherever `initialize()` was called. A location that isn't an absolute path
28
- * (`native`, `<anonymous>`, or a value that has already been relativized)
29
- * doesn't start with `/` and is returned unchanged — applying this twice is a
30
- * no-op, which lets `T.recursive` thread an already-relativized file back
31
- * through here uniformly.
32
- */
33
- export declare function relativize(root: string, file: string): string;
34
- /**
35
- * Resolve the file that (transitively) triggered the current call, so
36
- * construction can be attributed to the source file the user wrote it in.
37
- *
38
- * Primary path: `Error.captureStackTrace` (V8, and Bun for Node compatibility)
39
- * captures the full stack, then `firstExternalFrame` skips this library's own
40
- * frames by path — no need to hardcode how many frames to exclude, so it stays
41
- * correct as internal call depth changes.
42
- *
43
- * Fallback: engines without `captureStackTrace` get the whole raw stack,
44
- * position-stripped, hashed as-is rather than guessing which frame to isolate.
45
- * Lower fidelity (sensitive to edits anywhere in the visible call chain, not
46
- * just the immediate caller), but rarely exercised — Bun, Node, and Chrome all
47
- * support the primary path. Left unnormalized: a whole multi-line stack has no
48
- * single location for `normalizeLocation`'s separator/drive rewriting to apply
49
- * to, so this path never relativizes — it always falls through `relativize`'s
50
- * non-absolute passthrough instead.
51
- *
52
- * Both options exist for a library that wraps fabricator and wants to attribute
53
- * a construction to _its own_ caller rather than to itself —
54
- * `@ghostry/extern`'s testing scope is the motivating case: it opens a `wrap`
55
- * per test and wants the resolved site to be the test file, not `extern`'s own
56
- * module. This module's own callers (`resolveAttribution`'s `"call site"`
57
- * branch, `resolveRootFile`) pass neither.
58
- *
59
- * `skip`, when given, is a list of _additional_ roots to exclude — layered onto
60
- * `OWN_ROOT`, never replacing it. With a wrapper between fabricator and the
61
- * real caller, the stack reads fabricator → wrapper → caller: omitting
62
- * `OWN_ROOT` from the skip set would make this resolve to fabricator's own file
63
- * instead of stopping at the wrapper.
64
- *
65
- * Always a list, never a bare root: a _chain_ of wrappers needs every link
66
- * named, and any link left out is where resolution stops. An integration
67
- * layered on another integration reads fabricator → inner → outer → caller —
68
- * `@ghostry/extern`'s fabricator extension sits between fabricator and extern
69
- * exactly this way.
70
- *
71
- * `root`, when given, relativizes the result exactly as a `{ kind: "rooted" }`
72
- * attribution policy does ({@link relativize}) — so a caller needs no separate
73
- * import to get a checkout-relative path.
74
- */
75
- export declare function resolveCallerFile(options?: {
76
- readonly skip?: readonly string[];
77
- readonly root?: string;
78
- }): string;