@effected/tsconfig-json 0.3.1 → 0.3.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.
- package/PortableTsconfig.js +16 -12
- package/README.md +41 -0
- 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 +174 -33
- package/package.json +2 -2
package/PortableTsconfig.js
CHANGED
|
@@ -101,16 +101,6 @@ const PRESERVED_OPTIONS = [
|
|
|
101
101
|
* is filtered, which is the safe outcome.)
|
|
102
102
|
*/
|
|
103
103
|
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
104
|
const make = (input) => {
|
|
115
105
|
const source = isResolvedTsconfig(input) ? input.compilerOptions : input;
|
|
116
106
|
const compilerOptions = {};
|
|
@@ -126,13 +116,27 @@ const make = (input) => {
|
|
|
126
116
|
};
|
|
127
117
|
};
|
|
128
118
|
/**
|
|
129
|
-
* The portable-tsconfig filter: {@link (PortableTsconfig:
|
|
119
|
+
* The portable-tsconfig filter: {@link (PortableTsconfig:class).make}
|
|
130
120
|
* narrows a resolved or bare compiler-options object to the allow-listed,
|
|
131
121
|
* machine-independent subset described on {@link (PortableTsconfig:interface)}.
|
|
132
122
|
*
|
|
133
123
|
* @public
|
|
134
124
|
*/
|
|
135
|
-
|
|
125
|
+
var PortableTsconfig = class {
|
|
126
|
+
constructor() {}
|
|
127
|
+
/**
|
|
128
|
+
* Project a {@link (ResolvedTsconfig:interface)} or a bare
|
|
129
|
+
* `CompilerOptions.Type` down to a {@link (PortableTsconfig:interface)}:
|
|
130
|
+
* copy only the allow-listed type-semantics options, force
|
|
131
|
+
* `composite: false` and `noEmit: true` regardless of what the source
|
|
132
|
+
* declared, and stamp `$schema`. Every other key — including every
|
|
133
|
+
* unknown passthrough key the source preserved for forward tolerance —
|
|
134
|
+
* is dropped; this is an allow-list, not a deny-list, so an option this
|
|
135
|
+
* package does not yet classify never leaks onto the portable shape by
|
|
136
|
+
* accident.
|
|
137
|
+
*/
|
|
138
|
+
static make = make;
|
|
139
|
+
};
|
|
136
140
|
|
|
137
141
|
//#endregion
|
|
138
142
|
export { PortableTsconfig };
|
package/README.md
CHANGED
|
@@ -104,6 +104,47 @@ const compilerOptions = TsconfigLoaderSync.compilerOptions("./tsconfig.json", op
|
|
|
104
104
|
|
|
105
105
|
`load` and `resolve` have the same synchronous forms. Failures are the async pipeline's own typed errors thrown as themselves — `TsconfigParseError`, `TsconfigExtendsError` or a `PlatformError` wrapping whatever your `readFile` threw — never a fiber-failure wrapper.
|
|
106
106
|
|
|
107
|
+
## TypeScript 7 and the classic compiler API
|
|
108
|
+
|
|
109
|
+
TypeScript 7's native `tsc` ships a version-only stub as its `.` export — there is no JS compiler API behind it. A package that drives the typechecker as a library (`@typescript/vfs`, the language service, the Program API) can neither type against nor runtime-load a TypeScript 7 install, and the obvious fix of pinning the dev `typescript` back to 6 forfeits the native `tsc` and leaves toolchain peers on `^7` unmet. The recipe that keeps both starts here, because this package is what removes the compile-time half of the dependency.
|
|
110
|
+
|
|
111
|
+
1. Type against the tsconfig JSON form, not the compiler. Public option types use `CompilerOptions.Type` — `{ target: "es2022" }`, strings all the way down — so nothing in `src` or the tests imports `typescript`, not even as a type. The dev `typescript` stays on 7, native `tsc --noEmit` still runs the typecheck, and the toolchain's `^7` peer stays satisfied.
|
|
112
|
+
2. Convert at a single runtime seam. `TsEnumCodec.encodeCompilerOptions` maps the string form to the numeric enums a real compiler expects and returns `ProgrammaticCompilerOptions`, the shape a `ts.CompilerOptions`-typed API takes without a cast. Only that one call site knows a compiler exists.
|
|
113
|
+
3. Alias a classic install for the test runtime, where the JS API is genuinely needed: a dev-only `"typescript-classic": "npm:typescript@^6.0.3"` plus a vitest `resolve.alias` mapping `typescript` to it. The consumer-facing peer stays an optional `^6` — runtime-only, for callers of the compiler-touching module.
|
|
114
|
+
4. Pass `tsLibDirectory` explicitly when you drive `@typescript/vfs`. It locates `lib.*.d.ts` through `require.resolve("typescript")`, which under this setup resolves the TypeScript 7 install, and that install has no lib directory: the map comes back **empty**, silently, with no error to follow. Derive the directory from the module you actually loaded.
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"devDependencies": {
|
|
119
|
+
"typescript-classic": "npm:typescript@^6.0.3"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { defineConfig } from "vitest/config";
|
|
126
|
+
|
|
127
|
+
export default defineConfig({
|
|
128
|
+
resolve: { alias: { typescript: "typescript-classic" } },
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
import { dirname } from "node:path";
|
|
134
|
+
import { TsEnumCodec } from "@effected/tsconfig-json";
|
|
135
|
+
import { createDefaultMapFromNodeModules } from "@typescript/vfs";
|
|
136
|
+
import ts from "typescript";
|
|
137
|
+
|
|
138
|
+
const fsMap = createDefaultMapFromNodeModules(
|
|
139
|
+
TsEnumCodec.encodeCompilerOptions({ target: "es2023", lib: ["esnext"] }),
|
|
140
|
+
ts,
|
|
141
|
+
dirname(ts.sys.getExecutingFilePath()),
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
console.log(fsMap.size);
|
|
145
|
+
// the lib files the loaded compiler ships; drop the third argument and this is 0
|
|
146
|
+
```
|
|
147
|
+
|
|
107
148
|
## Features
|
|
108
149
|
|
|
109
150
|
- `TsconfigJson` / `TsconfigJsonFromString` — the document schema and its JSONC string codec. Comments and trailing commas are legal in every parse; there is no JSON-strict path.
|
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,27 @@ interface PortableTsconfig {
|
|
|
578
604
|
readonly compilerOptions: Record<string, unknown>;
|
|
579
605
|
}
|
|
580
606
|
/**
|
|
581
|
-
* The portable-tsconfig filter: {@link (PortableTsconfig:
|
|
607
|
+
* The portable-tsconfig filter: {@link (PortableTsconfig:class).make}
|
|
582
608
|
* narrows a resolved or bare compiler-options object to the allow-listed,
|
|
583
609
|
* machine-independent subset described on {@link (PortableTsconfig:interface)}.
|
|
584
610
|
*
|
|
585
611
|
* @public
|
|
586
612
|
*/
|
|
587
|
-
declare
|
|
588
|
-
|
|
589
|
-
|
|
613
|
+
declare class PortableTsconfig {
|
|
614
|
+
private constructor();
|
|
615
|
+
/**
|
|
616
|
+
* Project a {@link (ResolvedTsconfig:interface)} or a bare
|
|
617
|
+
* `CompilerOptions.Type` down to a {@link (PortableTsconfig:interface)}:
|
|
618
|
+
* copy only the allow-listed type-semantics options, force
|
|
619
|
+
* `composite: false` and `noEmit: true` regardless of what the source
|
|
620
|
+
* declared, and stamp `$schema`. Every other key — including every
|
|
621
|
+
* unknown passthrough key the source preserved for forward tolerance —
|
|
622
|
+
* is dropped; this is an allow-list, not a deny-list, so an option this
|
|
623
|
+
* package does not yet classify never leaks onto the portable shape by
|
|
624
|
+
* accident.
|
|
625
|
+
*/
|
|
626
|
+
static readonly make: (input: ResolvedTsconfig | CompilerOptions.Type) => PortableTsconfig;
|
|
627
|
+
}
|
|
590
628
|
//#endregion
|
|
591
629
|
//#region src/TsconfigDiscovery.d.ts
|
|
592
630
|
/**
|
|
@@ -605,9 +643,18 @@ interface FindNearestOptions {
|
|
|
605
643
|
*
|
|
606
644
|
* @public
|
|
607
645
|
*/
|
|
608
|
-
declare
|
|
609
|
-
|
|
610
|
-
|
|
646
|
+
declare class TsconfigDiscovery {
|
|
647
|
+
private constructor();
|
|
648
|
+
/**
|
|
649
|
+
* Find the nearest `tsconfig.json` (or `options.filename`) at or above
|
|
650
|
+
* `start`, ascending toward the filesystem root. Absence — nowhere on the
|
|
651
|
+
* chain, or every candidate unreadable — is `Option.none()`, never an
|
|
652
|
+
* error; discovery is best-effort per `Walker.findUpward`'s absorption
|
|
653
|
+
* posture, and a permission-denied probe on one directory does not hide a
|
|
654
|
+
* config file above it.
|
|
655
|
+
*/
|
|
656
|
+
static readonly findNearest: (start: string, options?: FindNearestOptions) => Effect.Effect<Option.Option<string>, never, FileSystem.FileSystem | Path.Path>;
|
|
657
|
+
}
|
|
611
658
|
//#endregion
|
|
612
659
|
//#region src/TsconfigLoader.d.ts
|
|
613
660
|
declare const TsconfigExtendsError_base: Schema.Class<TsconfigExtendsError, Schema.TaggedStruct<"TsconfigExtendsError", {
|
|
@@ -642,8 +689,16 @@ declare class TsconfigExtendsError extends TsconfigExtendsError_base {
|
|
|
642
689
|
*
|
|
643
690
|
* @public
|
|
644
691
|
*/
|
|
645
|
-
declare
|
|
646
|
-
|
|
692
|
+
declare class TsconfigLoader {
|
|
693
|
+
private constructor();
|
|
694
|
+
/**
|
|
695
|
+
* Read one config file and decode it through {@link TsconfigJsonFromString}.
|
|
696
|
+
* A decode failure is wrapped in a {@link TsconfigParseError} carrying the
|
|
697
|
+
* file's absolute path; a `PlatformError` from the read flows through
|
|
698
|
+
* untranslated. No `extends` resolution — {@link TsconfigLoader.resolve}
|
|
699
|
+
* drives that.
|
|
700
|
+
*/
|
|
701
|
+
static readonly load: (configPath: string) => Effect.Effect<{
|
|
647
702
|
readonly [x: string]: unknown;
|
|
648
703
|
readonly compilerOptions?: {
|
|
649
704
|
readonly [x: string]: unknown;
|
|
@@ -790,8 +845,26 @@ declare const TsconfigLoader: {
|
|
|
790
845
|
readonly compileOnSave?: boolean | undefined;
|
|
791
846
|
readonly $schema?: string | undefined;
|
|
792
847
|
}, PlatformError.PlatformError | TsconfigParseError, FileSystem.FileSystem | Path.Path>;
|
|
793
|
-
|
|
794
|
-
|
|
848
|
+
/**
|
|
849
|
+
* Resolve a tsconfig.json and its full `extends` chain into a
|
|
850
|
+
* {@link (ResolvedTsconfig:interface)}: load and decode each config,
|
|
851
|
+
* absolutize its path options (E5), resolve `extends` depth-first with
|
|
852
|
+
* per-branch cycle and depth guards (E1-E3, E6), fold the chain
|
|
853
|
+
* own-config-last (E4), then substitute a leading `${configDir}` once
|
|
854
|
+
* against the top config's directory (E5 final phase). `configPath` +
|
|
855
|
+
* `extendedPaths` come back base-most first, own config last. Every
|
|
856
|
+
* failure is a typed error — `TsconfigParseError` (a malformed file,
|
|
857
|
+
* carrying that file's path), `TsconfigExtendsError` (a broken chain), or
|
|
858
|
+
* a `PlatformError` from IO — never a defect.
|
|
859
|
+
*/
|
|
860
|
+
static readonly resolve: (configPath: string) => Effect.Effect<ResolvedTsconfig, PlatformError.PlatformError | TsconfigExtendsError | TsconfigParseError, FileSystem.FileSystem | Path.Path>;
|
|
861
|
+
/**
|
|
862
|
+
* Resolve a tsconfig.json's full `extends` chain and project out the
|
|
863
|
+
* merged `compilerOptions` — a thin projection of
|
|
864
|
+
* {@link TsconfigLoader.resolve} for the common "just give me the
|
|
865
|
+
* effective options" query. Same pipeline, same typed failures.
|
|
866
|
+
*/
|
|
867
|
+
static readonly compilerOptions: (configPath: string) => Effect.Effect<{
|
|
795
868
|
readonly [x: string]: unknown;
|
|
796
869
|
readonly target?: "es2015" | "es2016" | "es2017" | "es2018" | "es2019" | "es2020" | "es2021" | "es2022" | "es2023" | "es2024" | "es2025" | "es5" | "es6" | "esnext" | undefined;
|
|
797
870
|
readonly module?: "amd" | "commonjs" | "es2015" | "es2020" | "es2022" | "es6" | "esnext" | "node16" | "node18" | "node20" | "nodenext" | "none" | "preserve" | "system" | "umd" | undefined;
|
|
@@ -909,7 +982,7 @@ declare const TsconfigLoader: {
|
|
|
909
982
|
}[] | undefined;
|
|
910
983
|
readonly maxNodeModuleJsDepth?: number | undefined;
|
|
911
984
|
}, PlatformError.PlatformError | TsconfigExtendsError | TsconfigParseError, FileSystem.FileSystem | Path.Path>;
|
|
912
|
-
}
|
|
985
|
+
}
|
|
913
986
|
//#endregion
|
|
914
987
|
//#region src/TsconfigLoaderSync.d.ts
|
|
915
988
|
/**
|
|
@@ -1012,11 +1085,30 @@ interface TsconfigLoaderSyncOptions {
|
|
|
1012
1085
|
*
|
|
1013
1086
|
* @public
|
|
1014
1087
|
*/
|
|
1015
|
-
declare
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1088
|
+
declare class TsconfigLoaderSync {
|
|
1089
|
+
private constructor();
|
|
1090
|
+
/**
|
|
1091
|
+
* {@link TsconfigLoader.load}, synchronously: read and decode one config
|
|
1092
|
+
* file through the consumer-supplied operations. Throws
|
|
1093
|
+
* `TsconfigParseError` or a `PlatformError` — the async pipeline's exact
|
|
1094
|
+
* typed failures.
|
|
1095
|
+
*/
|
|
1096
|
+
static readonly load: (configPath: string, options: TsconfigLoaderSyncOptions) => TsconfigJson.Type;
|
|
1097
|
+
/**
|
|
1098
|
+
* {@link TsconfigLoader.resolve}, synchronously: the full load -\>
|
|
1099
|
+
* extends -\> merge -\> `${configDir}` pipeline through the
|
|
1100
|
+
* consumer-supplied operations. Throws `TsconfigParseError`,
|
|
1101
|
+
* `TsconfigExtendsError` or a `PlatformError` — the async pipeline's exact
|
|
1102
|
+
* typed failures.
|
|
1103
|
+
*/
|
|
1104
|
+
static readonly resolve: (configPath: string, options: TsconfigLoaderSyncOptions) => ResolvedTsconfig;
|
|
1105
|
+
/**
|
|
1106
|
+
* {@link TsconfigLoader.compilerOptions}, synchronously: resolve the full
|
|
1107
|
+
* `extends` chain and project out the merged `compilerOptions`. Throws
|
|
1108
|
+
* the same typed failures as {@link TsconfigLoaderSync.resolve}.
|
|
1109
|
+
*/
|
|
1110
|
+
static readonly compilerOptions: (configPath: string, options: TsconfigLoaderSyncOptions) => CompilerOptions.Type;
|
|
1111
|
+
}
|
|
1020
1112
|
//#endregion
|
|
1021
1113
|
//#region src/TsEnumCodec.d.ts
|
|
1022
1114
|
/**
|
|
@@ -1068,7 +1160,7 @@ type ProgrammaticCompilerOptionsValue = string | number | boolean | (string | nu
|
|
|
1068
1160
|
readonly circular?: boolean;
|
|
1069
1161
|
}[] | null | undefined;
|
|
1070
1162
|
/**
|
|
1071
|
-
* The shape {@link
|
|
1163
|
+
* The shape {@link TsEnumCodec.encodeCompilerOptions} returns: the
|
|
1072
1164
|
* numeric-enum-encoded `compilerOptions` a virtual-TS environment and the
|
|
1073
1165
|
* TypeScript compiler API consume programmatically.
|
|
1074
1166
|
*
|
|
@@ -1115,13 +1207,62 @@ interface ProgrammaticCompilerOptions {
|
|
|
1115
1207
|
*
|
|
1116
1208
|
* @public
|
|
1117
1209
|
*/
|
|
1118
|
-
declare
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1210
|
+
declare class TsEnumCodec {
|
|
1211
|
+
private constructor();
|
|
1212
|
+
/**
|
|
1213
|
+
* Encodes a family's canonical (or alias) string spelling to its numeric
|
|
1214
|
+
* form. `Option.none()` for a string with no table entry — never guessed.
|
|
1215
|
+
*/
|
|
1216
|
+
static readonly encode: (family: EnumFamily, value: string) => Option.Option<number>;
|
|
1217
|
+
/**
|
|
1218
|
+
* Decodes a family's numeric value to its canonical string spelling.
|
|
1219
|
+
* `Option.none()` for a numeric value with no table entry (a future TS
|
|
1220
|
+
* enum member) — never guessed.
|
|
1221
|
+
*/
|
|
1222
|
+
static readonly decode: (family: EnumFamily, value: number) => Option.Option<string>;
|
|
1223
|
+
/**
|
|
1224
|
+
* Normalizes any spelling of a `lib` reference — the plain short name
|
|
1225
|
+
* (`esnext`), the on-disk file name (`lib.esnext.d.ts`), or an absolute
|
|
1226
|
+
* path to one (`/…/typescript/lib/lib.dom.iterable.d.ts`) — to the
|
|
1227
|
+
* canonical lowercase short name (`esnext`, `dom.iterable`). Strips a
|
|
1228
|
+
* leading directory, the `lib.` prefix and the `.d.ts` suffix; idempotent
|
|
1229
|
+
* on an already-short name.
|
|
1230
|
+
*/
|
|
1231
|
+
static readonly normalizeLibReference: (lib: string) => string;
|
|
1232
|
+
/**
|
|
1233
|
+
* Encodes a decoded `compilerOptions` object into the
|
|
1234
|
+
* numeric-enum-shaped {@link ProgrammaticCompilerOptions} form
|
|
1235
|
+
* `ts.CompilerOptions` (and `@typescript/vfs`'s `TsEnvironment`) expect:
|
|
1236
|
+
* every R1.6 enum family becomes its numeric value, and `lib` entries
|
|
1237
|
+
* become the file-name form (`lib.esnext.d.ts`) — see the module banner
|
|
1238
|
+
* for the evidence. Every other key (booleans, strings, arrays, unknown
|
|
1239
|
+
* passthrough keys) is copied through untouched.
|
|
1240
|
+
*
|
|
1241
|
+
* @remarks
|
|
1242
|
+
* The return carries this package's single narrowing from the codec's
|
|
1243
|
+
* internal `Record<string, unknown>` (whose values include the schema's
|
|
1244
|
+
* `unknown` passthrough and its `readonly` arrays) to
|
|
1245
|
+
* {@link ProgrammaticCompilerOptions} — see that type's docs for why the
|
|
1246
|
+
* package owns this one assertion instead of leaving every consumer to
|
|
1247
|
+
* cast. Runtime behavior is unchanged; only the declared return type
|
|
1248
|
+
* narrows.
|
|
1249
|
+
*/
|
|
1250
|
+
static readonly encodeCompilerOptions: (options: CompilerOptions.Type) => ProgrammaticCompilerOptions;
|
|
1251
|
+
/**
|
|
1252
|
+
* Decodes a numeric-enum-shaped `compilerOptions` object (as produced by
|
|
1253
|
+
* {@link TsEnumCodec.encodeCompilerOptions} or read off a live
|
|
1254
|
+
* `ts.CompilerOptions`) back into the string-enum shape this package's
|
|
1255
|
+
* schemas use: every R1.6 enum family becomes its canonical string, and
|
|
1256
|
+
* `lib` entries become the short form. A numeric value with no table
|
|
1257
|
+
* entry — a future TS enum member — is left as-is (passthrough, never an
|
|
1258
|
+
* error) — which is why the return type stays the wider
|
|
1259
|
+
* `Record<string, unknown>` rather than
|
|
1260
|
+
* {@link (CompilerOptions:namespace).Type}: an unmappable passthrough
|
|
1261
|
+
* value would violate that narrower type's contract. Every other key is
|
|
1262
|
+
* copied through untouched.
|
|
1263
|
+
*/
|
|
1264
|
+
static readonly decodeCompilerOptions: (numeric: Readonly<Record<string, unknown>>) => Record<string, unknown>;
|
|
1265
|
+
}
|
|
1125
1266
|
//#endregion
|
|
1126
1267
|
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 };
|
|
1127
1268
|
//# 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.
|
|
3
|
+
"version": "0.3.3",
|
|
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": {
|