@effected/tsconfig-json 0.3.3 → 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.
@@ -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,13 +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
- const make = (input) => {
105
+ const make = (input, options) => {
105
106
  const source = isResolvedTsconfig(input) ? input.compilerOptions : input;
106
107
  const compilerOptions = {};
107
108
  for (const key of PRESERVED_OPTIONS) {
108
109
  const value = source[key];
109
110
  if (value !== void 0) compilerOptions[key] = value;
110
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
+ }
111
116
  compilerOptions.composite = false;
112
117
  compilerOptions.noEmit = true;
113
118
  return {
@@ -134,6 +139,19 @@ var PortableTsconfig = class {
134
139
  * is dropped; this is an allow-list, not a deny-list, so an option this
135
140
  * package does not yet classify never leaks onto the portable shape by
136
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.
137
155
  */
138
156
  static make = make;
139
157
  };
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/index.d.ts CHANGED
@@ -603,6 +603,28 @@ interface PortableTsconfig {
603
603
  /** The allow-listed, forced-flag-applied compiler options. */
604
604
  readonly compilerOptions: Record<string, unknown>;
605
605
  }
606
+ /**
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
+ }
606
628
  /**
607
629
  * The portable-tsconfig filter: {@link (PortableTsconfig:class).make}
608
630
  * narrows a resolved or bare compiler-options object to the allow-listed,
@@ -622,8 +644,21 @@ declare class PortableTsconfig {
622
644
  * is dropped; this is an allow-list, not a deny-list, so an option this
623
645
  * package does not yet classify never leaks onto the portable shape by
624
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.
625
660
  */
626
- static readonly make: (input: ResolvedTsconfig | CompilerOptions.Type) => PortableTsconfig;
661
+ static readonly make: (input: ResolvedTsconfig | CompilerOptions.Type, options?: PortableTsconfigOptions) => PortableTsconfig;
627
662
  }
628
663
  //#endregion
629
664
  //#region src/TsconfigDiscovery.d.ts
@@ -1264,5 +1299,5 @@ declare class TsEnumCodec {
1264
1299
  static readonly decodeCompilerOptions: (numeric: Readonly<Record<string, unknown>>) => Record<string, unknown>;
1265
1300
  }
1266
1301
  //#endregion
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 };
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 };
1268
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.3",
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": [