@effected/tsconfig-json 0.2.6 → 0.3.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/README.md CHANGED
@@ -112,7 +112,7 @@ const compilerOptions = TsconfigLoaderSync.compilerOptions("./tsconfig.json", op
112
112
  - `TsconfigLoaderSync` — the synchronous facade for sync-only hosts: `load`, `resolve` and `compilerOptions` over consumer-supplied `{ fileSystem, path }` operations, running the same pipeline and throwing the same typed errors.
113
113
  - `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.
114
114
  - `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.
115
- - `TsEnumCodec` — the string↔numeric enum tables as plain data with zero `typescript` imports. `encodeCompilerOptions` produces the numeric shape `ts.CompilerOptions` expects, with `lib` entries in the file-name form the compiler resolves verbatim; `decodeCompilerOptions` reverses it.
115
+ - `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.
116
116
  - `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.
117
117
  - `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()`.
118
118
  - 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.
package/TsEnumCodec.js CHANGED
@@ -135,11 +135,19 @@ const COMPILER_OPTION_ENUM_KEYS = [
135
135
  ];
136
136
  /**
137
137
  * Encodes a decoded `compilerOptions` object into the numeric-enum-shaped
138
- * form `ts.CompilerOptions` (and `@typescript/vfs`'s `TsEnvironment`) expect:
139
- * every R1.6 enum family becomes its numeric value, and `lib` entries become
140
- * the file-name form (`lib.esnext.d.ts`) see the module banner for the
141
- * evidence. Every other key (booleans, strings, arrays, unknown passthrough
142
- * keys) is copied through untouched.
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.
143
151
  *
144
152
  * @public
145
153
  */
package/index.d.ts CHANGED
@@ -1026,6 +1026,88 @@ declare const TsconfigLoaderSync: {
1026
1026
  * @public
1027
1027
  */
1028
1028
  type EnumFamily = "target" | "module" | "moduleResolution" | "jsx" | "newLine" | "moduleDetection" | "watchFile" | "watchDirectory" | "fallbackPolling";
1029
+ /**
1030
+ * A single value a programmatic `compilerOptions` entry can hold — a
1031
+ * structural transcription of TypeScript's own `CompilerOptionsValue`,
1032
+ * transcribed (not imported) to honor this package's zero-`typescript` rule.
1033
+ *
1034
+ * Transcribed verbatim from `typescript@6.0.3`'s
1035
+ * `node_modules/typescript/lib/typescript.d.ts` (the version `@typescript/vfs@1.6.4`,
1036
+ * the encode target's consumer, pins):
1037
+ *
1038
+ * ```ts
1039
+ * type CompilerOptionsValue = string | number | boolean | (string | number)[]
1040
+ * | string[] | MapLike<string[]> | PluginImport[] | ProjectReference[]
1041
+ * | null | undefined;
1042
+ * interface MapLike<T> { [index: string]: T }
1043
+ * interface PluginImport { name: string }
1044
+ * interface ProjectReference { path: string; originalPath?: string; prepend?: boolean; circular?: boolean }
1045
+ * ```
1046
+ *
1047
+ * The one member deliberately omitted is `TsConfigSourceFile` (present only in
1048
+ * the interface's index signature, not `CompilerOptionsValue` itself): it is a
1049
+ * full parsed-AST node the compiler synthesizes, never a value reachable from
1050
+ * JSON, so it cannot appear in options this codec builds. Omitting it keeps the
1051
+ * union a strict structural subset of the compiler's own index-signature value
1052
+ * type, which is what assignability to `ts.CompilerOptions` requires. Arrays
1053
+ * are intentionally mutable (`string[]`, not `readonly string[]`): TypeScript's
1054
+ * mutable array members are not assignable from a `readonly` array, and the one
1055
+ * narrowing below reconciles this with the codec's actual `readonly`-array
1056
+ * outputs.
1057
+ *
1058
+ * @public
1059
+ */
1060
+ type ProgrammaticCompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | {
1061
+ readonly [index: string]: string[];
1062
+ } | {
1063
+ readonly name: string;
1064
+ }[] | {
1065
+ readonly path: string;
1066
+ readonly originalPath?: string;
1067
+ readonly prepend?: boolean;
1068
+ readonly circular?: boolean;
1069
+ }[] | null | undefined;
1070
+ /**
1071
+ * The shape {@link (TsEnumCodec:variable).encodeCompilerOptions} returns: the
1072
+ * numeric-enum-encoded `compilerOptions` a virtual-TS environment and the
1073
+ * TypeScript compiler API consume programmatically.
1074
+ *
1075
+ * It is deliberately shaped to be assignable to TypeScript's `ts.CompilerOptions`
1076
+ * without naming it (the zero-`typescript` rule), so a consumer handing the
1077
+ * result to `@typescript/vfs`'s `createVirtualTypeScriptEnvironment` /
1078
+ * `createDefaultMapFromNodeModules` or to `ts.createProgram` no longer ends the
1079
+ * pipeline with a cast. Verified assignable to the real `ts.CompilerOptions`
1080
+ * (`typescript@6.0.3`, `@typescript/vfs@1.6.4`) by a compile-time test
1081
+ * (`__test__/TsEnumCodec.assignability.test.ts`).
1082
+ *
1083
+ * What it honestly **claims**: the six enum-family keys read back as `number`
1084
+ * (they are always encoded — a decoded `CompilerOptions.Type` constrains each
1085
+ * to a spelling the codec's tables cover, so the runtime "unknown string passes
1086
+ * through unencoded" branch is unreachable for a well-typed input); `lib` reads
1087
+ * back as `string[]` (the file-name form); every other value is one of the
1088
+ * structural forms `ts.CompilerOptions` accepts.
1089
+ *
1090
+ * What it does **not** prove: that an arbitrary passthrough value carried
1091
+ * through from JSONC (the schema preserves unknown keys as `unknown`) fits
1092
+ * {@link ProgrammaticCompilerOptionsValue}. Neither does `ts.CompilerOptions`:
1093
+ * its own index signature makes the identical unproven claim, and any consumer
1094
+ * feeding parsed tsconfig to `ts.createProgram` relies on it. The single
1095
+ * narrowing that bridges the codec's `unknown`/`readonly` outputs to this type
1096
+ * lives once, at `encodeCompilerOptions`'s return (below), so the assertion is
1097
+ * owned here rather than re-made at every call site.
1098
+ *
1099
+ * @public
1100
+ */
1101
+ interface ProgrammaticCompilerOptions {
1102
+ readonly [option: string]: ProgrammaticCompilerOptionsValue;
1103
+ readonly target?: number;
1104
+ readonly module?: number;
1105
+ readonly moduleResolution?: number;
1106
+ readonly jsx?: number;
1107
+ readonly newLine?: number;
1108
+ readonly moduleDetection?: number;
1109
+ readonly lib?: string[];
1110
+ }
1029
1111
  /**
1030
1112
  * The string↔numeric enum codec for `compilerOptions` / `watchOptions`
1031
1113
  * families, per R1.6. Plain data: every lookup is a synchronous map read
@@ -1037,9 +1119,9 @@ declare const TsEnumCodec: {
1037
1119
  readonly encode: (family: EnumFamily, value: string) => Option.Option<number>;
1038
1120
  readonly decode: (family: EnumFamily, value: number) => Option.Option<string>;
1039
1121
  readonly normalizeLibReference: (lib: string) => string;
1040
- readonly encodeCompilerOptions: (options: CompilerOptions.Type) => Record<string, unknown>;
1122
+ readonly encodeCompilerOptions: (options: CompilerOptions.Type) => ProgrammaticCompilerOptions;
1041
1123
  readonly decodeCompilerOptions: (numeric: Readonly<Record<string, unknown>>) => Record<string, unknown>;
1042
1124
  };
1043
1125
  //#endregion
1044
- export { CompilerOptions, type EnumFamily, FallbackPolling, type FindNearestOptions, Jsx, JsxConfig, Lib, Module, ModuleDetection, ModuleResolution, NewLine, PortableTsconfig, Reference, ResolvedTsconfig, type SyncFileSystem, type SyncPath, Target, TsEnumCodec, TsconfigDiscovery, TsconfigExtendsError, TsconfigJson, TsconfigJsonFromString, TsconfigLoader, TsconfigLoaderSync, type TsconfigLoaderSyncOptions, TsconfigParseError, TypeAcquisition, WatchDirectory, WatchFile, WatchOptions };
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 };
1045
1127
  //# sourceMappingURL=index.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effected/tsconfig-json",
3
- "version": "0.2.6",
3
+ "version": "0.3.0",
4
4
  "private": false,
5
5
  "description": "Composable tsconfig.json handling for Effect: schemas, extends-chain resolution, and config discovery.",
6
6
  "keywords": [
@@ -39,8 +39,8 @@
39
39
  "./package.json": "./package.json"
40
40
  },
41
41
  "peerDependencies": {
42
- "@effected/jsonc": "0.5.0",
43
- "@effected/walker": "0.3.0",
42
+ "@effected/jsonc": "~0.5.0",
43
+ "@effected/walker": "~0.3.1",
44
44
  "effect": "4.0.0-beta.99"
45
45
  },
46
46
  "engines": {