@moostjs/vite 0.6.53 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -92,7 +92,7 @@ app.init()
92
92
 
93
93
  Requests matching Moost routes (e.g. `/api/hello/world`) are handled by Moost with the full pipeline (interceptors, DI, validation). Everything else (`/`, `/about`, static assets) falls through to Vite.
94
94
 
95
- The optional `prefix` option adds a fast-path check — requests not matching the prefix skip Moost entirely:
95
+ The optional `prefix` option declares the API mount(s) (a string or a list) — requests outside every mount skip Moost entirely, and an unmatched route under a mount gets Moost's `404` JSON error instead of the frontend's `index.html` — a static file under the mount (e.g. `/.well-known/security.txt`) is still served for `GET`/`HEAD` — and `prefixFallthrough: true` lets unmatched routes fall through instead:
96
96
 
97
97
  ```ts
98
98
  moostVite({
@@ -102,7 +102,7 @@ moostVite({
102
102
  })
103
103
  ```
104
104
 
105
- Note that the production server generated by `vite build` defaults the prefix to `'/api'` when the option is omitted — set `prefix` explicitly so dev (where all requests pass through Moost without it) and prod route the same way.
105
+ Without `prefix`, every request enters Moost first and unmatched routes fall through to the frontend — in dev and in the generated production server alike.
106
106
 
107
107
  ## SSR Mode
108
108
 
@@ -272,7 +272,8 @@ The plugin injects a `__VITE_ID` decorator on `@Injectable` and `@Controller` cl
272
272
  | `onEject` | `function` | — | Hook to control DI instance ejection during HMR |
273
273
  | `ssrFetch` | `boolean` | `true` | Enable local fetch interception for SSR |
274
274
  | `middleware` | `boolean` | `false` | Run Moost as Connect middleware (Vite serves frontend) |
275
- | `prefix` | `string` | `'/api'` (prod server) | URL prefix filter for middleware mode (e.g. `'/api'`); the production server defaults to `'/api'` when omitted |
275
+ | `prefix` | `string \| string[]` | — | API mount(s) for middleware mode: requests outside skip Moost, unmatched routes inside get Moost's `404` |
276
+ | `prefixFallthrough` | `boolean` | `false` | Let unmatched routes under `prefix` fall through to the frontend instead of Moost's `404` |
276
277
  | `ssrEntry` | `string` | — | Vue/React SSR entry module (e.g. `'/src/entry-server.ts'`) |
277
278
  | `ssrOutlet` | `string` | `'<!--ssr-outlet-->'` | HTML placeholder for SSR-rendered content |
278
279
  | `ssrState` | `string` | `'<!--ssr-state-->'` | HTML placeholder for SSR state transfer script |
package/dist/index.cjs CHANGED
@@ -816,6 +816,45 @@ const DEFAULT_PRECOMPRESS_INCLUDE = /\.(?:m?js|cjs|css|html?|svg|json|webmanifes
816
816
  gzip: opts.gzip !== false
817
817
  };
818
818
  }
819
+ /** The decoded pathname of a request url, the way sirv looks files up. */ function requestPathname(url) {
820
+ const end = url.search(/[?#]/);
821
+ const pathname = end === -1 ? url : url.slice(0, end);
822
+ if (!pathname.includes("%")) return pathname;
823
+ try {
824
+ return decodeURI(pathname);
825
+ } catch {
826
+ return pathname;
827
+ }
828
+ }
829
+ /**
830
+ * The no-match handler of an API mount (a `prefix` without `prefixFallthrough`): a GET/HEAD
831
+ * that names a static file is served (`tryStatic`, with `notFound` for a miss); anything else
832
+ * gets Moost's own 404 — never the SPA shell or an SSR page.
833
+ */ function apiMountNoMatch(tryStatic, notFound) {
834
+ return (req, res) => {
835
+ if (req.method === "GET" || req.method === "HEAD") tryStatic(req, res, notFound);
836
+ else notFound(req, res);
837
+ };
838
+ }
839
+ /** Resolved public-dir roots (`publicDir` is fixed per dev server). */ const publicRoots = /* @__PURE__ */ new Map();
840
+ /**
841
+ * Whether `url` names a file inside `publicDir` (Vite's `public/`), for the dev server: a GET
842
+ * under an API mount that no route matched is served from there before Moost's 404.
843
+ */ function isPublicFile(publicDir, url) {
844
+ if (!publicDir) return false;
845
+ let root = publicRoots.get(publicDir);
846
+ if (!root) {
847
+ root = (0, node_path.resolve)(publicDir);
848
+ publicRoots.set(publicDir, root);
849
+ }
850
+ const file = (0, node_path.resolve)(root, `.${requestPathname(url)}`);
851
+ if (file !== root && !file.startsWith(root + node_path.sep)) return false;
852
+ try {
853
+ return (0, node_fs.statSync)(file, { throwIfNoEntry: false })?.isFile() ?? false;
854
+ } catch {
855
+ return false;
856
+ }
857
+ }
819
858
 
820
859
  //#endregion
821
860
  //#region packages/vite/src/moost-vite.ts
@@ -923,10 +962,10 @@ function moostVite(options) {
923
962
  if (bootingGeneration !== bootGeneration) logger.error(`⚠️ A stale Moost boot captured the HTTP middleware (boot generation ${bootingGeneration}, latest ${bootGeneration}) — an HMR reload race; a follow-up reload will replace it.`);
924
963
  httpCaptured = true;
925
964
  moostHttpRef.current = this;
926
- if (options.middleware) moostMiddleware = this.getServerCb((req) => {
927
- pendingNextMap.get(req)?.();
928
- });
929
- else moostMiddleware = this.getServerCb();
965
+ if (options.middleware) {
966
+ const toVite = (req) => pendingNextMap.get(req)?.();
967
+ moostMiddleware = this.getServerCb(prefixes && !options.prefixFallthrough ? apiMountNoMatch((req, res, miss) => isPublicFile(resolvedConfig?.publicDir, req.url || "/") ? toVite(req) : miss(req, res), this.getServerCb()) : toVite);
968
+ } else moostMiddleware = this.getServerCb();
930
969
  if (options.ssrFetch !== false && moduleExports?.enableLocalFetch) {
931
970
  if (localFetchTeardown) localFetchTeardown();
932
971
  localFetchTeardown = moduleExports.enableLocalFetch(this);
@@ -1046,6 +1085,7 @@ function moostVite(options) {
1046
1085
  "process.env.MOOST_DEFERRED_ENV": "\"production\"",
1047
1086
  __MOOST_ENTRY__: JSON.stringify(`./${entryKey}.js`),
1048
1087
  __MOOST_PREFIX__: JSON.stringify(prefixes ?? null),
1088
+ __MOOST_PREFIX_FALLTHROUGH__: JSON.stringify(options.prefixFallthrough === true),
1049
1089
  __MOOST_SSR_FORWARDING__: JSON.stringify(ssrForwarding),
1050
1090
  __MOOST_SSR_ENTRY__: "undefined",
1051
1091
  __MOOST_SSR_OUTLET__: JSON.stringify(ssrOutlet),
@@ -1155,6 +1195,7 @@ function moostVite(options) {
1155
1195
  ssrEntry: options.ssrEntry,
1156
1196
  serverEntry: options.serverEntry,
1157
1197
  prefix: prefixes,
1198
+ prefixFallthrough: options.prefixFallthrough,
1158
1199
  ssrOutlet: options.ssrOutlet,
1159
1200
  ssrState: options.ssrState,
1160
1201
  ssrHead: options.ssrHead,
package/dist/index.d.ts CHANGED
@@ -146,7 +146,8 @@ interface TMoostViteDevOptions {
146
146
  * When enabled, Moost runs first and unmatched requests fall through to
147
147
  * Vite's default handler (static assets, Vue/React pages, HMR client).
148
148
  * With `prefix` configured, requests outside the mount(s) skip the Moost
149
- * router entirely (fast path).
149
+ * router entirely (fast path), and unmatched routes inside a mount get
150
+ * Moost's 404 (see `prefix`).
150
151
  *
151
152
  * Use this for fullstack apps where Vite serves the frontend (Vue, React, etc.)
152
153
  * and Moost handles API routes.
@@ -158,13 +159,24 @@ interface TMoostViteDevOptions {
158
159
  * URL mount(s) for Moost routes in middleware mode — a single prefix or a
159
160
  * list of prefixes. Requests outside every mount skip the Moost router and
160
161
  * go straight to the frontend handler (an optimization/guard, in both dev
161
- * and the generated prod server). When omitted, every request enters Moost
162
+ * and the generated prod server). A prefix is an API mount: an unmatched
163
+ * route under it gets Moost's own 404 (JSON) in dev and production instead
164
+ * of the SPA shell or an SSR page — set `prefixFallthrough: true` to let it
165
+ * fall through to the frontend. When omitted, every request enters Moost
162
166
  * first and unmatched routes fall through to the frontend.
163
167
  * Ignored when `middleware` is `false`.
164
168
  *
165
169
  * Example: `'/api'` or `['/api', '/.well-known']`
166
170
  */
167
171
  prefix?: string | string[];
172
+ /**
173
+ * Let unmatched routes under `prefix` fall through to the frontend (static
174
+ * files, SPA shell, SSR page) instead of answering Moost's 404.
175
+ * Applies in dev and is baked into the generated production server.
176
+ *
177
+ * Default: `false`.
178
+ */
179
+ prefixFallthrough?: boolean;
168
180
  /**
169
181
  * Vue/React SSR entry module path. Used by the SSR server helper
170
182
  * (`@moostjs/vite/server`) for server-side rendering.
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
1
+ import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync, statSync, writeFileSync } from "node:fs";
2
2
  import { dirname, join, relative, resolve, sep } from "node:path";
3
3
  import { createServerModuleRunner } from "vite";
4
4
  import MagicString from "magic-string";
@@ -787,6 +787,45 @@ const DEFAULT_PRECOMPRESS_INCLUDE = /\.(?:m?js|cjs|css|html?|svg|json|webmanifes
787
787
  gzip: opts.gzip !== false
788
788
  };
789
789
  }
790
+ /** The decoded pathname of a request url, the way sirv looks files up. */ function requestPathname(url) {
791
+ const end = url.search(/[?#]/);
792
+ const pathname = end === -1 ? url : url.slice(0, end);
793
+ if (!pathname.includes("%")) return pathname;
794
+ try {
795
+ return decodeURI(pathname);
796
+ } catch {
797
+ return pathname;
798
+ }
799
+ }
800
+ /**
801
+ * The no-match handler of an API mount (a `prefix` without `prefixFallthrough`): a GET/HEAD
802
+ * that names a static file is served (`tryStatic`, with `notFound` for a miss); anything else
803
+ * gets Moost's own 404 — never the SPA shell or an SSR page.
804
+ */ function apiMountNoMatch(tryStatic, notFound) {
805
+ return (req, res) => {
806
+ if (req.method === "GET" || req.method === "HEAD") tryStatic(req, res, notFound);
807
+ else notFound(req, res);
808
+ };
809
+ }
810
+ /** Resolved public-dir roots (`publicDir` is fixed per dev server). */ const publicRoots = /* @__PURE__ */ new Map();
811
+ /**
812
+ * Whether `url` names a file inside `publicDir` (Vite's `public/`), for the dev server: a GET
813
+ * under an API mount that no route matched is served from there before Moost's 404.
814
+ */ function isPublicFile(publicDir, url) {
815
+ if (!publicDir) return false;
816
+ let root = publicRoots.get(publicDir);
817
+ if (!root) {
818
+ root = resolve(publicDir);
819
+ publicRoots.set(publicDir, root);
820
+ }
821
+ const file = resolve(root, `.${requestPathname(url)}`);
822
+ if (file !== root && !file.startsWith(root + sep)) return false;
823
+ try {
824
+ return statSync(file, { throwIfNoEntry: false })?.isFile() ?? false;
825
+ } catch {
826
+ return false;
827
+ }
828
+ }
790
829
 
791
830
  //#endregion
792
831
  //#region packages/vite/src/moost-vite.ts
@@ -892,10 +931,10 @@ function moostVite(options) {
892
931
  if (bootingGeneration !== bootGeneration) logger.error(`⚠️ A stale Moost boot captured the HTTP middleware (boot generation ${bootingGeneration}, latest ${bootGeneration}) — an HMR reload race; a follow-up reload will replace it.`);
893
932
  httpCaptured = true;
894
933
  moostHttpRef.current = this;
895
- if (options.middleware) moostMiddleware = this.getServerCb((req) => {
896
- pendingNextMap.get(req)?.();
897
- });
898
- else moostMiddleware = this.getServerCb();
934
+ if (options.middleware) {
935
+ const toVite = (req) => pendingNextMap.get(req)?.();
936
+ moostMiddleware = this.getServerCb(prefixes && !options.prefixFallthrough ? apiMountNoMatch((req, res, miss) => isPublicFile(resolvedConfig?.publicDir, req.url || "/") ? toVite(req) : miss(req, res), this.getServerCb()) : toVite);
937
+ } else moostMiddleware = this.getServerCb();
899
938
  if (options.ssrFetch !== false && moduleExports?.enableLocalFetch) {
900
939
  if (localFetchTeardown) localFetchTeardown();
901
940
  localFetchTeardown = moduleExports.enableLocalFetch(this);
@@ -1015,6 +1054,7 @@ function moostVite(options) {
1015
1054
  "process.env.MOOST_DEFERRED_ENV": "\"production\"",
1016
1055
  __MOOST_ENTRY__: JSON.stringify(`./${entryKey}.js`),
1017
1056
  __MOOST_PREFIX__: JSON.stringify(prefixes ?? null),
1057
+ __MOOST_PREFIX_FALLTHROUGH__: JSON.stringify(options.prefixFallthrough === true),
1018
1058
  __MOOST_SSR_FORWARDING__: JSON.stringify(ssrForwarding),
1019
1059
  __MOOST_SSR_ENTRY__: "undefined",
1020
1060
  __MOOST_SSR_OUTLET__: JSON.stringify(ssrOutlet),
@@ -1124,6 +1164,7 @@ function moostVite(options) {
1124
1164
  ssrEntry: options.ssrEntry,
1125
1165
  serverEntry: options.serverEntry,
1126
1166
  prefix: prefixes,
1167
+ prefixFallthrough: options.prefixFallthrough,
1127
1168
  ssrOutlet: options.ssrOutlet,
1128
1169
  ssrState: options.ssrState,
1129
1170
  ssrHead: options.ssrHead,
@@ -47,6 +47,16 @@ const DEFAULT_REVALIDATE_CACHE_CONTROL = "no-cache";
47
47
  }
48
48
  }
49
49
  /**
50
+ * The no-match handler of an API mount (a `prefix` without `prefixFallthrough`): a GET/HEAD
51
+ * that names a static file is served (`tryStatic`, with `notFound` for a miss); anything else
52
+ * gets Moost's own 404 — never the SPA shell or an SSR page.
53
+ */ function apiMountNoMatch(tryStatic, notFound) {
54
+ return (req, res) => {
55
+ if (req.method === "GET" || req.method === "HEAD") tryStatic(req, res, notFound);
56
+ else notFound(req, res);
57
+ };
58
+ }
59
+ /**
50
60
  * The root `index.html` (and precompressed siblings) is the SPA/SSR template:
51
61
  * it is never served as a static file, but by the SPA/SSR fallback (in SSR mode
52
62
  * a raw template would leak its unfilled `<!--ssr-outlet-->` placeholders).
@@ -111,7 +121,7 @@ const DEFAULT_REVALIDATE_CACHE_CONTROL = "no-cache";
111
121
  /**
112
122
  * Static file serving (sirv) with the cache policy and the precompressed
113
123
  * variants; requests that match no file — and the root `index.html` template —
114
- * go to `servePage` (SSR render or SPA shell).
124
+ * go to `fallback`, by default `servePage` (SSR render or SPA shell).
115
125
  */ async function createStaticHandler(clientDir, variants, cache, servePage) {
116
126
  const { default: sirv } = await import("sirv");
117
127
  const negotiate = variants.brotli || variants.gzip;
@@ -126,10 +136,10 @@ const DEFAULT_REVALIDATE_CACHE_CONTROL = "no-cache";
126
136
  if (vary) res.setHeader("Vary", vary);
127
137
  }
128
138
  });
129
- return (req, res) => {
139
+ return (req, res, fallback = servePage) => {
130
140
  const pathname = requestPathname(req.url || "/");
131
141
  if (isIndexTemplatePath(pathname)) {
132
- servePage(req, res);
142
+ fallback(req, res);
133
143
  return;
134
144
  }
135
145
  const restore = [];
@@ -141,7 +151,7 @@ const DEFAULT_REVALIDATE_CACHE_CONTROL = "no-cache";
141
151
  }
142
152
  serve(req, res, () => {
143
153
  for (const undo of restore) undo();
144
- servePage(req, res);
154
+ fallback(req, res);
145
155
  });
146
156
  };
147
157
  }
@@ -304,6 +314,7 @@ async function createSSRServer(options) {
304
314
  const ssrState = opts.ssrState || (__MOOST_SSR_STATE__ !== void 0 ? __MOOST_SSR_STATE__ : DEFAULT_SSR_STATE);
305
315
  const ssrHead = opts.ssrHead || (__MOOST_SSR_HEAD__ !== void 0 ? __MOOST_SSR_HEAD__ : DEFAULT_SSR_HEAD);
306
316
  const prefixes = normalizePrefixes(opts.prefix ?? __MOOST_PREFIX__);
317
+ const prefixFallthrough = opts.prefixFallthrough ?? __MOOST_PREFIX_FALLTHROUGH__ ?? false;
307
318
  const ssrForwarding = opts.ssrFetchForwarding ?? __MOOST_SSR_FORWARDING__ ?? true;
308
319
  const variants = resolvePrecompressed(__MOOST_PRECOMPRESS__, opts.precompressed);
309
320
  const cache = resolveCacheControl(__MOOST_CACHE_CONTROL__, opts.cacheControl);
@@ -321,7 +332,7 @@ async function createSSRServer(options) {
321
332
  let captured = false;
322
333
  const origListen = MoostHttp.prototype.listen;
323
334
  MoostHttp.prototype.listen = function(...args) {
324
- moostHandler = this.getServerCb((req, res) => serveStatic(req, res));
335
+ moostHandler = this.getServerCb(prefixes && !prefixFallthrough ? apiMountNoMatch((req, res, miss) => serveStatic(req, res, miss), this.getServerCb()) : (req, res) => serveStatic(req, res));
325
336
  moostHttpRef.instance = this;
326
337
  captured = true;
327
338
  setTimeout(() => args.filter((a) => typeof a === "function").forEach((a) => a()), 1);
@@ -85,10 +85,18 @@ interface TSSRServerOptions {
85
85
  /**
86
86
  * Override: URL mount(s) for Moost routes (e.g., '/api' or ['/api', '/.well-known']).
87
87
  * Requests outside every mount skip the Moost router (optimization/guard).
88
+ * A prefix is an API mount: an unmatched route under it gets Moost's own
89
+ * 404 (JSON), never the SPA shell or an SSR page (see `prefixFallthrough`).
88
90
  * When omitted (and not baked by the plugin), every request enters Moost first
89
91
  * and unmatched routes fall through to static/SSR — same as dev.
90
92
  */
91
93
  prefix?: string | string[];
94
+ /**
95
+ * Override: let unmatched routes under `prefix` fall through to static files
96
+ * and the SPA/SSR page instead of answering Moost's 404.
97
+ * Default: baked from the plugin's `prefixFallthrough` option (`false`).
98
+ */
99
+ prefixFallthrough?: boolean;
92
100
  /** Override: port number (default: process.env.PORT || 3000) */
93
101
  port?: number;
94
102
  /** Override: bind address, e.g. '127.0.0.1' (default: process.env.HOST, else all interfaces) */
@@ -1,7 +1,7 @@
1
1
  import { once } from "node:events";
2
+ import "node:fs";
2
3
  import { readFile } from "node:fs/promises";
3
4
  import { join } from "node:path";
4
- import "node:fs";
5
5
  import "node:module";
6
6
  import { createLogger } from "moost";
7
7
 
@@ -48,6 +48,16 @@ const DEFAULT_REVALIDATE_CACHE_CONTROL = "no-cache";
48
48
  }
49
49
  }
50
50
  /**
51
+ * The no-match handler of an API mount (a `prefix` without `prefixFallthrough`): a GET/HEAD
52
+ * that names a static file is served (`tryStatic`, with `notFound` for a miss); anything else
53
+ * gets Moost's own 404 — never the SPA shell or an SSR page.
54
+ */ function apiMountNoMatch(tryStatic, notFound) {
55
+ return (req, res) => {
56
+ if (req.method === "GET" || req.method === "HEAD") tryStatic(req, res, notFound);
57
+ else notFound(req, res);
58
+ };
59
+ }
60
+ /**
51
61
  * The root `index.html` (and precompressed siblings) is the SPA/SSR template:
52
62
  * it is never served as a static file, but by the SPA/SSR fallback (in SSR mode
53
63
  * a raw template would leak its unfilled `<!--ssr-outlet-->` placeholders).
@@ -112,7 +122,7 @@ const DEFAULT_REVALIDATE_CACHE_CONTROL = "no-cache";
112
122
  /**
113
123
  * Static file serving (sirv) with the cache policy and the precompressed
114
124
  * variants; requests that match no file — and the root `index.html` template —
115
- * go to `servePage` (SSR render or SPA shell).
125
+ * go to `fallback`, by default `servePage` (SSR render or SPA shell).
116
126
  */ async function createStaticHandler(clientDir, variants, cache, servePage) {
117
127
  const { default: sirv } = await import("sirv");
118
128
  const negotiate = variants.brotli || variants.gzip;
@@ -127,10 +137,10 @@ const DEFAULT_REVALIDATE_CACHE_CONTROL = "no-cache";
127
137
  if (vary) res.setHeader("Vary", vary);
128
138
  }
129
139
  });
130
- return (req, res) => {
140
+ return (req, res, fallback = servePage) => {
131
141
  const pathname = requestPathname(req.url || "/");
132
142
  if (isIndexTemplatePath(pathname)) {
133
- servePage(req, res);
143
+ fallback(req, res);
134
144
  return;
135
145
  }
136
146
  const restore = [];
@@ -142,7 +152,7 @@ const DEFAULT_REVALIDATE_CACHE_CONTROL = "no-cache";
142
152
  }
143
153
  serve(req, res, () => {
144
154
  for (const undo of restore) undo();
145
- servePage(req, res);
155
+ fallback(req, res);
146
156
  });
147
157
  };
148
158
  }
@@ -305,6 +315,7 @@ async function createSSRServer(options) {
305
315
  const ssrState = opts.ssrState || (__MOOST_SSR_STATE__ !== void 0 ? __MOOST_SSR_STATE__ : DEFAULT_SSR_STATE);
306
316
  const ssrHead = opts.ssrHead || (__MOOST_SSR_HEAD__ !== void 0 ? __MOOST_SSR_HEAD__ : DEFAULT_SSR_HEAD);
307
317
  const prefixes = normalizePrefixes(opts.prefix ?? __MOOST_PREFIX__);
318
+ const prefixFallthrough = opts.prefixFallthrough ?? __MOOST_PREFIX_FALLTHROUGH__ ?? false;
308
319
  const ssrForwarding = opts.ssrFetchForwarding ?? __MOOST_SSR_FORWARDING__ ?? true;
309
320
  const variants = resolvePrecompressed(__MOOST_PRECOMPRESS__, opts.precompressed);
310
321
  const cache = resolveCacheControl(__MOOST_CACHE_CONTROL__, opts.cacheControl);
@@ -322,7 +333,7 @@ async function createSSRServer(options) {
322
333
  let captured = false;
323
334
  const origListen = MoostHttp.prototype.listen;
324
335
  MoostHttp.prototype.listen = function(...args) {
325
- moostHandler = this.getServerCb((req, res) => serveStatic(req, res));
336
+ moostHandler = this.getServerCb(prefixes && !prefixFallthrough ? apiMountNoMatch((req, res, miss) => serveStatic(req, res, miss), this.getServerCb()) : (req, res) => serveStatic(req, res));
326
337
  moostHttpRef.instance = this;
327
338
  captured = true;
328
339
  setTimeout(() => args.filter((a) => typeof a === "function").forEach((a) => a()), 1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moostjs/vite",
3
- "version": "0.6.53",
3
+ "version": "0.7.1",
4
4
  "description": "Vite Dev plugin for moostjs",
5
5
  "keywords": [
6
6
  "composables",
@@ -50,21 +50,16 @@
50
50
  ]
51
51
  },
52
52
  "dependencies": {
53
- "magic-string": "^0.30.21"
53
+ "magic-string": "^0.30.21",
54
+ "sirv": "^3.0.2"
54
55
  },
55
56
  "devDependencies": {
56
- "vitest": "3.2.7"
57
+ "vitest": "4.1.12"
57
58
  },
58
59
  "peerDependencies": {
59
- "sirv": "^3.0.0",
60
60
  "vite": "^8.0.0",
61
- "@moostjs/event-http": "^0.6.53",
62
- "moost": "^0.6.53"
63
- },
64
- "peerDependenciesMeta": {
65
- "sirv": {
66
- "optional": true
67
- }
61
+ "@moostjs/event-http": "^0.7.1",
62
+ "moost": "^0.7.1"
68
63
  },
69
64
  "scripts": {
70
65
  "pub": "pnpm publish --access public",