typesync 0.14.1 → 0.14.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/dist/cli.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- /**
2
- * Starts the TypeSync CLI.
3
- */
1
+
2
+ //#region dist/.tsdown-types-es/cli.d.ts
4
3
  declare function startCli(): Promise<void>;
5
4
 
6
- export { startCli };
5
+ //#endregion
6
+ export { startCli };
package/dist/cli.js CHANGED
@@ -1,14 +1,14 @@
1
- import { createConfigService, createPackageSource, createTypeSyncer, uniq } from "./type-syncer-D93oGCvC.js";
1
+ import { createConfigService, createPackageSource, createTypeSyncer, uniq } from "./type-syncer-D40qMMFq.js";
2
2
  import * as path$1 from "node:path";
3
3
  import * as path from "node:path";
4
4
  import { InjectionMode, asFunction, createContainer } from "awilix";
5
- import chalk from "chalk";
6
- import { oraPromise } from "ora";
5
+ import { blue, bold, cyan, gray, green, magenta, red, white } from "ansis";
6
+ import { Spinner } from "picospinner";
7
+ import * as yaml from "yaml";
7
8
  import { glob } from "tinyglobby";
8
9
  import * as fsp from "node:fs/promises";
9
10
  import { readFile } from "node:fs/promises";
10
11
  import detectIndent from "detect-indent";
11
- import yaml from "js-yaml";
12
12
 
13
13
  //#region rolldown:runtime
14
14
  var __defProp = Object.defineProperty;
@@ -22,18 +22,25 @@ var __export = (target, all) => {
22
22
  //#endregion
23
23
  //#region src/cli-util.ts
24
24
  function log(message) {
25
- console.log(`${chalk.white("»")} ${chalk.gray(message)}`);
25
+ console.log(`${white`»`} ${gray(message)}`);
26
26
  }
27
27
  function success(text) {
28
- console.log(`${chalk.green("✔")} ${chalk.white(text)}`);
28
+ console.log(`${green`✔`} ${white(text)}`);
29
29
  }
30
30
  function error(err) {
31
31
  const msg = err instanceof Error ? err.message : err;
32
32
  const stack = err instanceof Error ? `\nStack:\n${err.stack}` : "";
33
- console.log(`${chalk.red("✖")} ${chalk.bgRed(chalk.white(msg))}${stack}`);
33
+ console.log(`${red`✖`} ${white.bgRed(msg)}${stack}`);
34
34
  }
35
35
  async function spinWhile(text, fn) {
36
- return await oraPromise(fn(), { text: ` ${chalk.gray(text)}` });
36
+ const spinner = new Spinner({
37
+ text: gray` ${text}`,
38
+ symbolFormatter: blue
39
+ });
40
+ spinner.start();
41
+ return await fn().finally(() => {
42
+ spinner.stop();
43
+ });
37
44
  }
38
45
  function parseArguments(argv) {
39
46
  const flags = {};
@@ -103,17 +110,17 @@ function createWorkspaceResolverService({ readFileContents: readFileContents$1 }
103
110
  } };
104
111
  async function getWorkspaces(packageJson, root) {
105
112
  const packageJsonWorkspaces = packageJson.workspaces;
106
- if (packageJsonWorkspaces !== undefined) return packageJsonWorkspaces;
113
+ if (packageJsonWorkspaces !== void 0) return packageJsonWorkspaces;
107
114
  return await getPnpmWorkspaces(root);
108
115
  }
109
116
  async function getPnpmWorkspaces(root) {
110
117
  try {
111
118
  const filePath = path$1.join(root, "pnpm-workspace.yaml");
112
119
  const contents = await readFileContents$1(filePath);
113
- const pnpmWorkspaces = yaml.load(contents);
120
+ const pnpmWorkspaces = yaml.parse(contents);
114
121
  return pnpmWorkspaces.packages;
115
122
  } catch {
116
- return undefined;
123
+ return void 0;
117
124
  }
118
125
  }
119
126
  }
@@ -127,7 +134,7 @@ function ensureWorkspacesArray(data) {
127
134
  //#endregion
128
135
  //#region package.json
129
136
  var name = "typesync";
130
- var version = "0.14.1";
137
+ var version = "0.14.3";
131
138
  var type = "module";
132
139
  var description = "Install missing TypeScript typings for your dependencies.";
133
140
  var engines = { "node": "^18.20.0 || ^20.10.0 || >=22.0.0" };
@@ -147,7 +154,7 @@ var scripts = {
147
154
  "lint:watch": "nodemon --exec npm run lint",
148
155
  "build": "tsdown",
149
156
  "build:watch": "tsdown --watch",
150
- "run-cli": "npm run build && node bin/typesync",
157
+ "run-cli": "npm run build -- --silent && node bin/typesync",
151
158
  "run-cli:dry": "npm run run-cli -- --dry",
152
159
  "do:publish": "npm run lint && npm run test && npm run build && npm publish",
153
160
  "release:patch": "npm version patch && npm run do:publish && git push --follow-tags",
@@ -163,33 +170,33 @@ var license = "MIT";
163
170
  var bugs = { "url": "https://github.com/jeffijoe/typesync/issues" };
164
171
  var homepage = "https://github.com/jeffijoe/typesync#readme";
165
172
  var dependencies = {
166
- "awilix": "^12.0.4",
167
- "chalk": "^5.4.1",
168
- "cosmiconfig": "^9.0.0",
173
+ "ansis": "^3.17.0",
174
+ "awilix": "^12.0.5",
169
175
  "detect-indent": "^7.0.1",
170
- "js-yaml": "^4.1.0",
176
+ "lilconfig": "^3.1.3",
171
177
  "npm-registry-fetch": "^18.0.2",
172
- "ora": "^8.1.1",
178
+ "picospinner": "^3.0.0",
173
179
  "semver": "^7.7.0",
174
- "tinyglobby": "^0.2.10"
180
+ "tinyglobby": "^0.2.12",
181
+ "yaml": "^2.7.1"
175
182
  };
176
183
  var devDependencies = {
177
- "@eslint/js": "^9.19.0",
178
- "@types/js-yaml": "~4.0.9 || ~4.1.0",
179
- "@types/node": "^22.13.0",
180
- "@types/npm-registry-fetch": "^8.0.7 || ~17.1.0",
181
- "@types/semver": "~7.5.8 || ~7.6.0",
182
- "@vitest/coverage-v8": "^3.0.4",
183
- "@vitest/ui": "^3.0.4",
184
- "eslint": "^9.19.0",
185
- "globals": "^15.14.0",
184
+ "@eslint/js": "^9.23.0",
185
+ "@types/node": "^22.13.17",
186
+ "@types/npm-registry-fetch": "^8.0.7 || ~18.0.0",
187
+ "@types/semver": "~7.7.0",
188
+ "@vitest/coverage-v8": "^3.1.1",
189
+ "@vitest/ui": "^3.1.1",
190
+ "eslint": "^9.23.0",
191
+ "globals": "^16.0.0",
186
192
  "nodemon": "^3.1.9",
187
- "oxc-transform": "^0.48.1",
188
- "prettier": "^3.4.2",
189
- "tsdown": "^0.5.6",
190
- "typescript": "^5.7.3",
191
- "typescript-eslint": "^8.22.0",
192
- "vitest": "^3.0.4"
193
+ "prettier": "^3.5.3",
194
+ "publint": "^0.3.9",
195
+ "tsdown": "^0.7.2",
196
+ "typescript": "^5.8.2",
197
+ "typescript-eslint": "^8.29.0",
198
+ "unplugin-unused": "^0.4.4",
199
+ "vitest": "^3.1.1"
193
200
  };
194
201
  var packageManager = "npm@10.8.2";
195
202
  var package_default = {
@@ -241,19 +248,19 @@ async function run(syncer) {
241
248
  printHelp();
242
249
  return;
243
250
  }
244
- log(`TypeSync v${chalk.white(package_default.version)}`);
251
+ log(`TypeSync v${white(package_default.version)}`);
245
252
  if (flags.dry) log("—— DRY RUN — will not modify file ——");
246
- const result = await spinWhile(`Syncing type definitions in ${chalk.cyan(filePath)}...`, async () => await syncer.sync(filePath, flags));
253
+ const result = await spinWhile(`Syncing type definitions in ${cyan(filePath)}...`, async () => await syncer.sync(filePath, flags));
247
254
  const syncedFilesOutput = result.syncedFiles.map(renderSyncedFile).join("\n\n");
248
255
  const totals = result.syncedFiles.reduce((accum, f) => ({ newTypings: accum.newTypings + f.newTypings.length }), { newTypings: 0 });
249
- const syncMessage = `\n\n${syncedFilesOutput}\n\n✨ Run ${chalk.green("typesync")} again without the ${chalk.gray("--dry")} flag to update your ${chalk.gray("package.json")}.`;
256
+ const syncMessage = `\n\n${syncedFilesOutput}\n\n✨ Run ${green`typesync`} again without the ${gray`--dry`} flag to update your ${gray`package.json`}.`;
250
257
  if (flags.dry === "fail" && totals.newTypings > 0) {
251
258
  error("Typings changed; check failed.");
252
259
  log(syncMessage);
253
260
  process.exitCode = 1;
254
261
  return;
255
262
  }
256
- success(totals.newTypings === 0 ? `No new typings to add, looks like you're all synced up!` : flags.dry ? `${totals.newTypings.toString()} new typings can be added.${syncMessage}` : `${totals.newTypings.toString()} new typings added.\n\n${syncedFilesOutput}\n\n✨ Go ahead and run ${chalk.green("npm install")}, ${chalk.green("yarn")}, or ${chalk.green("pnpm i")} to install the packages that were added.`);
263
+ success(totals.newTypings === 0 ? `No new typings to add, looks like you're all synced up!` : flags.dry ? `${totals.newTypings.toString()} new typings can be added.${syncMessage}` : `${totals.newTypings.toString()} new typings added.\n\n${syncedFilesOutput}\n\n✨ Go ahead and run ${green`npm install`}, ${green`yarn`}, or ${green`pnpm i`} to install the packages that were added.`);
257
264
  }
258
265
  /**
259
266
  * Renders a type definition.
@@ -262,7 +269,7 @@ async function run(syncer) {
262
269
  */
263
270
  function renderTypeDef(typeDef, isLast) {
264
271
  const treeNode = isLast ? "└─" : "├─";
265
- return `${treeNode} ${chalk.green.bold("+")} ${chalk.gray("@types/")}${chalk.bold.blue(typeDef.typingsName)}`;
272
+ return `${treeNode} ${green.bold`+`} ${gray`@types/`}${bold.blue(typeDef.typingsName)}`;
266
273
  }
267
274
  /**
268
275
  * Renders a synced file.
@@ -270,9 +277,9 @@ function renderTypeDef(typeDef, isLast) {
270
277
  * @param file
271
278
  */
272
279
  function renderSyncedFile(file) {
273
- const badge = file.newTypings.length === 0 ? chalk.blue.bold("(no new typings added)") : chalk.green.bold(`(${file.newTypings.length.toString()} new typings added)`);
280
+ const badge = file.newTypings.length === 0 ? blue.bold`(no new typings added)` : green.bold`(${file.newTypings.length.toString()} new typings added)`;
274
281
  const dirName = path.basename(path.dirname(path.resolve(file.filePath)));
275
- const title = `📦 ${file.package.name ?? dirName} ${chalk.gray.italic(`— ${file.filePath}`)} ${badge}`;
282
+ const title = `📦 ${file.package.name ?? dirName} ${gray.italic`— ${file.filePath}`} ${badge}`;
276
283
  const nl = "\n";
277
284
  const combined = [...file.newTypings.map((t) => ({
278
285
  ...t,
@@ -286,12 +293,12 @@ function renderSyncedFile(file) {
286
293
  */
287
294
  function printHelp() {
288
295
  console.log(`
289
- ${chalk.blue.bold("typesync")} - adds missing TypeScript definitions to package.json
296
+ ${blue.bold`typesync`} - adds missing TypeScript definitions to package.json
290
297
 
291
298
  Options
292
- ${chalk.magenta.bold("--dry")} dry run, won't save the package.json
293
- ${chalk.magenta.bold("--ignoredeps=<deps|dev|peer|optional>")} ignores dependencies in the specified sections (comma separate for multiple). Example: ${chalk.magenta("ignoredeps=dev,peer")}
294
- ${chalk.magenta.bold("--help")} shows this help menu
299
+ ${magenta.bold`--dry`} dry run, won't save the package.json
300
+ ${magenta.bold`--ignoredeps=<deps|dev|peer|optional>`} ignores dependencies in the specified sections (comma separate for multiple). Example: ${magenta`ignoredeps=dev,peer`}
301
+ ${magenta.bold`--help`} shows this help menu
295
302
  `.trim());
296
303
  }
297
304
 
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","names":["message: string","text: string","err: Error | string","fn: () => Promise<T>","argv: Array<string>","flags: ICLIArguments['flags']","args: Array<string>","filePath: string","packageJson: IPackageFile","root: string","data?: IWorkspacesSection","fsUtils","syncer: ITypeSyncer","packageJson","typeDef: IPackageTypingDescriptor","isLast: boolean","file: ISyncedFile"],"sources":["../src/cli-util.ts","../src/globber.ts","../src/fs-utils.ts","../src/package-json-file-service.ts","../src/workspace-resolver.ts","../package.json","../src/cli.ts"],"sourcesContent":["import chalk from 'chalk'\nimport { oraPromise } from 'ora'\nimport type { ICLIArguments } from './types'\n\n/**\n * Like regular console.log, but better.\n * @param message\n */\nexport function log(message: string): void {\n console.log(`${chalk.white('»')} ${chalk.gray(message)}`)\n}\n\n/**\n * Makes success feel even sweeter.\n * @param text\n */\nexport function success(text: string): void {\n console.log(`${chalk.green('✔')} ${chalk.white(text)}`)\n}\n\n/**\n * Logs an error all pretty.\n * @param err\n */\nexport function error(err: Error | string): void {\n const msg = err instanceof Error ? err.message : err\n const stack = err instanceof Error ? `\\nStack:\\n${err.stack}` : ''\n console.log(`${chalk.red('✖')} ${chalk.bgRed(chalk.white(msg))}${stack}`)\n}\n\n/**\n * Spins while doing work. Stops when done.\n * @param text\n * @param fn\n */\nexport async function spinWhile<T>(\n text: string,\n fn: () => Promise<T>,\n): Promise<T> {\n return await oraPromise(fn(), {\n text: ` ${chalk.gray(text)}`,\n })\n}\n\n/**\n * Super simple argument parser.\n * @param argv\n */\nexport function parseArguments(argv: Array<string>): ICLIArguments {\n const flags: ICLIArguments['flags'] = {}\n const args: Array<string> = []\n for (const arg of argv) {\n if (arg.startsWith('--')) {\n if (arg.includes('=')) {\n const idx = arg.indexOf('=')\n const afterEq = arg.substring(idx + 1)\n flags[arg.substring(2, idx)] = afterEq\n } else {\n flags[arg.substring(2)] = true\n }\n } else {\n args.push(arg)\n }\n }\n return { flags, args }\n}\n","import { glob } from 'tinyglobby'\nimport { uniq } from './util'\n\n/**\n * Globber interface.\n */\nexport interface IGlobber {\n /**\n * Globs for directory names.\n *\n * @param root\n */\n globDirs(\n this: void,\n root: string,\n patterns: Array<string>,\n ignore?: Array<string>,\n ): Promise<Array<string>>\n}\n\n/**\n * Creates a globber.\n */\nexport function createGlobber(): IGlobber {\n return {\n async globDirs(root, patterns, ignore = []): Promise<Array<string>> {\n const source = await glob(patterns, {\n cwd: root,\n ignore: ['**/node_modules/**', ...ignore],\n onlyDirectories: true,\n })\n\n return uniq(source)\n },\n }\n}\n","import { readFile } from 'node:fs/promises'\n\nexport async function readFileContents(filePath: string): Promise<string> {\n try {\n return await readFile(filePath, 'utf-8')\n /* v8 ignore next */\n } catch (err) {\n /* v8 ignore next 3 */\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n throw new Error(`${filePath} does not exist.`)\n }\n\n /* v8 ignore next 2 */\n throw err\n }\n}\n","import * as fsp from 'node:fs/promises'\nimport detectIndent from 'detect-indent'\nimport { readFileContents } from './fs-utils'\nimport type { IPackageFile } from './types'\n\n/**\n * File service.\n */\nexport interface IPackageJSONService {\n /**\n * Reads and parses JSON from the specified file. Path is relative to the current working directory.\n */\n readPackageFile(this: void, filePath: string): Promise<IPackageFile>\n /**\n * Writes the JSON to the specified file.\n */\n writePackageFile(\n this: void,\n filePath: string,\n fileContents: IPackageFile,\n ): Promise<void>\n}\n\nexport function createPackageJSONFileService(): IPackageJSONService {\n return {\n readPackageFile: async (filePath) => {\n const contents = await readFileContents(filePath)\n return JSON.parse(contents) as IPackageFile\n },\n writePackageFile: async (filePath, fileContent) => {\n const contents = await readFileContents(filePath)\n const { indent } = detectIndent(contents)\n const trailingNewline = contents.length ? contents.endsWith('\\n') : false\n const data = JSON.stringify(\n fileContent,\n null,\n indent /* v8 ignore next */ || ' ',\n )\n await fsp.writeFile(filePath, data + (trailingNewline ? '\\n' : ''))\n },\n }\n}\n","import * as path from 'node:path'\nimport yaml from 'js-yaml'\nimport type * as fsUtils from './fs-utils'\nimport type { IGlobber } from './globber'\nimport type { IPackageFile } from './types'\n\n/**\n * Service for fetching monorepo workspaces in a standardized format agnostic of the package manager used.\n * It is used to allow syncing all types in a workspace when run from the root of a monorepo.\n */\nexport interface IWorkspaceResolverService {\n /**\n * Reads, parses, and normalizes a workspaces configuration from the following files, in this order:\n * - `package.json` `workspaces` field, as an array of globs.\n * - `package.json` `workspaces` field, as an object with a `packages` field, which is an array of globs.\n * - `pnpm-workspace.yaml` `packages` field, as an array of globs.\n *\n * Path is relative to the current working directory.\n * Note that this returns a list of directories, not paths to the manifests themselves.\n */\n getWorkspaces(\n this: void,\n packageJson: IPackageFile,\n root: string,\n globber: IGlobber,\n ignored: IWorkspacesArray,\n ): Promise<IWorkspacesArray>\n}\n\n/**\n * @example\n * ```json\n * \"workspaces\": [\n * \"packages/*\",\n * ]\n * ```\n */\nexport type IWorkspacesArray = Array<string>\n\n/**\n * @example\n * ```yaml\n * packages:\n * - 'packages/*'\n * ```\n */\nexport interface IWorkspacesObject {\n packages?: IWorkspacesArray\n}\n\n/**\n * @see {@link IWorkspacesArray}\n */\nexport type NpmWorkspacesConfig = IWorkspacesArray\n\n/**\n * Yarn is a special snowflake.\n *\n * @example\n * ```json\n * \"workspaces\": {\n * \"packages\": [\n * \"packages/*\",\n * ],\n * \"nohoist\": []\n * }\n * ```\n */\nexport type YarnWorkspacesConfig =\n | IWorkspacesArray\n | (IWorkspacesObject & { nohoist?: Array<string> })\n\n/**\n * The contents of a `pnpm-workspace.yaml` file.\n *\n * @example\n * ```yaml\n * packages:\n * - 'packages/*'\n * ```\n */\nexport type PnpmWorkspacesConfig = IWorkspacesObject\n\n/**\n * @see {@link IWorkspacesArray}\n */\nexport type BunWorkspacesConfig = IWorkspacesArray\n\n/**\n * Section in `package.json` representing workspaces.\n */\nexport type IWorkspacesSection =\n | NpmWorkspacesConfig\n | YarnWorkspacesConfig\n // eslint-disable-next-line @typescript-eslint/no-duplicate-type-constituents -- We want to explicitly enumerate each package manager's options.\n | BunWorkspacesConfig\n\nexport function createWorkspaceResolverService({\n readFileContents,\n}: {\n readFileContents: typeof fsUtils.readFileContents\n}): IWorkspaceResolverService {\n return {\n getWorkspaces: async (packageJson, root, globber, ignored) => {\n const workspaces = await getWorkspaces(packageJson, root)\n\n return await globber.globDirs(\n root,\n ensureWorkspacesArray(workspaces),\n ignored,\n )\n },\n }\n\n async function getWorkspaces(\n packageJson: IPackageFile,\n root: string,\n ): Promise<IWorkspacesSection | undefined> {\n const packageJsonWorkspaces = packageJson.workspaces\n if (packageJsonWorkspaces !== undefined) {\n return packageJsonWorkspaces\n }\n\n return await getPnpmWorkspaces(root)\n }\n\n async function getPnpmWorkspaces(\n root: string,\n ): Promise<IWorkspacesArray | undefined> {\n try {\n const filePath = path.join(root, 'pnpm-workspace.yaml')\n const contents = await readFileContents(filePath)\n const pnpmWorkspaces = yaml.load(contents) as PnpmWorkspacesConfig\n\n return pnpmWorkspaces.packages\n } catch {\n return undefined\n }\n }\n}\n\n/**\n * Ensures that we have a valid workspaces array.\n *\n * @param data\n */\nexport function ensureWorkspacesArray(\n data?: IWorkspacesSection,\n): IWorkspacesArray {\n if (!data) {\n return []\n }\n\n if (!Array.isArray(data)) {\n return ensureWorkspacesArray(data.packages)\n }\n\n if (!data.every((s) => typeof s === 'string')) {\n return []\n }\n\n return data\n}\n","{\n \"name\": \"typesync\",\n \"version\": \"0.14.1\",\n \"type\": \"module\",\n \"description\": \"Install missing TypeScript typings for your dependencies.\",\n \"engines\": {\n \"node\": \"^18.20.0 || ^20.10.0 || >=22.0.0\"\n },\n \"files\": [\n \"dist\",\n \"bin\"\n ],\n \"bin\": {\n \"typesync\": \"./bin/typesync\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n }\n },\n \"scripts\": {\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest --ui\",\n \"fix\": \"eslint --fix && npm run format\",\n \"lint\": \"eslint && tsc && npm run format:check\",\n \"format\": \"prettier --write 'src/**/*.ts'\",\n \"format:check\": \"prettier --check 'src/**/*.ts'\",\n \"lint:watch\": \"nodemon --exec npm run lint\",\n \"build\": \"tsdown\",\n \"build:watch\": \"tsdown --watch\",\n \"run-cli\": \"npm run build && node bin/typesync\",\n \"run-cli:dry\": \"npm run run-cli -- --dry\",\n \"do:publish\": \"npm run lint && npm run test && npm run build && npm publish\",\n \"release:patch\": \"npm version patch && npm run do:publish && git push --follow-tags\",\n \"release:minor\": \"npm version minor && npm run do:publish && git push --follow-tags\",\n \"release:prerelease\": \"npm version prerelease && npm run do:publish && git push --follow-tags\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/jeffijoe/typesync.git\"\n },\n \"author\": \"Jeff Hansen <jeff@jeffijoe.com>\",\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https://github.com/jeffijoe/typesync/issues\"\n },\n \"homepage\": \"https://github.com/jeffijoe/typesync#readme\",\n \"dependencies\": {\n \"awilix\": \"^12.0.4\",\n \"chalk\": \"^5.4.1\",\n \"cosmiconfig\": \"^9.0.0\",\n \"detect-indent\": \"^7.0.1\",\n \"js-yaml\": \"^4.1.0\",\n \"npm-registry-fetch\": \"^18.0.2\",\n \"ora\": \"^8.1.1\",\n \"semver\": \"^7.7.0\",\n \"tinyglobby\": \"^0.2.10\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.19.0\",\n \"@types/js-yaml\": \"~4.0.9 || ~4.1.0\",\n \"@types/node\": \"^22.13.0\",\n \"@types/npm-registry-fetch\": \"^8.0.7 || ~17.1.0\",\n \"@types/semver\": \"~7.5.8 || ~7.6.0\",\n \"@vitest/coverage-v8\": \"^3.0.4\",\n \"@vitest/ui\": \"^3.0.4\",\n \"eslint\": \"^9.19.0\",\n \"globals\": \"^15.14.0\",\n \"nodemon\": \"^3.1.9\",\n \"oxc-transform\": \"^0.48.1\",\n \"prettier\": \"^3.4.2\",\n \"tsdown\": \"^0.5.6\",\n \"typescript\": \"^5.7.3\",\n \"typescript-eslint\": \"^8.22.0\",\n \"vitest\": \"^3.0.4\"\n },\n \"packageManager\": \"npm@10.8.2\"\n}\n","import * as path from 'node:path'\nimport { asFunction, createContainer, InjectionMode } from 'awilix'\nimport chalk from 'chalk'\nimport * as C from './cli-util'\nimport { createConfigService } from './config-service'\nimport { createGlobber } from './globber'\nimport { createPackageJSONFileService } from './package-json-file-service'\nimport { createPackageSource } from './package-source'\nimport { createTypeSyncer } from './type-syncer'\nimport type {\n IPackageTypingDescriptor,\n ISyncedFile,\n ITypeSyncer,\n} from './types'\nimport { createWorkspaceResolverService } from './workspace-resolver'\nimport * as fsUtils from './fs-utils'\nimport packageJson from '../package.json' with { type: 'json' }\n\n/**\n * Starts the TypeSync CLI.\n */\nexport async function startCli(): Promise<void> {\n try {\n // Awilix is a dependency injection container.\n const container = createContainer({\n injectionMode: InjectionMode.CLASSIC,\n }).register({\n packageJSONService: asFunction(createPackageJSONFileService).singleton(),\n workspaceResolverService: asFunction(() =>\n createWorkspaceResolverService(fsUtils),\n ).singleton(),\n packageSource: asFunction(createPackageSource).singleton(),\n configService: asFunction(createConfigService).singleton(),\n globber: asFunction(createGlobber).singleton(),\n typeSyncer: asFunction(createTypeSyncer),\n })\n await run(container.resolve<ITypeSyncer>('typeSyncer'))\n } catch (err) {\n C.error(err as any)\n process.exitCode = 1\n }\n}\n\n/**\n * Actual CLI runner. Uses the `syncer` instance to sync.\n * @param syncer\n */\nasync function run(syncer: ITypeSyncer) {\n const { args, flags } = C.parseArguments(process.argv.slice(2))\n const [filePath = 'package.json'] = args\n if (flags.help) {\n printHelp()\n return\n }\n\n C.log(`TypeSync v${chalk.white(packageJson.version)}`)\n if (flags.dry) {\n C.log('—— DRY RUN — will not modify file ——')\n }\n const result = await C.spinWhile(\n `Syncing type definitions in ${chalk.cyan(filePath)}...`,\n async () => await syncer.sync(filePath, flags),\n )\n\n const syncedFilesOutput = result.syncedFiles\n .map(renderSyncedFile)\n .join('\\n\\n')\n const totals = result.syncedFiles.reduce(\n (accum, f) => ({\n newTypings: accum.newTypings + f.newTypings.length,\n }),\n { newTypings: 0 },\n )\n\n const syncMessage = `\\n\\n${syncedFilesOutput}\\n\\n✨ Run ${chalk.green('typesync')} again without the ${chalk.gray('--dry')} flag to update your ${chalk.gray('package.json')}.`\n if (flags.dry === 'fail' && totals.newTypings > 0) {\n C.error('Typings changed; check failed.')\n C.log(syncMessage)\n process.exitCode = 1\n return\n }\n C.success(\n totals.newTypings === 0\n ? `No new typings to add, looks like you're all synced up!`\n : flags.dry\n ? `${totals.newTypings.toString()} new typings can be added.${syncMessage}`\n : `${totals.newTypings.toString()} new typings added.\\n\\n${syncedFilesOutput}\\n\\n✨ Go ahead and run ${chalk.green('npm install')}, ${chalk.green('yarn')}, or ${chalk.green('pnpm i')} to install the packages that were added.`,\n )\n}\n\n/**\n * Renders a type definition.\n * @param typeDef\n * @param isLast\n */\nfunction renderTypeDef(typeDef: IPackageTypingDescriptor, isLast: boolean) {\n const treeNode = isLast ? '└─' : '├─'\n return `${treeNode} ${chalk.green.bold('+')} ${chalk.gray('@types/')}${chalk.bold.blue(typeDef.typingsName)}`\n}\n\n/**\n * Renders a synced file.\n *\n * @param file\n */\nfunction renderSyncedFile(file: ISyncedFile) {\n const badge =\n file.newTypings.length === 0\n ? chalk.blue.bold('(no new typings added)')\n : chalk.green.bold(\n `(${file.newTypings.length.toString()} new typings added)`,\n )\n\n const dirName = path.basename(path.dirname(path.resolve(file.filePath)))\n const title = `📦 ${file.package.name ?? dirName} ${chalk.gray.italic(\n `— ${file.filePath}`,\n )} ${badge}`\n\n const nl = '\\n'\n const combined = [...file.newTypings.map((t) => ({ ...t, action: 'add' }))]\n const rendered =\n title +\n nl +\n combined\n .map((t) => renderTypeDef(t, combined[combined.length - 1] === t))\n .join(nl)\n\n return rendered\n}\n\n/**\n * Prints the help text.\n */\nfunction printHelp() {\n console.log(\n `\n${chalk.blue.bold('typesync')} - adds missing TypeScript definitions to package.json\n\nOptions\n ${chalk.magenta.bold('--dry')} dry run, won't save the package.json\n ${chalk.magenta.bold('--ignoredeps=<deps|dev|peer|optional>')} ignores dependencies in the specified sections (comma separate for multiple). Example: ${chalk.magenta('ignoredeps=dev,peer')}\n ${chalk.magenta.bold('--help')} shows this help menu\n `.trim(),\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","names":["message: string","text: string","err: Error | string","fn: () => Promise<T>","argv: Array<string>","flags: ICLIArguments['flags']","args: Array<string>","filePath: string","packageJson: IPackageFile","root: string","data?: IWorkspacesSection","syncer: ITypeSyncer","typeDef: IPackageTypingDescriptor","isLast: boolean","file: ISyncedFile"],"sources":["../src/cli-util.ts","../src/globber.ts","../src/fs-utils.ts","../src/package-json-file-service.ts","../src/workspace-resolver.ts","../package.json","../src/cli.ts"],"sourcesContent":["import { white, gray, green, red, blue } from 'ansis'\nimport { Spinner } from 'picospinner'\nimport type { ICLIArguments } from './types'\n\n/**\n * Like regular console.log, but better.\n * @param message\n */\nexport function log(message: string): void {\n console.log(`${white`»`} ${gray(message)}`)\n}\n\n/**\n * Makes success feel even sweeter.\n * @param text\n */\nexport function success(text: string): void {\n console.log(`${green`✔`} ${white(text)}`)\n}\n\n/**\n * Logs an error all pretty.\n * @param err\n */\nexport function error(err: Error | string): void {\n const msg = err instanceof Error ? err.message : err\n const stack = err instanceof Error ? `\\nStack:\\n${err.stack}` : ''\n console.log(`${red`✖`} ${white.bgRed(msg)}${stack}`)\n}\n\n/**\n * Spins while doing work. Stops when done.\n * @param text\n * @param fn\n */\nexport async function spinWhile<T>(\n text: string,\n fn: () => Promise<T>,\n): Promise<T> {\n const spinner = new Spinner({ text: gray` ${text}`, symbolFormatter: blue })\n spinner.start()\n\n return await fn().finally(() => {\n spinner.stop()\n })\n}\n\n/**\n * Super simple argument parser.\n * @param argv\n */\nexport function parseArguments(argv: Array<string>): ICLIArguments {\n const flags: ICLIArguments['flags'] = {}\n const args: Array<string> = []\n for (const arg of argv) {\n if (arg.startsWith('--')) {\n if (arg.includes('=')) {\n const idx = arg.indexOf('=')\n const afterEq = arg.substring(idx + 1)\n flags[arg.substring(2, idx)] = afterEq\n } else {\n flags[arg.substring(2)] = true\n }\n } else {\n args.push(arg)\n }\n }\n return { flags, args }\n}\n","import { glob } from 'tinyglobby'\nimport { uniq } from './util'\n\n/**\n * Globber interface.\n */\nexport interface IGlobber {\n /**\n * Globs for directory names.\n *\n * @param root\n */\n globDirs(\n this: void,\n root: string,\n patterns: Array<string>,\n ignore?: Array<string>,\n ): Promise<Array<string>>\n}\n\n/**\n * Creates a globber.\n */\nexport function createGlobber(): IGlobber {\n return {\n async globDirs(root, patterns, ignore = []): Promise<Array<string>> {\n const source = await glob(patterns, {\n cwd: root,\n ignore: ['**/node_modules/**', ...ignore],\n onlyDirectories: true,\n })\n\n return uniq(source)\n },\n }\n}\n","import { readFile } from 'node:fs/promises'\n\nexport async function readFileContents(filePath: string): Promise<string> {\n try {\n return await readFile(filePath, 'utf-8')\n /* v8 ignore next */\n } catch (err) {\n /* v8 ignore next 3 */\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n throw new Error(`${filePath} does not exist.`)\n }\n\n /* v8 ignore next 2 */\n throw err\n }\n}\n","import * as fsp from 'node:fs/promises'\nimport detectIndent from 'detect-indent'\nimport { readFileContents } from './fs-utils'\nimport type { IPackageFile } from './types'\n\n/**\n * File service.\n */\nexport interface IPackageJSONService {\n /**\n * Reads and parses JSON from the specified file. Path is relative to the current working directory.\n */\n readPackageFile(this: void, filePath: string): Promise<IPackageFile>\n /**\n * Writes the JSON to the specified file.\n */\n writePackageFile(\n this: void,\n filePath: string,\n fileContents: IPackageFile,\n ): Promise<void>\n}\n\nexport function createPackageJSONFileService(): IPackageJSONService {\n return {\n readPackageFile: async (filePath) => {\n const contents = await readFileContents(filePath)\n return JSON.parse(contents) as IPackageFile\n },\n writePackageFile: async (filePath, fileContent) => {\n const contents = await readFileContents(filePath)\n const { indent } = detectIndent(contents)\n const trailingNewline = contents.length ? contents.endsWith('\\n') : false\n const data = JSON.stringify(\n fileContent,\n null,\n indent /* v8 ignore next */ || ' ',\n )\n await fsp.writeFile(filePath, data + (trailingNewline ? '\\n' : ''))\n },\n }\n}\n","import * as path from 'node:path'\nimport * as yaml from 'yaml'\nimport type * as fsUtils from './fs-utils'\nimport type { IGlobber } from './globber'\nimport type { IPackageFile } from './types'\n\n/**\n * Service for fetching monorepo workspaces in a standardized format agnostic of the package manager used.\n * It is used to allow syncing all types in a workspace when run from the root of a monorepo.\n */\nexport interface IWorkspaceResolverService {\n /**\n * Reads, parses, and normalizes a workspaces configuration from the following files, in this order:\n * - `package.json` `workspaces` field, as an array of globs.\n * - `package.json` `workspaces` field, as an object with a `packages` field, which is an array of globs.\n * - `pnpm-workspace.yaml` `packages` field, as an array of globs.\n *\n * Path is relative to the current working directory.\n * Note that this returns a list of directories, not paths to the manifests themselves.\n */\n getWorkspaces(\n this: void,\n packageJson: IPackageFile,\n root: string,\n globber: IGlobber,\n ignored: IWorkspacesArray,\n ): Promise<IWorkspacesArray>\n}\n\n/**\n * @example\n * ```json\n * \"workspaces\": [\n * \"packages/*\",\n * ]\n * ```\n */\nexport type IWorkspacesArray = Array<string>\n\n/**\n * @example\n * ```yaml\n * packages:\n * - 'packages/*'\n * ```\n */\nexport interface IWorkspacesObject {\n packages?: IWorkspacesArray\n}\n\n/**\n * @see {@link IWorkspacesArray}\n */\nexport type NpmWorkspacesConfig = IWorkspacesArray\n\n/**\n * Yarn is a special snowflake.\n *\n * @example\n * ```json\n * \"workspaces\": {\n * \"packages\": [\n * \"packages/*\",\n * ],\n * \"nohoist\": []\n * }\n * ```\n */\nexport type YarnWorkspacesConfig =\n | IWorkspacesArray\n | (IWorkspacesObject & { nohoist?: Array<string> })\n\n/**\n * The contents of a `pnpm-workspace.yaml` file.\n *\n * @example\n * ```yaml\n * packages:\n * - 'packages/*'\n * ```\n */\nexport type PnpmWorkspacesConfig = IWorkspacesObject\n\n/**\n * @see {@link IWorkspacesArray}\n */\nexport type BunWorkspacesConfig = IWorkspacesArray\n\n/**\n * Section in `package.json` representing workspaces.\n */\nexport type IWorkspacesSection =\n | NpmWorkspacesConfig\n | YarnWorkspacesConfig\n // eslint-disable-next-line @typescript-eslint/no-duplicate-type-constituents -- We want to explicitly enumerate each package manager's options.\n | BunWorkspacesConfig\n\nexport function createWorkspaceResolverService({\n readFileContents,\n}: {\n readFileContents: typeof fsUtils.readFileContents\n}): IWorkspaceResolverService {\n return {\n getWorkspaces: async (packageJson, root, globber, ignored) => {\n const workspaces = await getWorkspaces(packageJson, root)\n\n return await globber.globDirs(\n root,\n ensureWorkspacesArray(workspaces),\n ignored,\n )\n },\n }\n\n async function getWorkspaces(\n packageJson: IPackageFile,\n root: string,\n ): Promise<IWorkspacesSection | undefined> {\n const packageJsonWorkspaces = packageJson.workspaces\n if (packageJsonWorkspaces !== undefined) {\n return packageJsonWorkspaces\n }\n\n return await getPnpmWorkspaces(root)\n }\n\n async function getPnpmWorkspaces(\n root: string,\n ): Promise<IWorkspacesArray | undefined> {\n try {\n const filePath = path.join(root, 'pnpm-workspace.yaml')\n const contents = await readFileContents(filePath)\n const pnpmWorkspaces = yaml.parse(\n contents,\n ) as unknown as PnpmWorkspacesConfig\n\n return pnpmWorkspaces.packages\n } catch {\n return undefined\n }\n }\n}\n\n/**\n * Ensures that we have a valid workspaces array.\n *\n * @param data\n */\nexport function ensureWorkspacesArray(\n data?: IWorkspacesSection,\n): IWorkspacesArray {\n if (!data) {\n return []\n }\n\n if (!Array.isArray(data)) {\n return ensureWorkspacesArray(data.packages)\n }\n\n if (!data.every((s) => typeof s === 'string')) {\n return []\n }\n\n return data\n}\n","{\n \"name\": \"typesync\",\n \"version\": \"0.14.3\",\n \"type\": \"module\",\n \"description\": \"Install missing TypeScript typings for your dependencies.\",\n \"engines\": {\n \"node\": \"^18.20.0 || ^20.10.0 || >=22.0.0\"\n },\n \"files\": [\n \"dist\",\n \"bin\"\n ],\n \"bin\": {\n \"typesync\": \"./bin/typesync\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n }\n },\n \"scripts\": {\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest --ui\",\n \"fix\": \"eslint --fix && npm run format\",\n \"lint\": \"eslint && tsc && npm run format:check\",\n \"format\": \"prettier --write 'src/**/*.ts'\",\n \"format:check\": \"prettier --check 'src/**/*.ts'\",\n \"lint:watch\": \"nodemon --exec npm run lint\",\n \"build\": \"tsdown\",\n \"build:watch\": \"tsdown --watch\",\n \"run-cli\": \"npm run build -- --silent && node bin/typesync\",\n \"run-cli:dry\": \"npm run run-cli -- --dry\",\n \"do:publish\": \"npm run lint && npm run test && npm run build && npm publish\",\n \"release:patch\": \"npm version patch && npm run do:publish && git push --follow-tags\",\n \"release:minor\": \"npm version minor && npm run do:publish && git push --follow-tags\",\n \"release:prerelease\": \"npm version prerelease && npm run do:publish && git push --follow-tags\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/jeffijoe/typesync.git\"\n },\n \"author\": \"Jeff Hansen <jeff@jeffijoe.com>\",\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https://github.com/jeffijoe/typesync/issues\"\n },\n \"homepage\": \"https://github.com/jeffijoe/typesync#readme\",\n \"dependencies\": {\n \"ansis\": \"^3.17.0\",\n \"awilix\": \"^12.0.5\",\n \"detect-indent\": \"^7.0.1\",\n \"lilconfig\": \"^3.1.3\",\n \"npm-registry-fetch\": \"^18.0.2\",\n \"picospinner\": \"^3.0.0\",\n \"semver\": \"^7.7.0\",\n \"tinyglobby\": \"^0.2.12\",\n \"yaml\": \"^2.7.1\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.23.0\",\n \"@types/node\": \"^22.13.17\",\n \"@types/npm-registry-fetch\": \"^8.0.7 || ~18.0.0\",\n \"@types/semver\": \"~7.7.0\",\n \"@vitest/coverage-v8\": \"^3.1.1\",\n \"@vitest/ui\": \"^3.1.1\",\n \"eslint\": \"^9.23.0\",\n \"globals\": \"^16.0.0\",\n \"nodemon\": \"^3.1.9\",\n \"prettier\": \"^3.5.3\",\n \"publint\": \"^0.3.9\",\n \"tsdown\": \"^0.7.2\",\n \"typescript\": \"^5.8.2\",\n \"typescript-eslint\": \"^8.29.0\",\n \"unplugin-unused\": \"^0.4.4\",\n \"vitest\": \"^3.1.1\"\n },\n \"packageManager\": \"npm@10.8.2\"\n}\n","import * as path from 'node:path'\nimport { asFunction, createContainer, InjectionMode } from 'awilix'\nimport { blue, bold, cyan, gray, green, magenta, white } from 'ansis'\nimport * as C from './cli-util'\nimport { createConfigService } from './config-service'\nimport { createGlobber } from './globber'\nimport { createPackageJSONFileService } from './package-json-file-service'\nimport { createPackageSource } from './package-source'\nimport { createTypeSyncer } from './type-syncer'\nimport type {\n IPackageTypingDescriptor,\n ISyncedFile,\n ITypeSyncer,\n} from './types'\nimport { createWorkspaceResolverService } from './workspace-resolver'\nimport * as fsUtils from './fs-utils'\nimport packageJson from '../package.json' with { type: 'json' }\n\n/**\n * Starts the TypeSync CLI.\n */\nexport async function startCli(): Promise<void> {\n try {\n // Awilix is a dependency injection container.\n const container = createContainer({\n injectionMode: InjectionMode.CLASSIC,\n }).register({\n packageJSONService: asFunction(createPackageJSONFileService).singleton(),\n workspaceResolverService: asFunction(() =>\n createWorkspaceResolverService(fsUtils),\n ).singleton(),\n packageSource: asFunction(createPackageSource).singleton(),\n configService: asFunction(createConfigService).singleton(),\n globber: asFunction(createGlobber).singleton(),\n typeSyncer: asFunction(createTypeSyncer),\n })\n await run(container.resolve<ITypeSyncer>('typeSyncer'))\n } catch (err) {\n C.error(err as any)\n process.exitCode = 1\n }\n}\n\n/**\n * Actual CLI runner. Uses the `syncer` instance to sync.\n * @param syncer\n */\nasync function run(syncer: ITypeSyncer) {\n const { args, flags } = C.parseArguments(process.argv.slice(2))\n const [filePath = 'package.json'] = args\n if (flags.help) {\n printHelp()\n return\n }\n\n C.log(`TypeSync v${white(packageJson.version)}`)\n if (flags.dry) {\n C.log('—— DRY RUN — will not modify file ——')\n }\n const result = await C.spinWhile(\n `Syncing type definitions in ${cyan(filePath)}...`,\n async () => await syncer.sync(filePath, flags),\n )\n\n const syncedFilesOutput = result.syncedFiles\n .map(renderSyncedFile)\n .join('\\n\\n')\n const totals = result.syncedFiles.reduce(\n (accum, f) => ({\n newTypings: accum.newTypings + f.newTypings.length,\n }),\n { newTypings: 0 },\n )\n\n const syncMessage = `\\n\\n${syncedFilesOutput}\\n\\n✨ Run ${green`typesync`} again without the ${gray`--dry`} flag to update your ${gray`package.json`}.`\n if (flags.dry === 'fail' && totals.newTypings > 0) {\n C.error('Typings changed; check failed.')\n C.log(syncMessage)\n process.exitCode = 1\n return\n }\n C.success(\n totals.newTypings === 0\n ? `No new typings to add, looks like you're all synced up!`\n : flags.dry\n ? `${totals.newTypings.toString()} new typings can be added.${syncMessage}`\n : `${totals.newTypings.toString()} new typings added.\\n\\n${syncedFilesOutput}\\n\\n✨ Go ahead and run ${green`npm install`}, ${green`yarn`}, or ${green`pnpm i`} to install the packages that were added.`,\n )\n}\n\n/**\n * Renders a type definition.\n * @param typeDef\n * @param isLast\n */\nfunction renderTypeDef(typeDef: IPackageTypingDescriptor, isLast: boolean) {\n const treeNode = isLast ? '└─' : '├─'\n return `${treeNode} ${green.bold`+`} ${gray`@types/`}${bold.blue(typeDef.typingsName)}`\n}\n\n/**\n * Renders a synced file.\n *\n * @param file\n */\nfunction renderSyncedFile(file: ISyncedFile) {\n const badge =\n file.newTypings.length === 0\n ? blue.bold`(no new typings added)`\n : green.bold`(${file.newTypings.length.toString()} new typings added)`\n\n const dirName = path.basename(path.dirname(path.resolve(file.filePath)))\n const title = `📦 ${file.package.name ?? dirName} ${gray.italic`— ${file.filePath}`} ${badge}`\n\n const nl = '\\n'\n const combined = [...file.newTypings.map((t) => ({ ...t, action: 'add' }))]\n const rendered =\n title +\n nl +\n combined\n .map((t) => renderTypeDef(t, combined[combined.length - 1] === t))\n .join(nl)\n\n return rendered\n}\n\n/**\n * Prints the help text.\n */\nfunction printHelp() {\n console.log(\n `\n${blue.bold`typesync`} - adds missing TypeScript definitions to package.json\n\nOptions\n ${magenta.bold`--dry`} dry run, won't save the package.json\n ${magenta.bold`--ignoredeps=<deps|dev|peer|optional>`} ignores dependencies in the specified sections (comma separate for multiple). Example: ${magenta`ignoredeps=dev,peer`}\n ${magenta.bold`--help`} shows this help menu\n `.trim(),\n )\n}\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- /**
2
- * Globber interface.
3
- */
1
+
2
+ //#region dist/.tsdown-types-es/globber.d.ts
4
3
  interface IGlobber {
5
4
  /**
6
5
  * Globs for directory names.
@@ -10,10 +9,8 @@ interface IGlobber {
10
9
  globDirs(this: void, root: string, patterns: Array<string>, ignore?: Array<string>): Promise<Array<string>>;
11
10
  }
12
11
 
13
- /**
14
- * Service for fetching monorepo workspaces in a standardized format agnostic of the package manager used.
15
- * It is used to allow syncing all types in a workspace when run from the root of a monorepo.
16
- */
12
+ //#endregion
13
+ //#region dist/.tsdown-types-es/workspace-resolver.d.ts
17
14
  interface IWorkspaceResolverService {
18
15
  /**
19
16
  * Reads, parses, and normalizes a workspaces configuration from the following files, in this order:
@@ -26,63 +23,22 @@ interface IWorkspaceResolverService {
26
23
  */
27
24
  getWorkspaces(this: void, packageJson: IPackageFile, root: string, globber: IGlobber, ignored: IWorkspacesArray): Promise<IWorkspacesArray>;
28
25
  }
29
- /**
30
- * @example
31
- * ```json
32
- * "workspaces": [
33
- * "packages/*",
34
- * ]
35
- * ```
36
- */
37
26
  type IWorkspacesArray = Array<string>;
38
- /**
39
- * @example
40
- * ```yaml
41
- * packages:
42
- * - 'packages/*'
43
- * ```
44
- */
45
27
  interface IWorkspacesObject {
46
28
  packages?: IWorkspacesArray;
47
29
  }
48
- /**
49
- * @see {@link IWorkspacesArray}
50
- */
51
30
  type NpmWorkspacesConfig = IWorkspacesArray;
52
- /**
53
- * Yarn is a special snowflake.
54
- *
55
- * @example
56
- * ```json
57
- * "workspaces": {
58
- * "packages": [
59
- * "packages/*",
60
- * ],
61
- * "nohoist": []
62
- * }
63
- * ```
64
- */
65
31
  type YarnWorkspacesConfig = IWorkspacesArray | (IWorkspacesObject & {
66
32
  nohoist?: Array<string>
67
33
  });
68
- /**
69
- * @see {@link IWorkspacesArray}
70
- */
71
34
  type BunWorkspacesConfig = IWorkspacesArray;
72
- /**
73
- * Section in `package.json` representing workspaces.
74
- */
75
35
  type IWorkspacesSection = NpmWorkspacesConfig | YarnWorkspacesConfig | BunWorkspacesConfig;
76
36
 
77
- /**
78
- * The guts of the program.
79
- */
37
+ //#endregion
38
+ //#region dist/.tsdown-types-es/types.d.ts
80
39
  interface ITypeSyncer {
81
40
  sync(this: void, filePath: string, flags: ICLIArguments["flags"]): Promise<ISyncResult>;
82
41
  }
83
- /**
84
- * Sync options.
85
- */
86
42
  interface ISyncOptions {
87
43
  /**
88
44
  * Ignore certain deps.
@@ -97,9 +53,6 @@ interface ISyncOptions {
97
53
  */
98
54
  ignoreProjects?: IWorkspacesArray;
99
55
  }
100
- /**
101
- * Package.json file.
102
- */
103
56
  interface IPackageFile {
104
57
  name?: string;
105
58
  dependencies?: IDependenciesSection;
@@ -109,43 +62,25 @@ interface IPackageFile {
109
62
  workspaces?: IWorkspacesSection;
110
63
  [key: string]: unknown;
111
64
  }
112
- /**
113
- * Section in package.json representing dependencies.
114
- */
115
65
  type IDependenciesSection = Record<string, string>;
116
- /**
117
- * Package + version record, collected from the {"package": "^1.2.3"} sections.
118
- */
119
66
  interface IPackageVersion {
120
67
  name: string;
121
68
  version: string;
122
69
  }
123
- /**
124
- * Describes how a package may be typed.
125
- */
126
70
  interface IPackageTypingDescriptor {
127
71
  typingsName: string;
128
72
  codePackageName: string;
129
73
  typesPackageName: string;
130
74
  }
131
- /**
132
- * A type definition with the corresponding code package name.
133
- */
134
75
  interface ISyncedTypeDefinition extends IPackageTypingDescriptor {
135
76
  codePackageName: string;
136
77
  }
137
- /**
138
- * Sync result.
139
- */
140
78
  interface ISyncResult {
141
79
  /**
142
80
  * The files that were synced.
143
81
  */
144
82
  syncedFiles: Array<ISyncedFile>;
145
83
  }
146
- /**
147
- * A file that was synced.
148
- */
149
84
  interface ISyncedFile {
150
85
  /**
151
86
  * The cwd-relative path to the synced file.
@@ -160,26 +95,19 @@ interface ISyncedFile {
160
95
  */
161
96
  newTypings: Array<ISyncedTypeDefinition>;
162
97
  }
163
- /**
164
- * Dependency sections.
165
- */
166
98
  declare enum IDependencySection {
167
99
  dev = "dev",
168
100
  deps = "deps",
169
101
  optional = "optional",
170
102
  peer = "peer",
171
103
  }
172
- /**
173
- * CLI arguments.
174
- */
175
104
  interface ICLIArguments {
176
105
  flags: Record<string, boolean | string | undefined>;
177
106
  args: Array<string>;
178
107
  }
179
108
 
180
- /**
181
- * Config Service.
182
- */
109
+ //#endregion
110
+ //#region dist/.tsdown-types-es/config-service.d.ts
183
111
  interface IConfigService {
184
112
  /**
185
113
  * Get typesync config.
@@ -188,17 +116,15 @@ interface IConfigService {
188
116
  }
189
117
  declare function createConfigService(): IConfigService;
190
118
 
191
- /**
192
- * Version descriptor for versions returned in remote package info.
193
- */
119
+ //#endregion
120
+ //#region dist/.tsdown-types-es/versioning.d.ts
194
121
  interface IPackageVersionInfo {
195
122
  version: string;
196
123
  containsInternalTypings: boolean;
197
124
  }
198
125
 
199
- /**
200
- * Fetches info about a package.
201
- */
126
+ //#endregion
127
+ //#region dist/.tsdown-types-es/package-source.d.ts
202
128
  interface IPackageSource {
203
129
  /**
204
130
  * Fetches package info from an external source.
@@ -207,23 +133,16 @@ interface IPackageSource {
207
133
  */
208
134
  fetch(this: void, packageName: string): Promise<IPackageInfo | null>;
209
135
  }
210
- /**
211
- * Interface for the Package Info structure.
212
- */
213
136
  interface IPackageInfo {
214
137
  name: string;
215
138
  latestVersion: string;
216
139
  deprecated: boolean;
217
140
  versions: Array<IPackageVersionInfo>;
218
141
  }
219
- /**
220
- * Creates a package source.
221
- */
222
142
  declare function createPackageSource(): IPackageSource;
223
143
 
224
- /**
225
- * File service.
226
- */
144
+ //#endregion
145
+ //#region dist/.tsdown-types-es/package-json-file-service.d.ts
227
146
  interface IPackageJSONService {
228
147
  /**
229
148
  * Reads and parses JSON from the specified file. Path is relative to the current working directory.
@@ -235,12 +154,9 @@ interface IPackageJSONService {
235
154
  writePackageFile(this: void, filePath: string, fileContents: IPackageFile): Promise<void>;
236
155
  }
237
156
 
238
- /**
239
- * Creates a type syncer.
240
- *
241
- * @param packageJSONservice
242
- * @param typeDefinitionSource
243
- */
157
+ //#endregion
158
+ //#region dist/.tsdown-types-es/type-syncer.d.ts
244
159
  declare function createTypeSyncer(packageJSONService: IPackageJSONService, workspaceResolverService: IWorkspaceResolverService, packageSource: IPackageSource, configService: IConfigService, globber: IGlobber): ITypeSyncer;
245
160
 
246
- export { type ICLIArguments, type IConfigService, type IDependenciesSection, IDependencySection, type IPackageFile, type IPackageInfo, type IPackageSource, type IPackageTypingDescriptor, type IPackageVersion, type ISyncOptions, type ISyncResult, type ISyncedFile, type ISyncedTypeDefinition, type ITypeSyncer, createConfigService, createPackageSource, createTypeSyncer };
161
+ //#endregion
162
+ export { ICLIArguments, IConfigService, IDependenciesSection, IDependencySection, IPackageFile, IPackageInfo, IPackageSource, IPackageTypingDescriptor, IPackageVersion, ISyncOptions, ISyncResult, ISyncedFile, ISyncedTypeDefinition, ITypeSyncer, createConfigService, createPackageSource, createTypeSyncer };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { IDependencySection, createConfigService, createPackageSource, createTypeSyncer } from "./type-syncer-D93oGCvC.js";
1
+ import { IDependencySection, createConfigService, createPackageSource, createTypeSyncer } from "./type-syncer-D40qMMFq.js";
2
2
 
3
3
  export { IDependencySection, createConfigService, createPackageSource, createTypeSyncer };
@@ -1,11 +1,12 @@
1
1
  import * as path$1 from "node:path";
2
2
  import * as path from "node:path";
3
- import { cosmiconfig } from "cosmiconfig";
3
+ import { defaultLoaders, lilconfig } from "lilconfig";
4
+ import * as yaml from "yaml";
4
5
  import fetch from "npm-registry-fetch";
5
6
  import { compare, parse } from "semver";
6
7
 
7
8
  //#region src/types.ts
8
- let IDependencySection = function(IDependencySection$1) {
9
+ let IDependencySection = /* @__PURE__ */ function(IDependencySection$1) {
9
10
  IDependencySection$1["dev"] = "dev";
10
11
  IDependencySection$1["deps"] = "deps";
11
12
  IDependencySection$1["optional"] = "optional";
@@ -20,7 +21,7 @@ function uniq(source) {
20
21
  }
21
22
  function shrinkObject(source) {
22
23
  const object = {};
23
- for (const key in source) if (source[key] !== undefined) object[key] = source[key];
24
+ for (const key in source) if (source[key] !== void 0) object[key] = source[key];
24
25
  return object;
25
26
  }
26
27
  function mergeObjects(source) {
@@ -63,7 +64,37 @@ function memoizeAsync(fn) {
63
64
 
64
65
  //#endregion
65
66
  //#region src/config-service.ts
66
- const explorer = cosmiconfig("typesync");
67
+ async function loadYaml(_filepath, content) {
68
+ return await yaml.parse(content);
69
+ }
70
+ function searchPlaces(moduleName) {
71
+ const rcs = [
72
+ `.${moduleName}rc`,
73
+ `.${moduleName}rc.json`,
74
+ `.${moduleName}rc.yaml`,
75
+ `.${moduleName}rc.yml`,
76
+ `.${moduleName}rc.js`,
77
+ `.${moduleName}rc.mjs`,
78
+ `.${moduleName}rc.cjs`
79
+ ];
80
+ return [
81
+ "package.json",
82
+ ...rcs,
83
+ ...rcs.map((rc) => `.config/${rc}`),
84
+ `${moduleName}.config.js`,
85
+ `${moduleName}.config.mjs`,
86
+ `${moduleName}.config.cjs`
87
+ ];
88
+ }
89
+ const explorer = lilconfig("typesync", {
90
+ searchPlaces: searchPlaces("typesync"),
91
+ loaders: {
92
+ ...defaultLoaders,
93
+ ".yml": loadYaml,
94
+ ".yaml": loadYaml,
95
+ noExt: loadYaml
96
+ }
97
+ });
67
98
  function createConfigService() {
68
99
  return { readConfig: async (filePath, flags) => {
69
100
  const fileConfig = await explorer.search(path$1.dirname(filePath)).then((result) => result?.config ?? {});
@@ -77,7 +108,7 @@ function createConfigService() {
77
108
  function readCliConfig(flags) {
78
109
  const readValues = (key, validator) => {
79
110
  const values = flags[key];
80
- return typeof values === "string" ? values.split(",").filter((value) => validator ? validator(value) : true) : undefined;
111
+ return typeof values === "string" ? values.split(",").filter((value) => validator ? validator(value) : true) : void 0;
81
112
  };
82
113
  return {
83
114
  ignoreDeps: readValues("ignoredeps", isIgnoreDepConfigValue),
@@ -312,4 +343,4 @@ function getDependenciesBySection(file, section) {
312
343
 
313
344
  //#endregion
314
345
  export { IDependencySection, createConfigService, createPackageSource, createTypeSyncer, uniq };
315
- //# sourceMappingURL=type-syncer-D93oGCvC.js.map
346
+ //# sourceMappingURL=type-syncer-D40qMMFq.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-syncer-D40qMMFq.js","names":["source: Array<T>","source: T","object: Partial<T>","name: string","comparer?: (a: string, b: string) => number","result: Record<string, U>","fn: (...args: U) => Promise<V>","_filepath: string","content: string","moduleName: string","filePath: string","flags: ICLIArguments['flags']","fileConfig: ISyncOptions","key: string","validator?: (value: string) => boolean","value: string","availableVersions: Array<IPackageVersionInfo>","version: string","packageJSONService: IPackageJSONService","workspaceResolverService: IWorkspaceResolverService","packageSource: IPackageSource","configService: IConfigService","globber: IGlobber","filePath: string","flags: ICLIArguments['flags']","syncedFiles: Array<ISyncedFile>","ignoredWorkspaces: IWorkspacesArray","file: IPackageFile","opts: ISyncOptions","dryRun: boolean","used: ReturnType<typeof getPotentiallyUntypedPackages>","newPackageFile: IPackageFile","allPackageNames: Array<string>","packageName: string","section: IDependenciesSection","ignoredSection?: boolean","ignorePackages?: Array<string>","section: IDependencySection"],"sources":["../src/types.ts","../src/util.ts","../src/config-service.ts","../src/package-source.ts","../src/versioning.ts","../src/type-syncer.ts"],"sourcesContent":["import type { IWorkspacesArray, IWorkspacesSection } from './workspace-resolver'\n\n/**\n * The guts of the program.\n */\nexport interface ITypeSyncer {\n sync(\n this: void,\n filePath: string,\n flags: ICLIArguments['flags'],\n ): Promise<ISyncResult>\n}\n\n/**\n * Sync options.\n */\nexport interface ISyncOptions {\n /**\n * Ignore certain deps.\n */\n ignoreDeps?: Array<IDependencySection>\n\n /**\n * Ignore certain packages.\n */\n ignorePackages?: Array<string>\n\n /**\n * Skip resolution of certain projects in the workspace.\n */\n ignoreProjects?: IWorkspacesArray\n}\n\n/**\n * Package.json file.\n */\nexport interface IPackageFile {\n name?: string\n dependencies?: IDependenciesSection\n devDependencies?: IDependenciesSection\n peerDependencies?: IDependenciesSection\n optionalDependencies?: IDependenciesSection\n workspaces?: IWorkspacesSection\n [key: string]: unknown\n}\n\n/**\n * Section in package.json representing dependencies.\n */\nexport type IDependenciesSection = Record<string, string>\n\n/**\n * Package + version record, collected from the {\"package\": \"^1.2.3\"} sections.\n */\nexport interface IPackageVersion {\n name: string\n version: string\n}\n\n/**\n * Describes how a package may be typed.\n */\nexport interface IPackageTypingDescriptor {\n typingsName: string\n codePackageName: string\n typesPackageName: string\n}\n\n/**\n * A type definition with the corresponding code package name.\n */\nexport interface ISyncedTypeDefinition extends IPackageTypingDescriptor {\n codePackageName: string\n}\n\n/**\n * Sync result.\n */\nexport interface ISyncResult {\n /**\n * The files that were synced.\n */\n syncedFiles: Array<ISyncedFile>\n}\n\n/**\n * A file that was synced.\n */\nexport interface ISyncedFile {\n /**\n * The cwd-relative path to the synced file.\n */\n filePath: string\n /**\n * The package file that was synced.\n */\n package: IPackageFile\n /**\n * The new typings that were added.\n */\n newTypings: Array<ISyncedTypeDefinition>\n}\n\n/**\n * Dependency sections.\n */\nexport enum IDependencySection {\n dev = 'dev',\n deps = 'deps',\n optional = 'optional',\n peer = 'peer',\n}\n\n/**\n * CLI arguments.\n */\nexport interface ICLIArguments {\n flags: Record<string, boolean | string | undefined>\n args: Array<string>\n}\n","/**\n * Returns unique items.\n *\n * @param source The source to filter\n */\nexport function uniq<T>(source: Array<T>): Array<T> {\n return [...new Set(source)]\n}\n\n/**\n * Remove blank attributes in a object.\n *\n * @param source\n */\nexport function shrinkObject<T extends object>(source: T): Partial<T> {\n const object: Partial<T> = {}\n\n for (const key in source) {\n if (source[key] !== undefined) {\n object[key] = source[key]\n }\n }\n\n return object\n}\n\n/**\n * Merges a sequence of objects into a single object using `reduce`.\n *\n * @param source An array of objects to merge.\n */\nexport function mergeObjects<T>(source: Array<T>): T {\n return source.reduce((accum, next) => ({ ...accum, ...next }), {} as T)\n}\n\n/**\n * Returns the assumed types package name.\n * @param name Package name\n */\nexport function typed(name: string): string {\n // If the package is scoped, the typings scheme is slightly different.\n if (/^@.*?\\//i.test(name)) {\n const splat = name.split('/')\n return `@types/${splat[0].slice(1)}__${splat[1]}`\n }\n\n return `@types/${name}`\n}\n\n/**\n * Returns the assumed code package name based on a types package name.\n * @param name\n */\nexport function untyped(name: string): string {\n const prefix = '@types/'\n if (!name.startsWith(prefix)) {\n return name\n }\n name = name.substring(prefix.length)\n const splat = name.split('__')\n if (splat.length === 2) {\n return `@${splat[0]}/${splat[1]}`\n }\n return name\n}\n\n/**\n * Orders an object.\n * @param source\n */\nexport function orderObject<T extends Record<string | number | symbol, U>, U>(\n source: T,\n comparer?: (a: string, b: string) => number,\n): T {\n const keys = Object.keys(source).sort(comparer)\n const result: Record<string, U> = {}\n for (const key of keys) {\n result[key] = source[key]\n }\n\n return result as T\n}\n\n/**\n * Async memoize.\n *\n * @param fn\n */\nexport function memoizeAsync<U extends Array<W>, V, W>(\n fn: (...args: U) => Promise<V>,\n) {\n const cache = new Map<W, Promise<V>>()\n\n async function run(...args: U): Promise<V> {\n try {\n return await fn(...args)\n } catch (err) {\n cache.delete(args[0])\n throw err\n }\n }\n\n return async function (...args: U): Promise<V> {\n const key = args[0]\n if (cache.has(key)) {\n return await cache.get(key)!\n }\n\n const p = run(...args)\n cache.set(key, p)\n return await p\n }\n}\n","import * as path from 'node:path'\nimport { defaultLoaders, lilconfig } from 'lilconfig'\nimport {\n type ICLIArguments,\n IDependencySection,\n type ISyncOptions,\n} from './types'\nimport { shrinkObject } from './util'\nimport * as yaml from 'yaml'\n\n/**\n * Config Service.\n */\nexport interface IConfigService {\n /**\n * Get typesync config.\n */\n readConfig(\n this: void,\n filePath: string,\n flags: ICLIArguments['flags'],\n ): Promise<ISyncOptions>\n}\n\nasync function loadYaml(_filepath: string, content: string): Promise<unknown> {\n return await yaml.parse(content)\n}\n\n// Based on Cosmiconfig readme.\nfunction searchPlaces(moduleName: string) {\n const rcs = [\n `.${moduleName}rc`,\n `.${moduleName}rc.json`,\n `.${moduleName}rc.yaml`,\n `.${moduleName}rc.yml`,\n `.${moduleName}rc.js`,\n `.${moduleName}rc.mjs`,\n `.${moduleName}rc.cjs`,\n ]\n\n return [\n 'package.json',\n ...rcs,\n ...rcs.map((rc) => `.config/${rc}`),\n `${moduleName}.config.js`,\n `${moduleName}.config.mjs`,\n `${moduleName}.config.cjs`,\n ]\n}\n\nconst explorer = lilconfig('typesync', {\n searchPlaces: searchPlaces('typesync'),\n loaders: {\n ...defaultLoaders,\n '.yml': loadYaml,\n '.yaml': loadYaml,\n noExt: loadYaml,\n },\n})\n\nexport function createConfigService(): IConfigService {\n return {\n readConfig: async (filePath: string, flags: ICLIArguments['flags']) => {\n const fileConfig: ISyncOptions = await explorer\n .search(path.dirname(filePath))\n .then((result) => /* v8 ignore next */ result?.config ?? {})\n\n const cliConfig = readCliConfig(flags)\n\n return { ...shrinkObject(fileConfig), ...shrinkObject(cliConfig) }\n },\n }\n}\n\nfunction readCliConfig(flags: ICLIArguments['flags']): ISyncOptions {\n const readValues = <T extends string>(\n key: string,\n validator?: (value: string) => boolean,\n ): Array<T> | undefined => {\n const values = flags[key]\n return typeof values === 'string'\n ? values\n .split(',')\n .filter((value): value is T => (validator ? validator(value) : true))\n : undefined\n }\n\n return {\n ignoreDeps: readValues('ignoredeps', isIgnoreDepConfigValue),\n ignorePackages: readValues('ignorepackages'),\n ignoreProjects: readValues('ignoreprojects'),\n }\n}\n\nfunction isIgnoreDepConfigValue(value: string): value is IDependencySection {\n return Object.keys(IDependencySection).includes(value)\n}\n","import fetch from 'npm-registry-fetch'\nimport { compare } from 'semver'\nimport type { IPackageVersionInfo } from './versioning'\n\n/**\n * Fetches info about a package.\n */\nexport interface IPackageSource {\n /**\n * Fetches package info from an external source.\n *\n * @param packageName\n */\n fetch(this: void, packageName: string): Promise<IPackageInfo | null>\n}\n\n/**\n * Interface for the Package Info structure.\n */\nexport interface IPackageInfo {\n name: string\n latestVersion: string\n deprecated: boolean\n versions: Array<IPackageVersionInfo>\n}\n\n/**\n * Creates a package source.\n */\nexport function createPackageSource(): IPackageSource {\n return {\n /**\n * Fetches info about a package, or `null` if not found.\n */\n fetch: async (name) => {\n const response = await fetch(encodeURI(name)).catch((err) => {\n if (err.statusCode === 404) {\n return null\n /* v8 ignore next */\n }\n\n /* v8 ignore next */\n throw err\n })\n\n const data = await response?.json()\n\n if (!data?.versions) {\n return null\n }\n\n const versionIdentifiers = Object.keys(data.versions)\n .sort(compare)\n .reverse()\n const versions = versionIdentifiers.map<IPackageVersionInfo>((v) => {\n const item = data.versions[v]\n return {\n version: item.version,\n containsInternalTypings: !!item.types || !!item.typings,\n }\n })\n\n return {\n name: data.name,\n deprecated: Boolean(data.versions[versionIdentifiers[0]].deprecated),\n latestVersion: data['dist-tags'].latest,\n // Sort by version, highest version first.\n versions: versions,\n }\n },\n }\n}\n","import { parse } from 'semver'\n\n/**\n * Version descriptor for versions returned in remote package info.\n */\nexport interface IPackageVersionInfo {\n version: string\n containsInternalTypings: boolean\n}\n\n/**\n * Gets the closest matching package version info.\n *\n * @param availableVersions\n * @param version\n */\nexport function getClosestMatchingVersion(\n availableVersions: Array<IPackageVersionInfo>,\n version: string,\n): IPackageVersionInfo {\n const parsedVersion = parseVersion(version)\n if (!parsedVersion) {\n return availableVersions[0]\n }\n\n const bestMatch = availableVersions.find((v) => {\n const parsedAvailableVersion = parseVersion(v.version)\n if (!parsedAvailableVersion) {\n return false\n }\n\n if (parsedVersion.major !== parsedAvailableVersion.major) {\n return false\n }\n\n if (parsedVersion.minor !== parsedAvailableVersion.minor) {\n return false\n }\n\n return true\n })\n\n return bestMatch ?? availableVersions[0]\n}\n\n/**\n * Parses the version if possible.\n *\n * @param version\n * @returns\n */\nfunction parseVersion(version: string) {\n return parse(cleanVersion(version))\n}\n\n/**\n * Cleans the version of any semver range specifiers.\n * @param version\n * @returns\n */\nfunction cleanVersion(version: string) {\n return version.replace(/^[\\^~=\\s]/, '')\n}\n","import * as path from 'node:path'\nimport type { IConfigService } from './config-service'\nimport type { IGlobber } from './globber'\nimport type { IPackageJSONService } from './package-json-file-service'\nimport type { IPackageSource } from './package-source'\nimport {\n type ICLIArguments,\n type IDependenciesSection,\n IDependencySection,\n type IPackageFile,\n type IPackageTypingDescriptor,\n type IPackageVersion,\n type ISyncOptions,\n type ISyncResult,\n type ISyncedFile,\n type ITypeSyncer,\n} from './types'\nimport { memoizeAsync, mergeObjects, orderObject, typed, uniq } from './util'\nimport { getClosestMatchingVersion } from './versioning'\nimport type {\n IWorkspaceResolverService,\n IWorkspacesArray,\n} from './workspace-resolver'\n\n/**\n * Creates a type syncer.\n *\n * @param packageJSONservice\n * @param typeDefinitionSource\n */\nexport function createTypeSyncer(\n packageJSONService: IPackageJSONService,\n workspaceResolverService: IWorkspaceResolverService,\n packageSource: IPackageSource,\n configService: IConfigService,\n globber: IGlobber,\n): ITypeSyncer {\n const fetchPackageInfo = memoizeAsync(packageSource.fetch)\n\n return {\n sync,\n }\n\n /**\n * Syncs typings in the specified package.json.\n */\n async function sync(\n filePath: string,\n flags: ICLIArguments['flags'],\n ): Promise<ISyncResult> {\n const dryRun = !!flags.dry\n const syncOpts = await configService.readConfig(filePath, flags)\n const { file, subManifests } = await getManifests(\n filePath,\n globber,\n syncOpts.ignoreProjects ?? [],\n )\n\n const syncedFiles: Array<ISyncedFile> = await Promise.all([\n syncFile(filePath, file, syncOpts, dryRun),\n ...subManifests.map(\n async (p) =>\n await syncFile(\n p,\n await packageJSONService.readPackageFile(p),\n syncOpts,\n dryRun,\n ),\n ),\n ])\n\n return {\n syncedFiles,\n }\n }\n\n /**\n * Get the `package.json` files and sub-packages.\n *\n * @param filePath\n * @param globber\n */\n async function getManifests(\n filePath: string,\n globber: IGlobber,\n ignoredWorkspaces: IWorkspacesArray,\n ) {\n const root = path.dirname(filePath)\n const file = await packageJSONService.readPackageFile(filePath)\n const subPackages = await workspaceResolverService.getWorkspaces(\n file,\n root,\n globber,\n ignoredWorkspaces,\n )\n const subManifests = subPackages.map((p) =>\n path.join(root, p, 'package.json'),\n )\n\n return {\n file,\n subManifests,\n }\n }\n\n /**\n * Syncs a single file.\n *\n * @param filePath\n * @param file\n * @param allTypings\n * @param opts\n */\n async function syncFile(\n filePath: string,\n file: IPackageFile,\n opts: ISyncOptions,\n dryRun: boolean,\n ): Promise<ISyncedFile> {\n const { ignoreDeps, ignorePackages } = opts\n\n const allLocalPackages = Object.values(IDependencySection)\n .map((dep) => {\n const section = getDependenciesBySection(file, dep)\n if (!section) return []\n\n const ignoredSection = ignoreDeps?.includes(dep)\n return getPackagesFromSection(section, ignoredSection, ignorePackages)\n })\n .flat()\n const allPackageNames = uniq(allLocalPackages.map((p) => p.name))\n const potentiallyUntypedPackages =\n getPotentiallyUntypedPackages(allPackageNames)\n\n // This is pushed to in the inner `map`, because packages that have DT-typings\n // *as well* as internal typings should be excluded.\n const used: ReturnType<typeof getPotentiallyUntypedPackages> = []\n const devDepsToAdd = await Promise.all(\n potentiallyUntypedPackages.map(async (t) => {\n // Fetch the code package from the source.\n const typePackageInfoPromise = fetchPackageInfo(t.typesPackageName)\n const codePackageInfo = await fetchPackageInfo(t.codePackageName)\n\n // If the code package was not found, there's nothing else to do.\n if (!codePackageInfo) {\n return {}\n }\n\n const localCodePackage = allLocalPackages.find(\n (p) => p.name === t.codePackageName,\n )!\n\n // Find the closest matching code package version relative to what's in our package.json\n const closestMatchingCodeVersion = getClosestMatchingVersion(\n codePackageInfo.versions,\n localCodePackage.version,\n )\n\n // If the closest matching version contains internal typings, don't include it.\n if (closestMatchingCodeVersion.containsInternalTypings) {\n return {}\n }\n\n // Look for the closest matching typings package.\n const typePackageInfo = await typePackageInfoPromise\n\n // If the types package was not found, or if it was deprecated, there's nothing else to do.\n if (!typePackageInfo || typePackageInfo.deprecated) {\n return {}\n }\n\n // Gets the closest matching typings version, or the newest one.\n const closestMatchingTypingsVersion = getClosestMatchingVersion(\n typePackageInfo.versions,\n localCodePackage.version,\n )\n\n const version = closestMatchingTypingsVersion.version\n const semverRangeSpecifier = '~'\n used.push(t)\n return {\n [t.typesPackageName]: semverRangeSpecifier + version,\n }\n }),\n ).then(mergeObjects)\n const devDeps = file.devDependencies\n if (!dryRun) {\n const newPackageFile: IPackageFile = { ...file }\n\n if (Object.keys(devDepsToAdd).length > 0) {\n newPackageFile.devDependencies = orderObject({\n ...devDepsToAdd,\n ...devDeps,\n })\n\n await packageJSONService.writePackageFile(filePath, newPackageFile)\n }\n }\n\n return {\n filePath,\n newTypings: used,\n package: file,\n }\n }\n}\n\n/**\n * Returns an array of packages that do not have a `@types/` package.\n *\n * @param allPackageNames Used to filter the typings that are new.\n * @param allTypings All typings available\n */\nfunction getPotentiallyUntypedPackages(\n allPackageNames: Array<string>,\n): Array<IPackageTypingDescriptor> {\n const existingTypings = allPackageNames.filter((x) => x.startsWith('@types/'))\n\n return allPackageNames.flatMap((p) => {\n // Ignore typings packages themselves.\n if (p.startsWith('@types/')) {\n return []\n }\n\n const typingsName = getTypingsName(p)\n const fullTypingsPackage = typed(p)\n const alreadyHasTyping = existingTypings.includes(fullTypingsPackage)\n if (alreadyHasTyping) {\n return []\n }\n\n return [\n {\n typingsName: typingsName,\n typesPackageName: fullTypingsPackage,\n codePackageName: p,\n },\n ]\n })\n}\n\n/**\n * Gets the typings name for the specified package name.\n * For example, `koa` would be `koa`, but `@koa/router` would be `koa__router`.\n *\n * @param packageName the package name to generate the typings name for\n */\nfunction getTypingsName(packageName: string) {\n const scopeInfo = getPackageScope(packageName)\n\n return scopeInfo && scopeInfo[0] !== 'types'\n ? `${scopeInfo[0]}__${scopeInfo[1]}`\n : packageName\n}\n\n/**\n * If a package is scoped, returns the scope + package as a tuple, otherwise null.\n *\n * @param packageName Package name to check scope for.\n */\nfunction getPackageScope(packageName: string): [string, string] | null {\n const EXPR = /^@([^/]+)\\/(.*)$/i\n const matches = EXPR.exec(packageName)\n if (!matches) {\n return null\n }\n\n return [matches[1], matches[2]]\n}\n\n/**\n * Get packages from a dependency section\n *\n * @param section\n * @param ignoredSection\n * @param ignorePackages\n */\nfunction getPackagesFromSection(\n section: IDependenciesSection,\n ignoredSection?: boolean,\n ignorePackages?: Array<string>,\n): Array<IPackageVersion> {\n return Object.keys(section).flatMap((name) => {\n const isTyping = name.startsWith('@types/')\n\n // Never ignore `@types` packages.\n if (!isTyping) {\n // If it's not a `@types` package, check whether the section or package is ignored.\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- We want to check for false as well.\n if (ignoredSection || ignorePackages?.includes(name)) {\n return []\n }\n }\n\n return [{ name, version: section[name] }]\n })\n}\n\n/**\n * Get dependencies from a package section\n *\n * @param file Package file\n * @param section Package section, eg: dev, peer\n */\nfunction getDependenciesBySection(\n file: IPackageFile,\n section: IDependencySection,\n): IDependenciesSection | undefined {\n const dependenciesSection = (() => {\n switch (section) {\n case IDependencySection.deps:\n return file.dependencies\n case IDependencySection.dev:\n return file.devDependencies\n case IDependencySection.optional:\n return file.optionalDependencies\n case IDependencySection.peer:\n return file.peerDependencies\n }\n })()\n return dependenciesSection\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typesync",
3
- "version": "0.14.1",
3
+ "version": "0.14.3",
4
4
  "type": "module",
5
5
  "description": "Install missing TypeScript typings for your dependencies.",
6
6
  "engines": {
@@ -29,7 +29,7 @@
29
29
  "lint:watch": "nodemon --exec npm run lint",
30
30
  "build": "tsdown",
31
31
  "build:watch": "tsdown --watch",
32
- "run-cli": "npm run build && node bin/typesync",
32
+ "run-cli": "npm run build -- --silent && node bin/typesync",
33
33
  "run-cli:dry": "npm run run-cli -- --dry",
34
34
  "do:publish": "npm run lint && npm run test && npm run build && npm publish",
35
35
  "release:patch": "npm version patch && npm run do:publish && git push --follow-tags",
@@ -47,33 +47,33 @@
47
47
  },
48
48
  "homepage": "https://github.com/jeffijoe/typesync#readme",
49
49
  "dependencies": {
50
- "awilix": "^12.0.4",
51
- "chalk": "^5.4.1",
52
- "cosmiconfig": "^9.0.0",
50
+ "ansis": "^3.17.0",
51
+ "awilix": "^12.0.5",
53
52
  "detect-indent": "^7.0.1",
54
- "js-yaml": "^4.1.0",
53
+ "lilconfig": "^3.1.3",
55
54
  "npm-registry-fetch": "^18.0.2",
56
- "ora": "^8.1.1",
55
+ "picospinner": "^3.0.0",
57
56
  "semver": "^7.7.0",
58
- "tinyglobby": "^0.2.10"
57
+ "tinyglobby": "^0.2.12",
58
+ "yaml": "^2.7.1"
59
59
  },
60
60
  "devDependencies": {
61
- "@eslint/js": "^9.19.0",
62
- "@types/js-yaml": "~4.0.9 || ~4.1.0",
63
- "@types/node": "^22.13.0",
64
- "@types/npm-registry-fetch": "^8.0.7 || ~17.1.0",
65
- "@types/semver": "~7.5.8 || ~7.6.0",
66
- "@vitest/coverage-v8": "^3.0.4",
67
- "@vitest/ui": "^3.0.4",
68
- "eslint": "^9.19.0",
69
- "globals": "^15.14.0",
61
+ "@eslint/js": "^9.23.0",
62
+ "@types/node": "^22.13.17",
63
+ "@types/npm-registry-fetch": "^8.0.7 || ~18.0.0",
64
+ "@types/semver": "~7.7.0",
65
+ "@vitest/coverage-v8": "^3.1.1",
66
+ "@vitest/ui": "^3.1.1",
67
+ "eslint": "^9.23.0",
68
+ "globals": "^16.0.0",
70
69
  "nodemon": "^3.1.9",
71
- "oxc-transform": "^0.48.1",
72
- "prettier": "^3.4.2",
73
- "tsdown": "^0.5.6",
74
- "typescript": "^5.7.3",
75
- "typescript-eslint": "^8.22.0",
76
- "vitest": "^3.0.4"
70
+ "prettier": "^3.5.3",
71
+ "publint": "^0.3.9",
72
+ "tsdown": "^0.7.2",
73
+ "typescript": "^5.8.2",
74
+ "typescript-eslint": "^8.29.0",
75
+ "unplugin-unused": "^0.4.4",
76
+ "vitest": "^3.1.1"
77
77
  },
78
78
  "packageManager": "npm@10.8.2"
79
79
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"type-syncer-D93oGCvC.js","names":["source: Array<T>","source: T","object: Partial<T>","name: string","comparer?: (a: string, b: string) => number","result: Record<string, U>","fn: (...args: U) => Promise<V>","filePath: string","flags: ICLIArguments['flags']","fileConfig: ISyncOptions","key: string","validator?: (value: string) => boolean","value: string","availableVersions: Array<IPackageVersionInfo>","version: string","packageJSONService: IPackageJSONService","workspaceResolverService: IWorkspaceResolverService","packageSource: IPackageSource","configService: IConfigService","globber: IGlobber","filePath: string","flags: ICLIArguments['flags']","syncedFiles: Array<ISyncedFile>","ignoredWorkspaces: IWorkspacesArray","globber","file: IPackageFile","opts: ISyncOptions","dryRun: boolean","used: ReturnType<typeof getPotentiallyUntypedPackages>","newPackageFile: IPackageFile","allPackageNames: Array<string>","packageName: string","section: IDependenciesSection","ignoredSection?: boolean","ignorePackages?: Array<string>","section: IDependencySection"],"sources":["../src/types.ts","../src/util.ts","../src/config-service.ts","../src/package-source.ts","../src/versioning.ts","../src/type-syncer.ts"],"sourcesContent":["import type { IWorkspacesArray, IWorkspacesSection } from './workspace-resolver'\n\n/**\n * The guts of the program.\n */\nexport interface ITypeSyncer {\n sync(\n this: void,\n filePath: string,\n flags: ICLIArguments['flags'],\n ): Promise<ISyncResult>\n}\n\n/**\n * Sync options.\n */\nexport interface ISyncOptions {\n /**\n * Ignore certain deps.\n */\n ignoreDeps?: Array<IDependencySection>\n\n /**\n * Ignore certain packages.\n */\n ignorePackages?: Array<string>\n\n /**\n * Skip resolution of certain projects in the workspace.\n */\n ignoreProjects?: IWorkspacesArray\n}\n\n/**\n * Package.json file.\n */\nexport interface IPackageFile {\n name?: string\n dependencies?: IDependenciesSection\n devDependencies?: IDependenciesSection\n peerDependencies?: IDependenciesSection\n optionalDependencies?: IDependenciesSection\n workspaces?: IWorkspacesSection\n [key: string]: unknown\n}\n\n/**\n * Section in package.json representing dependencies.\n */\nexport type IDependenciesSection = Record<string, string>\n\n/**\n * Package + version record, collected from the {\"package\": \"^1.2.3\"} sections.\n */\nexport interface IPackageVersion {\n name: string\n version: string\n}\n\n/**\n * Describes how a package may be typed.\n */\nexport interface IPackageTypingDescriptor {\n typingsName: string\n codePackageName: string\n typesPackageName: string\n}\n\n/**\n * A type definition with the corresponding code package name.\n */\nexport interface ISyncedTypeDefinition extends IPackageTypingDescriptor {\n codePackageName: string\n}\n\n/**\n * Sync result.\n */\nexport interface ISyncResult {\n /**\n * The files that were synced.\n */\n syncedFiles: Array<ISyncedFile>\n}\n\n/**\n * A file that was synced.\n */\nexport interface ISyncedFile {\n /**\n * The cwd-relative path to the synced file.\n */\n filePath: string\n /**\n * The package file that was synced.\n */\n package: IPackageFile\n /**\n * The new typings that were added.\n */\n newTypings: Array<ISyncedTypeDefinition>\n}\n\n/**\n * Dependency sections.\n */\nexport enum IDependencySection {\n dev = 'dev',\n deps = 'deps',\n optional = 'optional',\n peer = 'peer',\n}\n\n/**\n * CLI arguments.\n */\nexport interface ICLIArguments {\n flags: Record<string, boolean | string | undefined>\n args: Array<string>\n}\n","/**\n * Returns unique items.\n *\n * @param source The source to filter\n */\nexport function uniq<T>(source: Array<T>): Array<T> {\n return [...new Set(source)]\n}\n\n/**\n * Remove blank attributes in a object.\n *\n * @param source\n */\nexport function shrinkObject<T extends object>(source: T): Partial<T> {\n const object: Partial<T> = {}\n\n for (const key in source) {\n if (source[key] !== undefined) {\n object[key] = source[key]\n }\n }\n\n return object\n}\n\n/**\n * Merges a sequence of objects into a single object using `reduce`.\n *\n * @param source An array of objects to merge.\n */\nexport function mergeObjects<T>(source: Array<T>): T {\n return source.reduce((accum, next) => ({ ...accum, ...next }), {} as T)\n}\n\n/**\n * Returns the assumed types package name.\n * @param name Package name\n */\nexport function typed(name: string): string {\n // If the package is scoped, the typings scheme is slightly different.\n if (/^@.*?\\//i.test(name)) {\n const splat = name.split('/')\n return `@types/${splat[0].slice(1)}__${splat[1]}`\n }\n\n return `@types/${name}`\n}\n\n/**\n * Returns the assumed code package name based on a types package name.\n * @param name\n */\nexport function untyped(name: string): string {\n const prefix = '@types/'\n if (!name.startsWith(prefix)) {\n return name\n }\n name = name.substring(prefix.length)\n const splat = name.split('__')\n if (splat.length === 2) {\n return `@${splat[0]}/${splat[1]}`\n }\n return name\n}\n\n/**\n * Orders an object.\n * @param source\n */\nexport function orderObject<T extends Record<string | number | symbol, U>, U>(\n source: T,\n comparer?: (a: string, b: string) => number,\n): T {\n const keys = Object.keys(source).sort(comparer)\n const result: Record<string, U> = {}\n for (const key of keys) {\n result[key] = source[key]\n }\n\n return result as T\n}\n\n/**\n * Async memoize.\n *\n * @param fn\n */\nexport function memoizeAsync<U extends Array<W>, V, W>(\n fn: (...args: U) => Promise<V>,\n) {\n const cache = new Map<W, Promise<V>>()\n\n async function run(...args: U): Promise<V> {\n try {\n return await fn(...args)\n } catch (err) {\n cache.delete(args[0])\n throw err\n }\n }\n\n return async function (...args: U): Promise<V> {\n const key = args[0]\n if (cache.has(key)) {\n return await cache.get(key)!\n }\n\n const p = run(...args)\n cache.set(key, p)\n return await p\n }\n}\n","import * as path from 'node:path'\nimport { cosmiconfig } from 'cosmiconfig'\nimport {\n type ICLIArguments,\n IDependencySection,\n type ISyncOptions,\n} from './types'\nimport { shrinkObject } from './util'\n\n/**\n * Config Service.\n */\nexport interface IConfigService {\n /**\n * Get typesync config.\n */\n readConfig(\n this: void,\n filePath: string,\n flags: ICLIArguments['flags'],\n ): Promise<ISyncOptions>\n}\n\nconst explorer = cosmiconfig('typesync')\n\nexport function createConfigService(): IConfigService {\n return {\n readConfig: async (filePath: string, flags: ICLIArguments['flags']) => {\n const fileConfig: ISyncOptions = await explorer\n .search(path.dirname(filePath))\n .then((result) => /* v8 ignore next */ result?.config ?? {})\n\n const cliConfig = readCliConfig(flags)\n\n return { ...shrinkObject(fileConfig), ...shrinkObject(cliConfig) }\n },\n }\n}\n\nfunction readCliConfig(flags: ICLIArguments['flags']): ISyncOptions {\n const readValues = <T extends string>(\n key: string,\n validator?: (value: string) => boolean,\n ): Array<T> | undefined => {\n const values = flags[key]\n return typeof values === 'string'\n ? values\n .split(',')\n .filter((value): value is T => (validator ? validator(value) : true))\n : undefined\n }\n\n return {\n ignoreDeps: readValues('ignoredeps', isIgnoreDepConfigValue),\n ignorePackages: readValues('ignorepackages'),\n ignoreProjects: readValues('ignoreprojects'),\n }\n}\n\nfunction isIgnoreDepConfigValue(value: string): value is IDependencySection {\n return Object.keys(IDependencySection).includes(value)\n}\n","import fetch from 'npm-registry-fetch'\nimport { compare } from 'semver'\nimport type { IPackageVersionInfo } from './versioning'\n\n/**\n * Fetches info about a package.\n */\nexport interface IPackageSource {\n /**\n * Fetches package info from an external source.\n *\n * @param packageName\n */\n fetch(this: void, packageName: string): Promise<IPackageInfo | null>\n}\n\n/**\n * Interface for the Package Info structure.\n */\nexport interface IPackageInfo {\n name: string\n latestVersion: string\n deprecated: boolean\n versions: Array<IPackageVersionInfo>\n}\n\n/**\n * Creates a package source.\n */\nexport function createPackageSource(): IPackageSource {\n return {\n /**\n * Fetches info about a package, or `null` if not found.\n */\n fetch: async (name) => {\n const response = await fetch(encodeURI(name)).catch((err) => {\n if (err.statusCode === 404) {\n return null\n /* v8 ignore next */\n }\n\n /* v8 ignore next */\n throw err\n })\n\n const data = await response?.json()\n\n if (!data?.versions) {\n return null\n }\n\n const versionIdentifiers = Object.keys(data.versions)\n .sort(compare)\n .reverse()\n const versions = versionIdentifiers.map<IPackageVersionInfo>((v) => {\n const item = data.versions[v]\n return {\n version: item.version,\n containsInternalTypings: !!item.types || !!item.typings,\n }\n })\n\n return {\n name: data.name,\n deprecated: Boolean(data.versions[versionIdentifiers[0]].deprecated),\n latestVersion: data['dist-tags'].latest,\n // Sort by version, highest version first.\n versions: versions,\n }\n },\n }\n}\n","import { parse } from 'semver'\n\n/**\n * Version descriptor for versions returned in remote package info.\n */\nexport interface IPackageVersionInfo {\n version: string\n containsInternalTypings: boolean\n}\n\n/**\n * Gets the closest matching package version info.\n *\n * @param availableVersions\n * @param version\n */\nexport function getClosestMatchingVersion(\n availableVersions: Array<IPackageVersionInfo>,\n version: string,\n): IPackageVersionInfo {\n const parsedVersion = parseVersion(version)\n if (!parsedVersion) {\n return availableVersions[0]\n }\n\n const bestMatch = availableVersions.find((v) => {\n const parsedAvailableVersion = parseVersion(v.version)\n if (!parsedAvailableVersion) {\n return false\n }\n\n if (parsedVersion.major !== parsedAvailableVersion.major) {\n return false\n }\n\n if (parsedVersion.minor !== parsedAvailableVersion.minor) {\n return false\n }\n\n return true\n })\n\n return bestMatch ?? availableVersions[0]\n}\n\n/**\n * Parses the version if possible.\n *\n * @param version\n * @returns\n */\nfunction parseVersion(version: string) {\n return parse(cleanVersion(version))\n}\n\n/**\n * Cleans the version of any semver range specifiers.\n * @param version\n * @returns\n */\nfunction cleanVersion(version: string) {\n return version.replace(/^[\\^~=\\s]/, '')\n}\n","import * as path from 'node:path'\nimport type { IConfigService } from './config-service'\nimport type { IGlobber } from './globber'\nimport type { IPackageJSONService } from './package-json-file-service'\nimport type { IPackageSource } from './package-source'\nimport {\n type ICLIArguments,\n type IDependenciesSection,\n IDependencySection,\n type IPackageFile,\n type IPackageTypingDescriptor,\n type IPackageVersion,\n type ISyncOptions,\n type ISyncResult,\n type ISyncedFile,\n type ITypeSyncer,\n} from './types'\nimport { memoizeAsync, mergeObjects, orderObject, typed, uniq } from './util'\nimport { getClosestMatchingVersion } from './versioning'\nimport type {\n IWorkspaceResolverService,\n IWorkspacesArray,\n} from './workspace-resolver'\n\n/**\n * Creates a type syncer.\n *\n * @param packageJSONservice\n * @param typeDefinitionSource\n */\nexport function createTypeSyncer(\n packageJSONService: IPackageJSONService,\n workspaceResolverService: IWorkspaceResolverService,\n packageSource: IPackageSource,\n configService: IConfigService,\n globber: IGlobber,\n): ITypeSyncer {\n const fetchPackageInfo = memoizeAsync(packageSource.fetch)\n\n return {\n sync,\n }\n\n /**\n * Syncs typings in the specified package.json.\n */\n async function sync(\n filePath: string,\n flags: ICLIArguments['flags'],\n ): Promise<ISyncResult> {\n const dryRun = !!flags.dry\n const syncOpts = await configService.readConfig(filePath, flags)\n const { file, subManifests } = await getManifests(\n filePath,\n globber,\n syncOpts.ignoreProjects ?? [],\n )\n\n const syncedFiles: Array<ISyncedFile> = await Promise.all([\n syncFile(filePath, file, syncOpts, dryRun),\n ...subManifests.map(\n async (p) =>\n await syncFile(\n p,\n await packageJSONService.readPackageFile(p),\n syncOpts,\n dryRun,\n ),\n ),\n ])\n\n return {\n syncedFiles,\n }\n }\n\n /**\n * Get the `package.json` files and sub-packages.\n *\n * @param filePath\n * @param globber\n */\n async function getManifests(\n filePath: string,\n globber: IGlobber,\n ignoredWorkspaces: IWorkspacesArray,\n ) {\n const root = path.dirname(filePath)\n const file = await packageJSONService.readPackageFile(filePath)\n const subPackages = await workspaceResolverService.getWorkspaces(\n file,\n root,\n globber,\n ignoredWorkspaces,\n )\n const subManifests = subPackages.map((p) =>\n path.join(root, p, 'package.json'),\n )\n\n return {\n file,\n subManifests,\n }\n }\n\n /**\n * Syncs a single file.\n *\n * @param filePath\n * @param file\n * @param allTypings\n * @param opts\n */\n async function syncFile(\n filePath: string,\n file: IPackageFile,\n opts: ISyncOptions,\n dryRun: boolean,\n ): Promise<ISyncedFile> {\n const { ignoreDeps, ignorePackages } = opts\n\n const allLocalPackages = Object.values(IDependencySection)\n .map((dep) => {\n const section = getDependenciesBySection(file, dep)\n if (!section) return []\n\n const ignoredSection = ignoreDeps?.includes(dep)\n return getPackagesFromSection(section, ignoredSection, ignorePackages)\n })\n .flat()\n const allPackageNames = uniq(allLocalPackages.map((p) => p.name))\n const potentiallyUntypedPackages =\n getPotentiallyUntypedPackages(allPackageNames)\n\n // This is pushed to in the inner `map`, because packages that have DT-typings\n // *as well* as internal typings should be excluded.\n const used: ReturnType<typeof getPotentiallyUntypedPackages> = []\n const devDepsToAdd = await Promise.all(\n potentiallyUntypedPackages.map(async (t) => {\n // Fetch the code package from the source.\n const typePackageInfoPromise = fetchPackageInfo(t.typesPackageName)\n const codePackageInfo = await fetchPackageInfo(t.codePackageName)\n\n // If the code package was not found, there's nothing else to do.\n if (!codePackageInfo) {\n return {}\n }\n\n const localCodePackage = allLocalPackages.find(\n (p) => p.name === t.codePackageName,\n )!\n\n // Find the closest matching code package version relative to what's in our package.json\n const closestMatchingCodeVersion = getClosestMatchingVersion(\n codePackageInfo.versions,\n localCodePackage.version,\n )\n\n // If the closest matching version contains internal typings, don't include it.\n if (closestMatchingCodeVersion.containsInternalTypings) {\n return {}\n }\n\n // Look for the closest matching typings package.\n const typePackageInfo = await typePackageInfoPromise\n\n // If the types package was not found, or if it was deprecated, there's nothing else to do.\n if (!typePackageInfo || typePackageInfo.deprecated) {\n return {}\n }\n\n // Gets the closest matching typings version, or the newest one.\n const closestMatchingTypingsVersion = getClosestMatchingVersion(\n typePackageInfo.versions,\n localCodePackage.version,\n )\n\n const version = closestMatchingTypingsVersion.version\n const semverRangeSpecifier = '~'\n used.push(t)\n return {\n [t.typesPackageName]: semverRangeSpecifier + version,\n }\n }),\n ).then(mergeObjects)\n const devDeps = file.devDependencies\n if (!dryRun) {\n const newPackageFile: IPackageFile = { ...file }\n\n if (Object.keys(devDepsToAdd).length > 0) {\n newPackageFile.devDependencies = orderObject({\n ...devDepsToAdd,\n ...devDeps,\n })\n\n await packageJSONService.writePackageFile(filePath, newPackageFile)\n }\n }\n\n return {\n filePath,\n newTypings: used,\n package: file,\n }\n }\n}\n\n/**\n * Returns an array of packages that do not have a `@types/` package.\n *\n * @param allPackageNames Used to filter the typings that are new.\n * @param allTypings All typings available\n */\nfunction getPotentiallyUntypedPackages(\n allPackageNames: Array<string>,\n): Array<IPackageTypingDescriptor> {\n const existingTypings = allPackageNames.filter((x) => x.startsWith('@types/'))\n\n return allPackageNames.flatMap((p) => {\n // Ignore typings packages themselves.\n if (p.startsWith('@types/')) {\n return []\n }\n\n const typingsName = getTypingsName(p)\n const fullTypingsPackage = typed(p)\n const alreadyHasTyping = existingTypings.includes(fullTypingsPackage)\n if (alreadyHasTyping) {\n return []\n }\n\n return [\n {\n typingsName: typingsName,\n typesPackageName: fullTypingsPackage,\n codePackageName: p,\n },\n ]\n })\n}\n\n/**\n * Gets the typings name for the specified package name.\n * For example, `koa` would be `koa`, but `@koa/router` would be `koa__router`.\n *\n * @param packageName the package name to generate the typings name for\n */\nfunction getTypingsName(packageName: string) {\n const scopeInfo = getPackageScope(packageName)\n\n return scopeInfo && scopeInfo[0] !== 'types'\n ? `${scopeInfo[0]}__${scopeInfo[1]}`\n : packageName\n}\n\n/**\n * If a package is scoped, returns the scope + package as a tuple, otherwise null.\n *\n * @param packageName Package name to check scope for.\n */\nfunction getPackageScope(packageName: string): [string, string] | null {\n const EXPR = /^@([^/]+)\\/(.*)$/i\n const matches = EXPR.exec(packageName)\n if (!matches) {\n return null\n }\n\n return [matches[1], matches[2]]\n}\n\n/**\n * Get packages from a dependency section\n *\n * @param section\n * @param ignoredSection\n * @param ignorePackages\n */\nfunction getPackagesFromSection(\n section: IDependenciesSection,\n ignoredSection?: boolean,\n ignorePackages?: Array<string>,\n): Array<IPackageVersion> {\n return Object.keys(section).flatMap((name) => {\n const isTyping = name.startsWith('@types/')\n\n // Never ignore `@types` packages.\n if (!isTyping) {\n // If it's not a `@types` package, check whether the section or package is ignored.\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- We want to check for false as well.\n if (ignoredSection || ignorePackages?.includes(name)) {\n return []\n }\n }\n\n return [{ name, version: section[name] }]\n })\n}\n\n/**\n * Get dependencies from a package section\n *\n * @param file Package file\n * @param section Package section, eg: dev, peer\n */\nfunction getDependenciesBySection(\n file: IPackageFile,\n section: IDependencySection,\n): IDependenciesSection | undefined {\n const dependenciesSection = (() => {\n switch (section) {\n case IDependencySection.deps:\n return file.dependencies\n case IDependencySection.dev:\n return file.devDependencies\n case IDependencySection.optional:\n return file.optionalDependencies\n case IDependencySection.peer:\n return file.peerDependencies\n }\n })()\n return dependenciesSection\n}\n"],"mappings":"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"}