@dtsx/vite 0.0.0-stage → 0.11.40

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/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2024 Open Web Foundation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,157 @@
1
- # Temporary Holding Version
1
+ # @dtsx/vite
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A Vite plugin for automatic TypeScript declaration file generation using dtsx.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @dtsx/vite -d
9
+ # or
10
+ npm install @dtsx/vite --save-dev
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```typescript
16
+ // vite.config.ts
17
+ import { defineConfig } from 'vite'
18
+ import { dts } from '@dtsx/vite'
19
+
20
+ export default defineConfig({
21
+ plugins: [
22
+ dts({
23
+ // Options
24
+ }),
25
+ ],
26
+ })
27
+ ```
28
+
29
+ ## Options
30
+
31
+ | Option | Type | Default | Description |
32
+ |--------|------|---------|-------------|
33
+ | `trigger` | `'build' \| 'serve' \| 'both'` | `'build'` | When to generate declarations |
34
+ | `timing` | `'before' \| 'after'` | `'before'` | Generate before Vite writes the bundle (after it empties `outDir`) or after the build |
35
+ | `root` | `string` | folder of `build.lib.entry`, else `./src` | Source root; declarations mirror the source from here |
36
+ | `outdir` | `string` | Vite `build.outDir` | Output directory for declarations |
37
+ | `entryPointsOnly` | `boolean` | `true` | Only generate for entry points |
38
+ | `declarationDir` | `string` | Vite outDir | Output directory for declarations |
39
+ | `bundle` | `boolean` | `false` | Bundle all declarations into one file |
40
+ | `bundleOutput` | `string` | `'index.d.ts'` | Bundled output filename |
41
+ | `exclude` | `(string \| RegExp)[]` | `[]` | Patterns to exclude |
42
+ | `include` | `(string \| RegExp)[]` | `[]` | Patterns to include |
43
+ | `emitOnError` | `boolean` | `true` | Emit even with type errors |
44
+
45
+ ## Examples
46
+
47
+ ### Basic Usage
48
+
49
+ ```typescript
50
+ // vite.config.ts
51
+ import { defineConfig } from 'vite'
52
+ import { dts } from '@dtsx/vite'
53
+
54
+ export default defineConfig({
55
+ plugins: [dts()],
56
+ })
57
+ ```
58
+
59
+ ### With Bundled Declarations
60
+
61
+ ```typescript
62
+ // vite.config.ts
63
+ import { defineConfig } from 'vite'
64
+ import { dts } from '@dtsx/vite'
65
+
66
+ export default defineConfig({
67
+ plugins: [
68
+ dts({
69
+ bundle: true,
70
+ bundleOutput: 'types.d.ts',
71
+ }),
72
+ ],
73
+ })
74
+ ```
75
+
76
+ ### Library Mode
77
+
78
+ ```typescript
79
+ // vite.config.ts
80
+ import { defineConfig } from 'vite'
81
+ import { dts } from '@dtsx/vite'
82
+
83
+ export default defineConfig({
84
+ build: {
85
+ lib: {
86
+ entry: 'src/index.ts',
87
+ formats: ['es', 'cjs'],
88
+ },
89
+ },
90
+ plugins: [
91
+ dts({
92
+ entryPointsOnly: true,
93
+ }),
94
+ ],
95
+ })
96
+ ```
97
+
98
+ ### With Callbacks
99
+
100
+ ```typescript
101
+ // vite.config.ts
102
+ import { defineConfig } from 'vite'
103
+ import { dts } from '@dtsx/vite'
104
+
105
+ export default defineConfig({
106
+ plugins: [
107
+ dts({
108
+ onStart: () => {
109
+ console.log('Starting declaration generation...')
110
+ },
111
+ onSuccess: (stats) => {
112
+ console.log(`Generated ${stats.totalFiles} files in ${stats.totalTime}ms`)
113
+ },
114
+ onError: (error) => {
115
+ console.error('Failed to generate declarations:', error.message)
116
+ },
117
+ }),
118
+ ],
119
+ })
120
+ ```
121
+
122
+ ### Filter Files
123
+
124
+ ```typescript
125
+ // vite.config.ts
126
+ import { defineConfig } from 'vite'
127
+ import { dts } from '@dtsx/vite'
128
+
129
+ export default defineConfig({
130
+ plugins: [
131
+ dts({
132
+ include: [/src\/lib/],
133
+ exclude: ['test', /\.spec\.ts$/],
134
+ }),
135
+ ],
136
+ })
137
+ ```
138
+
139
+ ### Dev Server Mode
140
+
141
+ ```typescript
142
+ // vite.config.ts
143
+ import { defineConfig } from 'vite'
144
+ import { dts } from '@dtsx/vite'
145
+
146
+ export default defineConfig({
147
+ plugins: [
148
+ dts({
149
+ trigger: 'both', // Generate on both build and dev server start
150
+ }),
151
+ ],
152
+ })
153
+ ```
154
+
155
+ ## License
156
+
157
+ MIT
@@ -0,0 +1,39 @@
1
+ import type { DtsGenerationOption, GenerationStats } from '@dtsx/dtsx';
2
+ import type { Plugin } from 'vite';
3
+ export type { DtsGenerationOption, GenerationStats };
4
+ /**
5
+ * Creates a Vite plugin for generating TypeScript declaration files
6
+ * @param options - Configuration options for DTS generation
7
+ * @returns Vite Plugin instance
8
+ */
9
+ export declare function dts(options?: DtsPluginOptions): Plugin;
10
+ /**
11
+ * Create a minimal Vite plugin for just type checking
12
+ */
13
+ export declare function dtsCheck(_options?: Partial<DtsPluginOptions>): Plugin;
14
+ /**
15
+ * Create a Vite plugin that bundles all declarations into one file
16
+ */
17
+ export declare function dtsBundled(options?: DtsPluginOptions & { bundleOutput?: string }): Plugin;
18
+ /**
19
+ * Configuration interface extending DtsGenerationOption with Vite-specific properties
20
+ */
21
+ export declare interface DtsPluginOptions extends DtsGenerationOption {
22
+ trigger?: 'build' | 'serve' | 'both'
23
+ watch?: boolean
24
+ watchDebounce?: number
25
+ watchPatterns?: string[]
26
+ timing?: 'before' | 'after'
27
+ hmr?: boolean
28
+ insertTypesEntry?: boolean
29
+ typesEntry?: string
30
+ external?: (string | RegExp)[]
31
+ includePrivate?: boolean
32
+ sourceMaps?: boolean
33
+ skipIfUpToDate?: boolean
34
+ onSuccess?: (stats: GenerationStats) => void | Promise<void>
35
+ onError?: (error: Error) => void | Promise<void>
36
+ onFileChange?: (file: string) => void | Promise<void>
37
+ onStart?: () => void | Promise<void>
38
+ }
39
+ export default dts;
package/dist/index.js ADDED
@@ -0,0 +1,268 @@
1
+ // @bun
2
+ // src/index.ts
3
+ import { watch as fsWatch } from "fs";
4
+ import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "path";
5
+ import { generate } from "@dtsx/dtsx";
6
+ function dts(options = {}) {
7
+ const {
8
+ trigger = "build",
9
+ watch: enableWatch,
10
+ watchDebounce = 300,
11
+ watchPatterns = [],
12
+ timing = "before",
13
+ hmr = false,
14
+ insertTypesEntry = false,
15
+ typesEntry = "index.d.ts",
16
+ external = [],
17
+ includePrivate = false,
18
+ sourceMaps = false,
19
+ skipIfUpToDate = true,
20
+ onSuccess,
21
+ onError,
22
+ onFileChange,
23
+ onStart,
24
+ ...dtsOptions
25
+ } = options;
26
+ const state = {
27
+ viteConfig: null,
28
+ server: null,
29
+ watcher: null,
30
+ debounceTimer: null,
31
+ lastGeneratedAt: 0,
32
+ isGenerating: false,
33
+ changedFiles: new Set
34
+ };
35
+ let generatedThisBuild = false;
36
+ async function generateDeclarations(changedFiles) {
37
+ if (state.isGenerating) {
38
+ return null;
39
+ }
40
+ state.isGenerating = true;
41
+ try {
42
+ await onStart?.();
43
+ const config = normalizeConfig(dtsOptions, state.viteConfig);
44
+ const stats = await generate(config);
45
+ state.lastGeneratedAt = Date.now();
46
+ state.changedFiles.clear();
47
+ await onSuccess?.(stats);
48
+ if (hmr && state.server) {
49
+ notifyTypeChanges(state.server, config.outdir || "dist");
50
+ }
51
+ return stats;
52
+ } catch (error) {
53
+ const err = error instanceof Error ? error : new Error(String(error));
54
+ if (onError) {
55
+ await onError(err);
56
+ } else {
57
+ console.error("[vite-plugin-dtsx] Error generating declarations:", err.message);
58
+ throw err;
59
+ }
60
+ return null;
61
+ } finally {
62
+ state.isGenerating = false;
63
+ }
64
+ }
65
+ function handleFileChange(filePath) {
66
+ if (!shouldProcessFile(filePath, dtsOptions.entrypoints, dtsOptions.exclude)) {
67
+ return;
68
+ }
69
+ state.changedFiles.add(filePath);
70
+ onFileChange?.(filePath);
71
+ if (state.debounceTimer) {
72
+ clearTimeout(state.debounceTimer);
73
+ }
74
+ state.debounceTimer = setTimeout(() => {
75
+ const files = Array.from(state.changedFiles);
76
+ generateDeclarations(files);
77
+ }, watchDebounce);
78
+ }
79
+ function startWatcher(root) {
80
+ if (state.watcher) {
81
+ return;
82
+ }
83
+ try {
84
+ state.watcher = fsWatch(root, { recursive: true }, (_eventType, filename) => {
85
+ if (filename && filename.endsWith(".ts") && !filename.endsWith(".d.ts")) {
86
+ handleFileChange(join(root, filename));
87
+ }
88
+ });
89
+ console.log("[vite-plugin-dtsx] Watching for file changes...");
90
+ } catch (error) {
91
+ console.error("[vite-plugin-dtsx] Failed to start watcher:", error);
92
+ }
93
+ }
94
+ function stopWatcher() {
95
+ if (state.watcher) {
96
+ state.watcher.close();
97
+ state.watcher = null;
98
+ }
99
+ if (state.debounceTimer) {
100
+ clearTimeout(state.debounceTimer);
101
+ state.debounceTimer = null;
102
+ }
103
+ }
104
+ return {
105
+ name: "vite-plugin-dtsx",
106
+ enforce: timing === "before" ? "pre" : "post",
107
+ configResolved(config) {
108
+ state.viteConfig = config;
109
+ },
110
+ configureServer(server) {
111
+ state.server = server;
112
+ const shouldWatch = enableWatch ?? true;
113
+ if (shouldWatch && (trigger === "serve" || trigger === "both")) {
114
+ const { cwd, root } = normalizeConfig(dtsOptions, state.viteConfig);
115
+ startWatcher(resolve(cwd, root));
116
+ }
117
+ },
118
+ async buildStart() {
119
+ if (timing !== "before" || state.viteConfig?.command !== "serve")
120
+ return;
121
+ if (trigger !== "serve" && trigger !== "both")
122
+ return;
123
+ await generateDeclarations();
124
+ },
125
+ async renderStart() {
126
+ if (timing !== "before" || generatedThisBuild)
127
+ return;
128
+ if (state.viteConfig?.command !== "build" || trigger === "serve")
129
+ return;
130
+ generatedThisBuild = true;
131
+ await generateDeclarations();
132
+ },
133
+ async closeBundle() {
134
+ generatedThisBuild = false;
135
+ if (timing !== "after")
136
+ return;
137
+ if (trigger === "build" || trigger === "both") {
138
+ await generateDeclarations();
139
+ }
140
+ },
141
+ async buildEnd() {
142
+ stopWatcher();
143
+ },
144
+ async handleHotUpdate({ file, server }) {
145
+ if (!hmr)
146
+ return;
147
+ if (file.endsWith(".ts") && !file.endsWith(".d.ts")) {
148
+ handleFileChange(file);
149
+ }
150
+ return;
151
+ },
152
+ generateBundle(_, bundle) {
153
+ if (!insertTypesEntry)
154
+ return;
155
+ const typesPath = typesEntry;
156
+ if (bundle[typesPath])
157
+ return;
158
+ const libConfig = state.viteConfig?.build?.lib;
159
+ const libName = libConfig && typeof libConfig === "object" && "name" in libConfig ? libConfig.name : "library";
160
+ bundle[typesPath] = {
161
+ type: "asset",
162
+ fileName: typesPath,
163
+ source: `// Type definitions for ${libName}
164
+ // Generated by vite-plugin-dtsx
165
+
166
+ export * from './${basename(typesPath, ".d.ts")}';
167
+ `,
168
+ name: typesPath,
169
+ names: [typesPath],
170
+ originalFileName: null,
171
+ originalFileNames: [],
172
+ needsCodeReference: false
173
+ };
174
+ }
175
+ };
176
+ }
177
+ function normalizeConfig(options, viteConfig) {
178
+ const cwd = options.cwd || viteConfig?.root || process.cwd();
179
+ const root = options.root || defaultRoot(cwd, viteConfig);
180
+ const outdir = options.outdir || viteConfig?.build?.outDir || "./dist";
181
+ const exclude = [...options.exclude ?? []];
182
+ const configFile = viteConfig?.configFile;
183
+ if (!options.root && configFile && isInside(configFile, resolve(cwd, root)))
184
+ exclude.push(configFile);
185
+ return {
186
+ ...options,
187
+ cwd,
188
+ root,
189
+ entrypoints: options.entrypoints || ["**/*.ts"],
190
+ exclude,
191
+ outdir,
192
+ clean: options.clean,
193
+ tsconfigPath: options.tsconfigPath
194
+ };
195
+ }
196
+ function defaultRoot(cwd, viteConfig) {
197
+ const lib = viteConfig?.build?.lib;
198
+ const entry = lib ? lib.entry : undefined;
199
+ const entries = typeof entry === "string" ? [entry] : Array.isArray(entry) ? entry : entry ? Object.values(entry) : [];
200
+ if (entries.length === 0)
201
+ return "./src";
202
+ const directories = entries.map((file) => dirname(resolve(cwd, file)));
203
+ return directories.reduce(commonDirectory);
204
+ }
205
+ function commonDirectory(a, b) {
206
+ let common = a;
207
+ while (!isInside(b, common) && dirname(common) !== common)
208
+ common = dirname(common);
209
+ return common;
210
+ }
211
+ function isInside(path, directory) {
212
+ const rel = relative(directory, path);
213
+ return rel === "" || !rel.startsWith(`..${sep}`) && rel !== ".." && !isAbsolute(rel);
214
+ }
215
+ function shouldProcessFile(filePath, _include, exclude) {
216
+ if (filePath.endsWith(".d.ts")) {
217
+ return false;
218
+ }
219
+ if (filePath.includes("node_modules")) {
220
+ return false;
221
+ }
222
+ if (!filePath.endsWith(".ts") && !filePath.endsWith(".tsx")) {
223
+ return false;
224
+ }
225
+ if (exclude) {
226
+ for (const pattern of exclude) {
227
+ if (filePath.includes(pattern)) {
228
+ return false;
229
+ }
230
+ }
231
+ }
232
+ return true;
233
+ }
234
+ function notifyTypeChanges(server, outdir) {
235
+ server.ws.send({
236
+ type: "custom",
237
+ event: "dtsx:types-updated",
238
+ data: {
239
+ outdir,
240
+ timestamp: Date.now()
241
+ }
242
+ });
243
+ }
244
+ function dtsCheck(_options = {}) {
245
+ return {
246
+ name: "vite-plugin-dtsx-check",
247
+ enforce: "pre",
248
+ async buildStart() {
249
+ console.log("[vite-plugin-dtsx] Type checking...");
250
+ }
251
+ };
252
+ }
253
+ function dtsBundled(options = {}) {
254
+ const { bundleOutput: _bundleOutput = "types.d.ts", ...dtsOptions } = options;
255
+ return {
256
+ ...dts({
257
+ ...dtsOptions
258
+ }),
259
+ name: "vite-plugin-dtsx-bundled"
260
+ };
261
+ }
262
+ var src_default = dts;
263
+ export {
264
+ src_default as default,
265
+ dts,
266
+ dtsBundled,
267
+ dtsCheck
268
+ };
package/package.json CHANGED
@@ -1,6 +1,64 @@
1
1
  {
2
2
  "name": "@dtsx/vite",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "type": "module",
4
+ "version": "0.11.40",
5
+ "description": "A modern, fast .d.ts generation tool, powered by Bun.",
6
+ "author": "Chris Breuer <chris@stacksjs.org>",
7
+ "license": "MIT",
8
+ "homepage": "https://github.com/stacksjs/dtsx#readme",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/stacksjs/dtsx.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/stacksjs/dtsx/issues"
15
+ },
16
+ "keywords": [
17
+ "dts",
18
+ "generation",
19
+ "isolated declarations",
20
+ "development",
21
+ "bun",
22
+ "stacks",
23
+ "typescript",
24
+ "javascript"
25
+ ],
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.js"
30
+ }
31
+ },
32
+ "module": "./dist/index.js",
33
+ "types": "./dist/index.d.ts",
34
+ "files": [
35
+ "dist"
36
+ ],
37
+ "scripts": {
38
+ "build": "bun build.ts",
39
+ "lint": "bunx --bun pickier run . --mode lint",
40
+ "lint:fix": "bunx --bun pickier run . --mode lint --fix",
41
+ "fresh": "bunx rimraf node_modules/ bun.lock && bun i",
42
+ "changelog": "bunx changelogen --output CHANGELOG.md",
43
+ "prepublishOnly": "bun --bun run build",
44
+ "release": "bun run changelog && bunx bumpp package.json --all",
45
+ "test": "bun test",
46
+ "typecheck": "bunx tsc --noEmit"
47
+ },
48
+ "dependencies": {
49
+ "@dtsx/dtsx": "0.11.40"
50
+ },
51
+ "devDependencies": {
52
+ "vite": "^8.3.6"
53
+ },
54
+ "peerDependencies": {
55
+ "vite": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
56
+ },
57
+ "git-hooks": {
58
+ "pre-commit": {
59
+ "staged-lint": {
60
+ "*.{js,ts,json,yaml,yml,md}": "bunx --bun pickier run . --mode lint --fix"
61
+ }
62
+ }
63
+ }
64
+ }