@effected/tsconfig-json 0.3.2 → 0.4.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.
- package/PortableTsconfig.js +35 -13
- package/README.md +6 -1
- package/ResolvedTsconfig.js +33 -34
- package/TsEnumCodec.js +55 -61
- package/TsconfigDiscovery.js +12 -11
- package/TsconfigLoader.js +30 -33
- package/TsconfigLoaderSync.js +23 -26
- package/index.d.ts +210 -34
- package/package.json +2 -2
package/PortableTsconfig.js
CHANGED
|
@@ -86,6 +86,7 @@ const PRESERVED_OPTIONS = [
|
|
|
86
86
|
...PRESERVED_ENUM_OPTIONS,
|
|
87
87
|
...PRESERVED_STRING_OPTIONS
|
|
88
88
|
];
|
|
89
|
+
const OPT_IN_TYPES_OPTION = "types";
|
|
89
90
|
/**
|
|
90
91
|
* A `ResolvedTsconfig` carries a string `configPath`, an array `extendedPaths`
|
|
91
92
|
* AND an object `compilerOptions`; a bare `CompilerOptions.Type` never carries
|
|
@@ -101,23 +102,17 @@ const PRESERVED_OPTIONS = [
|
|
|
101
102
|
* is filtered, which is the safe outcome.)
|
|
102
103
|
*/
|
|
103
104
|
const isResolvedTsconfig = (input) => typeof input.configPath === "string" && Array.isArray(input.extendedPaths) && typeof input.compilerOptions === "object" && input.compilerOptions !== null;
|
|
104
|
-
|
|
105
|
-
* Project a {@link (ResolvedTsconfig:interface)} or a bare
|
|
106
|
-
* `CompilerOptions.Type` down to a {@link (PortableTsconfig:interface)}: copy
|
|
107
|
-
* only the allow-listed type-semantics options, force `composite: false` and
|
|
108
|
-
* `noEmit: true` regardless of what the source declared, and stamp `$schema`.
|
|
109
|
-
* Every other key — including every unknown passthrough key the source
|
|
110
|
-
* preserved for forward tolerance — is dropped; this is an allow-list, not a
|
|
111
|
-
* deny-list, so an option this package does not yet classify never leaks onto
|
|
112
|
-
* the portable shape by accident.
|
|
113
|
-
*/
|
|
114
|
-
const make = (input) => {
|
|
105
|
+
const make = (input, options) => {
|
|
115
106
|
const source = isResolvedTsconfig(input) ? input.compilerOptions : input;
|
|
116
107
|
const compilerOptions = {};
|
|
117
108
|
for (const key of PRESERVED_OPTIONS) {
|
|
118
109
|
const value = source[key];
|
|
119
110
|
if (value !== void 0) compilerOptions[key] = value;
|
|
120
111
|
}
|
|
112
|
+
if (options?.includeTypes === true) {
|
|
113
|
+
const types = source[OPT_IN_TYPES_OPTION];
|
|
114
|
+
if (types !== void 0) compilerOptions[OPT_IN_TYPES_OPTION] = types;
|
|
115
|
+
}
|
|
121
116
|
compilerOptions.composite = false;
|
|
122
117
|
compilerOptions.noEmit = true;
|
|
123
118
|
return {
|
|
@@ -126,13 +121,40 @@ const make = (input) => {
|
|
|
126
121
|
};
|
|
127
122
|
};
|
|
128
123
|
/**
|
|
129
|
-
* The portable-tsconfig filter: {@link (PortableTsconfig:
|
|
124
|
+
* The portable-tsconfig filter: {@link (PortableTsconfig:class).make}
|
|
130
125
|
* narrows a resolved or bare compiler-options object to the allow-listed,
|
|
131
126
|
* machine-independent subset described on {@link (PortableTsconfig:interface)}.
|
|
132
127
|
*
|
|
133
128
|
* @public
|
|
134
129
|
*/
|
|
135
|
-
|
|
130
|
+
var PortableTsconfig = class {
|
|
131
|
+
constructor() {}
|
|
132
|
+
/**
|
|
133
|
+
* Project a {@link (ResolvedTsconfig:interface)} or a bare
|
|
134
|
+
* `CompilerOptions.Type` down to a {@link (PortableTsconfig:interface)}:
|
|
135
|
+
* copy only the allow-listed type-semantics options, force
|
|
136
|
+
* `composite: false` and `noEmit: true` regardless of what the source
|
|
137
|
+
* declared, and stamp `$schema`. Every other key — including every
|
|
138
|
+
* unknown passthrough key the source preserved for forward tolerance —
|
|
139
|
+
* is dropped; this is an allow-list, not a deny-list, so an option this
|
|
140
|
+
* package does not yet classify never leaks onto the portable shape by
|
|
141
|
+
* accident.
|
|
142
|
+
*
|
|
143
|
+
* `types` is the one deliberate exception, and it is opt-in rather than
|
|
144
|
+
* unclassified: it is portable (package names, not paths) but carrying it
|
|
145
|
+
* makes TypeScript demand those packages be resolvable, which a virtual
|
|
146
|
+
* environment with no `node_modules` cannot satisfy. Pass
|
|
147
|
+
* {@link PortableTsconfigOptions.includeTypes} when the consumer
|
|
148
|
+
* materializes `@types`; leave it off for the permissive default. Related
|
|
149
|
+
* `typeRoots` is never carried — machine-specific,
|
|
150
|
+
* config-location-dependent directories.
|
|
151
|
+
*
|
|
152
|
+
* @param input - The resolved config, or a bare compiler-options bag.
|
|
153
|
+
* @param options - Opt-ins for options that are portable but
|
|
154
|
+
* resolution-dependent. Omitted means the strict, always-safe subset.
|
|
155
|
+
*/
|
|
156
|
+
static make = make;
|
|
157
|
+
};
|
|
136
158
|
|
|
137
159
|
//#endregion
|
|
138
160
|
export { PortableTsconfig };
|
package/README.md
CHANGED
|
@@ -82,8 +82,13 @@ console.log(TsEnumCodec.encodeCompilerOptions({ target: "es2023", strict: true,
|
|
|
82
82
|
|
|
83
83
|
console.log(PortableTsconfig.make(resolved).compilerOptions.noEmit);
|
|
84
84
|
// true — always forced, whatever the source config declared
|
|
85
|
+
|
|
86
|
+
console.log(PortableTsconfig.make(resolved, { includeTypes: true }).compilerOptions.types);
|
|
87
|
+
// carries the source config's `types` package names when it declares them, omitted when absent
|
|
85
88
|
```
|
|
86
89
|
|
|
90
|
+
`includeTypes` is opt-in and defaults to `false` because emitting `types` makes tsc demand those `@types` packages resolve — a hard error in a virtual environment with no `node_modules`. Pass it when your environment materializes `@types` itself; leave it off for the permissive default where TypeScript auto-includes whatever it finds.
|
|
91
|
+
|
|
87
92
|
## Synchronous loading
|
|
88
93
|
|
|
89
94
|
Bundler plugin hooks and config factories often cannot await. `TsconfigLoaderSync` runs the unchanged loader pipeline synchronously over file and path operations you supply — the package still imports no `node:*` module, and Node's built-ins satisfy the operations directly:
|
|
@@ -154,7 +159,7 @@ console.log(fsMap.size);
|
|
|
154
159
|
- `ResolvedTsconfig` — the pure merge engine behind `resolve`: per-field merge semantics, path-option absolutization against the declaring config's directory, final `${configDir}` substitution and `pathsBase` provenance, with no filesystem access at all.
|
|
155
160
|
- `TsconfigDiscovery.findNearest` — the nearest `tsconfig.json` (or any filename via `options.filename`) at or above a starting directory, over `@effected/walker`; one unreadable ancestor cannot hide a config above it.
|
|
156
161
|
- `TsEnumCodec` — the string↔numeric enum tables as plain data with zero `typescript` imports. `encodeCompilerOptions` returns the exported `ProgrammaticCompilerOptions` type — the numeric shape `ts.CompilerOptions` expects, so you hand it to a `ts.CompilerOptions`-shaped API without a cast — with `lib` entries in the file-name form the compiler resolves verbatim; `decodeCompilerOptions` reverses it.
|
|
157
|
-
- `PortableTsconfig.make` — an allow-list projection down to machine-independent type-semantics options, with `composite: false` and `noEmit: true` forced: the slice a virtual TypeScript environment (Twoslash, API Extractor, an in-memory language service) can safely inherit.
|
|
162
|
+
- `PortableTsconfig.make` — an allow-list projection down to machine-independent type-semantics options, with `composite: false` and `noEmit: true` forced: the slice a virtual TypeScript environment (Twoslash, API Extractor, an in-memory language service) can safely inherit. An optional `{ includeTypes }` argument carries the source config's `types` package names onto the portable shape too, for a caller whose virtual environment can resolve `@types` packages itself; `typeRoots` stays dropped either way, since it names machine-specific, config-location-dependent directories.
|
|
158
163
|
- `JsxConfig.fromCompilerOptions` — the JSX transform a bundler can configure, projected from decoded options: `react-jsx` / `react-jsxdev` select the automatic runtime with its import source (defaulting to `react`, tsc's own default), `react` selects classic, and `preserve`, `react-native` or an absent `jsx` yield `Option.none()`.
|
|
159
164
|
- Typed failures everywhere: a malformed file is a `TsconfigParseError` carrying its path, a broken chain is a `TsconfigExtendsError` with a `not-found` / `cycle` / `depth` / `empty` reason and the full resolution chain, and IO errors flow through as `PlatformError`. Nothing fails as a defect.
|
|
160
165
|
|
package/ResolvedTsconfig.js
CHANGED
|
@@ -72,16 +72,6 @@ const transformCompilerOptionPaths = (co, transform, includePathsValues) => {
|
|
|
72
72
|
}
|
|
73
73
|
return out;
|
|
74
74
|
};
|
|
75
|
-
/**
|
|
76
|
-
* Absolutize a config's path-typed options (E5) against its own `configDir`,
|
|
77
|
-
* using the injected `join` (`Path.Path.resolve` at the call site — so an
|
|
78
|
-
* already-absolute value is preserved). `${configDir}`-prefixed values are
|
|
79
|
-
* exempt (resolved later, in {@link (ResolvedTsconfig:variable).substituteConfigDir}), and
|
|
80
|
-
* `paths` VALUES stay verbatim. Only `compilerOptions` path surfaces are
|
|
81
|
-
* touched; `files`/`include`/`exclude` are re-rooted at merge time instead (E4).
|
|
82
|
-
*
|
|
83
|
-
* @public
|
|
84
|
-
*/
|
|
85
75
|
const absolutize = (doc, configDir, join) => {
|
|
86
76
|
const co = doc.compilerOptions;
|
|
87
77
|
if (co === void 0) return doc;
|
|
@@ -153,14 +143,6 @@ const mergeWatchOptions = (base, derived) => {
|
|
|
153
143
|
...derived
|
|
154
144
|
};
|
|
155
145
|
};
|
|
156
|
-
/**
|
|
157
|
-
* Fold one more-derived config onto the accumulated base (E4), derived winning.
|
|
158
|
-
* The loader (Task 8) applies this across the resolution chain, own config last.
|
|
159
|
-
* `derivedPath` is the derived config's absolute normalized path, from which the
|
|
160
|
-
* re-rooting frame and `pathsBase` are computed.
|
|
161
|
-
*
|
|
162
|
-
* @public
|
|
163
|
-
*/
|
|
164
146
|
const merge = (base, derived, derivedPath) => {
|
|
165
147
|
const finalDir = dirname(derivedPath);
|
|
166
148
|
const baseDir = dirname(base.configPath);
|
|
@@ -202,15 +184,6 @@ const substituteWatchExcludes = (wo, substitute) => {
|
|
|
202
184
|
}
|
|
203
185
|
return out;
|
|
204
186
|
};
|
|
205
|
-
/**
|
|
206
|
-
* The E5 final phase: replace a leading `${configDir}` token (case-insensitive,
|
|
207
|
-
* leading position only) with `finalDir` — the top-level extending config's
|
|
208
|
-
* directory — across every eligible surface: compilerOptions path options,
|
|
209
|
-
* `paths` values, `files`/`include`/`exclude`, and `watchOptions`'
|
|
210
|
-
* `excludeDirectories`/`excludeFiles`. Every other field is left untouched.
|
|
211
|
-
*
|
|
212
|
-
* @public
|
|
213
|
-
*/
|
|
214
187
|
const substituteConfigDir = (resolved, finalDir) => {
|
|
215
188
|
const substitute = (value) => startsWithConfigDir(value) ? finalDir + value.slice(CONFIG_DIR_TEMPLATE.length) : value;
|
|
216
189
|
const compilerOptions = transformCompilerOptionPaths(resolved.compilerOptions, substitute, true);
|
|
@@ -229,16 +202,42 @@ const substituteConfigDir = (resolved, finalDir) => {
|
|
|
229
202
|
};
|
|
230
203
|
/**
|
|
231
204
|
* The pure extends-merge engine: parse-time path absolutization
|
|
232
|
-
* ({@link (ResolvedTsconfig:
|
|
233
|
-
* ({@link (ResolvedTsconfig:
|
|
234
|
-
* phase ({@link (ResolvedTsconfig:
|
|
205
|
+
* ({@link (ResolvedTsconfig:class).absolutize}), the per-field merge fold
|
|
206
|
+
* ({@link (ResolvedTsconfig:class).merge}), and the `${configDir}` final
|
|
207
|
+
* phase ({@link (ResolvedTsconfig:class).substituteConfigDir}).
|
|
235
208
|
*
|
|
236
209
|
* @public
|
|
237
210
|
*/
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
211
|
+
var ResolvedTsconfig = class {
|
|
212
|
+
constructor() {}
|
|
213
|
+
/**
|
|
214
|
+
* Absolutize a config's path-typed options (E5) against its own
|
|
215
|
+
* `configDir`, using the injected `join` (`Path.Path.resolve` at the call
|
|
216
|
+
* site — so an already-absolute value is preserved). `${configDir}`-prefixed
|
|
217
|
+
* values are exempt (resolved later, in
|
|
218
|
+
* {@link (ResolvedTsconfig:class).substituteConfigDir}), and `paths`
|
|
219
|
+
* VALUES stay verbatim. Only `compilerOptions` path surfaces are touched;
|
|
220
|
+
* `files`/`include`/`exclude` are re-rooted at merge time instead (E4).
|
|
221
|
+
*/
|
|
222
|
+
static absolutize = absolutize;
|
|
223
|
+
/**
|
|
224
|
+
* Fold one more-derived config onto the accumulated base (E4), derived
|
|
225
|
+
* winning. The loader (Task 8) applies this across the resolution chain,
|
|
226
|
+
* own config last. `derivedPath` is the derived config's absolute
|
|
227
|
+
* normalized path, from which the re-rooting frame and `pathsBase` are
|
|
228
|
+
* computed.
|
|
229
|
+
*/
|
|
230
|
+
static merge = merge;
|
|
231
|
+
/**
|
|
232
|
+
* The E5 final phase: replace a leading `${configDir}` token
|
|
233
|
+
* (case-insensitive, leading position only) with `finalDir` — the
|
|
234
|
+
* top-level extending config's directory — across every eligible
|
|
235
|
+
* surface: compilerOptions path options, `paths` values,
|
|
236
|
+
* `files`/`include`/`exclude`, and `watchOptions`'
|
|
237
|
+
* `excludeDirectories`/`excludeFiles`. Every other field is left
|
|
238
|
+
* untouched.
|
|
239
|
+
*/
|
|
240
|
+
static substituteConfigDir = substituteConfigDir;
|
|
242
241
|
};
|
|
243
242
|
|
|
244
243
|
//#endregion
|
package/TsEnumCodec.js
CHANGED
|
@@ -94,31 +94,8 @@ const TABLES = {
|
|
|
94
94
|
["fixedchunksize", 3]
|
|
95
95
|
])
|
|
96
96
|
};
|
|
97
|
-
/**
|
|
98
|
-
* Encodes a family's canonical (or alias) string spelling to its numeric
|
|
99
|
-
* form. `Option.none()` for a string with no table entry — never guessed.
|
|
100
|
-
*
|
|
101
|
-
* @public
|
|
102
|
-
*/
|
|
103
97
|
const encode = (family, value) => Option.fromNullishOr(TABLES[family].forward.get(value));
|
|
104
|
-
/**
|
|
105
|
-
* Decodes a family's numeric value to its canonical string spelling.
|
|
106
|
-
* `Option.none()` for a numeric value with no table entry (a future TS enum
|
|
107
|
-
* member) — never guessed.
|
|
108
|
-
*
|
|
109
|
-
* @public
|
|
110
|
-
*/
|
|
111
98
|
const decode = (family, value) => Option.fromNullishOr(TABLES[family].reverse.get(value));
|
|
112
|
-
/**
|
|
113
|
-
* Normalizes any spelling of a `lib` reference — the plain short name
|
|
114
|
-
* (`esnext`), the on-disk file name (`lib.esnext.d.ts`), or an absolute path
|
|
115
|
-
* to one (`/…/typescript/lib/lib.dom.iterable.d.ts`) — to the canonical
|
|
116
|
-
* lowercase short name (`esnext`, `dom.iterable`). Strips a leading
|
|
117
|
-
* directory, the `lib.` prefix and the `.d.ts` suffix; idempotent on an
|
|
118
|
-
* already-short name.
|
|
119
|
-
*
|
|
120
|
-
* @public
|
|
121
|
-
*/
|
|
122
99
|
const normalizeLibReference = (lib) => {
|
|
123
100
|
const base = (lib.split("/").pop() ?? lib).toLowerCase();
|
|
124
101
|
const withoutPrefix = base.startsWith("lib.") ? base.slice(4) : base;
|
|
@@ -133,24 +110,6 @@ const COMPILER_OPTION_ENUM_KEYS = [
|
|
|
133
110
|
["newLine", "newLine"],
|
|
134
111
|
["moduleDetection", "moduleDetection"]
|
|
135
112
|
];
|
|
136
|
-
/**
|
|
137
|
-
* Encodes a decoded `compilerOptions` object into the numeric-enum-shaped
|
|
138
|
-
* {@link ProgrammaticCompilerOptions} form `ts.CompilerOptions` (and
|
|
139
|
-
* `@typescript/vfs`'s `TsEnvironment`) expect: every R1.6 enum family becomes
|
|
140
|
-
* its numeric value, and `lib` entries become the file-name form
|
|
141
|
-
* (`lib.esnext.d.ts`) — see the module banner for the evidence. Every other key
|
|
142
|
-
* (booleans, strings, arrays, unknown passthrough keys) is copied through
|
|
143
|
-
* untouched.
|
|
144
|
-
*
|
|
145
|
-
* The return carries this package's single narrowing from the codec's internal
|
|
146
|
-
* `Record<string, unknown>` (whose values include the schema's `unknown`
|
|
147
|
-
* passthrough and its `readonly` arrays) to {@link ProgrammaticCompilerOptions}
|
|
148
|
-
* — see that type's docs for why the package owns this one assertion instead of
|
|
149
|
-
* leaving every consumer to cast. Runtime behavior is unchanged; only the
|
|
150
|
-
* declared return type narrows.
|
|
151
|
-
*
|
|
152
|
-
* @public
|
|
153
|
-
*/
|
|
154
113
|
const encodeCompilerOptions = (options) => {
|
|
155
114
|
const source = options;
|
|
156
115
|
const result = { ...source };
|
|
@@ -165,20 +124,6 @@ const encodeCompilerOptions = (options) => {
|
|
|
165
124
|
if (Array.isArray(lib)) result.lib = lib.map((entry) => typeof entry === "string" ? `lib.${normalizeLibReference(entry)}.d.ts` : entry);
|
|
166
125
|
return result;
|
|
167
126
|
};
|
|
168
|
-
/**
|
|
169
|
-
* Decodes a numeric-enum-shaped `compilerOptions` object (as produced by
|
|
170
|
-
* {@link (TsEnumCodec:variable).encodeCompilerOptions} or read off a live
|
|
171
|
-
* `ts.CompilerOptions`) back into the string-enum shape this package's
|
|
172
|
-
* schemas use: every R1.6 enum family becomes its canonical string, and
|
|
173
|
-
* `lib` entries become the short form. A numeric value with no table entry —
|
|
174
|
-
* a future TS enum member — is left as-is (passthrough, never an error) —
|
|
175
|
-
* which is why the return type stays the wider `Record<string, unknown>`
|
|
176
|
-
* rather than {@link (CompilerOptions:variable).Type}: an unmappable
|
|
177
|
-
* passthrough value would violate that narrower type's contract. Every other
|
|
178
|
-
* key is copied through untouched.
|
|
179
|
-
*
|
|
180
|
-
* @public
|
|
181
|
-
*/
|
|
182
127
|
const decodeCompilerOptions = (numeric) => {
|
|
183
128
|
const result = { ...numeric };
|
|
184
129
|
for (const [key, family] of COMPILER_OPTION_ENUM_KEYS) {
|
|
@@ -199,12 +144,61 @@ const decodeCompilerOptions = (numeric) => {
|
|
|
199
144
|
*
|
|
200
145
|
* @public
|
|
201
146
|
*/
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
147
|
+
var TsEnumCodec = class {
|
|
148
|
+
constructor() {}
|
|
149
|
+
/**
|
|
150
|
+
* Encodes a family's canonical (or alias) string spelling to its numeric
|
|
151
|
+
* form. `Option.none()` for a string with no table entry — never guessed.
|
|
152
|
+
*/
|
|
153
|
+
static encode = encode;
|
|
154
|
+
/**
|
|
155
|
+
* Decodes a family's numeric value to its canonical string spelling.
|
|
156
|
+
* `Option.none()` for a numeric value with no table entry (a future TS
|
|
157
|
+
* enum member) — never guessed.
|
|
158
|
+
*/
|
|
159
|
+
static decode = decode;
|
|
160
|
+
/**
|
|
161
|
+
* Normalizes any spelling of a `lib` reference — the plain short name
|
|
162
|
+
* (`esnext`), the on-disk file name (`lib.esnext.d.ts`), or an absolute
|
|
163
|
+
* path to one (`/…/typescript/lib/lib.dom.iterable.d.ts`) — to the
|
|
164
|
+
* canonical lowercase short name (`esnext`, `dom.iterable`). Strips a
|
|
165
|
+
* leading directory, the `lib.` prefix and the `.d.ts` suffix; idempotent
|
|
166
|
+
* on an already-short name.
|
|
167
|
+
*/
|
|
168
|
+
static normalizeLibReference = normalizeLibReference;
|
|
169
|
+
/**
|
|
170
|
+
* Encodes a decoded `compilerOptions` object into the
|
|
171
|
+
* numeric-enum-shaped {@link ProgrammaticCompilerOptions} form
|
|
172
|
+
* `ts.CompilerOptions` (and `@typescript/vfs`'s `TsEnvironment`) expect:
|
|
173
|
+
* every R1.6 enum family becomes its numeric value, and `lib` entries
|
|
174
|
+
* become the file-name form (`lib.esnext.d.ts`) — see the module banner
|
|
175
|
+
* for the evidence. Every other key (booleans, strings, arrays, unknown
|
|
176
|
+
* passthrough keys) is copied through untouched.
|
|
177
|
+
*
|
|
178
|
+
* @remarks
|
|
179
|
+
* The return carries this package's single narrowing from the codec's
|
|
180
|
+
* internal `Record<string, unknown>` (whose values include the schema's
|
|
181
|
+
* `unknown` passthrough and its `readonly` arrays) to
|
|
182
|
+
* {@link ProgrammaticCompilerOptions} — see that type's docs for why the
|
|
183
|
+
* package owns this one assertion instead of leaving every consumer to
|
|
184
|
+
* cast. Runtime behavior is unchanged; only the declared return type
|
|
185
|
+
* narrows.
|
|
186
|
+
*/
|
|
187
|
+
static encodeCompilerOptions = encodeCompilerOptions;
|
|
188
|
+
/**
|
|
189
|
+
* Decodes a numeric-enum-shaped `compilerOptions` object (as produced by
|
|
190
|
+
* {@link TsEnumCodec.encodeCompilerOptions} or read off a live
|
|
191
|
+
* `ts.CompilerOptions`) back into the string-enum shape this package's
|
|
192
|
+
* schemas use: every R1.6 enum family becomes its canonical string, and
|
|
193
|
+
* `lib` entries become the short form. A numeric value with no table
|
|
194
|
+
* entry — a future TS enum member — is left as-is (passthrough, never an
|
|
195
|
+
* error) — which is why the return type stays the wider
|
|
196
|
+
* `Record<string, unknown>` rather than
|
|
197
|
+
* {@link (CompilerOptions:namespace).Type}: an unmappable passthrough
|
|
198
|
+
* value would violate that narrower type's contract. Every other key is
|
|
199
|
+
* copied through untouched.
|
|
200
|
+
*/
|
|
201
|
+
static decodeCompilerOptions = decodeCompilerOptions;
|
|
208
202
|
};
|
|
209
203
|
|
|
210
204
|
//#endregion
|
package/TsconfigDiscovery.js
CHANGED
|
@@ -2,16 +2,6 @@ import { Effect, Path } from "effect";
|
|
|
2
2
|
import { Walker } from "@effected/walker";
|
|
3
3
|
|
|
4
4
|
//#region src/TsconfigDiscovery.ts
|
|
5
|
-
/**
|
|
6
|
-
* Find the nearest `tsconfig.json` (or `options.filename`) at or above
|
|
7
|
-
* `start`, ascending toward the filesystem root. Absence — nowhere on the
|
|
8
|
-
* chain, or every candidate unreadable — is `Option.none()`, never an error;
|
|
9
|
-
* discovery is best-effort per `Walker.findUpward`'s absorption posture, and a
|
|
10
|
-
* permission-denied probe on one directory does not hide a config file above
|
|
11
|
-
* it.
|
|
12
|
-
*
|
|
13
|
-
* @public
|
|
14
|
-
*/
|
|
15
5
|
const findNearest = (start, options) => Effect.gen(function* () {
|
|
16
6
|
const path = yield* Path.Path;
|
|
17
7
|
const filename = options?.filename ?? "tsconfig.json";
|
|
@@ -23,7 +13,18 @@ const findNearest = (start, options) => Effect.gen(function* () {
|
|
|
23
13
|
*
|
|
24
14
|
* @public
|
|
25
15
|
*/
|
|
26
|
-
|
|
16
|
+
var TsconfigDiscovery = class {
|
|
17
|
+
constructor() {}
|
|
18
|
+
/**
|
|
19
|
+
* Find the nearest `tsconfig.json` (or `options.filename`) at or above
|
|
20
|
+
* `start`, ascending toward the filesystem root. Absence — nowhere on the
|
|
21
|
+
* chain, or every candidate unreadable — is `Option.none()`, never an
|
|
22
|
+
* error; discovery is best-effort per `Walker.findUpward`'s absorption
|
|
23
|
+
* posture, and a permission-denied probe on one directory does not hide a
|
|
24
|
+
* config file above it.
|
|
25
|
+
*/
|
|
26
|
+
static findNearest = findNearest;
|
|
27
|
+
};
|
|
27
28
|
|
|
28
29
|
//#endregion
|
|
29
30
|
export { TsconfigDiscovery };
|
package/TsconfigLoader.js
CHANGED
|
@@ -58,14 +58,6 @@ const loadAbs = (abs) => Effect.gen(function* () {
|
|
|
58
58
|
cause
|
|
59
59
|
})));
|
|
60
60
|
});
|
|
61
|
-
/**
|
|
62
|
-
* Read one config file and decode it through {@link TsconfigJsonFromString}. A
|
|
63
|
-
* decode failure is wrapped in a {@link TsconfigParseError} carrying the file's
|
|
64
|
-
* absolute path; a `PlatformError` from the read flows through untranslated. No
|
|
65
|
-
* `extends` resolution — {@link TsconfigLoader.resolve} drives that.
|
|
66
|
-
*
|
|
67
|
-
* @public
|
|
68
|
-
*/
|
|
69
61
|
const load = Effect.fn("TsconfigLoader.load")(function* (configPath) {
|
|
70
62
|
const path = yield* Path.Path;
|
|
71
63
|
return yield* loadAbs(normalizeSlashes(path.resolve(configPath)));
|
|
@@ -119,19 +111,6 @@ const collect = (configPath, chain) => Effect.gen(function* () {
|
|
|
119
111
|
});
|
|
120
112
|
return layers;
|
|
121
113
|
});
|
|
122
|
-
/**
|
|
123
|
-
* Resolve a tsconfig.json and its full `extends` chain into a
|
|
124
|
-
* {@link (ResolvedTsconfig:interface)}: load and decode each config, absolutize its path
|
|
125
|
-
* options (E5), resolve `extends` depth-first with per-branch cycle and depth
|
|
126
|
-
* guards (E1-E3, E6), fold the chain own-config-last (E4), then substitute a
|
|
127
|
-
* leading `${configDir}` once against the top config's directory (E5 final
|
|
128
|
-
* phase). `configPath` + `extendedPaths` come back base-most first, own config
|
|
129
|
-
* last. Every failure is a typed error — `TsconfigParseError` (a malformed file,
|
|
130
|
-
* carrying that file's path), `TsconfigExtendsError` (a broken chain), or a
|
|
131
|
-
* `PlatformError` from IO — never a defect.
|
|
132
|
-
*
|
|
133
|
-
* @public
|
|
134
|
-
*/
|
|
135
114
|
const resolve = Effect.fn("TsconfigLoader.resolve")(function* (configPath) {
|
|
136
115
|
const path = yield* Path.Path;
|
|
137
116
|
const topAbs = normalizeSlashes(path.resolve(configPath));
|
|
@@ -144,14 +123,6 @@ const resolve = Effect.fn("TsconfigLoader.resolve")(function* (configPath) {
|
|
|
144
123
|
for (const entry of layers) acc = ResolvedTsconfig.merge(acc, entry.doc, entry.path);
|
|
145
124
|
return ResolvedTsconfig.substituteConfigDir(acc, path.dirname(topAbs));
|
|
146
125
|
});
|
|
147
|
-
/**
|
|
148
|
-
* Resolve a tsconfig.json's full `extends` chain and project out the merged
|
|
149
|
-
* `compilerOptions` — a thin projection of {@link TsconfigLoader.resolve} for
|
|
150
|
-
* the common "just give me the effective options" query. Same pipeline, same
|
|
151
|
-
* typed failures.
|
|
152
|
-
*
|
|
153
|
-
* @public
|
|
154
|
-
*/
|
|
155
126
|
const compilerOptions = Effect.fn("TsconfigLoader.compilerOptions")(function* (configPath) {
|
|
156
127
|
return (yield* resolve(configPath)).compilerOptions;
|
|
157
128
|
});
|
|
@@ -163,10 +134,36 @@ const compilerOptions = Effect.fn("TsconfigLoader.compilerOptions")(function* (c
|
|
|
163
134
|
*
|
|
164
135
|
* @public
|
|
165
136
|
*/
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
137
|
+
var TsconfigLoader = class {
|
|
138
|
+
constructor() {}
|
|
139
|
+
/**
|
|
140
|
+
* Read one config file and decode it through {@link TsconfigJsonFromString}.
|
|
141
|
+
* A decode failure is wrapped in a {@link TsconfigParseError} carrying the
|
|
142
|
+
* file's absolute path; a `PlatformError` from the read flows through
|
|
143
|
+
* untranslated. No `extends` resolution — {@link TsconfigLoader.resolve}
|
|
144
|
+
* drives that.
|
|
145
|
+
*/
|
|
146
|
+
static load = load;
|
|
147
|
+
/**
|
|
148
|
+
* Resolve a tsconfig.json and its full `extends` chain into a
|
|
149
|
+
* {@link (ResolvedTsconfig:interface)}: load and decode each config,
|
|
150
|
+
* absolutize its path options (E5), resolve `extends` depth-first with
|
|
151
|
+
* per-branch cycle and depth guards (E1-E3, E6), fold the chain
|
|
152
|
+
* own-config-last (E4), then substitute a leading `${configDir}` once
|
|
153
|
+
* against the top config's directory (E5 final phase). `configPath` +
|
|
154
|
+
* `extendedPaths` come back base-most first, own config last. Every
|
|
155
|
+
* failure is a typed error — `TsconfigParseError` (a malformed file,
|
|
156
|
+
* carrying that file's path), `TsconfigExtendsError` (a broken chain), or
|
|
157
|
+
* a `PlatformError` from IO — never a defect.
|
|
158
|
+
*/
|
|
159
|
+
static resolve = resolve;
|
|
160
|
+
/**
|
|
161
|
+
* Resolve a tsconfig.json's full `extends` chain and project out the
|
|
162
|
+
* merged `compilerOptions` — a thin projection of
|
|
163
|
+
* {@link TsconfigLoader.resolve} for the common "just give me the
|
|
164
|
+
* effective options" query. Same pipeline, same typed failures.
|
|
165
|
+
*/
|
|
166
|
+
static compilerOptions = compilerOptions;
|
|
170
167
|
};
|
|
171
168
|
|
|
172
169
|
//#endregion
|
package/TsconfigLoaderSync.js
CHANGED
|
@@ -67,30 +67,8 @@ const runWith = (options, effect) => {
|
|
|
67
67
|
if (Result.isSuccess(defect)) throw defect.success;
|
|
68
68
|
throw Cause.squash(exit.cause);
|
|
69
69
|
};
|
|
70
|
-
/**
|
|
71
|
-
* {@link TsconfigLoader.load}, synchronously: read and decode one config file
|
|
72
|
-
* through the consumer-supplied operations. Throws `TsconfigParseError` or a
|
|
73
|
-
* `PlatformError` — the async pipeline's exact typed failures.
|
|
74
|
-
*
|
|
75
|
-
* @public
|
|
76
|
-
*/
|
|
77
70
|
const load = (configPath, options) => runWith(options, TsconfigLoader.load(configPath));
|
|
78
|
-
/**
|
|
79
|
-
* {@link TsconfigLoader.resolve}, synchronously: the full load -\> extends -\>
|
|
80
|
-
* merge -\> `${configDir}` pipeline through the consumer-supplied operations.
|
|
81
|
-
* Throws `TsconfigParseError`, `TsconfigExtendsError` or a `PlatformError` —
|
|
82
|
-
* the async pipeline's exact typed failures.
|
|
83
|
-
*
|
|
84
|
-
* @public
|
|
85
|
-
*/
|
|
86
71
|
const resolve = (configPath, options) => runWith(options, TsconfigLoader.resolve(configPath));
|
|
87
|
-
/**
|
|
88
|
-
* {@link TsconfigLoader.compilerOptions}, synchronously: resolve the full
|
|
89
|
-
* `extends` chain and project out the merged `compilerOptions`. Throws the
|
|
90
|
-
* same typed failures as {@link TsconfigLoaderSync.resolve}.
|
|
91
|
-
*
|
|
92
|
-
* @public
|
|
93
|
-
*/
|
|
94
72
|
const compilerOptions = (configPath, options) => resolve(configPath, options).compilerOptions;
|
|
95
73
|
/**
|
|
96
74
|
* The synchronous tsconfig.json loader facade: the {@link TsconfigLoader}
|
|
@@ -121,10 +99,29 @@ const compilerOptions = (configPath, options) => resolve(configPath, options).co
|
|
|
121
99
|
*
|
|
122
100
|
* @public
|
|
123
101
|
*/
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
102
|
+
var TsconfigLoaderSync = class {
|
|
103
|
+
constructor() {}
|
|
104
|
+
/**
|
|
105
|
+
* {@link TsconfigLoader.load}, synchronously: read and decode one config
|
|
106
|
+
* file through the consumer-supplied operations. Throws
|
|
107
|
+
* `TsconfigParseError` or a `PlatformError` — the async pipeline's exact
|
|
108
|
+
* typed failures.
|
|
109
|
+
*/
|
|
110
|
+
static load = load;
|
|
111
|
+
/**
|
|
112
|
+
* {@link TsconfigLoader.resolve}, synchronously: the full load -\>
|
|
113
|
+
* extends -\> merge -\> `${configDir}` pipeline through the
|
|
114
|
+
* consumer-supplied operations. Throws `TsconfigParseError`,
|
|
115
|
+
* `TsconfigExtendsError` or a `PlatformError` — the async pipeline's exact
|
|
116
|
+
* typed failures.
|
|
117
|
+
*/
|
|
118
|
+
static resolve = resolve;
|
|
119
|
+
/**
|
|
120
|
+
* {@link TsconfigLoader.compilerOptions}, synchronously: resolve the full
|
|
121
|
+
* `extends` chain and project out the merged `compilerOptions`. Throws
|
|
122
|
+
* the same typed failures as {@link TsconfigLoaderSync.resolve}.
|
|
123
|
+
*/
|
|
124
|
+
static compilerOptions = compilerOptions;
|
|
128
125
|
};
|
|
129
126
|
|
|
130
127
|
//#endregion
|
package/index.d.ts
CHANGED
|
@@ -550,17 +550,43 @@ interface ResolvedTsconfig {
|
|
|
550
550
|
}
|
|
551
551
|
/**
|
|
552
552
|
* The pure extends-merge engine: parse-time path absolutization
|
|
553
|
-
* ({@link (ResolvedTsconfig:
|
|
554
|
-
* ({@link (ResolvedTsconfig:
|
|
555
|
-
* phase ({@link (ResolvedTsconfig:
|
|
553
|
+
* ({@link (ResolvedTsconfig:class).absolutize}), the per-field merge fold
|
|
554
|
+
* ({@link (ResolvedTsconfig:class).merge}), and the `${configDir}` final
|
|
555
|
+
* phase ({@link (ResolvedTsconfig:class).substituteConfigDir}).
|
|
556
556
|
*
|
|
557
557
|
* @public
|
|
558
558
|
*/
|
|
559
|
-
declare
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
559
|
+
declare class ResolvedTsconfig {
|
|
560
|
+
private constructor();
|
|
561
|
+
/**
|
|
562
|
+
* Absolutize a config's path-typed options (E5) against its own
|
|
563
|
+
* `configDir`, using the injected `join` (`Path.Path.resolve` at the call
|
|
564
|
+
* site — so an already-absolute value is preserved). `${configDir}`-prefixed
|
|
565
|
+
* values are exempt (resolved later, in
|
|
566
|
+
* {@link (ResolvedTsconfig:class).substituteConfigDir}), and `paths`
|
|
567
|
+
* VALUES stay verbatim. Only `compilerOptions` path surfaces are touched;
|
|
568
|
+
* `files`/`include`/`exclude` are re-rooted at merge time instead (E4).
|
|
569
|
+
*/
|
|
570
|
+
static readonly absolutize: (doc: TsconfigJson.Type, configDir: string, join: (a: string, b: string) => string) => TsconfigJson.Type;
|
|
571
|
+
/**
|
|
572
|
+
* Fold one more-derived config onto the accumulated base (E4), derived
|
|
573
|
+
* winning. The loader (Task 8) applies this across the resolution chain,
|
|
574
|
+
* own config last. `derivedPath` is the derived config's absolute
|
|
575
|
+
* normalized path, from which the re-rooting frame and `pathsBase` are
|
|
576
|
+
* computed.
|
|
577
|
+
*/
|
|
578
|
+
static readonly merge: (base: ResolvedTsconfig, derived: TsconfigJson.Type, derivedPath: string) => ResolvedTsconfig;
|
|
579
|
+
/**
|
|
580
|
+
* The E5 final phase: replace a leading `${configDir}` token
|
|
581
|
+
* (case-insensitive, leading position only) with `finalDir` — the
|
|
582
|
+
* top-level extending config's directory — across every eligible
|
|
583
|
+
* surface: compilerOptions path options, `paths` values,
|
|
584
|
+
* `files`/`include`/`exclude`, and `watchOptions`'
|
|
585
|
+
* `excludeDirectories`/`excludeFiles`. Every other field is left
|
|
586
|
+
* untouched.
|
|
587
|
+
*/
|
|
588
|
+
static readonly substituteConfigDir: (resolved: ResolvedTsconfig, finalDir: string) => ResolvedTsconfig;
|
|
589
|
+
}
|
|
564
590
|
//#endregion
|
|
565
591
|
//#region src/PortableTsconfig.d.ts
|
|
566
592
|
/**
|
|
@@ -578,15 +604,62 @@ interface PortableTsconfig {
|
|
|
578
604
|
readonly compilerOptions: Record<string, unknown>;
|
|
579
605
|
}
|
|
580
606
|
/**
|
|
581
|
-
*
|
|
607
|
+
* Options for {@link (PortableTsconfig:class).make}.
|
|
608
|
+
*
|
|
609
|
+
* @public
|
|
610
|
+
*/
|
|
611
|
+
interface PortableTsconfigOptions {
|
|
612
|
+
/**
|
|
613
|
+
* Carry `types` (an array of `@types` package NAMES) onto the portable
|
|
614
|
+
* shape when the source declares it. Defaults to `false`.
|
|
615
|
+
*
|
|
616
|
+
* Opt in when the consuming environment can resolve those packages — it
|
|
617
|
+
* materializes `@types` into its virtual filesystem, or type-checks against
|
|
618
|
+
* a real `node_modules`. Leaving it off keeps the permissive default, where
|
|
619
|
+
* TypeScript auto-includes whatever `@types` the environment happens to
|
|
620
|
+
* have and never errors on a missing one.
|
|
621
|
+
*
|
|
622
|
+
* `typeRoots` is NOT carried under this flag: it names filesystem
|
|
623
|
+
* directories, which are machine-specific and config-location-dependent,
|
|
624
|
+
* so they are never portable.
|
|
625
|
+
*/
|
|
626
|
+
readonly includeTypes?: boolean;
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* The portable-tsconfig filter: {@link (PortableTsconfig:class).make}
|
|
582
630
|
* narrows a resolved or bare compiler-options object to the allow-listed,
|
|
583
631
|
* machine-independent subset described on {@link (PortableTsconfig:interface)}.
|
|
584
632
|
*
|
|
585
633
|
* @public
|
|
586
634
|
*/
|
|
587
|
-
declare
|
|
588
|
-
|
|
589
|
-
|
|
635
|
+
declare class PortableTsconfig {
|
|
636
|
+
private constructor();
|
|
637
|
+
/**
|
|
638
|
+
* Project a {@link (ResolvedTsconfig:interface)} or a bare
|
|
639
|
+
* `CompilerOptions.Type` down to a {@link (PortableTsconfig:interface)}:
|
|
640
|
+
* copy only the allow-listed type-semantics options, force
|
|
641
|
+
* `composite: false` and `noEmit: true` regardless of what the source
|
|
642
|
+
* declared, and stamp `$schema`. Every other key — including every
|
|
643
|
+
* unknown passthrough key the source preserved for forward tolerance —
|
|
644
|
+
* is dropped; this is an allow-list, not a deny-list, so an option this
|
|
645
|
+
* package does not yet classify never leaks onto the portable shape by
|
|
646
|
+
* accident.
|
|
647
|
+
*
|
|
648
|
+
* `types` is the one deliberate exception, and it is opt-in rather than
|
|
649
|
+
* unclassified: it is portable (package names, not paths) but carrying it
|
|
650
|
+
* makes TypeScript demand those packages be resolvable, which a virtual
|
|
651
|
+
* environment with no `node_modules` cannot satisfy. Pass
|
|
652
|
+
* {@link PortableTsconfigOptions.includeTypes} when the consumer
|
|
653
|
+
* materializes `@types`; leave it off for the permissive default. Related
|
|
654
|
+
* `typeRoots` is never carried — machine-specific,
|
|
655
|
+
* config-location-dependent directories.
|
|
656
|
+
*
|
|
657
|
+
* @param input - The resolved config, or a bare compiler-options bag.
|
|
658
|
+
* @param options - Opt-ins for options that are portable but
|
|
659
|
+
* resolution-dependent. Omitted means the strict, always-safe subset.
|
|
660
|
+
*/
|
|
661
|
+
static readonly make: (input: ResolvedTsconfig | CompilerOptions.Type, options?: PortableTsconfigOptions) => PortableTsconfig;
|
|
662
|
+
}
|
|
590
663
|
//#endregion
|
|
591
664
|
//#region src/TsconfigDiscovery.d.ts
|
|
592
665
|
/**
|
|
@@ -605,9 +678,18 @@ interface FindNearestOptions {
|
|
|
605
678
|
*
|
|
606
679
|
* @public
|
|
607
680
|
*/
|
|
608
|
-
declare
|
|
609
|
-
|
|
610
|
-
|
|
681
|
+
declare class TsconfigDiscovery {
|
|
682
|
+
private constructor();
|
|
683
|
+
/**
|
|
684
|
+
* Find the nearest `tsconfig.json` (or `options.filename`) at or above
|
|
685
|
+
* `start`, ascending toward the filesystem root. Absence — nowhere on the
|
|
686
|
+
* chain, or every candidate unreadable — is `Option.none()`, never an
|
|
687
|
+
* error; discovery is best-effort per `Walker.findUpward`'s absorption
|
|
688
|
+
* posture, and a permission-denied probe on one directory does not hide a
|
|
689
|
+
* config file above it.
|
|
690
|
+
*/
|
|
691
|
+
static readonly findNearest: (start: string, options?: FindNearestOptions) => Effect.Effect<Option.Option<string>, never, FileSystem.FileSystem | Path.Path>;
|
|
692
|
+
}
|
|
611
693
|
//#endregion
|
|
612
694
|
//#region src/TsconfigLoader.d.ts
|
|
613
695
|
declare const TsconfigExtendsError_base: Schema.Class<TsconfigExtendsError, Schema.TaggedStruct<"TsconfigExtendsError", {
|
|
@@ -642,8 +724,16 @@ declare class TsconfigExtendsError extends TsconfigExtendsError_base {
|
|
|
642
724
|
*
|
|
643
725
|
* @public
|
|
644
726
|
*/
|
|
645
|
-
declare
|
|
646
|
-
|
|
727
|
+
declare class TsconfigLoader {
|
|
728
|
+
private constructor();
|
|
729
|
+
/**
|
|
730
|
+
* Read one config file and decode it through {@link TsconfigJsonFromString}.
|
|
731
|
+
* A decode failure is wrapped in a {@link TsconfigParseError} carrying the
|
|
732
|
+
* file's absolute path; a `PlatformError` from the read flows through
|
|
733
|
+
* untranslated. No `extends` resolution — {@link TsconfigLoader.resolve}
|
|
734
|
+
* drives that.
|
|
735
|
+
*/
|
|
736
|
+
static readonly load: (configPath: string) => Effect.Effect<{
|
|
647
737
|
readonly [x: string]: unknown;
|
|
648
738
|
readonly compilerOptions?: {
|
|
649
739
|
readonly [x: string]: unknown;
|
|
@@ -790,8 +880,26 @@ declare const TsconfigLoader: {
|
|
|
790
880
|
readonly compileOnSave?: boolean | undefined;
|
|
791
881
|
readonly $schema?: string | undefined;
|
|
792
882
|
}, PlatformError.PlatformError | TsconfigParseError, FileSystem.FileSystem | Path.Path>;
|
|
793
|
-
|
|
794
|
-
|
|
883
|
+
/**
|
|
884
|
+
* Resolve a tsconfig.json and its full `extends` chain into a
|
|
885
|
+
* {@link (ResolvedTsconfig:interface)}: load and decode each config,
|
|
886
|
+
* absolutize its path options (E5), resolve `extends` depth-first with
|
|
887
|
+
* per-branch cycle and depth guards (E1-E3, E6), fold the chain
|
|
888
|
+
* own-config-last (E4), then substitute a leading `${configDir}` once
|
|
889
|
+
* against the top config's directory (E5 final phase). `configPath` +
|
|
890
|
+
* `extendedPaths` come back base-most first, own config last. Every
|
|
891
|
+
* failure is a typed error — `TsconfigParseError` (a malformed file,
|
|
892
|
+
* carrying that file's path), `TsconfigExtendsError` (a broken chain), or
|
|
893
|
+
* a `PlatformError` from IO — never a defect.
|
|
894
|
+
*/
|
|
895
|
+
static readonly resolve: (configPath: string) => Effect.Effect<ResolvedTsconfig, PlatformError.PlatformError | TsconfigExtendsError | TsconfigParseError, FileSystem.FileSystem | Path.Path>;
|
|
896
|
+
/**
|
|
897
|
+
* Resolve a tsconfig.json's full `extends` chain and project out the
|
|
898
|
+
* merged `compilerOptions` — a thin projection of
|
|
899
|
+
* {@link TsconfigLoader.resolve} for the common "just give me the
|
|
900
|
+
* effective options" query. Same pipeline, same typed failures.
|
|
901
|
+
*/
|
|
902
|
+
static readonly compilerOptions: (configPath: string) => Effect.Effect<{
|
|
795
903
|
readonly [x: string]: unknown;
|
|
796
904
|
readonly target?: "es2015" | "es2016" | "es2017" | "es2018" | "es2019" | "es2020" | "es2021" | "es2022" | "es2023" | "es2024" | "es2025" | "es5" | "es6" | "esnext" | undefined;
|
|
797
905
|
readonly module?: "amd" | "commonjs" | "es2015" | "es2020" | "es2022" | "es6" | "esnext" | "node16" | "node18" | "node20" | "nodenext" | "none" | "preserve" | "system" | "umd" | undefined;
|
|
@@ -909,7 +1017,7 @@ declare const TsconfigLoader: {
|
|
|
909
1017
|
}[] | undefined;
|
|
910
1018
|
readonly maxNodeModuleJsDepth?: number | undefined;
|
|
911
1019
|
}, PlatformError.PlatformError | TsconfigExtendsError | TsconfigParseError, FileSystem.FileSystem | Path.Path>;
|
|
912
|
-
}
|
|
1020
|
+
}
|
|
913
1021
|
//#endregion
|
|
914
1022
|
//#region src/TsconfigLoaderSync.d.ts
|
|
915
1023
|
/**
|
|
@@ -1012,11 +1120,30 @@ interface TsconfigLoaderSyncOptions {
|
|
|
1012
1120
|
*
|
|
1013
1121
|
* @public
|
|
1014
1122
|
*/
|
|
1015
|
-
declare
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1123
|
+
declare class TsconfigLoaderSync {
|
|
1124
|
+
private constructor();
|
|
1125
|
+
/**
|
|
1126
|
+
* {@link TsconfigLoader.load}, synchronously: read and decode one config
|
|
1127
|
+
* file through the consumer-supplied operations. Throws
|
|
1128
|
+
* `TsconfigParseError` or a `PlatformError` — the async pipeline's exact
|
|
1129
|
+
* typed failures.
|
|
1130
|
+
*/
|
|
1131
|
+
static readonly load: (configPath: string, options: TsconfigLoaderSyncOptions) => TsconfigJson.Type;
|
|
1132
|
+
/**
|
|
1133
|
+
* {@link TsconfigLoader.resolve}, synchronously: the full load -\>
|
|
1134
|
+
* extends -\> merge -\> `${configDir}` pipeline through the
|
|
1135
|
+
* consumer-supplied operations. Throws `TsconfigParseError`,
|
|
1136
|
+
* `TsconfigExtendsError` or a `PlatformError` — the async pipeline's exact
|
|
1137
|
+
* typed failures.
|
|
1138
|
+
*/
|
|
1139
|
+
static readonly resolve: (configPath: string, options: TsconfigLoaderSyncOptions) => ResolvedTsconfig;
|
|
1140
|
+
/**
|
|
1141
|
+
* {@link TsconfigLoader.compilerOptions}, synchronously: resolve the full
|
|
1142
|
+
* `extends` chain and project out the merged `compilerOptions`. Throws
|
|
1143
|
+
* the same typed failures as {@link TsconfigLoaderSync.resolve}.
|
|
1144
|
+
*/
|
|
1145
|
+
static readonly compilerOptions: (configPath: string, options: TsconfigLoaderSyncOptions) => CompilerOptions.Type;
|
|
1146
|
+
}
|
|
1020
1147
|
//#endregion
|
|
1021
1148
|
//#region src/TsEnumCodec.d.ts
|
|
1022
1149
|
/**
|
|
@@ -1068,7 +1195,7 @@ type ProgrammaticCompilerOptionsValue = string | number | boolean | (string | nu
|
|
|
1068
1195
|
readonly circular?: boolean;
|
|
1069
1196
|
}[] | null | undefined;
|
|
1070
1197
|
/**
|
|
1071
|
-
* The shape {@link
|
|
1198
|
+
* The shape {@link TsEnumCodec.encodeCompilerOptions} returns: the
|
|
1072
1199
|
* numeric-enum-encoded `compilerOptions` a virtual-TS environment and the
|
|
1073
1200
|
* TypeScript compiler API consume programmatically.
|
|
1074
1201
|
*
|
|
@@ -1115,13 +1242,62 @@ interface ProgrammaticCompilerOptions {
|
|
|
1115
1242
|
*
|
|
1116
1243
|
* @public
|
|
1117
1244
|
*/
|
|
1118
|
-
declare
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1245
|
+
declare class TsEnumCodec {
|
|
1246
|
+
private constructor();
|
|
1247
|
+
/**
|
|
1248
|
+
* Encodes a family's canonical (or alias) string spelling to its numeric
|
|
1249
|
+
* form. `Option.none()` for a string with no table entry — never guessed.
|
|
1250
|
+
*/
|
|
1251
|
+
static readonly encode: (family: EnumFamily, value: string) => Option.Option<number>;
|
|
1252
|
+
/**
|
|
1253
|
+
* Decodes a family's numeric value to its canonical string spelling.
|
|
1254
|
+
* `Option.none()` for a numeric value with no table entry (a future TS
|
|
1255
|
+
* enum member) — never guessed.
|
|
1256
|
+
*/
|
|
1257
|
+
static readonly decode: (family: EnumFamily, value: number) => Option.Option<string>;
|
|
1258
|
+
/**
|
|
1259
|
+
* Normalizes any spelling of a `lib` reference — the plain short name
|
|
1260
|
+
* (`esnext`), the on-disk file name (`lib.esnext.d.ts`), or an absolute
|
|
1261
|
+
* path to one (`/…/typescript/lib/lib.dom.iterable.d.ts`) — to the
|
|
1262
|
+
* canonical lowercase short name (`esnext`, `dom.iterable`). Strips a
|
|
1263
|
+
* leading directory, the `lib.` prefix and the `.d.ts` suffix; idempotent
|
|
1264
|
+
* on an already-short name.
|
|
1265
|
+
*/
|
|
1266
|
+
static readonly normalizeLibReference: (lib: string) => string;
|
|
1267
|
+
/**
|
|
1268
|
+
* Encodes a decoded `compilerOptions` object into the
|
|
1269
|
+
* numeric-enum-shaped {@link ProgrammaticCompilerOptions} form
|
|
1270
|
+
* `ts.CompilerOptions` (and `@typescript/vfs`'s `TsEnvironment`) expect:
|
|
1271
|
+
* every R1.6 enum family becomes its numeric value, and `lib` entries
|
|
1272
|
+
* become the file-name form (`lib.esnext.d.ts`) — see the module banner
|
|
1273
|
+
* for the evidence. Every other key (booleans, strings, arrays, unknown
|
|
1274
|
+
* passthrough keys) is copied through untouched.
|
|
1275
|
+
*
|
|
1276
|
+
* @remarks
|
|
1277
|
+
* The return carries this package's single narrowing from the codec's
|
|
1278
|
+
* internal `Record<string, unknown>` (whose values include the schema's
|
|
1279
|
+
* `unknown` passthrough and its `readonly` arrays) to
|
|
1280
|
+
* {@link ProgrammaticCompilerOptions} — see that type's docs for why the
|
|
1281
|
+
* package owns this one assertion instead of leaving every consumer to
|
|
1282
|
+
* cast. Runtime behavior is unchanged; only the declared return type
|
|
1283
|
+
* narrows.
|
|
1284
|
+
*/
|
|
1285
|
+
static readonly encodeCompilerOptions: (options: CompilerOptions.Type) => ProgrammaticCompilerOptions;
|
|
1286
|
+
/**
|
|
1287
|
+
* Decodes a numeric-enum-shaped `compilerOptions` object (as produced by
|
|
1288
|
+
* {@link TsEnumCodec.encodeCompilerOptions} or read off a live
|
|
1289
|
+
* `ts.CompilerOptions`) back into the string-enum shape this package's
|
|
1290
|
+
* schemas use: every R1.6 enum family becomes its canonical string, and
|
|
1291
|
+
* `lib` entries become the short form. A numeric value with no table
|
|
1292
|
+
* entry — a future TS enum member — is left as-is (passthrough, never an
|
|
1293
|
+
* error) — which is why the return type stays the wider
|
|
1294
|
+
* `Record<string, unknown>` rather than
|
|
1295
|
+
* {@link (CompilerOptions:namespace).Type}: an unmappable passthrough
|
|
1296
|
+
* value would violate that narrower type's contract. Every other key is
|
|
1297
|
+
* copied through untouched.
|
|
1298
|
+
*/
|
|
1299
|
+
static readonly decodeCompilerOptions: (numeric: Readonly<Record<string, unknown>>) => Record<string, unknown>;
|
|
1300
|
+
}
|
|
1125
1301
|
//#endregion
|
|
1126
|
-
export { CompilerOptions, type EnumFamily, FallbackPolling, type FindNearestOptions, Jsx, JsxConfig, Lib, Module, ModuleDetection, ModuleResolution, NewLine, PortableTsconfig, type ProgrammaticCompilerOptions, type ProgrammaticCompilerOptionsValue, Reference, ResolvedTsconfig, type SyncFileSystem, type SyncPath, Target, TsEnumCodec, TsconfigDiscovery, TsconfigExtendsError, TsconfigJson, TsconfigJsonFromString, TsconfigLoader, TsconfigLoaderSync, type TsconfigLoaderSyncOptions, TsconfigParseError, TypeAcquisition, WatchDirectory, WatchFile, WatchOptions };
|
|
1302
|
+
export { CompilerOptions, type EnumFamily, FallbackPolling, type FindNearestOptions, Jsx, JsxConfig, Lib, Module, ModuleDetection, ModuleResolution, NewLine, PortableTsconfig, type PortableTsconfigOptions, type ProgrammaticCompilerOptions, type ProgrammaticCompilerOptionsValue, Reference, ResolvedTsconfig, type SyncFileSystem, type SyncPath, Target, TsEnumCodec, TsconfigDiscovery, TsconfigExtendsError, TsconfigJson, TsconfigJsonFromString, TsconfigLoader, TsconfigLoaderSync, type TsconfigLoaderSyncOptions, TsconfigParseError, TypeAcquisition, WatchDirectory, WatchFile, WatchOptions };
|
|
1127
1303
|
//# sourceMappingURL=index.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effected/tsconfig-json",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Composable tsconfig.json handling for Effect: schemas, extends-chain resolution, and config discovery.",
|
|
6
6
|
"keywords": [
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"@effected/jsonc": "~0.5.1",
|
|
43
|
-
"@effected/walker": "~0.3.
|
|
43
|
+
"@effected/walker": "~0.3.3",
|
|
44
44
|
"effect": "4.0.0-beta.101"
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|