@tuyau/core 1.0.0 → 1.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.
@@ -0,0 +1,438 @@
1
+ import { Options, KyResponse, KyRequest, HTTPError } from 'ky';
2
+ import { ClientRouteMatchItTokens } from '@adonisjs/http-server/client/url_builder';
3
+
4
+ /**
5
+ * Supported HTTP methods for API endpoints
6
+ */
7
+ type Method = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
8
+ /**
9
+ * Options for the `current` method to match params and/or query
10
+ */
11
+ interface CurrentRouteOptions {
12
+ params?: Record<string, any>;
13
+ query?: Record<string, any>;
14
+ }
15
+ /**
16
+ * Base endpoint types structure
17
+ */
18
+ interface EndpointTypes {
19
+ paramsTuple: [...any[]];
20
+ params: Record<string, string | number | boolean | bigint | (string | number | boolean | bigint)[]>;
21
+ query: Record<string, any>;
22
+ body: unknown;
23
+ response: unknown;
24
+ errorResponse?: unknown;
25
+ }
26
+ /**
27
+ * Schema endpoint, used in generated registry.schema.d.ts
28
+ * Does not include tokens (only present in runtime routes)
29
+ */
30
+ interface SchemaEndpoint {
31
+ methods: Method[];
32
+ pattern: string;
33
+ types: EndpointTypes;
34
+ }
35
+ /**
36
+ * Definition of an AdonisJS endpoint with types and metadata
37
+ * Includes tokens for runtime route building
38
+ */
39
+ interface AdonisEndpoint extends SchemaEndpoint {
40
+ tokens: ClientRouteMatchItTokens[];
41
+ }
42
+ /**
43
+ * Extract query params from a validator type if it has a 'query' property.
44
+ * Used in generated registry to separate query params from body for POST/PUT/PATCH/DELETE.
45
+ * For GET/HEAD, use ExtractQueryForGet instead.
46
+ */
47
+ type ExtractQuery<T> = 'query' extends keyof T ? T extends {
48
+ query?: infer Q;
49
+ } ? Q : {} : {};
50
+ /**
51
+ * Extract query params for GET/HEAD requests.
52
+ * Excludes headers, cookies, and params from the validator type since these are not query params.
53
+ */
54
+ type ExtractQueryForGet<T> = Omit<T, 'headers' | 'cookies' | 'params'>;
55
+ /**
56
+ * Extract body from a validator type, excluding reserved properties.
57
+ * Excludes 'query', 'params', 'headers', and 'cookies' as these are handled separately by AdonisJS.
58
+ */
59
+ type ExtractBody<T> = Omit<T, 'query' | 'params' | 'headers' | 'cookies'>;
60
+ /**
61
+ * Success status codes (2xx)
62
+ */
63
+ type SuccessStatus = 200 | 201 | 202 | 203 | 204 | 205 | 206;
64
+ /**
65
+ * Extract the actual response type from a controller return type.
66
+ * - Success responses (2xx): extracts `__response`
67
+ * - Error responses (non-2xx with __response/__status): returns `never` to filter from unions
68
+ * - Plain types (no __status): returns as-is
69
+ */
70
+ type ExtractResponse<T> = T extends {
71
+ __response: infer R;
72
+ __status: SuccessStatus;
73
+ } ? R : T extends {
74
+ __response: unknown;
75
+ __status: number;
76
+ } ? never : T;
77
+ /**
78
+ * Inverse of ExtractResponse — extracts non-2xx status types as a discriminated union.
79
+ * Each member has `{ status: S; response: R }` for narrowing via `isStatus()`.
80
+ */
81
+ type ExtractErrorResponse<T> = T extends {
82
+ __response: infer R;
83
+ __status: infer S;
84
+ } ? S extends SuccessStatus ? never : {
85
+ status: S;
86
+ response: R;
87
+ } : never;
88
+ /**
89
+ * Registry mapping endpoint names to their definitions
90
+ */
91
+ interface AdonisRegistry extends Record<string, AdonisEndpoint> {
92
+ }
93
+ type ValueOf<T> = T[keyof T];
94
+ /**
95
+ * Convert a union type to an intersection type
96
+ */
97
+ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
98
+ /**
99
+ * Structure of a Tuyau registry containing routes and optional tree
100
+ */
101
+ interface TuyauRegistry<Routes extends Record<string, AdonisEndpoint> = Record<string, AdonisEndpoint>, Tree = unknown> {
102
+ routes: Routes;
103
+ $tree?: Tree;
104
+ }
105
+ /**
106
+ * Extracts the $tree type from a registry
107
+ * Uses direct access instead of conditional type for performance
108
+ */
109
+ type InferTree<R extends TuyauRegistry> = R['$tree'];
110
+ /**
111
+ * Extracts the routes from a registry
112
+ */
113
+ type InferRoutes<R extends TuyauRegistry> = R['routes'];
114
+ type Endpoints = ValueOf<AdonisRegistry>;
115
+ type EndpointByName<Name extends keyof AdonisRegistry & string> = AdonisRegistry[Name];
116
+ /**
117
+ * Supported response types for overriding Content-Type based parsing
118
+ */
119
+ type ResponseType = 'json' | 'text' | 'arrayBuffer' | 'blob';
120
+ /**
121
+ * Tuyau-specific request options (not part of Ky)
122
+ */
123
+ type TuyauRequestOptions = {
124
+ responseType?: ResponseType;
125
+ };
126
+ /**
127
+ * Pre-computed base Ky options to avoid recomputing Omit on every request
128
+ */
129
+ type BaseRequestOptions = Omit<Options, 'body' | 'params' | 'searchParams' | 'method' | 'json' | 'prefixUrl'>;
130
+ /**
131
+ * Helper types for optional/required fields - using literal types instead of mapped types
132
+ */
133
+ type ParamsArg<T> = keyof T extends never ? {} : {} extends T ? {
134
+ params?: T;
135
+ } : {
136
+ params: T;
137
+ };
138
+ type QueryArg<T> = keyof T extends never ? {} : {} extends T ? {
139
+ query?: T;
140
+ } : {
141
+ query: T;
142
+ };
143
+ type BodyArg<T> = keyof T extends never ? {} : {} extends T ? {
144
+ body?: T;
145
+ } : {
146
+ body: T;
147
+ };
148
+ /**
149
+ * Request args without ky options
150
+ */
151
+ type RawRequestArgs<E extends SchemaEndpoint> = ParamsArg<E['types']['params']> & QueryArg<E['types']['query']> & BodyArg<E['types']['body']>;
152
+ /**
153
+ * Constructs the request arguments type for an endpoint
154
+ */
155
+ type RequestArgs<E extends SchemaEndpoint> = RawRequestArgs<E> & BaseRequestOptions & TuyauRequestOptions;
156
+ /**
157
+ * Extracts response type from an endpoint
158
+ */
159
+ type ResponseOf<E extends SchemaEndpoint> = E['types']['response'];
160
+ /**
161
+ * Extracts error response type from an endpoint
162
+ */
163
+ type ErrorResponseOf<E extends SchemaEndpoint> = E['types'] extends {
164
+ errorResponse: infer ER;
165
+ } ? ER : unknown;
166
+ /**
167
+ * Normalizes the error type to satisfy TuyauError's constraint.
168
+ * Routes without typed errors pass `unknown`, which maps to `{ response: any }`.
169
+ * Always includes a `{ status: number; response: unknown }` fallback so that
170
+ * catch-all blocks after exhaustive `isStatus()` checks never resolve to `never`.
171
+ */
172
+ type NormalizeError$1<E> = (E extends {
173
+ response: any;
174
+ } ? E : {
175
+ response: any;
176
+ }) | {
177
+ status: number;
178
+ response: unknown;
179
+ };
180
+ /**
181
+ * Function type for calling an endpoint
182
+ */
183
+ type EndpointFn<E extends SchemaEndpoint> = (args: RequestArgs<E>) => TuyauPromise<E['types']['response'], ErrorResponseOf<E>>;
184
+ /**
185
+ * Function type for an endpoint with inlined args
186
+ */
187
+ type EndpointFnInline<E extends AdonisEndpoint> = (args: ParamsArg<E['types']['params']> & QueryArg<E['types']['query']> & BodyArg<E['types']['body']> & BaseRequestOptions & TuyauRequestOptions) => TuyauPromise<E['types']['response'], ErrorResponseOf<E>>;
188
+ /**
189
+ * Transforms a pre-computed ApiDefinition tree into callable endpoint functions
190
+ * This recursively converts each endpoint in the tree to a callable function
191
+ * Handles intersection types where a node is both an endpoint AND has children
192
+ */
193
+ type TransformApiDefinition<T> = {
194
+ [K in keyof T]: T[K] extends AdonisEndpoint ? EndpointFnInline<T[K]> & TransformApiDefinition<Omit<T[K], keyof AdonisEndpoint>> : TransformApiDefinition<T[K]>;
195
+ };
196
+ /**
197
+ * Filters endpoints by HTTP method
198
+ */
199
+ type EndpointsByMethod<Reg extends Record<string, AdonisEndpoint>, M extends Method> = {
200
+ [K in keyof Reg]: M extends Reg[K]['methods'][number] ? Reg[K] : never;
201
+ }[keyof Reg];
202
+ type StrKeys<R> = Extract<keyof R, string>;
203
+ type RegValues<R> = R[StrKeys<R>];
204
+ /**
205
+ * Gets URL patterns for endpoints matching a specific HTTP method
206
+ */
207
+ type PatternsByMethod<Reg extends Record<string, AdonisEndpoint>, M extends Method> = EndpointsByMethod<Reg, M>['pattern'];
208
+ /**
209
+ * Finds an endpoint by HTTP method and URL pattern
210
+ */
211
+ type EndpointByMethodPattern<R extends Record<string, AdonisEndpoint>, M extends Method, P extends PatternsByMethod<R, M>> = FilterByMethodPathForRegistry<R, M, P>;
212
+ /**
213
+ * Plugin function type for extending Tuyau functionality
214
+ */
215
+ interface TuyauPlugin {
216
+ (params: {
217
+ options: TuyauConfiguration<any>;
218
+ }): void;
219
+ }
220
+ type MaybeArray<T> = T | T[];
221
+ /**
222
+ * Type for URL query parameters
223
+ */
224
+ type QueryParameterPrimitive = string | number | boolean | Date | null | undefined;
225
+ interface QueryParameters extends Record<string, QueryParameterPrimitive | Array<QueryParameterPrimitive | QueryParameters> | QueryParameters> {
226
+ }
227
+ /**
228
+ * Configuration options for creating a Tuyau client
229
+ */
230
+ interface TuyauConfiguration<T extends TuyauRegistry> extends Omit<Options, 'prefixUrl' | 'body' | 'json' | 'method' | 'searchParams'> {
231
+ registry: T;
232
+ baseUrl: string;
233
+ plugins?: TuyauPlugin[];
234
+ }
235
+ /**
236
+ * Should be augmented by the user to provide their endpoint registry
237
+ * Structure: { routes: Record<string, AdonisEndpoint>, $tree: ApiDefinition }
238
+ */
239
+ interface UserRegistry {
240
+ }
241
+ type UserAdonisRegistry = UserRegistry extends {
242
+ routes: infer R;
243
+ } ? R extends Record<string, AdonisEndpoint> ? R : Record<string, AdonisEndpoint> : Record<string, AdonisEndpoint>;
244
+ type UserEndpointByName<Name extends keyof UserAdonisRegistry> = UserAdonisRegistry[Name];
245
+ type FilterByMethodPathForRegistry<Reg extends Record<string, AdonisEndpoint>, M extends Method, P extends ValueOf<Reg>['pattern'] & string> = {
246
+ [K in keyof Reg]: Reg[K]['pattern'] extends P ? M extends Reg[K]['methods'][number] ? Reg[K] : never : never;
247
+ }[keyof Reg];
248
+ type EndpointByNameForRegistry<Reg extends Record<string, AdonisEndpoint>, Name extends keyof Reg> = Reg[Name];
249
+ /**
250
+ * Internal type utilities for working with endpoints by HTTP method and path pattern
251
+ * Accepts a registry as generic parameter
252
+ */
253
+ declare namespace PathWithRegistry {
254
+ type Request<Reg extends Record<string, AdonisEndpoint>, M extends Method, P extends PatternsByMethod<Reg, M>> = RequestArgs<FilterByMethodPathForRegistry<Reg, M, P>>;
255
+ type Response<Reg extends Record<string, AdonisEndpoint>, M extends Method, P extends PatternsByMethod<Reg, M>> = ResponseOf<FilterByMethodPathForRegistry<Reg, M, P>>;
256
+ type Params<Reg extends Record<string, AdonisEndpoint>, M extends Method, P extends PatternsByMethod<Reg, M>> = FilterByMethodPathForRegistry<Reg, M, P>['types']['params'];
257
+ type Body<Reg extends Record<string, AdonisEndpoint>, M extends Method, P extends PatternsByMethod<Reg, M>> = FilterByMethodPathForRegistry<Reg, M, P>['types']['body'];
258
+ type Query<Reg extends Record<string, AdonisEndpoint>, M extends Method, P extends PatternsByMethod<Reg, M>> = FilterByMethodPathForRegistry<Reg, M, P>['types']['query'];
259
+ type Error<Reg extends Record<string, AdonisEndpoint>, M extends Method, P extends PatternsByMethod<Reg, M>> = TuyauError<NormalizeError$1<ErrorResponseOf<FilterByMethodPathForRegistry<Reg, M, P>>>>;
260
+ }
261
+ /**
262
+ * Internal type utilities for working with endpoints by route name
263
+ * Accepts a registry as generic parameter
264
+ */
265
+ declare namespace RouteWithRegistry {
266
+ type Request<Reg extends Record<string, AdonisEndpoint>, Name extends keyof Reg> = RequestArgs<EndpointByNameForRegistry<Reg, Name>>;
267
+ type Response<Reg extends Record<string, AdonisEndpoint>, Name extends keyof Reg> = ResponseOf<EndpointByNameForRegistry<Reg, Name>>;
268
+ type Params<Reg extends Record<string, AdonisEndpoint>, Name extends keyof Reg> = EndpointByNameForRegistry<Reg, Name>['types']['params'];
269
+ type Body<Reg extends Record<string, AdonisEndpoint>, Name extends keyof Reg> = EndpointByNameForRegistry<Reg, Name>['types']['body'];
270
+ type Query<Reg extends Record<string, AdonisEndpoint>, Name extends keyof Reg> = EndpointByNameForRegistry<Reg, Name>['types']['query'];
271
+ type Error<Reg extends Record<string, AdonisEndpoint>, Name extends keyof Reg> = TuyauError<NormalizeError$1<ErrorResponseOf<EndpointByNameForRegistry<Reg, Name>>>>;
272
+ }
273
+ /**
274
+ * Type utilities for working with endpoints by HTTP method and path pattern
275
+ * Uses the user-augmented registry
276
+ */
277
+ declare namespace Path {
278
+ type Request<M extends Method, P extends PatternsByMethod<UserAdonisRegistry, M>> = RequestArgs<FilterByMethodPathForRegistry<UserAdonisRegistry, M, P>>;
279
+ type Response<M extends Method, P extends PatternsByMethod<UserAdonisRegistry, M>> = ResponseOf<FilterByMethodPathForRegistry<UserAdonisRegistry, M, P>>;
280
+ type Params<M extends Method, P extends PatternsByMethod<UserAdonisRegistry, M>> = FilterByMethodPathForRegistry<UserAdonisRegistry, M, P>['types']['params'];
281
+ type Body<M extends Method, P extends PatternsByMethod<UserAdonisRegistry, M>> = FilterByMethodPathForRegistry<UserAdonisRegistry, M, P>['types']['body'];
282
+ type Query<M extends Method, P extends PatternsByMethod<UserAdonisRegistry, M>> = FilterByMethodPathForRegistry<UserAdonisRegistry, M, P>['types']['query'];
283
+ type Error<M extends Method, P extends PatternsByMethod<UserAdonisRegistry, M>> = TuyauError<NormalizeError$1<ErrorResponseOf<FilterByMethodPathForRegistry<UserAdonisRegistry, M, P>>>>;
284
+ }
285
+ /**
286
+ * Type utilities for working with endpoints by route name
287
+ * Uses the user-augmented registry
288
+ */
289
+ declare namespace Route {
290
+ type Request<Name extends keyof UserAdonisRegistry> = RequestArgs<UserEndpointByName<Name>>;
291
+ type Response<Name extends keyof UserAdonisRegistry> = ResponseOf<UserEndpointByName<Name>>;
292
+ type Params<Name extends keyof UserAdonisRegistry> = UserEndpointByName<Name>['types']['params'];
293
+ type Body<Name extends keyof UserAdonisRegistry> = UserEndpointByName<Name>['types']['body'];
294
+ type Query<Name extends keyof UserAdonisRegistry> = UserEndpointByName<Name>['types']['query'];
295
+ type Error<Name extends keyof UserAdonisRegistry> = TuyauError<NormalizeError$1<ErrorResponseOf<UserEndpointByName<Name>>>>;
296
+ }
297
+ /**
298
+ * Extracts literal status codes from E, filtering out the wide `number` from the fallback.
299
+ * `number extends 404` is false → keep. `number extends number` is true → skip.
300
+ */
301
+ type KnownStatuses<E> = E extends {
302
+ status: infer S extends number;
303
+ } ? number extends S ? never : S : never;
304
+ type ParamsShape<E> = E extends {
305
+ types: {
306
+ paramsTuple: infer PT;
307
+ params: infer P;
308
+ };
309
+ } ? (PT extends [] ? {
310
+ paramsTuple?: PT;
311
+ } : {
312
+ paramsTuple: PT;
313
+ }) & (keyof P extends never ? {} : {
314
+ params: P;
315
+ }) : never;
316
+ type RegistryGroupedByMethod<R extends Record<string, AdonisEndpoint>, M extends Method = Method> = {
317
+ [K in M | 'ALL']: {
318
+ [Route in keyof R as K extends 'ALL' ? Route : K extends R[Route]['methods'][number] ? Route : never]: ParamsShape<R[Route]>;
319
+ };
320
+ };
321
+
322
+ /**
323
+ * Base class for all errors exposed by Tuyau.
324
+ *
325
+ * `isStatus()` can be used to narrow HTTP errors to a specific typed response payload.
326
+ */
327
+ declare class TuyauError<E extends {
328
+ response: any;
329
+ } = {
330
+ response: any;
331
+ }> extends Error {
332
+ /**
333
+ * Error kind exposed by Tuyau.
334
+ * - `'http'`: the server responded with a non-2xx status code.
335
+ * - `'network'`: the request failed before receiving a response.
336
+ */
337
+ kind: 'http' | 'network';
338
+ /**
339
+ * HTTP status code returned by the server.
340
+ * `undefined` when the request failed before a response was received.
341
+ */
342
+ status: number | undefined;
343
+ /**
344
+ * Original Ky response object for HTTP errors.
345
+ * `undefined` for network errors.
346
+ */
347
+ rawResponse: KyResponse | undefined;
348
+ /**
349
+ * Original Ky request object when available.
350
+ */
351
+ rawRequest: KyRequest | undefined;
352
+ /**
353
+ * Parsed error payload returned by the server.
354
+ * `undefined` for network errors.
355
+ */
356
+ response: E['response'] | undefined;
357
+ constructor(message: string, options?: ErrorOptions);
358
+ /**
359
+ * Type guard that narrows the error to a specific HTTP status code.
360
+ * After calling `isStatus(422)`, the `response` property is narrowed
361
+ * to the type associated with that status code.
362
+ */
363
+ isStatus<S extends KnownStatuses<E> | (number & {})>(status: S): this is TuyauHTTPError<Extract<E, {
364
+ status: S;
365
+ }>>;
366
+ /**
367
+ * Type guard that narrows to a 422 validation error.
368
+ * Alias for `isStatus(422)`.
369
+ */
370
+ isValidationError(): this is TuyauHTTPError<Extract<E, {
371
+ status: 422;
372
+ }>>;
373
+ }
374
+ declare class TuyauHTTPError<E extends {
375
+ response: any;
376
+ } = {
377
+ response: any;
378
+ }> extends TuyauError<E> {
379
+ kind: 'http';
380
+ status: number | undefined;
381
+ rawResponse: KyResponse | undefined;
382
+ rawRequest: KyRequest | undefined;
383
+ response: E['response'];
384
+ constructor(kyError: HTTPError, response: any);
385
+ }
386
+ /**
387
+ * Network error that occurs when the server is unreachable or the client is offline
388
+ */
389
+ declare class TuyauNetworkError extends TuyauError<{
390
+ response: never;
391
+ }> {
392
+ kind: 'network';
393
+ status: undefined;
394
+ rawResponse: undefined;
395
+ rawRequest: KyRequest | undefined;
396
+ response: undefined;
397
+ constructor(cause: Error, request?: {
398
+ url: string;
399
+ method: string;
400
+ });
401
+ }
402
+
403
+ /**
404
+ * Normalizes the error type to satisfy TuyauError's constraint.
405
+ * Routes without typed errors pass `unknown`, which maps to `{ response: any }`.
406
+ * Always includes a `{ status: number; response: unknown }` fallback so that
407
+ * catch-all blocks after exhaustive `isStatus()` checks never resolve to `never`.
408
+ */
409
+ type NormalizeError<E> = (E extends {
410
+ response: any;
411
+ } ? E : {
412
+ response: any;
413
+ }) | {
414
+ status: number;
415
+ response: unknown;
416
+ };
417
+ /**
418
+ * A promise wrapper that adds `.safe()` for non-throwing error handling.
419
+ * Implements PromiseLike so `await` works transparently.
420
+ */
421
+ declare class TuyauPromise<Data, Errors = unknown> implements PromiseLike<Data> {
422
+ #private;
423
+ constructor(promise: Promise<Data>);
424
+ then<R1 = Data, R2 = never>(onfulfilled?: ((value: Data) => R1 | PromiseLike<R1>) | null, onrejected?: ((reason: any) => R2 | PromiseLike<R2>) | null): Promise<R1 | R2>;
425
+ catch<R = never>(onrejected?: ((reason: any) => R | PromiseLike<R>) | null): Promise<Data | R>;
426
+ finally(onfinally?: (() => void) | null): Promise<Data>;
427
+ /**
428
+ * Returns a tuple instead of throwing on error.
429
+ * - On success: `[data, null]`
430
+ * - On error: `[null, TuyauError]`
431
+ */
432
+ safe(): Promise<[
433
+ data: Data,
434
+ error: null
435
+ ] | [data: null, error: TuyauError<NormalizeError<Errors>>]>;
436
+ }
437
+
438
+ export { type AdonisEndpoint as A, type BaseRequestOptions as B, type CurrentRouteOptions as C, type TuyauPlugin as D, type EndpointByMethodPattern as E, type MaybeArray as F, type UserRegistry as G, PathWithRegistry as H, type InferRoutes as I, RouteWithRegistry as J, Path as K, Route as L, type Method as M, type KnownStatuses as N, type PatternsByMethod as P, type QueryParameters as Q, type RegistryGroupedByMethod as R, type StrKeys as S, type TuyauRegistry as T, type UnionToIntersection as U, type ValueOf as V, type TuyauConfiguration as a, type TransformApiDefinition as b, type InferTree as c, type RequestArgs as d, TuyauPromise as e, type ErrorResponseOf as f, TuyauError as g, TuyauHTTPError as h, TuyauNetworkError as i, type EndpointTypes as j, type SchemaEndpoint as k, type ExtractQuery as l, type ExtractQueryForGet as m, type ExtractBody as n, type ExtractResponse as o, type ExtractErrorResponse as p, type AdonisRegistry as q, type Endpoints as r, type EndpointByName as s, type ResponseType as t, type TuyauRequestOptions as u, type RawRequestArgs as v, type ResponseOf as w, type EndpointFn as x, type EndpointsByMethod as y, type RegValues as z };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tuyau/core",
3
3
  "type": "module",
4
- "version": "1.0.0",
4
+ "version": "1.2.0",
5
5
  "description": "E2E typesafe client for AdonisJS",
6
6
  "author": "Julien Ripouteau <julien@ripouteau.com>",
7
7
  "license": "MIT",
@@ -48,22 +48,22 @@
48
48
  }
49
49
  },
50
50
  "dependencies": {
51
- "ky": "^1.14.2",
51
+ "ky": "^1.14.3",
52
52
  "object-to-formdata": "^4.5.1"
53
53
  },
54
54
  "devDependencies": {
55
- "@adonisjs/assembler": "^8.0.0-next.27",
56
- "@adonisjs/core": "^7.0.0-next.16",
57
- "@adonisjs/http-server": "^8.0.0-next.16",
58
- "@faker-js/faker": "^10.1.0",
59
- "@poppinss/ts-exec": "^1.4.1",
60
- "@types/node": "^25.0.3",
55
+ "@adonisjs/assembler": "^8.0.0",
56
+ "@adonisjs/core": "^7.0.1",
57
+ "@adonisjs/http-server": "^8.0.0",
58
+ "@faker-js/faker": "^10.3.0",
59
+ "@poppinss/ts-exec": "^1.4.4",
60
+ "@types/node": "^25.3.3",
61
61
  "@typescript/analyze-trace": "^0.10.1",
62
- "@vinejs/vine": "^4.2.0"
62
+ "@vinejs/vine": "^4.3.0"
63
63
  },
64
64
  "publishConfig": {
65
65
  "access": "public",
66
- "tag": "beta"
66
+ "tag": "latest"
67
67
  },
68
68
  "c8": {
69
69
  "reporter": [
@@ -90,7 +90,7 @@
90
90
  "clean": "del-cli build",
91
91
  "copy:templates": "copyfiles --up 1 \"stubs/**/*.stub\" build",
92
92
  "typecheck": "tsc --noEmit",
93
- "format": "prettier --write .",
93
+ "format": "oxfmt --write .",
94
94
  "quick:test": "node --import=@poppinss/ts-exec --enable-source-maps bin/test.ts --force-exit",
95
95
  "test": "c8 npm run quick:test",
96
96
  "index:commands": "adonis-kit index build/commands",