merge-tsconfigs 0.1.1 → 0.1.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/README.md CHANGED
@@ -2,15 +2,17 @@
2
2
 
3
3
  ![Typed with TypeScript](https://flat.badgen.net/badge/icon/Typed?icon=typescript&label&labelColor=blue&color=555555)
4
4
  [![npm version](https://badge.fury.io/js/merge-tsconfigs.svg)](https://badge.fury.io/js/merge-tsconfigs)
5
+ [![unpkg](https://img.shields.io/badge/unpkg-blue.svg)](https://unpkg.com/merge-tsconfigs@0.1.1/dist/index.js)
6
+ [![skypack](https://img.shields.io/badge/skypack-blueviolet.svg)](https://cdn.skypack.dev/merge-tsconfigs?min)
5
7
  ![ci](https://github.com/yowainwright/merge-tsconfigs/actions/workflows/ci.yml/badge.svg)
6
8
  [![Github](https://badgen.net/badge/icon/github?icon=github&label&color=grey)](https://github.com/yowainwright/merge-tsconfigs)
7
9
  ![Twitter](https://img.shields.io/twitter/url?url=https%3A%2F%2Fgithub.com%2Fyowainwright%2Fmerge-tsconfigs)
8
10
 
9
- _Merge-tsconfigs_ is a CLI and node tool for merging tsconfig files into the exact tsconfig file you want. 💪
11
+ **WIP:** _Merge-tsconfigs_ is a CLI and node tool for merging tsconfig files into the exact tsconfig file you want. 💪
10
12
 
11
13
  ---
12
14
 
13
- **[Why do I want this?](#why-do-i-want-this)** | **[Example](#for-example)** | **[How do I use this?](#how-do-i-use-this)** | **[CLI API](#cli-api)** | **[Node API](#node-api)** | **[Install](#how-do-i-start-using-this)**
15
+ **[Why do I want this?](#why-do-i-want-this)** | **[Example](#for-example)** | **[How do I use this?](#how-do-i-use-this)** | **[CLI API](#cli-api)** | **[Node API](#node-api)** | **[How do I start using this?](#how-do-i-start-using-this)**
14
16
 
15
17
  ---
16
18
 
@@ -82,7 +84,8 @@ Options:
82
84
  -e, --exclude [exclude...] files to exclude, matches a glob or array pattern
83
85
  -h, --help display help for command
84
86
  ```
85
- \*compiler options are not added above for readability (but they can be leveraged). To view all cli options, run `merge-tsconfigs --help`!
87
+
88
+ \*`compilerOptions` are not added above for readability (but they can be leveraged). To view all cli options, run `merge-tsconfigs --help`! `compilerOptions.paths` aren't implemented.
86
89
 
87
90
  #### Recipes
88
91
 
@@ -90,34 +93,84 @@ Merge tsconfig files into a single tsconfig
90
93
 
91
94
  ```sh
92
95
  merge-tsconfigs ./tsconfig.json ./tsconfig.build.json
93
- # => ./tsconfig.merged.json
96
+ # ./tsconfig.json + ./tsconfig.build.json => ./tsconfig.merged.json
94
97
  ```
95
98
 
96
99
  Merge tsconfig files a specific tsconfig file
97
100
 
98
101
  ```sh
99
102
  merge-tsconfigs ./tsconfig.json ./tsconfig.build.json --out ./tsconfig.out.json
100
- # => ./tsconfig.out.json
103
+ # ./tsconfig.json + ./tsconfig.build.json => ./tsconfig.out.json
101
104
  ```
102
105
 
103
106
  Merge tsconfig files with unique `include` and `exclude` strings
104
107
 
105
108
  ```sh
106
109
  merge-tsconfigs ./tsconfig.json ./tsconfig.build.json --include 'src/**.ts' --exclude 'test/**.ts'
107
- # => ./tsconfig.merged.json
110
+ # ./tsconfig.json + ./tsconfig.build.json => ./tsconfig.merged.json
111
+ ```
112
+
113
+ ```ts
114
+ // tsconfig.merged.json
115
+ {
116
+ "compilerOptions": {
117
+ // ...options
118
+ },
119
+ "include": ["src/**.ts"],
120
+ "exclude": ["test/**.ts", "config/*.ts"]
121
+ }
108
122
  ```
109
123
 
110
124
  Merge tsconfig files with unique `include` and `exclude` or by using arrays
111
125
 
112
126
  ```sh
113
127
  merge-tsconfigs ./tsconfig.json ./tsconfig.build.json --include 'src/**.ts' --exclude 'test/**.ts' 'config/*.ts'
114
- # => ./tsconfig.merged.json
128
+ # ./tsconfig.json + ./tsconfig.build.json => ./tsconfig.merged.json
129
+ ```
130
+
131
+ ```ts
132
+ // tsconfig.merged.json
133
+ {
134
+ "compilerOptions": {
135
+ // ...options
136
+ },
137
+ "include": ["src/**.ts"],
138
+ "exclude": ["test/**.ts", "config/*.ts"]
139
+ }
115
140
  ```
116
141
 
117
142
  Sprinkle in some `compilerOptions` to the mix
118
143
 
119
144
  ```sh
120
145
  merge-tsconfigs ./tsconfig.json ./tsconfig.build.json --out ./tsconfig.out.json --allowJs true --noEmit true
146
+ # ./tsconfig.json + ./tsconfig.build.json => ./tsconfig.out.json
147
+ ```
148
+
149
+ ```ts
150
+ // tsconfig.out.json
151
+ {
152
+ "compilerOptions": {
153
+ "allowJS": true,
154
+ "noEmit": true,
155
+ }
156
+ }
157
+ ```
158
+
159
+ Delete a compiler option
160
+
161
+ ```sh
162
+ merge-tsconfigs ./tsconfig.json ./tsconfig.build.json --allowJS --noEmit 'delete'
163
+ # ./tsconfig.json + ./tsconfig.build.json => ./tsconfig.merged.json
164
+ ```
165
+
166
+ ```ts
167
+ // tsconfig.merged.json
168
+ {
169
+ "compilerOptions": {
170
+ "allowJS": true,
171
+ // "noEmit": true, // deleted
172
+ }
173
+ }
121
174
  ```
122
175
 
123
176
  ---
@@ -152,7 +205,7 @@ Merge tsconfig files into a single tsconfig
152
205
  const config = mergeTsconfigs({
153
206
  files: ['./tsconfig.json', './tsconfig.build.json'],
154
207
  });
155
- // => config = { ... }
208
+ // ./tsconfig.json + ./tsconfig.build.json => ./tsconfig.merged.json
156
209
  ```
157
210
 
158
211
  Merge tsconfig files into a custom output file
@@ -162,7 +215,7 @@ const config = mergeTsconfigs({
162
215
  files: ['./tsconfig.json', './tsconfig.build.json'],
163
216
  out: './new-dir/tsconfig.out.json',
164
217
  });
165
- // => config = { ... }
218
+ // ./tsconfig.json + ./tsconfig.build.json => ./tsconfig.out.json
166
219
  ```
167
220
 
168
221
  ---
@@ -175,7 +228,14 @@ Install merge-tsconfigs with your preferred package manager.
175
228
  npm install merge-tsconfigs --save-dev
176
229
  ```
177
230
 
178
- \*unpkg and skypack support coming very soon! 🚀
231
+ \*_Untested_: In, Deno, Snowpack, or other options, you can import merge-tsconfigs directly into your project.
232
+ ```ts
233
+ import mergeTsconfigs from 'npm:merge-tsconfigs';
234
+ // or
235
+ import mergeTsconfigs from "https://cdn.skypack.dev/merge-tsconfigs@latest";
236
+ // or
237
+ import mergeTsconfigs from "https://unpkg.com/merge-tsconfigs@latest/dist/index.js";
238
+ ```
179
239
 
180
240
  ---
181
241
 
package/dist/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,10 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
18
24
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
25
 
20
26
  // src/index.ts
@@ -23,9 +29,11 @@ __export(src_exports, {
23
29
  default: () => src_default,
24
30
  logger: () => logger,
25
31
  mergeConfigContent: () => mergeConfigContent,
32
+ mergeConfigObjects: () => mergeConfigObjects,
26
33
  mergeTsConfigs: () => mergeTsConfigs,
27
34
  resolveJSON: () => resolveJSON,
28
35
  script: () => script,
36
+ updateCompilerOptions: () => updateCompilerOptions,
29
37
  writeTsconfig: () => writeTsconfig
30
38
  });
31
39
  module.exports = __toCommonJS(src_exports);
@@ -33,6 +41,7 @@ module.exports = __toCommonJS(src_exports);
33
41
  // src/scripts.ts
34
42
  var import_fs = require("fs");
35
43
  var import_path = require("path");
44
+ var import_json5 = __toESM(require("json5"), 1);
36
45
  var logger = ({ isDebugging = false, emoji = `\u{1F6E3}\uFE0F`, gap = ` => `, name = "merge-tsconfigs" }) => (type) => (section) => (message) => (err) => {
37
46
  const debugMsg = isDebugging ? "debugging:" : "";
38
47
  const sectionMsg = section.length ? `${section}:` : "";
@@ -60,7 +69,7 @@ var logger = ({ isDebugging = false, emoji = `\u{1F6E3}\uFE0F`, gap = ` => `, na
60
69
  };
61
70
  function resolveJSON(path, debug = false) {
62
71
  try {
63
- const json = JSON.parse((0, import_fs.readFileSync)(path, "utf8"));
72
+ const json = import_json5.default.parse((0, import_fs.readFileSync)(path, "utf8"));
64
73
  return json;
65
74
  } catch (err) {
66
75
  console.log({ err });
@@ -69,6 +78,26 @@ function resolveJSON(path, debug = false) {
69
78
  return {};
70
79
  }
71
80
  }
81
+ var mergeConfigObjects = (tsconfig1, tsconfig2) => ({
82
+ ...tsconfig1,
83
+ ...tsconfig2,
84
+ compilerOptions: {
85
+ ...tsconfig1?.compilerOptions,
86
+ ...tsconfig2?.compilerOptions
87
+ },
88
+ ...tsconfig1?.exclude || tsconfig2?.exclude ? {
89
+ exclude: [
90
+ ...tsconfig1?.exclude || [],
91
+ ...tsconfig2?.exclude || []
92
+ ]
93
+ } : {},
94
+ ...tsconfig1?.include || tsconfig2?.include ? {
95
+ include: [
96
+ ...tsconfig1?.include || [],
97
+ ...tsconfig2?.include || []
98
+ ]
99
+ } : {}
100
+ });
72
101
  var mergeConfigContent = (tsconfigs, cwd, debug = false) => tsconfigs.reduce((acc = {}, tsconfig) => {
73
102
  const path = `${cwd}/${tsconfig}`;
74
103
  let tsconfigJSON = resolveJSON(path, debug);
@@ -80,44 +109,45 @@ var mergeConfigContent = (tsconfigs, cwd, debug = false) => tsconfigs.reduce((ac
80
109
  logger({ isDebugging: debug })("error")("mergeConfigContent")("Parent tsconfig:merge-tsconfigs only handles extending from a parent, consider extending tsconfigs less.")(parentTsconfig);
81
110
  }
82
111
  const { extends: _, ...tsconfigWithoutExtends } = tsconfigJSON;
83
- tsconfigJSON = {
84
- ...parentTsconfig,
85
- ...tsconfigWithoutExtends,
86
- compilerOptions: {
87
- ...parentTsconfig?.compilerOptions,
88
- ...tsconfigWithoutExtends?.compilerOptions
89
- }
90
- };
112
+ tsconfigJSON = mergeConfigObjects(parentTsconfig, tsconfigWithoutExtends);
91
113
  }
92
114
  if (!tsconfigJSON) {
93
115
  if (debug)
94
116
  logger({ isDebugging: debug })("error")("mergeConfigContent")("There was an error:")(tsconfigJSON);
95
117
  return acc;
96
118
  }
97
- return {
98
- ...acc,
99
- ...tsconfigJSON,
100
- compilerOptions: {
101
- ...acc?.compilerOptions,
102
- ...tsconfigJSON?.compilerOptions
103
- }
104
- };
119
+ return mergeConfigObjects(acc, tsconfigJSON);
105
120
  }, {});
106
121
  var writeTsconfig = (tsconfig, cwd, out, isTesting) => {
107
122
  if (isTesting)
108
123
  return tsconfig;
109
- const path = out.length ? out : `${cwd}/tsconfig.merged.json`;
124
+ const path = `${cwd}/${out}`;
110
125
  (0, import_fs.mkdirSync)((0, import_path.dirname)(path), { recursive: true });
111
126
  (0, import_fs.writeFileSync)(path, JSON.stringify(tsconfig, null, 2));
112
127
  return tsconfig;
113
128
  };
129
+ var updateCompilerOptions = (compilerOptions2 = {}, currentCompilerOptions) => {
130
+ const compilerOptionKeys = compilerOptions2 ? Object.keys(compilerOptions2) : [];
131
+ const hasCompilerOptions = compilerOptionKeys.length > 0;
132
+ if (!hasCompilerOptions)
133
+ return {};
134
+ return compilerOptionKeys.reduce((acc = {}, key) => {
135
+ const updatedOptions = { ...acc, ...currentCompilerOptions };
136
+ const value = compilerOptions2?.[key];
137
+ if (updatedOptions?.[key] === "delete") {
138
+ delete updatedOptions[key];
139
+ return updatedOptions || {};
140
+ }
141
+ return { ...updatedOptions, [key]: value };
142
+ }, {});
143
+ };
114
144
  var mergeTsConfigs = ({
115
145
  tsconfigs = [],
116
146
  exclude,
117
147
  include,
118
148
  compilerOptions: compilerOptions2,
119
149
  debug = false,
120
- out = "",
150
+ out = "tsconfig.merged.json",
121
151
  isTesting = false
122
152
  }) => {
123
153
  if (tsconfigs.length === 0) {
@@ -129,14 +159,14 @@ var mergeTsConfigs = ({
129
159
  const updatedTsconfig = mergeConfigContent(tsconfigs, cwd, debug);
130
160
  if (debug)
131
161
  logger({ isDebugging: debug })("debug")("mergeTsConfig")("Updated tsconfig:")(updatedTsconfig);
162
+ const updatedCompilerOptions = updateCompilerOptions(compilerOptions2, updatedTsconfig?.compilerOptions || {});
163
+ const updatedExclude = exclude ? { exclude: [...updatedTsconfig?.exclude || [], ...exclude] } : {};
164
+ const updatedInclude = include ? { include: [...updatedTsconfig.include || [], ...include] } : {};
132
165
  const tsconfig = {
133
166
  ...updatedTsconfig,
134
- ...exclude ? [...updatedTsconfig?.exclude || [], ...exclude] : updatedTsconfig?.exclude,
135
- ...include ? [...updatedTsconfig.include || [], ...include] : updatedTsconfig?.include,
136
- compilerOptions: {
137
- ...updatedTsconfig?.compilerOptions,
138
- ...compilerOptions2
139
- }
167
+ ...updatedExclude,
168
+ ...updatedInclude,
169
+ ...Object.keys(updatedCompilerOptions).length > 0 ? { compilerOptions: updatedCompilerOptions } : {}
140
170
  };
141
171
  return writeTsconfig(tsconfig, cwd, out, isTesting);
142
172
  };
@@ -189,14 +219,22 @@ var compilerOptions = {
189
219
  };
190
220
 
191
221
  // src/program.ts
192
- async function action(files, options = {}) {
193
- const { debug = false, isTesting = false, isTestingCLI = false, ...compilerOptions2 } = options;
194
- if (isTestingCLI) {
195
- console.info({ files, options });
196
- return;
197
- }
222
+ function action(files, options = {}) {
198
223
  try {
199
- await script({ debug, tsconfigs: files, compilerOptions: compilerOptions2 });
224
+ const {
225
+ debug = false,
226
+ exclude,
227
+ include,
228
+ isTesting = false,
229
+ isTestingCLI = false,
230
+ out,
231
+ ...compilerOptions2
232
+ } = options;
233
+ if (isTestingCLI) {
234
+ console.info({ files, options });
235
+ return;
236
+ }
237
+ script({ debug, exclude, include, isTesting, out, tsconfigs: files, compilerOptions: compilerOptions2 });
200
238
  } catch (err) {
201
239
  logger({ isDebugging: options.debug })("error")("action")("There was an error:")(err);
202
240
  }
@@ -211,6 +249,8 @@ Object.keys(compilerOptions).map((name) => ({ name, value: compilerOptions[name]
211
249
  import_commander.program.option(`--${name} <${value}>`, `tsconfig.compilerOptions.${name}`);
212
250
  } else if (value === "array") {
213
251
  import_commander.program.option(`--${name} [${value}...]`, `tsconfig.compilerOptions.${name}`);
252
+ } else if (value === "object") {
253
+ import_commander.program.option(`--${name} <${value}>`, `tsconfig.compilerOptions.${name}`);
214
254
  }
215
255
  });
216
256
  import_commander.program.action(action).parse(process.argv);
@@ -221,8 +261,10 @@ var src_default = scripts_default;
221
261
  0 && (module.exports = {
222
262
  logger,
223
263
  mergeConfigContent,
264
+ mergeConfigObjects,
224
265
  mergeTsConfigs,
225
266
  resolveJSON,
226
267
  script,
268
+ updateCompilerOptions,
227
269
  writeTsconfig
228
270
  });
package/dist/index.d.ts CHANGED
@@ -1,8 +1,14 @@
1
+ import * as type_fest_source_partial_deep from 'type-fest/source/partial-deep';
2
+ import * as typescript from 'typescript';
1
3
  import { CompilerOptions } from 'typescript';
2
4
  import { PartialDeep } from 'type-fest';
3
5
 
6
+ interface CompilerOptionOverrides {
7
+ [key: string]: string | boolean | string[] | undefined;
8
+ }
9
+ type PartialCompilerOptions = PartialDeep<CompilerOptions | CompilerOptionOverrides>;
4
10
  interface ConfigOptions {
5
- compilerOptions?: PartialDeep<CompilerOptions>;
11
+ compilerOptions?: PartialCompilerOptions;
6
12
  debug?: boolean;
7
13
  out?: string;
8
14
  tsconfigs?: string[];
@@ -25,9 +31,113 @@ interface TsConfig {
25
31
 
26
32
  declare const logger: ({ isDebugging, emoji, gap, name }: LoggerParams) => (type: string) => (section: string) => (message: string) => (err: unknown) => void;
27
33
  declare function resolveJSON(path: string, debug?: boolean): TsConfig;
34
+ declare const mergeConfigObjects: (tsconfig1: TsConfig, tsconfig2: TsConfig) => {
35
+ include?: string[] | undefined;
36
+ exclude?: string[] | undefined;
37
+ compilerOptions: {
38
+ [x: string]: string | number | boolean | string[] | (string | number)[] | typescript.PluginImport[] | typescript.ProjectReference[] | type_fest_source_partial_deep.PartialObjectDeep<typescript.MapLike<string[]>, {}> | type_fest_source_partial_deep.PartialObjectDeep<typescript.TsConfigSourceFile, {}> | null | undefined;
39
+ allowJs?: boolean | undefined;
40
+ allowSyntheticDefaultImports?: boolean | undefined;
41
+ allowUmdGlobalAccess?: boolean | undefined;
42
+ allowUnreachableCode?: boolean | undefined;
43
+ allowUnusedLabels?: boolean | undefined;
44
+ alwaysStrict?: boolean | undefined;
45
+ baseUrl?: string | undefined;
46
+ charset?: string | undefined;
47
+ checkJs?: boolean | undefined;
48
+ declaration?: boolean | undefined;
49
+ declarationMap?: boolean | undefined;
50
+ emitDeclarationOnly?: boolean | undefined;
51
+ declarationDir?: string | undefined;
52
+ disableSizeLimit?: boolean | undefined;
53
+ disableSourceOfProjectReferenceRedirect?: boolean | undefined;
54
+ disableSolutionSearching?: boolean | undefined;
55
+ disableReferencedProjectLoad?: boolean | undefined;
56
+ downlevelIteration?: boolean | undefined;
57
+ emitBOM?: boolean | undefined;
58
+ emitDecoratorMetadata?: boolean | undefined;
59
+ exactOptionalPropertyTypes?: boolean | undefined;
60
+ experimentalDecorators?: boolean | undefined;
61
+ forceConsistentCasingInFileNames?: boolean | undefined;
62
+ importHelpers?: boolean | undefined;
63
+ importsNotUsedAsValues?: typescript.ImportsNotUsedAsValues | undefined;
64
+ inlineSourceMap?: boolean | undefined;
65
+ inlineSources?: boolean | undefined;
66
+ isolatedModules?: boolean | undefined;
67
+ jsx?: typescript.JsxEmit | undefined;
68
+ keyofStringsOnly?: boolean | undefined;
69
+ lib?: string[] | undefined;
70
+ locale?: string | undefined;
71
+ mapRoot?: string | undefined;
72
+ maxNodeModuleJsDepth?: number | undefined;
73
+ module?: typescript.ModuleKind | undefined;
74
+ moduleResolution?: typescript.ModuleResolutionKind | undefined;
75
+ moduleSuffixes?: string[] | undefined;
76
+ moduleDetection?: typescript.ModuleDetectionKind | undefined;
77
+ newLine?: typescript.NewLineKind | undefined;
78
+ noEmit?: boolean | undefined;
79
+ noEmitHelpers?: boolean | undefined;
80
+ noEmitOnError?: boolean | undefined;
81
+ noErrorTruncation?: boolean | undefined;
82
+ noFallthroughCasesInSwitch?: boolean | undefined;
83
+ noImplicitAny?: boolean | undefined;
84
+ noImplicitReturns?: boolean | undefined;
85
+ noImplicitThis?: boolean | undefined;
86
+ noStrictGenericChecks?: boolean | undefined;
87
+ noUnusedLocals?: boolean | undefined;
88
+ noUnusedParameters?: boolean | undefined;
89
+ noImplicitUseStrict?: boolean | undefined;
90
+ noPropertyAccessFromIndexSignature?: boolean | undefined;
91
+ assumeChangesOnlyAffectDirectDependencies?: boolean | undefined;
92
+ noLib?: boolean | undefined;
93
+ noResolve?: boolean | undefined;
94
+ noUncheckedIndexedAccess?: boolean | undefined;
95
+ out?: string | undefined;
96
+ outDir?: string | undefined;
97
+ outFile?: string | undefined;
98
+ paths?: type_fest_source_partial_deep.PartialObjectDeep<typescript.MapLike<string[]>, {}> | undefined;
99
+ preserveConstEnums?: boolean | undefined;
100
+ noImplicitOverride?: boolean | undefined;
101
+ preserveSymlinks?: boolean | undefined;
102
+ preserveValueImports?: boolean | undefined;
103
+ project?: string | undefined;
104
+ reactNamespace?: string | undefined;
105
+ jsxFactory?: string | undefined;
106
+ jsxFragmentFactory?: string | undefined;
107
+ jsxImportSource?: string | undefined;
108
+ composite?: boolean | undefined;
109
+ incremental?: boolean | undefined;
110
+ tsBuildInfoFile?: string | undefined;
111
+ removeComments?: boolean | undefined;
112
+ rootDir?: string | undefined;
113
+ rootDirs?: string[] | undefined;
114
+ skipLibCheck?: boolean | undefined;
115
+ skipDefaultLibCheck?: boolean | undefined;
116
+ sourceMap?: boolean | undefined;
117
+ sourceRoot?: string | undefined;
118
+ strict?: boolean | undefined;
119
+ strictFunctionTypes?: boolean | undefined;
120
+ strictBindCallApply?: boolean | undefined;
121
+ strictNullChecks?: boolean | undefined;
122
+ strictPropertyInitialization?: boolean | undefined;
123
+ stripInternal?: boolean | undefined;
124
+ suppressExcessPropertyErrors?: boolean | undefined;
125
+ suppressImplicitAnyIndexErrors?: boolean | undefined;
126
+ target?: typescript.ScriptTarget | undefined;
127
+ traceResolution?: boolean | undefined;
128
+ useUnknownInCatchVariables?: boolean | undefined;
129
+ resolveJsonModule?: boolean | undefined;
130
+ types?: string[] | undefined;
131
+ typeRoots?: string[] | undefined;
132
+ esModuleInterop?: boolean | undefined;
133
+ useDefineForClassFields?: boolean | undefined;
134
+ };
135
+ extends?: string | undefined;
136
+ };
28
137
  declare const mergeConfigContent: (tsconfigs: string[], cwd: string, debug?: boolean) => TsConfig;
29
138
  declare const writeTsconfig: (tsconfig: TsConfig, cwd: string, out: string, isTesting: boolean) => TsConfig;
139
+ declare const updateCompilerOptions: (compilerOptions: PartialCompilerOptions | undefined, currentCompilerOptions: PartialCompilerOptions) => PartialCompilerOptions;
30
140
  declare const mergeTsConfigs: ({ tsconfigs, exclude, include, compilerOptions, debug, out, isTesting, }: ConfigOptions) => TsConfig | undefined;
31
141
  declare const script: ({ tsconfigs, exclude, include, compilerOptions, debug, out, isTesting, }: ConfigOptions) => TsConfig | undefined;
32
142
 
33
- export { mergeTsConfigs as default, logger, mergeConfigContent, mergeTsConfigs, resolveJSON, script, writeTsconfig };
143
+ export { mergeTsConfigs as default, logger, mergeConfigContent, mergeConfigObjects, mergeTsConfigs, resolveJSON, script, updateCompilerOptions, writeTsconfig };
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // src/scripts.ts
2
2
  import { mkdirSync, readFileSync, writeFileSync } from "fs";
3
3
  import { dirname, join } from "path";
4
+ import JSON5 from "json5";
4
5
  var logger = ({ isDebugging = false, emoji = `\u{1F6E3}\uFE0F`, gap = ` => `, name = "merge-tsconfigs" }) => (type) => (section) => (message) => (err) => {
5
6
  const debugMsg = isDebugging ? "debugging:" : "";
6
7
  const sectionMsg = section.length ? `${section}:` : "";
@@ -28,7 +29,7 @@ var logger = ({ isDebugging = false, emoji = `\u{1F6E3}\uFE0F`, gap = ` => `, na
28
29
  };
29
30
  function resolveJSON(path, debug = false) {
30
31
  try {
31
- const json = JSON.parse(readFileSync(path, "utf8"));
32
+ const json = JSON5.parse(readFileSync(path, "utf8"));
32
33
  return json;
33
34
  } catch (err) {
34
35
  console.log({ err });
@@ -37,6 +38,26 @@ function resolveJSON(path, debug = false) {
37
38
  return {};
38
39
  }
39
40
  }
41
+ var mergeConfigObjects = (tsconfig1, tsconfig2) => ({
42
+ ...tsconfig1,
43
+ ...tsconfig2,
44
+ compilerOptions: {
45
+ ...tsconfig1?.compilerOptions,
46
+ ...tsconfig2?.compilerOptions
47
+ },
48
+ ...tsconfig1?.exclude || tsconfig2?.exclude ? {
49
+ exclude: [
50
+ ...tsconfig1?.exclude || [],
51
+ ...tsconfig2?.exclude || []
52
+ ]
53
+ } : {},
54
+ ...tsconfig1?.include || tsconfig2?.include ? {
55
+ include: [
56
+ ...tsconfig1?.include || [],
57
+ ...tsconfig2?.include || []
58
+ ]
59
+ } : {}
60
+ });
40
61
  var mergeConfigContent = (tsconfigs, cwd, debug = false) => tsconfigs.reduce((acc = {}, tsconfig) => {
41
62
  const path = `${cwd}/${tsconfig}`;
42
63
  let tsconfigJSON = resolveJSON(path, debug);
@@ -48,44 +69,45 @@ var mergeConfigContent = (tsconfigs, cwd, debug = false) => tsconfigs.reduce((ac
48
69
  logger({ isDebugging: debug })("error")("mergeConfigContent")("Parent tsconfig:merge-tsconfigs only handles extending from a parent, consider extending tsconfigs less.")(parentTsconfig);
49
70
  }
50
71
  const { extends: _, ...tsconfigWithoutExtends } = tsconfigJSON;
51
- tsconfigJSON = {
52
- ...parentTsconfig,
53
- ...tsconfigWithoutExtends,
54
- compilerOptions: {
55
- ...parentTsconfig?.compilerOptions,
56
- ...tsconfigWithoutExtends?.compilerOptions
57
- }
58
- };
72
+ tsconfigJSON = mergeConfigObjects(parentTsconfig, tsconfigWithoutExtends);
59
73
  }
60
74
  if (!tsconfigJSON) {
61
75
  if (debug)
62
76
  logger({ isDebugging: debug })("error")("mergeConfigContent")("There was an error:")(tsconfigJSON);
63
77
  return acc;
64
78
  }
65
- return {
66
- ...acc,
67
- ...tsconfigJSON,
68
- compilerOptions: {
69
- ...acc?.compilerOptions,
70
- ...tsconfigJSON?.compilerOptions
71
- }
72
- };
79
+ return mergeConfigObjects(acc, tsconfigJSON);
73
80
  }, {});
74
81
  var writeTsconfig = (tsconfig, cwd, out, isTesting) => {
75
82
  if (isTesting)
76
83
  return tsconfig;
77
- const path = out.length ? out : `${cwd}/tsconfig.merged.json`;
84
+ const path = `${cwd}/${out}`;
78
85
  mkdirSync(dirname(path), { recursive: true });
79
86
  writeFileSync(path, JSON.stringify(tsconfig, null, 2));
80
87
  return tsconfig;
81
88
  };
89
+ var updateCompilerOptions = (compilerOptions2 = {}, currentCompilerOptions) => {
90
+ const compilerOptionKeys = compilerOptions2 ? Object.keys(compilerOptions2) : [];
91
+ const hasCompilerOptions = compilerOptionKeys.length > 0;
92
+ if (!hasCompilerOptions)
93
+ return {};
94
+ return compilerOptionKeys.reduce((acc = {}, key) => {
95
+ const updatedOptions = { ...acc, ...currentCompilerOptions };
96
+ const value = compilerOptions2?.[key];
97
+ if (updatedOptions?.[key] === "delete") {
98
+ delete updatedOptions[key];
99
+ return updatedOptions || {};
100
+ }
101
+ return { ...updatedOptions, [key]: value };
102
+ }, {});
103
+ };
82
104
  var mergeTsConfigs = ({
83
105
  tsconfigs = [],
84
106
  exclude,
85
107
  include,
86
108
  compilerOptions: compilerOptions2,
87
109
  debug = false,
88
- out = "",
110
+ out = "tsconfig.merged.json",
89
111
  isTesting = false
90
112
  }) => {
91
113
  if (tsconfigs.length === 0) {
@@ -97,14 +119,14 @@ var mergeTsConfigs = ({
97
119
  const updatedTsconfig = mergeConfigContent(tsconfigs, cwd, debug);
98
120
  if (debug)
99
121
  logger({ isDebugging: debug })("debug")("mergeTsConfig")("Updated tsconfig:")(updatedTsconfig);
122
+ const updatedCompilerOptions = updateCompilerOptions(compilerOptions2, updatedTsconfig?.compilerOptions || {});
123
+ const updatedExclude = exclude ? { exclude: [...updatedTsconfig?.exclude || [], ...exclude] } : {};
124
+ const updatedInclude = include ? { include: [...updatedTsconfig.include || [], ...include] } : {};
100
125
  const tsconfig = {
101
126
  ...updatedTsconfig,
102
- ...exclude ? [...updatedTsconfig?.exclude || [], ...exclude] : updatedTsconfig?.exclude,
103
- ...include ? [...updatedTsconfig.include || [], ...include] : updatedTsconfig?.include,
104
- compilerOptions: {
105
- ...updatedTsconfig?.compilerOptions,
106
- ...compilerOptions2
107
- }
127
+ ...updatedExclude,
128
+ ...updatedInclude,
129
+ ...Object.keys(updatedCompilerOptions).length > 0 ? { compilerOptions: updatedCompilerOptions } : {}
108
130
  };
109
131
  return writeTsconfig(tsconfig, cwd, out, isTesting);
110
132
  };
@@ -157,14 +179,22 @@ var compilerOptions = {
157
179
  };
158
180
 
159
181
  // src/program.ts
160
- async function action(files, options = {}) {
161
- const { debug = false, isTesting = false, isTestingCLI = false, ...compilerOptions2 } = options;
162
- if (isTestingCLI) {
163
- console.info({ files, options });
164
- return;
165
- }
182
+ function action(files, options = {}) {
166
183
  try {
167
- await script({ debug, tsconfigs: files, compilerOptions: compilerOptions2 });
184
+ const {
185
+ debug = false,
186
+ exclude,
187
+ include,
188
+ isTesting = false,
189
+ isTestingCLI = false,
190
+ out,
191
+ ...compilerOptions2
192
+ } = options;
193
+ if (isTestingCLI) {
194
+ console.info({ files, options });
195
+ return;
196
+ }
197
+ script({ debug, exclude, include, isTesting, out, tsconfigs: files, compilerOptions: compilerOptions2 });
168
198
  } catch (err) {
169
199
  logger({ isDebugging: options.debug })("error")("action")("There was an error:")(err);
170
200
  }
@@ -179,6 +209,8 @@ Object.keys(compilerOptions).map((name) => ({ name, value: compilerOptions[name]
179
209
  program.option(`--${name} <${value}>`, `tsconfig.compilerOptions.${name}`);
180
210
  } else if (value === "array") {
181
211
  program.option(`--${name} [${value}...]`, `tsconfig.compilerOptions.${name}`);
212
+ } else if (value === "object") {
213
+ program.option(`--${name} <${value}>`, `tsconfig.compilerOptions.${name}`);
182
214
  }
183
215
  });
184
216
  program.action(action).parse(process.argv);
@@ -189,8 +221,10 @@ export {
189
221
  src_default as default,
190
222
  logger,
191
223
  mergeConfigContent,
224
+ mergeConfigObjects,
192
225
  mergeTsConfigs,
193
226
  resolveJSON,
194
227
  script,
228
+ updateCompilerOptions,
195
229
  writeTsconfig
196
230
  };
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "merge-tsconfigs",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Merge-tsconfigs is a CLI and node tool for merging tsconfig files into the exact tsconfig file you want 🛣️",
5
5
  "type": "module",
6
6
  "module": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
+ "unpkg": "dist/index.js",
8
9
  "exports": {
9
10
  ".": {
10
11
  "import": "./dist/index.js",
@@ -21,6 +22,7 @@
21
22
  "build": "tsup src/index.ts --format esm,cjs --dts",
22
23
  "clean": "rimraf dist config",
23
24
  "cmd:test": "ts-node src/program.ts --isTestingCLI",
25
+ "cmd:test:cli": "ts-node src/program.ts 'tsconfig.json' --out 'tsconfig.test.json' --outDir 'fooboo' --debug",
24
26
  "commit": "git-cz",
25
27
  "commit-msg": "commitlint --edit $1",
26
28
  "lint": "eslint src --ext .ts",
@@ -35,7 +37,8 @@
35
37
  "update": "codependence --update"
36
38
  },
37
39
  "dependencies": {
38
- "commander": "^9.5.0"
40
+ "commander": "^9.5.0",
41
+ "json5": "^2.2.3"
39
42
  },
40
43
  "devDependencies": {
41
44
  "@commitlint/cli": "^17.4.2",