{"id":15655612,"url":"https://github.com/florianrappl/dets","last_synced_at":"2025-04-06T11:07:36.407Z","repository":{"id":42879565,"uuid":"230071751","full_name":"FlorianRappl/dets","owner":"FlorianRappl","description":"Generate a single declaration file for your TypeScript project. :rocket:","archived":false,"fork":false,"pushed_at":"2025-03-07T16:35:00.000Z","size":1357,"stargazers_count":28,"open_issues_count":2,"forks_count":7,"subscribers_count":3,"default_branch":"develop","last_synced_at":"2025-03-30T10:06:35.400Z","etag":null,"topics":["bundle","declaration","file","generation","hacktoberfest","single","types","typescript","typings"],"latest_commit_sha":null,"homepage":"https://piral.io","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FlorianRappl.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["FlorianRappl"],"custom":["https://www.paypal.me/FlorianRappl"]}},"created_at":"2019-12-25T08:41:52.000Z","updated_at":"2025-03-19T12:10:57.000Z","dependencies_parsed_at":"2023-02-08T12:31:39.500Z","dependency_job_id":"c6826b57-570f-4e7a-9f09-b9eaafbed546","html_url":"https://github.com/FlorianRappl/dets","commit_stats":{"total_commits":232,"total_committers":8,"mean_commits":29.0,"dds":"0.14655172413793105","last_synced_commit":"2b3ffb1438e01a0f9a5b11e039bd48d0076e66b9"},"previous_names":[],"tags_count":48,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlorianRappl%2Fdets","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlorianRappl%2Fdets/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlorianRappl%2Fdets/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlorianRappl%2Fdets/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FlorianRappl","download_url":"https://codeload.github.com/FlorianRappl/dets/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247471517,"owners_count":20944158,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bundle","declaration","file","generation","hacktoberfest","single","types","typescript","typings"],"created_at":"2024-10-03T13:00:03.516Z","updated_at":"2025-04-06T11:07:36.389Z","avatar_url":"https://github.com/FlorianRappl.png","language":"TypeScript","funding_links":["https://github.com/sponsors/FlorianRappl","https://www.paypal.me/FlorianRappl"],"categories":[],"sub_categories":[],"readme":"# dets\n\n[![Build Status](https://florianrappl.visualstudio.com/dets/_apis/build/status/FlorianRappl.dets?branchName=main)](https://florianrappl.visualstudio.com/dets/_build/latest?definitionId=23\u0026branchName=main)\n[![npm](https://img.shields.io/npm/v/dets.svg)](https://www.npmjs.com/package/dets)\n[![GitHub tag](https://img.shields.io/github/tag/FlorianRappl/dets.svg)](https://github.com/FlorianRappl/dets/releases)\n[![GitHub issues](https://img.shields.io/github/issues/FlorianRappl/dets.svg)](https://github.com/FlorianRappl/dets/issues)\n\n(pronounced: *deee - ts*)\n\n\u003e A TypeScript declaration file bundler.\n\n*dets* is a small utility to generate single-file TypeScript declaration files. It can operate in multiple modes.\n\nIt is best used if you want to selectively export an API or if you want to build an isolated *d.ts* file that does not depend on any other declaration packages.\n\n## Installation\n\nYou can run dets directly via `npx`. Otherwise, if you want to use it globally you can install it via:\n\n```sh\nnpm i dets -g\n```\n\nWe recommend a local installation though:\n\n```sh\nnpm i dets --save-dev\n```\n\n## Usage\n\nThere are two primary ways of using dets: Either via the command line or programmatically.\n\n### Special Treatments\n\n#### Ignoring Properties\n\nBy default, members that have a `@ignore` comment will be ignored. Therefore, an interface like\n\n```ts\ninterface Foo {\n  bar: boolean;\n  /**\n   * @ignore\n   */\n  foo: string;\n}\n```\n\nwill be changed by dets to look like:\n\n```ts\ninterface Foo {\n  bar: boolean;\n}\n```\n\nThis can be disabled via the CLI or programmatic options (`--no-ignore`). Additionally, a special comment like `@dets_preserve` could be added, too.\n\n```ts\ninterface Foo {\n  bar: boolean;\n  /**\n   * @ignore\n   * @dets_preserve\n   */\n  foo: string;\n}\n```\n\nHere, the property is kept, but the `dets_preserve` dets comment will be removed:\n\n```ts\ninterface Foo {\n  bar: boolean;\n  /**\n   * @ignore\n   */\n  foo: string;\n}\n```\n\n#### Removing Properties\n\nWhen doing interface merging certain properties may be desired to be hidden. To do this a special tag comment `@dets_removeprop` is used:\n\n```ts\n// original interface\ninterface Foo {\n  foo: string;\n  bar: boolean;\n}\n\n// somewhere later\n/**\n * @dets_removeprop foo\n */\ninterface Foo {\n  qxz: number;\n}\n```\n\nThis results in the merged interface, just without the excluded property:\n\n```ts\ninterface Foo {\n  bar: boolean;\n  qxz: number;\n}\n```\n\n#### Removing Inheritance Clauses\n\nWhen doing interface merging certain extend clauses may be desired to be hidden. To do this a special tag comment `@dets_removeclause` is used:\n\n```ts\n// original interface\ninterface Foo extends FooBase1, FooBase2 {\n  foo: string;\n}\n\n// somewhere later\n/**\n * @dets_removeclause FooBase1\n */\ninterface Foo {}\n```\n\nThis results in the merged interface, just without the excluded clauses:\n\n```ts\ninterface Foo extends FooBase2 {\n  foo: string;\n}\n```\n\n### From the CLI\n\nAn example call for dets from the command line is:\n\n```sh\ndets src/index.ts --name foo --files src/**/*.ts --out dist/index.d.ts\n```\n\nHere we use a glob pattern for the input files and an explicit path for the output.\n\nThe available command line arguments are:\n\n```plain\nPositionals:\n  entry  The entry level modules to be consumed.          [string] [default: []]\n\nOptions:\n  --help                Show help                                      [boolean]\n  --version             Show version number                            [boolean]\n  --name                Sets the name of the module.   [string] [default: \"foo\"]\n  --files               Sets the files referenced by TypeScript.\n                                                [array] [required] [default: []]\n  --types               Sets the type entry modules to export via their file\n                        path.                              [array] [default: []]\n  --apis                Sets the interfaces to include using\n                        \"InterfaceName:FilePath\" syntax.   [array] [default: []]\n  --imports             Sets the imports to avoid bundling in via their package\n                        names.                             [array] [default: []]\n  --ignore              Actively uses the ignore comment to drop properties.\n                                                       [boolean] [default: true]\n  --module-declaration  Wraps the declaration in a \"declare module\" block.\n                                                       [boolean] [default: true]\n  --out                 Sets the path to the output file.\n                                         [string] [default: \"./dist/index.d.ts\"]\n```\n\nIf `name` is omitted then the `name` from the closest `package.json` is taken.\n\nThe `files` and `types` allow more fine-grained control what files are seen by TypeScript and what types should be exported. Usually, you'd want to use the positional entry level modules instead.\n\n### From Node Applications\n\nAn example code for using dets in a Node.js application is:\n\n```ts\nimport { generateDeclaration } from \"dets\";\nimport { writeFileSync } from \"fs\";\n\nconst content = await generateDeclaration({\n  name: \"foo\",\n  root: process.cwd(),\n  files: [\"src/**/*.ts\"],\n  types: [\"src/index.ts\"]\n});\n\nwriteFileSync(\"dist/index.d.ts\", content, \"utf8\");\n```\n\nThis is effectively the same call as the example in the CLI section.\n\nThere are multiple other possibilities, which may be relevant.\n\nThe basis for most operations is a `DeclVisitorContext`, which can be created via the `setupVisitorContext` function.\n\n```ts\nimport { setupVisitorContext } from \"dets\";\n\nconst context = setupVisitorContext('foo', [\"src/**/*.ts\"]);\n```\n\nUsing the `DeclVisitorContext` you can fill from an exported object, which is automatically enriched with all available information form the given input files:\n\n```ts\nimport { fillVisitorContextFromApi } from \"dets\";\n\nfillVisitorContextFromApi(context, 'src/types/api.ts', 'MyExportedApi');\n```\n\nAlternatively, just get all exports from a given module.\n\nUsing the `DeclVisitorContext` you can fill from an exported object, which is automatically enriched with all available information form the given input files:\n\n```ts\nimport { fillVisitorContextFromTypes } from \"dets\";\n\nfillVisitorContextFromTypes(context, 'src/types/index.ts');\n```\n\n#### Using Plugins\n\ndets also comes with an integrated plugin system that allows customizing the behavior such as modifying the captured type information.\n\nAs an example:\n\n```ts\nimport { generateDeclaration, createExcludePlugin } from \"dets\";\nimport { writeFileSync } from \"fs\";\n\nconst content = await generateDeclaration({\n  name: \"foo\",\n  root: process.cwd(),\n  files: [\"src/**/*.ts\"],\n  types: [\"src/index.ts\"],\n  plugins: [createExcludePlugin(['foo'])],\n});\n\nwriteFileSync(\"dist/index.d.ts\", content, \"utf8\");\n```\n\nThis excludes the `foo` module from the output. Since the `foo` module was the subject to create only the declaration mergings on existing modules survive.\n\nFurthermore, custom plugins can be created, too:\n\n```ts\nimport { generateDeclaration } from \"dets\";\n\nconst printFoundModulesInConsole = {\n  // type of the plugin ('before-init' | 'before-process' | 'after-process' | 'before-stringify')\n  type: 'after-process',\n  // name of the plugin\n  name: 'console-printer',\n  // function to run with the created context\n  run(context) {\n    console.log('Found the following modules:', Object.keys(context.modules));\n  },\n};\n\nawait generateDeclaration({\n  name: \"foo\",\n  root: process.cwd(),\n  files: [\"src/**/*.ts\"],\n  types: [\"src/index.ts\"],\n  plugins: [printFoundModulesInConsole],\n});\n```\n\nThe provided syntax is considered \"classic\" - you can also create \"modern\" plugins using the full lifecycle:\n\n```ts\nimport { generateDeclaration } from \"dets\";\n\nconst printFoundModulesInConsole = {\n  // name of the plugin\n  name: 'console-printer',\n  // function to run with the created context\n  'before-init'(context) {\n    context.log.info('Starting the console-printer plugin');\n  },\n  'after-process'(context) {\n    console.log('Found the following modules:', Object.keys(context.modules));\n  },\n};\n\nawait generateDeclaration({\n  name: \"foo\",\n  root: process.cwd(),\n  files: [\"src/**/*.ts\"],\n  types: [\"src/index.ts\"],\n  plugins: [printFoundModulesInConsole],\n});\n```\n\nThe advantage of the modern plugin approach is that you can easily modify / integrate into multiple phases of dets with just a single plugin.\n\n## Development\n\nRight now *dets* is fully in development. So things may change in the (near) future.\n\nAny ideas, issues, or enhancements are much appreciated!\n\nWe follow common sense here, so I hope that we do not need a long code of conduct or anything overall complex for everyone to feel welcome here.\n\n## License\n\nMIT License (MIT). For more information see [LICENSE](./LICENSE) file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflorianrappl%2Fdets","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflorianrappl%2Fdets","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflorianrappl%2Fdets/lists"}