@navios/di 0.1.7 → 0.1.9

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,289 @@
1
+ import { expectTypeOf, test } from 'vitest'
2
+ import { z } from 'zod'
3
+
4
+ import { Injectable } from '../decorators/index.mjs'
5
+ import { InjectableType } from '../enums/index.mjs'
6
+ import { InjectionToken } from '../injection-token.mjs'
7
+
8
+ interface FooService {
9
+ makeFoo(): string
10
+ }
11
+
12
+ const simpleObjectSchema = z.object({
13
+ foo: z.string(),
14
+ })
15
+ const simpleOptionalObjectSchema = z
16
+ .object({
17
+ foo: z.string(),
18
+ })
19
+ .optional()
20
+ const simpleRecordSchema = z.record(z.string())
21
+ const simpleOptionalRecordSchema = z.record(z.string()).optional()
22
+
23
+ const typelessObjectToken = InjectionToken.create(
24
+ Symbol.for('Typeless object token'),
25
+ simpleObjectSchema,
26
+ )
27
+ const typelessOptionalObjectToken = InjectionToken.create(
28
+ Symbol.for('Typeless optional object token'),
29
+ simpleOptionalObjectSchema,
30
+ )
31
+ const typelessRecordToken = InjectionToken.create(
32
+ Symbol.for('Typeless record token'),
33
+ simpleRecordSchema,
34
+ )
35
+ const typelessOptionalRecordToken = InjectionToken.create(
36
+ Symbol.for('Typeless optional record token'),
37
+ simpleOptionalRecordSchema,
38
+ )
39
+
40
+ const typedObjectToken = InjectionToken.create<
41
+ FooService,
42
+ typeof simpleObjectSchema
43
+ >(Symbol.for('Typed object token'), simpleObjectSchema)
44
+ const typedOptionalObjectToken = InjectionToken.create<
45
+ FooService,
46
+ typeof simpleOptionalObjectSchema
47
+ >(Symbol.for('Typed optional object token'), simpleOptionalObjectSchema)
48
+ const typedRecordToken = InjectionToken.create<
49
+ FooService,
50
+ typeof simpleRecordSchema
51
+ >(Symbol.for('Typed record token'), simpleRecordSchema)
52
+ const typedOptionalRecordToken = InjectionToken.create<
53
+ FooService,
54
+ typeof simpleOptionalRecordSchema
55
+ >(Symbol.for('Typed optional record token'), simpleOptionalRecordSchema)
56
+
57
+ const typedToken = InjectionToken.create<FooService>(Symbol.for('Typed token'))
58
+
59
+ test('Injectable types', () => {
60
+ // #1
61
+ expectTypeOf(
62
+ @Injectable()
63
+ class {},
64
+ ).toBeConstructibleWith()
65
+ // #2
66
+ expectTypeOf(
67
+ @Injectable({
68
+ type: InjectableType.Factory,
69
+ })
70
+ class {
71
+ create() {}
72
+ },
73
+ ).toBeConstructibleWith()
74
+ expectTypeOf(
75
+ // @ts-expect-error should check that the class implements the factory
76
+ @Injectable({
77
+ type: InjectableType.Factory,
78
+ })
79
+ class {},
80
+ ).toBeConstructibleWith()
81
+
82
+ // #3 required argument
83
+ expectTypeOf(
84
+ @Injectable({
85
+ token: typelessObjectToken,
86
+ })
87
+ class {
88
+ constructor(public arg: z.infer<typeof simpleObjectSchema>) {}
89
+ },
90
+ ).toBeConstructibleWith({
91
+ foo: 'something',
92
+ })
93
+ // #3 it's required in token but optional in class allowed
94
+ expectTypeOf(
95
+ @Injectable({
96
+ token: typelessObjectToken,
97
+ })
98
+ class {
99
+ constructor(public arg?: z.infer<typeof simpleObjectSchema>) {}
100
+ },
101
+ ).toBeConstructibleWith({
102
+ foo: 'something',
103
+ })
104
+ // #3 optional value but class accepts it
105
+ expectTypeOf(
106
+ @Injectable({
107
+ token: typelessOptionalObjectToken,
108
+ })
109
+ class {
110
+ constructor(public arg: z.infer<typeof simpleOptionalObjectSchema>) {}
111
+ },
112
+ ).toBeConstructibleWith({
113
+ foo: 'something',
114
+ })
115
+ // #3 optional value and class accepts it
116
+ expectTypeOf(
117
+ @Injectable({
118
+ token: typelessOptionalObjectToken,
119
+ })
120
+ class {
121
+ constructor(public arg: z.infer<typeof simpleOptionalObjectSchema>) {}
122
+ },
123
+ ).toBeConstructibleWith(undefined)
124
+ // #3 compatible schemas
125
+ expectTypeOf(
126
+ @Injectable({
127
+ token: typelessOptionalObjectToken,
128
+ })
129
+ class {
130
+ constructor(public arg?: z.infer<typeof simpleObjectSchema>) {}
131
+ },
132
+ ).toBeConstructibleWith(undefined)
133
+ // #3 compatible schemas
134
+ expectTypeOf(
135
+ // @ts-expect-error token has optional schema, but Class has required, should fail
136
+ @Injectable({
137
+ token: typelessOptionalObjectToken,
138
+ })
139
+ class {
140
+ constructor(public arg: z.infer<typeof simpleObjectSchema>) {}
141
+ },
142
+ ).toBeConstructibleWith({
143
+ foo: 'something',
144
+ })
145
+
146
+ // #3 typed token and required argument
147
+ expectTypeOf(
148
+ @Injectable({
149
+ token: typedObjectToken,
150
+ })
151
+ class {
152
+ constructor(public arg: z.infer<typeof simpleObjectSchema>) {}
153
+
154
+ makeFoo() {
155
+ return this.arg.foo
156
+ }
157
+ },
158
+ ).toBeConstructibleWith({
159
+ foo: 'something',
160
+ })
161
+ // #3 typed token and required argument
162
+ expectTypeOf(
163
+ @Injectable({
164
+ token: typedOptionalObjectToken,
165
+ })
166
+ class {
167
+ constructor(public arg?: z.infer<typeof simpleObjectSchema>) {}
168
+
169
+ makeFoo() {
170
+ return this.arg?.foo ?? 'default'
171
+ }
172
+ },
173
+ ).toBeConstructibleWith({
174
+ foo: 'something',
175
+ })
176
+ // #3 should fail if not compatible
177
+ expectTypeOf(
178
+ // @ts-expect-error class doesn't implement the token type
179
+ @Injectable({
180
+ token: typedOptionalObjectToken,
181
+ })
182
+ class {
183
+ constructor(public arg?: z.infer<typeof simpleObjectSchema>) {}
184
+ },
185
+ ).toBeConstructibleWith({
186
+ foo: 'something',
187
+ })
188
+ // #3 should fail if not compatible
189
+ expectTypeOf(
190
+ // @ts-expect-error class doesn't implement the token type
191
+ @Injectable({
192
+ token: typedOptionalObjectToken,
193
+ })
194
+ class {
195
+ constructor(public arg?: z.infer<typeof simpleObjectSchema>) {}
196
+
197
+ makeFoo() {
198
+ return this.arg?.foo
199
+ }
200
+ },
201
+ ).toBeConstructibleWith({
202
+ foo: 'something',
203
+ })
204
+ // #3 typed token without schema
205
+ expectTypeOf(
206
+ @Injectable({
207
+ token: typedToken,
208
+ })
209
+ class {
210
+ constructor() {}
211
+ makeFoo() {
212
+ return 'foo'
213
+ }
214
+ },
215
+ ).toBeConstructibleWith()
216
+ // #3 typed token without schema fail if not compatible
217
+ expectTypeOf(
218
+ // @ts-expect-error class doesn't implement the token type
219
+ @Injectable({
220
+ token: typedToken,
221
+ })
222
+ class {
223
+ constructor() {}
224
+ },
225
+ ).toBeConstructibleWith()
226
+
227
+ // #4 factory with typed token
228
+ expectTypeOf(
229
+ @Injectable({
230
+ type: InjectableType.Factory,
231
+ token: typedToken,
232
+ })
233
+ class {
234
+ constructor() {}
235
+ create() {
236
+ return {
237
+ makeFoo: () => 'foo',
238
+ }
239
+ }
240
+ },
241
+ ).toBeConstructibleWith()
242
+ // #4 factory with typed token without schema should fail if not compatible
243
+ expectTypeOf(
244
+ // @ts-expect-error factory doesn't implement the token type
245
+ @Injectable({
246
+ type: InjectableType.Factory,
247
+ token: typedToken,
248
+ })
249
+ class {
250
+ constructor() {}
251
+ create(ctx: any, arg: z.infer<typeof simpleObjectSchema>) {
252
+ return {
253
+ makeFoo: () => 'foo',
254
+ }
255
+ }
256
+ },
257
+ ).toBeConstructibleWith()
258
+ // #4 factory with typed token fail if not compatible
259
+ expectTypeOf(
260
+ // @ts-expect-error class doesn't implement the token type
261
+ @Injectable({
262
+ type: InjectableType.Factory,
263
+ token: typedToken,
264
+ })
265
+ class {
266
+ constructor() {}
267
+ create() {
268
+ return {
269
+ // makeFoo: () => 'foo',
270
+ }
271
+ }
272
+ },
273
+ ).toBeConstructibleWith()
274
+ // #4 factory with typed token and schema
275
+ expectTypeOf(
276
+ @Injectable({
277
+ type: InjectableType.Factory,
278
+ token: typedObjectToken,
279
+ })
280
+ class {
281
+ constructor() {}
282
+ create(ctx: any, arg: z.infer<typeof simpleObjectSchema>) {
283
+ return {
284
+ makeFoo: () => 'foo',
285
+ }
286
+ }
287
+ },
288
+ )
289
+ })
@@ -1,13 +1,15 @@
1
- import { NaviosException } from '@navios/common'
2
-
3
1
  import { z } from 'zod'
4
2
 
5
3
  import type {
4
+ BaseInjectionTokenSchemaType,
6
5
  ClassType,
7
6
  ClassTypeWithArgument,
8
7
  ClassTypeWithInstance,
9
8
  ClassTypeWithInstanceAndArgument,
9
+ ClassTypeWithInstanceAndOptionalArgument,
10
+ ClassTypeWithOptionalArgument,
10
11
  InjectionTokenSchemaType,
12
+ OptionalInjectionTokenSchemaType,
11
13
  } from '../injection-token.mjs'
12
14
  import type { Factory, FactoryWithArgs } from '../interfaces/index.mjs'
13
15
  import type { Registry } from '../registry.mjs'
@@ -24,11 +26,12 @@ export interface InjectableOptions {
24
26
  token?: InjectionToken<any, any>
25
27
  registry?: Registry
26
28
  }
27
-
29
+ // #1 Simple constructorless class
28
30
  export function Injectable(): <T extends ClassType>(
29
31
  target: T,
30
32
  context: ClassDecoratorContext,
31
33
  ) => T
34
+ // #2 Factory class without arguments
32
35
  export function Injectable<R>(options: {
33
36
  scope?: InjectableScope
34
37
  type: InjectableType.Factory
@@ -36,42 +39,62 @@ export function Injectable<R>(options: {
36
39
  target: T,
37
40
  context: ClassDecoratorContext,
38
41
  ) => T
39
- export function Injectable<S extends InjectionTokenSchemaType>(options: {
40
- scope?: InjectableScope
41
- type?: InjectableType.Class
42
- token: InjectionToken<undefined, S>
43
- }): <T extends ClassTypeWithArgument<z.output<S>>>(
44
- target: T,
45
- context: ClassDecoratorContext,
46
- ) => T
47
- export function Injectable<R, S extends InjectionTokenSchemaType>(options: {
42
+
43
+ // #3 Class with typeless token and schema
44
+ export function Injectable<Type, Schema>(options: {
48
45
  scope?: InjectableScope
49
46
  type?: InjectableType.Class
50
- token: InjectionToken<R, S>
51
- }): <T extends ClassTypeWithInstanceAndArgument<R, z.output<S>>>(
52
- target: T,
53
- context: ClassDecoratorContext,
54
- ) => T
55
- export function Injectable<T extends ClassType>(options: {
56
- scope?: InjectableScope
57
- token: InjectionToken<T, undefined>
58
- }): (target: T, context: ClassDecoratorContext) => T
59
- export function Injectable<R, S extends InjectionTokenSchemaType>(options: {
47
+ token: InjectionToken<Type, Schema>
48
+ }): Schema extends BaseInjectionTokenSchemaType
49
+ ? Type extends undefined
50
+ ? <T extends ClassTypeWithArgument<z.output<Schema>>>(
51
+ target: T,
52
+ context: ClassDecoratorContext,
53
+ ) => T
54
+ : <T extends ClassTypeWithInstanceAndArgument<Type, z.output<Schema>>>(
55
+ target: T,
56
+ context: ClassDecoratorContext,
57
+ ) => T
58
+ : Schema extends OptionalInjectionTokenSchemaType
59
+ ? Type extends undefined
60
+ ? <T extends ClassTypeWithOptionalArgument<z.output<Schema>>>(
61
+ target: T,
62
+ context: ClassDecoratorContext,
63
+ ) => T
64
+ : <
65
+ T extends ClassTypeWithInstanceAndOptionalArgument<
66
+ Type,
67
+ z.output<Schema>
68
+ >,
69
+ >(
70
+ target: T,
71
+ context: ClassDecoratorContext,
72
+ ) => T
73
+ : Schema extends undefined
74
+ ? <R extends ClassTypeWithInstance<Type>>(
75
+ target: R,
76
+ context: ClassDecoratorContext,
77
+ ) => R
78
+ : never
79
+
80
+ // #4 Factory with typed token
81
+ export function Injectable<R, S>(options: {
60
82
  scope?: InjectableScope
61
83
  type: InjectableType.Factory
62
84
  token: InjectionToken<R, S>
63
- }): <T extends ClassTypeWithInstance<FactoryWithArgs<R, S>>>(
64
- target: T,
65
- context: ClassDecoratorContext,
66
- ) => T
67
- export function Injectable<R>(options: {
68
- scope?: InjectableScope
69
- type: InjectableType.Factory
70
- token: InjectionToken<R, undefined>
71
- }): <T extends ClassTypeWithInstance<Factory<R>>>(
72
- target: T,
73
- context: ClassDecoratorContext,
74
- ) => T
85
+ }): R extends undefined
86
+ ? never
87
+ : S extends InjectionTokenSchemaType
88
+ ? <T extends ClassTypeWithInstance<FactoryWithArgs<R, S>>>(
89
+ target: T,
90
+ context: ClassDecoratorContext,
91
+ ) => T
92
+ : S extends undefined
93
+ ? <T extends ClassTypeWithInstance<Factory<R>>>(
94
+ target: T,
95
+ context: ClassDecoratorContext,
96
+ ) => T
97
+ : never
75
98
  export function Injectable({
76
99
  scope = InjectableScope.Singleton,
77
100
  type = InjectableType.Class,
@@ -101,7 +124,7 @@ export function Injectable({
101
124
  async (ctx, args: any) => {
102
125
  const builder = await resolveService(ctx, target)
103
126
  if (typeof builder.create !== 'function') {
104
- throw new NaviosException(
127
+ throw new Error(
105
128
  `[ServiceLocator] Factory ${target.name} does not implement the create method.`,
106
129
  )
107
130
  }
@@ -1,15 +1,19 @@
1
1
  import type { AnyZodObject } from 'zod'
2
2
 
3
- import { randomUUID } from 'crypto'
4
-
5
3
  import { z, ZodOptional, ZodRecord } from 'zod'
6
4
 
7
5
  export type ClassType = new (...args: any[]) => any
8
6
  export type ClassTypeWithArgument<Arg> = new (arg: Arg) => any
7
+ export type ClassTypeWithOptionalArgument<Arg> = new (arg?: Arg) => any
9
8
 
10
9
  export type ClassTypeWithInstance<T> = new (...args: any[]) => T
11
10
  export type ClassTypeWithInstanceAndArgument<T, Arg> = new (arg: Arg) => T
11
+ export type ClassTypeWithInstanceAndOptionalArgument<T, Arg> = new (
12
+ arg?: Arg,
13
+ ) => T
12
14
 
15
+ export const Optional = Symbol('Optional')
16
+ export const Required = Symbol('Required')
13
17
  export type BaseInjectionTokenSchemaType = AnyZodObject | ZodRecord
14
18
 
15
19
  export type OptionalInjectionTokenSchemaType =
@@ -23,8 +27,17 @@ export type InjectionTokenSchemaType =
23
27
  export class InjectionToken<
24
28
  T,
25
29
  S extends InjectionTokenSchemaType | unknown = unknown,
30
+ Required extends boolean = S extends ZodOptional<AnyZodObject>
31
+ ? false
32
+ : S extends ZodOptional<ZodRecord>
33
+ ? false
34
+ : S extends AnyZodObject
35
+ ? true
36
+ : S extends ZodRecord
37
+ ? true
38
+ : false,
26
39
  > {
27
- public id = randomUUID()
40
+ public id = globalThis.crypto.randomUUID()
28
41
  private formattedName: string | null = null
29
42
 
30
43
  constructor(
@@ -38,7 +51,9 @@ export class InjectionToken<
38
51
  static create<T extends ClassType, Schema extends InjectionTokenSchemaType>(
39
52
  name: T,
40
53
  schema: Schema,
41
- ): InjectionToken<InstanceType<T>, Schema>
54
+ ): Schema['_def']['typeName'] extends 'ZodOptional'
55
+ ? InjectionToken<InstanceType<T>, Schema, false>
56
+ : InjectionToken<InstanceType<T>, Schema, true>
42
57
  static create<T>(name: string | symbol): InjectionToken<T, undefined>
43
58
  static create<T, Schema extends InjectionTokenSchemaType>(
44
59
  name: string | any,
@@ -1,11 +1,12 @@
1
1
  import { z } from 'zod'
2
2
 
3
+ import type { FactoryContext } from '../factory-context.mjs'
3
4
  import type { InjectionTokenSchemaType } from '../injection-token.mjs'
4
5
 
5
6
  export interface Factory<T> {
6
- create(ctx?: any): Promise<T> | T
7
+ create(ctx?: FactoryContext): Promise<T> | T
7
8
  }
8
9
 
9
10
  export interface FactoryWithArgs<T, A extends InjectionTokenSchemaType> {
10
- create(ctx: any, args: z.output<A>): Promise<T> | T
11
+ create(...args: [FactoryContext, z.output<A>]): Promise<T> | T
11
12
  }
@@ -1,5 +1,3 @@
1
- import { NaviosException } from '@navios/common'
2
-
3
1
  import type { FactoryContext } from './factory-context.mjs'
4
2
  import type { ClassType } from './injection-token.mjs'
5
3
 
@@ -30,11 +28,11 @@ export async function resolveService<T extends ClassType>(
30
28
  }
31
29
  if (promises.length > 0) {
32
30
  console.error(`[ServiceLocator] ${target.name} has problem with it's definition.
33
-
31
+
34
32
  One or more of the dependencies are registered as a InjectableScope.Instance and are used with syncInject.
35
-
33
+
36
34
  Please use inject instead of syncInject to load those dependencies.`)
37
- throw new NaviosException(
35
+ throw new Error(
38
36
  `[ServiceLocator] Service ${target.name} cannot be instantiated.`,
39
37
  )
40
38
  }
@@ -450,7 +450,7 @@ export class ServiceLocator {
450
450
  : undefined
451
451
  const instanceName = self.makeInstanceName(token, validatedArgs)
452
452
  dependencies.add(instanceName)
453
- return self.getOrThrowInstance(injectionToken, args)
453
+ return self.getOrThrowInstance(injectionToken, args as any)
454
454
  }
455
455
  throw new Error(
456
456
  `[ServiceLocator]#inject(): Invalid token type: ${typeof token}. Expected a class or an InjectionToken.`,
@@ -1,4 +1,4 @@
1
- import type { AnyZodObject, z } from 'zod'
1
+ import type { AnyZodObject, z, ZodType } from 'zod'
2
2
 
3
3
  import type {
4
4
  BaseInjectionTokenSchemaType,
@@ -6,6 +6,7 @@ import type {
6
6
  ClassType,
7
7
  FactoryInjectionToken,
8
8
  InjectionToken,
9
+ InjectionTokenSchemaType,
9
10
  OptionalInjectionTokenSchemaType,
10
11
  } from '../injection-token.mjs'
11
12
  import type { ServiceLocator } from '../service-locator.mjs'
@@ -15,30 +16,75 @@ import { InjectableTokenMeta } from '../symbols/index.mjs'
15
16
  export interface CreateInjectorsOptions {
16
17
  baseLocator: ServiceLocator
17
18
  }
19
+ type Join<TElements, TSeparator extends string> =
20
+ TElements extends Readonly<[infer First, ...infer Rest]>
21
+ ? Rest extends ReadonlyArray<string>
22
+ ? First extends string
23
+ ? `${First}${Rest extends [] ? '' : TSeparator}${Join<Rest, TSeparator>}`
24
+ : never
25
+ : never
26
+ : ''
27
+ // credits goes to https://stackoverflow.com/a/50375286
28
+ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
29
+ k: infer I,
30
+ ) => void
31
+ ? I
32
+ : never
33
+
34
+ // Converts union to overloaded function
35
+ type UnionToOvlds<U> = UnionToIntersection<
36
+ U extends any ? (f: U) => void : never
37
+ >
38
+
39
+ type PopUnion<U> = UnionToOvlds<U> extends (a: infer A) => void ? A : never
40
+
41
+ type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true
42
+
43
+ type UnionToArray<T, A extends unknown[] = []> =
44
+ IsUnion<T> extends true
45
+ ? UnionToArray<Exclude<T, PopUnion<T>>, [PopUnion<T>, ...A]>
46
+ : [T, ...A]
18
47
 
19
48
  export interface Injectors {
49
+ // #1 Simple class
20
50
  inject<T extends ClassType>(token: T): Promise<InstanceType<T>>
21
- inject<T, S extends BaseInjectionTokenSchemaType>(
51
+ // #2 Token with required Schema
52
+ inject<T, S extends InjectionTokenSchemaType>(
22
53
  token: InjectionToken<T, S>,
23
54
  args: z.input<S>,
24
55
  ): Promise<T>
25
- inject<T, S extends OptionalInjectionTokenSchemaType>(
26
- token: InjectionToken<T, S>,
27
- args?: z.input<S>,
28
- ): Promise<T>
56
+ // #3 Token with optional Schema
57
+ inject<T, S extends InjectionTokenSchemaType, R extends boolean>(
58
+ token: InjectionToken<T, S, R>,
59
+ ): R extends false
60
+ ? Promise<T>
61
+ : S extends ZodType<infer Type>
62
+ ? `Error: Your token requires args: ${Join<
63
+ UnionToArray<keyof Type>,
64
+ ', '
65
+ >}`
66
+ : 'Error: Your token requires args'
67
+ // #4 Token with no Schema
29
68
  inject<T>(token: InjectionToken<T, undefined>): Promise<T>
30
69
  inject<T>(token: BoundInjectionToken<T, any>): Promise<T>
31
70
  inject<T>(token: FactoryInjectionToken<T, any>): Promise<T>
32
71
 
33
72
  syncInject<T extends ClassType>(token: T): InstanceType<T>
34
- syncInject<T, S extends BaseInjectionTokenSchemaType>(
73
+ syncInject<T, S extends InjectionTokenSchemaType>(
35
74
  token: InjectionToken<T, S>,
36
75
  args: z.input<S>,
37
76
  ): T
38
- syncInject<T, S extends OptionalInjectionTokenSchemaType>(
39
- token: InjectionToken<T, S>,
40
- args?: z.input<S>,
41
- ): T
77
+ // #3 Token with optional Schema
78
+ syncInject<T, S extends InjectionTokenSchemaType, R extends boolean>(
79
+ token: InjectionToken<T, S, R>,
80
+ ): R extends false
81
+ ? T
82
+ : S extends ZodType<infer Type>
83
+ ? `Error: Your token requires args: ${Join<
84
+ UnionToArray<keyof Type>,
85
+ ', '
86
+ >}`
87
+ : 'Error: Your token requires args'
42
88
  syncInject<T>(token: InjectionToken<T, undefined>): T
43
89
  syncInject<T>(token: BoundInjectionToken<T, any>): T
44
90
  syncInject<T>(token: FactoryInjectionToken<T, any>): T
package/tsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "module": "Node18",
5
+ "outDir": "dist"
6
+ },
7
+ "include": ["src/**/*", "tsdown.config.mts"]
8
+ }
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from 'tsdown'
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.mts'],
5
+ outDir: 'lib',
6
+ format: ['esm', 'cjs'],
7
+ dts: true,
8
+ clean: true,
9
+ platform: 'neutral',
10
+ })
@@ -0,0 +1,9 @@
1
+ import { defineProject } from 'vitest/config'
2
+
3
+ export default defineProject({
4
+ test: {
5
+ typecheck: {
6
+ enabled: true,
7
+ },
8
+ },
9
+ })