@pentacore/vite-plugin-laravel-typefinder 4.0.2 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -17
- package/dist/index.d.ts +1 -77
- package/dist/index.js +245 -0
- package/package.json +24 -17
- package/dist/index.d.mts +0 -77
- package/dist/index.mjs +0 -2474
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @pentacore/vite-plugin-laravel-typefinder
|
|
2
2
|
|
|
3
|
-
A Vite plugin that
|
|
3
|
+
A Vite plugin that keeps your TypeScript type definitions in sync with your Laravel codebase. In development, it spawns a persistent `typefinder:watch` process that regenerates only the `.d.ts` files affected by each edit — typical latency is 20-60ms per change. In production builds, it runs a one-shot `typefinder:generate` before bundling.
|
|
4
4
|
|
|
5
|
-
> **This plugin is a companion to the [`pentacore/laravel-typefinder`](https://packagist.org/packages/pentacore/laravel-typefinder) Composer package — you must install that first.**
|
|
5
|
+
> **This plugin is a companion to the [`pentacore/laravel-typefinder`](https://packagist.org/packages/pentacore/laravel-typefinder) Composer package — you must install that first.**
|
|
6
6
|
|
|
7
7
|
## Requirements
|
|
8
8
|
|
|
@@ -28,31 +28,69 @@ import typefinder from '@pentacore/vite-plugin-laravel-typefinder';
|
|
|
28
28
|
export default defineConfig({
|
|
29
29
|
plugins: [
|
|
30
30
|
laravel({ input: ['resources/js/app.js'] }),
|
|
31
|
-
typefinder(
|
|
32
|
-
// All options are optional — defaults shown below
|
|
33
|
-
command: 'php artisan typefinder:generate',
|
|
34
|
-
watch: ['app/Models/**/*.php', 'app/Enums/**/*.php', 'app/Http/Requests/**/*.php'],
|
|
35
|
-
debounceMs: 100,
|
|
36
|
-
}),
|
|
31
|
+
typefinder(), // zero-config — all options are optional
|
|
37
32
|
],
|
|
38
33
|
});
|
|
39
34
|
```
|
|
40
35
|
|
|
41
|
-
##
|
|
36
|
+
## Configuration
|
|
42
37
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
All options are optional. Defaults work for a standard Laravel project with `php` on `$PATH`.
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
typefinder({
|
|
42
|
+
// Shell command for the long-lived watcher process.
|
|
43
|
+
// Override for Sail/Herd/Docker.
|
|
44
|
+
command: 'php artisan typefinder:watch',
|
|
45
|
+
|
|
46
|
+
// Shell command used in `vite build` (one-shot, no watcher).
|
|
47
|
+
// Set to `false` to skip generation entirely in build mode.
|
|
48
|
+
buildCommand: 'php artisan typefinder:generate --json',
|
|
49
|
+
|
|
50
|
+
// Override the paths the plugin watches. When unset (the default),
|
|
51
|
+
// paths come from the watcher's handshake, which mirrors your
|
|
52
|
+
// config/typefinder.php. Provide absolute paths.
|
|
53
|
+
watch: undefined,
|
|
54
|
+
|
|
55
|
+
// Debounce window (ms) for coalescing HMR events.
|
|
56
|
+
debounceMs: 100,
|
|
57
|
+
|
|
58
|
+
// How long to wait for the watcher's `ready` handshake before failing.
|
|
59
|
+
startupTimeoutMs: 10_000,
|
|
60
|
+
|
|
61
|
+
// Grace period between SIGTERM and SIGKILL when shutting down.
|
|
62
|
+
killTimeoutMs: 2_000,
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Runtime-specific examples
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
// Laravel Sail
|
|
70
|
+
typefinder({ command: './vendor/bin/sail artisan typefinder:watch' })
|
|
71
|
+
|
|
72
|
+
// Laravel Herd
|
|
73
|
+
typefinder({ command: 'herd php artisan typefinder:watch' })
|
|
74
|
+
|
|
75
|
+
// Docker Compose
|
|
76
|
+
typefinder({ command: 'docker compose exec app php artisan typefinder:watch' })
|
|
77
|
+
```
|
|
48
78
|
|
|
49
79
|
## Behavior
|
|
50
80
|
|
|
51
|
-
**
|
|
81
|
+
**Development (`vite dev`):** The plugin spawns `typefinder:watch` — a persistent Laravel process that boots once and accepts incremental regeneration requests over NDJSON. When a `.php` file matching the watched paths changes via HMR, the plugin sends the changed file paths to the watcher, which re-extracts only those files and rewrites only the affected `.d.ts` outputs. Multiple rapid edits within the debounce window are coalesced into a single request.
|
|
82
|
+
|
|
83
|
+
The watched paths are read from the watcher's startup handshake, which mirrors your `config/typefinder.php`. If you enable Inertia pages or broadcasting in the config, the plugin automatically watches those directories too — no manual `watch` array needed.
|
|
84
|
+
|
|
85
|
+
**Production (`vite build`):** No watcher. The plugin runs `typefinder:generate --json` once in `buildStart` and fails the build on non-zero exit. Set `buildCommand: false` to skip generation entirely (e.g. for pre-built containers without a PHP runtime).
|
|
86
|
+
|
|
87
|
+
**Shutdown:** The watcher is killed on `closeBundle` and on process exit. If the watcher dies mid-session (PHP fatal, OOM), the plugin logs the error and stops regenerating — restart the dev server to recover.
|
|
52
88
|
|
|
53
|
-
|
|
89
|
+
### Migration from v4.0
|
|
54
90
|
|
|
55
|
-
|
|
91
|
+
- `command` default changed from `typefinder:generate` to `typefinder:watch`. If you explicitly set `command`, update it — dev mode requires the long-lived watcher.
|
|
92
|
+
- `watch` default changed from a hardcoded path list to `undefined`, meaning "use whatever the watcher reports". Existing explicit `watch: [...]` configurations keep working unchanged.
|
|
93
|
+
- Regenerations now run against a persistent Laravel boot via NDJSON. Typical edit latency drops from ~300-500ms to ~20-60ms.
|
|
56
94
|
|
|
57
95
|
## Alternative install (from vendor)
|
|
58
96
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,77 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Options for the `typefinder` Vite plugin.
|
|
5
|
-
*
|
|
6
|
-
* All fields are optional — the defaults work for a standard Laravel project
|
|
7
|
-
* running PHP directly. Override `command` when using Sail, Herd, Docker, or
|
|
8
|
-
* any other PHP runtime wrapper. Extend `watch` when you use Typefinder's
|
|
9
|
-
* resource / page / broadcast features so the plugin regenerates on those
|
|
10
|
-
* file changes too.
|
|
11
|
-
*/
|
|
12
|
-
interface TypefinderOptions {
|
|
13
|
-
/**
|
|
14
|
-
* Glob patterns (relative to the Vite project root) whose changes should
|
|
15
|
-
* trigger a regeneration. Matched against each HMR update's file path.
|
|
16
|
-
*
|
|
17
|
-
* The default covers models, enums, and form requests — the always-on
|
|
18
|
-
* Typefinder categories. If you enable optional categories (Inertia pages,
|
|
19
|
-
* broadcasting) or use JSON resources, extend the list so updates on
|
|
20
|
-
* those directories also re-run the generator.
|
|
21
|
-
*
|
|
22
|
-
* @default ['app/Models/** /*.php', 'app/Enums/** /*.php', 'app/Http/Requests/** /*.php']
|
|
23
|
-
*/
|
|
24
|
-
watch?: string[];
|
|
25
|
-
/**
|
|
26
|
-
* Shell command used to regenerate types. Customize for non-standard
|
|
27
|
-
* PHP runtimes:
|
|
28
|
-
*
|
|
29
|
-
* - Sail: `'./vendor/bin/sail artisan typefinder:generate'`
|
|
30
|
-
* - Herd: `'herd php artisan typefinder:generate'`
|
|
31
|
-
* - Docker: `'docker compose exec app php artisan typefinder:generate'`
|
|
32
|
-
*
|
|
33
|
-
* @default 'php artisan typefinder:generate'
|
|
34
|
-
*/
|
|
35
|
-
command?: string;
|
|
36
|
-
/**
|
|
37
|
-
* Debounce window in milliseconds. When multiple files change within this
|
|
38
|
-
* window the plugin coalesces them into a single regeneration. Keep small
|
|
39
|
-
* for fast feedback; raise if your editor triggers noisy saves.
|
|
40
|
-
*
|
|
41
|
-
* @default 100
|
|
42
|
-
*/
|
|
43
|
-
debounceMs?: number;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Vite plugin that runs `php artisan typefinder:generate` automatically —
|
|
47
|
-
* once at `buildStart`, and again on every HMR update whose file path
|
|
48
|
-
* matches any pattern in {@link TypefinderOptions.watch}.
|
|
49
|
-
*
|
|
50
|
-
* Install the Composer package `pentacore/laravel-typefinder` in your Laravel
|
|
51
|
-
* app, then register this plugin in `vite.config.ts`:
|
|
52
|
-
*
|
|
53
|
-
* ```ts
|
|
54
|
-
* import { defineConfig } from 'vite';
|
|
55
|
-
* import laravel from 'laravel-vite-plugin';
|
|
56
|
-
* import typefinder from '@pentacore/vite-plugin-laravel-typefinder';
|
|
57
|
-
*
|
|
58
|
-
* export default defineConfig({
|
|
59
|
-
* plugins: [
|
|
60
|
-
* laravel({ input: ['resources/js/app.ts'] }),
|
|
61
|
-
* typefinder(),
|
|
62
|
-
* ],
|
|
63
|
-
* });
|
|
64
|
-
* ```
|
|
65
|
-
*
|
|
66
|
-
* Regenerations are debounced and serialized — concurrent triggers coalesce
|
|
67
|
-
* into at most one in-flight run plus one queued run. The plugin uses Vite's
|
|
68
|
-
* `enforce: 'pre'` ordering so types are fresh before other plugins inspect
|
|
69
|
-
* them.
|
|
70
|
-
*
|
|
71
|
-
* @param options Plugin options. See {@link TypefinderOptions}.
|
|
72
|
-
* @returns A Vite plugin.
|
|
73
|
-
*/
|
|
74
|
-
declare const typefinder: ({ watch, command, debounceMs, }?: TypefinderOptions) => Plugin;
|
|
75
|
-
|
|
76
|
-
export { typefinder as default, typefinder };
|
|
77
|
-
export type { TypefinderOptions };
|
|
1
|
+
export { }
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
var $ = Object.defineProperty;
|
|
2
|
+
var v = (l, s, t) => s in l ? $(l, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[s] = t;
|
|
3
|
+
var p = (l, s, t) => v(l, typeof s != "symbol" ? s + "" : s, t);
|
|
4
|
+
import { spawn as E, exec as S } from "node:child_process";
|
|
5
|
+
import { promisify as b } from "node:util";
|
|
6
|
+
import T from "picomatch";
|
|
7
|
+
import { EventEmitter as R } from "node:events";
|
|
8
|
+
const k = (l) => {
|
|
9
|
+
if (l.length === 0)
|
|
10
|
+
return () => !1;
|
|
11
|
+
const s = l.map((r) => `${r.replace(/\\/g, "/").replace(/\/$/, "")}/**/*.php`), t = T(s, { dot: !0 });
|
|
12
|
+
return (r) => {
|
|
13
|
+
const i = r.replace(/\\/g, "/");
|
|
14
|
+
return t(i);
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
class y extends R {
|
|
18
|
+
constructor(t, r, i) {
|
|
19
|
+
var a, d;
|
|
20
|
+
super();
|
|
21
|
+
p(this, "handshake");
|
|
22
|
+
p(this, "child");
|
|
23
|
+
p(this, "killTimeoutMs");
|
|
24
|
+
p(this, "buffer", "");
|
|
25
|
+
p(this, "inflight", null);
|
|
26
|
+
p(this, "nextBatch", null);
|
|
27
|
+
p(this, "nextResolvers", []);
|
|
28
|
+
p(this, "idCounter", 0);
|
|
29
|
+
p(this, "_dead", !1);
|
|
30
|
+
this.child = t, this.handshake = r, this.killTimeoutMs = i, (a = t.stdout) == null || a.on("data", (e) => {
|
|
31
|
+
this.onStdout(typeof e == "string" ? e : e.toString("utf8"));
|
|
32
|
+
}), (d = t.stderr) == null || d.on("data", (e) => {
|
|
33
|
+
const c = (typeof e == "string" ? e : e.toString("utf8")).trimEnd();
|
|
34
|
+
c !== "" && process.stderr.write(`[typefinder] ${c}
|
|
35
|
+
`);
|
|
36
|
+
}), t.on("exit", (e, c) => {
|
|
37
|
+
this._dead = !0;
|
|
38
|
+
const f = c ? `signal ${c}` : `exit code ${e ?? "null"}`;
|
|
39
|
+
this.emit("died", f), this.inflight && (this.inflight.reject(new Error(`watcher died (${f})`)), this.inflight = null);
|
|
40
|
+
for (const m of this.nextResolvers)
|
|
41
|
+
m.reject(new Error(`watcher died (${f})`));
|
|
42
|
+
this.nextResolvers = [], this.nextBatch = null;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
get dead() {
|
|
46
|
+
return this._dead;
|
|
47
|
+
}
|
|
48
|
+
static async spawn(t) {
|
|
49
|
+
const i = (t.spawnFn ?? ((a, d, e) => E(a, d, e)))(t.command, [], { cwd: t.cwd, shell: !0 });
|
|
50
|
+
return new Promise((a, d) => {
|
|
51
|
+
var w;
|
|
52
|
+
let e = "";
|
|
53
|
+
const c = (h) => {
|
|
54
|
+
var u;
|
|
55
|
+
e += typeof h == "string" ? h : h.toString("utf8");
|
|
56
|
+
const n = e.indexOf(`
|
|
57
|
+
`);
|
|
58
|
+
if (n === -1) return;
|
|
59
|
+
const o = e.slice(0, n);
|
|
60
|
+
e = e.slice(n + 1), clearTimeout(m), (u = i.stdout) == null || u.off("data", c), i.off("exit", f);
|
|
61
|
+
try {
|
|
62
|
+
const g = JSON.parse(o);
|
|
63
|
+
if (g.type !== "ready")
|
|
64
|
+
throw new Error("expected ready, got " + g.type);
|
|
65
|
+
const x = new y(i, g, t.killTimeoutMs ?? 2e3);
|
|
66
|
+
e.length > 0 && x.onStdout(e), a(x);
|
|
67
|
+
} catch (g) {
|
|
68
|
+
i.kill("SIGTERM"), d(new Error(`malformed handshake: ${g.message}`));
|
|
69
|
+
}
|
|
70
|
+
}, f = (h, n) => {
|
|
71
|
+
var o;
|
|
72
|
+
clearTimeout(m), (o = i.stdout) == null || o.off("data", c), d(new Error(`watcher exited before handshake (code=${h}, signal=${n})`));
|
|
73
|
+
}, m = setTimeout(() => {
|
|
74
|
+
var h;
|
|
75
|
+
(h = i.stdout) == null || h.off("data", c), i.off("exit", f), i.kill("SIGTERM"), d(new Error(`watcher startup timeout after ${t.startupTimeoutMs}ms`));
|
|
76
|
+
}, t.startupTimeoutMs);
|
|
77
|
+
(w = i.stdout) == null || w.on("data", c), i.on("exit", f);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
async regen(t) {
|
|
81
|
+
if (this._dead)
|
|
82
|
+
throw new Error("watcher is dead");
|
|
83
|
+
if (!this.inflight)
|
|
84
|
+
return this.dispatch(t);
|
|
85
|
+
this.nextBatch || (this.nextBatch = /* @__PURE__ */ new Set());
|
|
86
|
+
for (const r of t)
|
|
87
|
+
this.nextBatch.add(r);
|
|
88
|
+
return new Promise((r, i) => {
|
|
89
|
+
this.nextResolvers.push({ resolve: r, reject: i });
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
dispatch(t) {
|
|
93
|
+
var a;
|
|
94
|
+
const r = `r${++this.idCounter}`, i = { type: "regen", id: r, paths: t };
|
|
95
|
+
return (a = this.child.stdin) == null || a.write(JSON.stringify(i) + `
|
|
96
|
+
`), new Promise((d, e) => {
|
|
97
|
+
this.inflight = { id: r, resolve: d, reject: e };
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
onStdout(t) {
|
|
101
|
+
this.buffer += t;
|
|
102
|
+
let r;
|
|
103
|
+
for (; (r = this.buffer.indexOf(`
|
|
104
|
+
`)) !== -1; ) {
|
|
105
|
+
const i = this.buffer.slice(0, r);
|
|
106
|
+
this.buffer = this.buffer.slice(r + 1), i.trim() !== "" && this.handleLine(i);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
handleLine(t) {
|
|
110
|
+
let r;
|
|
111
|
+
try {
|
|
112
|
+
r = JSON.parse(t);
|
|
113
|
+
} catch {
|
|
114
|
+
process.stderr.write(`[typefinder] unparseable line: ${t}
|
|
115
|
+
`);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (r.type === "regen.done" || r.type === "regen.error") {
|
|
119
|
+
if (!this.inflight || "id" in r && this.inflight.id !== r.id)
|
|
120
|
+
return;
|
|
121
|
+
const i = this.inflight;
|
|
122
|
+
this.inflight = null, r.type === "regen.done" ? i.resolve(r) : i.reject(new Error(r.message)), this.drainQueued();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
drainQueued() {
|
|
126
|
+
if (!this.nextBatch || this.nextResolvers.length === 0) return;
|
|
127
|
+
const t = Array.from(this.nextBatch), r = [...this.nextResolvers];
|
|
128
|
+
this.nextBatch = null, this.nextResolvers = [], this.dispatch(t).then(
|
|
129
|
+
(i) => r.forEach((a) => a.resolve(i)),
|
|
130
|
+
(i) => r.forEach((a) => a.reject(i))
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
async kill() {
|
|
134
|
+
this._dead || await new Promise((t) => {
|
|
135
|
+
const r = setTimeout(() => {
|
|
136
|
+
this._dead || this.child.kill("SIGKILL");
|
|
137
|
+
}, this.killTimeoutMs);
|
|
138
|
+
this.child.once("exit", () => {
|
|
139
|
+
clearTimeout(r), t();
|
|
140
|
+
}), this.child.kill("SIGTERM");
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const M = b(S), G = ({
|
|
145
|
+
command: l = "php artisan typefinder:watch",
|
|
146
|
+
buildCommand: s = "php artisan typefinder:generate --json",
|
|
147
|
+
watch: t,
|
|
148
|
+
debounceMs: r = 100,
|
|
149
|
+
startupTimeoutMs: i = 1e4,
|
|
150
|
+
killTimeoutMs: a = 2e3
|
|
151
|
+
} = {}) => {
|
|
152
|
+
let d = process.cwd(), e = null, c = () => !1;
|
|
153
|
+
const f = /* @__PURE__ */ new Set();
|
|
154
|
+
let m, w = !1;
|
|
155
|
+
const h = () => {
|
|
156
|
+
clearTimeout(m), m = setTimeout(() => {
|
|
157
|
+
if (!e || e.dead) return;
|
|
158
|
+
const n = Array.from(f);
|
|
159
|
+
f.clear(), n.length !== 0 && e.regen(n).then((o) => {
|
|
160
|
+
o.changed.length > 0 && process.stderr.write(
|
|
161
|
+
`[typefinder] regen ${o.changed.length} file(s) in ${o.duration_ms}ms
|
|
162
|
+
`
|
|
163
|
+
);
|
|
164
|
+
for (const u of o.warnings)
|
|
165
|
+
process.stderr.write(`[typefinder] ${u}
|
|
166
|
+
`);
|
|
167
|
+
for (const u of o.failed)
|
|
168
|
+
process.stderr.write(`[typefinder] ${u.path}: ${u.message}
|
|
169
|
+
`);
|
|
170
|
+
}).catch((o) => {
|
|
171
|
+
process.stderr.write(`[typefinder] regen failed: ${o.message}
|
|
172
|
+
`);
|
|
173
|
+
});
|
|
174
|
+
}, r);
|
|
175
|
+
};
|
|
176
|
+
return {
|
|
177
|
+
name: "@pentacore/vite-plugin-laravel-typefinder",
|
|
178
|
+
enforce: "pre",
|
|
179
|
+
configResolved(n) {
|
|
180
|
+
d = n.root, w = n.command === "build";
|
|
181
|
+
},
|
|
182
|
+
async configureServer(n) {
|
|
183
|
+
var u;
|
|
184
|
+
if (w) return;
|
|
185
|
+
e = await y.spawn({
|
|
186
|
+
command: l,
|
|
187
|
+
cwd: d,
|
|
188
|
+
startupTimeoutMs: i,
|
|
189
|
+
killTimeoutMs: a
|
|
190
|
+
});
|
|
191
|
+
const o = t ?? B(e.handshake.categories);
|
|
192
|
+
c = k(o), e.on("died", (g) => {
|
|
193
|
+
process.stderr.write(
|
|
194
|
+
`[typefinder] watcher exited: ${g} — restart the dev server
|
|
195
|
+
`
|
|
196
|
+
);
|
|
197
|
+
}), n.ws.on("typefinder:full-regen", () => {
|
|
198
|
+
e && !e.dead && e.regen([]).catch((g) => {
|
|
199
|
+
process.stderr.write(`[typefinder] full regen failed: ${g.message}
|
|
200
|
+
`);
|
|
201
|
+
});
|
|
202
|
+
}), (u = n.httpServer) == null || u.once("close", () => void (e == null ? void 0 : e.kill())), process.once("exit", () => void (e == null ? void 0 : e.kill()));
|
|
203
|
+
},
|
|
204
|
+
async buildStart() {
|
|
205
|
+
if (w) {
|
|
206
|
+
if (s === !1) {
|
|
207
|
+
process.stderr.write(`[typefinder] build-time generation disabled
|
|
208
|
+
`);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
await M(s, { cwd: d });
|
|
213
|
+
} catch (n) {
|
|
214
|
+
const o = n instanceof Error ? n.message : String(n);
|
|
215
|
+
throw new Error(`[typefinder] build-time generation failed: ${o}`, { cause: n });
|
|
216
|
+
}
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (e && !e.dead) {
|
|
220
|
+
const n = await e.regen([]);
|
|
221
|
+
n.changed.length > 0 && process.stderr.write(
|
|
222
|
+
`[typefinder] initial regen: ${n.changed.length} file(s) in ${n.duration_ms}ms
|
|
223
|
+
`
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
handleHotUpdate({ file: n }) {
|
|
228
|
+
w || !e || e.dead || c(n) && (f.add(n), h());
|
|
229
|
+
},
|
|
230
|
+
async closeBundle() {
|
|
231
|
+
e && !e.dead && await e.kill();
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
}, B = (l) => {
|
|
235
|
+
const s = [];
|
|
236
|
+
for (const t of Object.keys(l)) {
|
|
237
|
+
const r = l[t];
|
|
238
|
+
r.enabled && s.push(...r.paths);
|
|
239
|
+
}
|
|
240
|
+
return s;
|
|
241
|
+
};
|
|
242
|
+
export {
|
|
243
|
+
G as default,
|
|
244
|
+
G as typefinder
|
|
245
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pentacore/vite-plugin-laravel-typefinder",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"description": "Vite plugin for Laravel Typefinder — auto-generate TypeScript types from Models, Enums, Casts, and Requests.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vite",
|
|
@@ -17,29 +17,36 @@
|
|
|
17
17
|
},
|
|
18
18
|
"type": "module",
|
|
19
19
|
"scripts": {
|
|
20
|
-
"build": "
|
|
21
|
-
"dev": "
|
|
20
|
+
"build": "vite build",
|
|
21
|
+
"dev": "vite build --watch",
|
|
22
22
|
"lint": "eslint src/",
|
|
23
|
-
"lint:fix": "eslint src/ --fix"
|
|
23
|
+
"lint:fix": "eslint src/ --fix",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest"
|
|
24
26
|
},
|
|
25
|
-
"module": "dist/index.
|
|
26
|
-
"types": "dist/index.d.
|
|
27
|
+
"module": "dist/index.js",
|
|
28
|
+
"types": "dist/index.d.ts",
|
|
27
29
|
"exports": {
|
|
28
30
|
".": {
|
|
29
|
-
"import": "./dist/index.
|
|
30
|
-
"types": "./dist/index.d.
|
|
31
|
+
"import": "./dist/index.js",
|
|
32
|
+
"types": "./dist/index.d.ts"
|
|
31
33
|
}
|
|
32
34
|
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"picomatch": "^4.0.4"
|
|
37
|
+
},
|
|
33
38
|
"devDependencies": {
|
|
34
|
-
"@
|
|
35
|
-
"eslint": "^
|
|
36
|
-
"@
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"typescript": "^
|
|
41
|
-
"
|
|
42
|
-
"vite": "^6.
|
|
39
|
+
"@codecov/vite-plugin": "^2.0.1",
|
|
40
|
+
"@eslint/js": "^10.0.1",
|
|
41
|
+
"@types/node": "^24.12.2",
|
|
42
|
+
"@types/picomatch": "^4.0.3",
|
|
43
|
+
"@vitest/coverage-v8": "^4.1.4",
|
|
44
|
+
"eslint": "^10.2.0",
|
|
45
|
+
"typescript": "^6.0.3",
|
|
46
|
+
"typescript-eslint": "^8.58.2",
|
|
47
|
+
"vite": "^6.4.2",
|
|
48
|
+
"vite-plugin-dts": "^4.5.4",
|
|
49
|
+
"vitest": "^4.1.4"
|
|
43
50
|
},
|
|
44
51
|
"files": [
|
|
45
52
|
"dist"
|
package/dist/index.d.mts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { Plugin } from 'vite';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Options for the `typefinder` Vite plugin.
|
|
5
|
-
*
|
|
6
|
-
* All fields are optional — the defaults work for a standard Laravel project
|
|
7
|
-
* running PHP directly. Override `command` when using Sail, Herd, Docker, or
|
|
8
|
-
* any other PHP runtime wrapper. Extend `watch` when you use Typefinder's
|
|
9
|
-
* resource / page / broadcast features so the plugin regenerates on those
|
|
10
|
-
* file changes too.
|
|
11
|
-
*/
|
|
12
|
-
interface TypefinderOptions {
|
|
13
|
-
/**
|
|
14
|
-
* Glob patterns (relative to the Vite project root) whose changes should
|
|
15
|
-
* trigger a regeneration. Matched against each HMR update's file path.
|
|
16
|
-
*
|
|
17
|
-
* The default covers models, enums, and form requests — the always-on
|
|
18
|
-
* Typefinder categories. If you enable optional categories (Inertia pages,
|
|
19
|
-
* broadcasting) or use JSON resources, extend the list so updates on
|
|
20
|
-
* those directories also re-run the generator.
|
|
21
|
-
*
|
|
22
|
-
* @default ['app/Models/** /*.php', 'app/Enums/** /*.php', 'app/Http/Requests/** /*.php']
|
|
23
|
-
*/
|
|
24
|
-
watch?: string[];
|
|
25
|
-
/**
|
|
26
|
-
* Shell command used to regenerate types. Customize for non-standard
|
|
27
|
-
* PHP runtimes:
|
|
28
|
-
*
|
|
29
|
-
* - Sail: `'./vendor/bin/sail artisan typefinder:generate'`
|
|
30
|
-
* - Herd: `'herd php artisan typefinder:generate'`
|
|
31
|
-
* - Docker: `'docker compose exec app php artisan typefinder:generate'`
|
|
32
|
-
*
|
|
33
|
-
* @default 'php artisan typefinder:generate'
|
|
34
|
-
*/
|
|
35
|
-
command?: string;
|
|
36
|
-
/**
|
|
37
|
-
* Debounce window in milliseconds. When multiple files change within this
|
|
38
|
-
* window the plugin coalesces them into a single regeneration. Keep small
|
|
39
|
-
* for fast feedback; raise if your editor triggers noisy saves.
|
|
40
|
-
*
|
|
41
|
-
* @default 100
|
|
42
|
-
*/
|
|
43
|
-
debounceMs?: number;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Vite plugin that runs `php artisan typefinder:generate` automatically —
|
|
47
|
-
* once at `buildStart`, and again on every HMR update whose file path
|
|
48
|
-
* matches any pattern in {@link TypefinderOptions.watch}.
|
|
49
|
-
*
|
|
50
|
-
* Install the Composer package `pentacore/laravel-typefinder` in your Laravel
|
|
51
|
-
* app, then register this plugin in `vite.config.ts`:
|
|
52
|
-
*
|
|
53
|
-
* ```ts
|
|
54
|
-
* import { defineConfig } from 'vite';
|
|
55
|
-
* import laravel from 'laravel-vite-plugin';
|
|
56
|
-
* import typefinder from '@pentacore/vite-plugin-laravel-typefinder';
|
|
57
|
-
*
|
|
58
|
-
* export default defineConfig({
|
|
59
|
-
* plugins: [
|
|
60
|
-
* laravel({ input: ['resources/js/app.ts'] }),
|
|
61
|
-
* typefinder(),
|
|
62
|
-
* ],
|
|
63
|
-
* });
|
|
64
|
-
* ```
|
|
65
|
-
*
|
|
66
|
-
* Regenerations are debounced and serialized — concurrent triggers coalesce
|
|
67
|
-
* into at most one in-flight run plus one queued run. The plugin uses Vite's
|
|
68
|
-
* `enforce: 'pre'` ordering so types are fresh before other plugins inspect
|
|
69
|
-
* them.
|
|
70
|
-
*
|
|
71
|
-
* @param options Plugin options. See {@link TypefinderOptions}.
|
|
72
|
-
* @returns A Vite plugin.
|
|
73
|
-
*/
|
|
74
|
-
declare const typefinder: ({ watch, command, debounceMs, }?: TypefinderOptions) => Plugin;
|
|
75
|
-
|
|
76
|
-
export { typefinder as default, typefinder };
|
|
77
|
-
export type { TypefinderOptions };
|