@koltakov/ffa-core 0.6.0 → 0.16.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/dist/index.d.ts CHANGED
@@ -1,4 +1,15 @@
1
- type FieldType = 'string' | 'number' | 'boolean' | 'uuid' | 'datetime' | 'enum' | 'belongsTo' | 'hasMany';
1
+ type FieldType = 'string' | 'number' | 'boolean' | 'uuid' | 'datetime' | 'enum' | 'belongsTo' | 'hasMany' | 'object' | 'array';
2
+ type StringFakeHint = 'email' | 'url' | 'domain' | 'ip' | 'username' | 'image' | 'avatar' | 'firstName' | 'lastName' | 'fullName' | 'phone' | 'city' | 'country' | 'address' | 'zip' | 'locale' | 'company' | 'jobTitle' | 'department' | 'currency' | 'word' | 'slug' | 'sentence' | 'paragraph' | 'bio' | 'color' | 'hexColor' | 'uuid';
3
+ type NumberFakeHint = 'price' | 'age' | 'rating' | 'percent' | 'lat' | 'lng' | 'year';
4
+ type FakeHint = StringFakeHint | NumberFakeHint;
5
+ /** Function that receives filtered items (before pagination) and returns any value */
6
+ type MetaFn = (items: Record<string, unknown>[]) => unknown;
7
+ /**
8
+ * A meta value is either:
9
+ * - a static value (string, number, boolean, object, array, …)
10
+ * - a MetaFn computed from the current filtered dataset
11
+ */
12
+ type MetaValue = MetaFn | unknown;
2
13
  interface FieldRules {
3
14
  required?: boolean;
4
15
  min?: number;
@@ -7,6 +18,10 @@ interface FieldRules {
7
18
  readonly?: boolean;
8
19
  entity?: string;
9
20
  enumValues?: string[];
21
+ fakeHint?: FakeHint;
22
+ objectFields?: Record<string, FieldDefinition>;
23
+ arrayItem?: FieldDefinition;
24
+ arrayCount?: [number, number];
10
25
  }
11
26
  interface FieldDefinition {
12
27
  type: FieldType;
@@ -15,6 +30,8 @@ interface FieldDefinition {
15
30
  interface EntityDefinition {
16
31
  fields: Record<string, FieldDefinition>;
17
32
  count?: number;
33
+ meta?: Record<string, MetaValue>;
34
+ seed?: Record<string, unknown>[];
18
35
  }
19
36
 
20
37
  interface ServerConfig {
@@ -24,6 +41,7 @@ interface ServerConfig {
24
41
  };
25
42
  persist?: boolean | string;
26
43
  delay?: number | [number, number];
44
+ errorRate?: number;
27
45
  }
28
46
  interface FfaConfig {
29
47
  server: ServerConfig;
@@ -33,13 +51,17 @@ declare function defineConfig(config: FfaConfig): FfaConfig;
33
51
 
34
52
  declare function entity(fields: Record<string, any>, options?: {
35
53
  count?: number;
54
+ meta?: Record<string, MetaValue>;
55
+ seed?: Record<string, unknown>[];
36
56
  }): {
37
57
  fields: Record<string, any>;
38
58
  count: number | undefined;
59
+ meta: Record<string, unknown> | undefined;
60
+ seed: Record<string, unknown>[] | undefined;
39
61
  };
40
62
 
41
63
  declare class FieldBuilder {
42
- private def;
64
+ protected def: FieldDefinition;
43
65
  constructor(type: FieldType, extraRules?: Partial<FieldRules>);
44
66
  required(): this;
45
67
  optional(): this;
@@ -47,18 +69,65 @@ declare class FieldBuilder {
47
69
  max(value: number): this;
48
70
  default(value: any): this;
49
71
  readonly(): this;
72
+ /** Explicit faker hint — overrides smart field-name detection */
73
+ fake(hint: FakeHint): this;
50
74
  build(): FieldDefinition;
51
75
  }
76
+ declare class StringFieldBuilder extends FieldBuilder {
77
+ constructor();
78
+ private hint;
79
+ email(): this;
80
+ url(): this;
81
+ domain(): this;
82
+ ip(): this;
83
+ username(): this;
84
+ image(): this;
85
+ avatar(): this;
86
+ firstName(): this;
87
+ lastName(): this;
88
+ fullName(): this;
89
+ phone(): this;
90
+ city(): this;
91
+ country(): this;
92
+ address(): this;
93
+ zip(): this;
94
+ locale(): this;
95
+ company(): this;
96
+ jobTitle(): this;
97
+ department(): this;
98
+ currency(): this;
99
+ word(): this;
100
+ slug(): this;
101
+ sentence(): this;
102
+ paragraph(): this;
103
+ bio(): this;
104
+ color(): this;
105
+ hexColor(): this;
106
+ uuid(): this;
107
+ }
108
+ declare class NumberFieldBuilder extends FieldBuilder {
109
+ constructor();
110
+ private hint;
111
+ price(): this;
112
+ age(): this;
113
+ rating(): this;
114
+ percent(): this;
115
+ lat(): this;
116
+ lng(): this;
117
+ year(): this;
118
+ }
52
119
 
53
- declare const string: () => FieldBuilder;
54
- declare const number: () => FieldBuilder;
120
+ declare const string: () => StringFieldBuilder;
121
+ declare const number: () => NumberFieldBuilder;
55
122
  declare const boolean: () => FieldBuilder;
56
123
  declare const uuid: () => FieldBuilder;
57
124
  declare const datetime: () => FieldBuilder;
58
125
  declare const enumField: (values: [string, ...string[]]) => FieldBuilder;
59
126
  declare const belongsTo: (entity: string) => FieldBuilder;
60
127
  declare const hasMany: (entity: string) => FieldBuilder;
128
+ declare const object: (fields: Record<string, FieldBuilder>) => FieldBuilder;
129
+ declare const array: (item: FieldBuilder, count?: [number, number]) => FieldBuilder;
61
130
 
62
- declare const __ffa_version = "0.6.0";
131
+ declare const __ffa_version = "0.16.0";
63
132
 
64
- export { type FfaConfig, __ffa_version, belongsTo, boolean, datetime, defineConfig, entity, enumField, hasMany, number, string, uuid };
133
+ export { type FakeHint, type FfaConfig, type MetaFn, type MetaValue, type NumberFakeHint, type StringFakeHint, __ffa_version, array, belongsTo, boolean, datetime, defineConfig, entity, enumField, hasMany, number, object, string, uuid };
package/dist/index.js CHANGED
@@ -14,7 +14,9 @@ function entity(fields, options) {
14
14
  }
15
15
  return {
16
16
  fields: builtFields,
17
- count: options?.count
17
+ count: options?.count,
18
+ meta: options?.meta,
19
+ seed: options?.seed
18
20
  };
19
21
  }
20
22
 
@@ -22,10 +24,7 @@ function entity(fields, options) {
22
24
  var FieldBuilder = class {
23
25
  def;
24
26
  constructor(type, extraRules) {
25
- this.def = {
26
- type,
27
- rules: { ...extraRules }
28
- };
27
+ this.def = { type, rules: { ...extraRules } };
29
28
  }
30
29
  required() {
31
30
  this.def.rules.required = true;
@@ -51,25 +50,170 @@ var FieldBuilder = class {
51
50
  this.def.rules.readonly = true;
52
51
  return this;
53
52
  }
53
+ /** Explicit faker hint — overrides smart field-name detection */
54
+ fake(hint) {
55
+ this.def.rules.fakeHint = hint;
56
+ return this;
57
+ }
54
58
  build() {
55
59
  return structuredClone(this.def);
56
60
  }
57
61
  };
62
+ var StringFieldBuilder = class extends FieldBuilder {
63
+ constructor() {
64
+ super("string");
65
+ }
66
+ hint(h) {
67
+ this.def.rules.fakeHint = h;
68
+ return this;
69
+ }
70
+ // Internet
71
+ email() {
72
+ return this.hint("email");
73
+ }
74
+ url() {
75
+ return this.hint("url");
76
+ }
77
+ domain() {
78
+ return this.hint("domain");
79
+ }
80
+ ip() {
81
+ return this.hint("ip");
82
+ }
83
+ username() {
84
+ return this.hint("username");
85
+ }
86
+ // Media
87
+ image() {
88
+ return this.hint("image");
89
+ }
90
+ avatar() {
91
+ return this.hint("avatar");
92
+ }
93
+ // Person
94
+ firstName() {
95
+ return this.hint("firstName");
96
+ }
97
+ lastName() {
98
+ return this.hint("lastName");
99
+ }
100
+ fullName() {
101
+ return this.hint("fullName");
102
+ }
103
+ // Contact
104
+ phone() {
105
+ return this.hint("phone");
106
+ }
107
+ // Location
108
+ city() {
109
+ return this.hint("city");
110
+ }
111
+ country() {
112
+ return this.hint("country");
113
+ }
114
+ address() {
115
+ return this.hint("address");
116
+ }
117
+ zip() {
118
+ return this.hint("zip");
119
+ }
120
+ locale() {
121
+ return this.hint("locale");
122
+ }
123
+ // Business
124
+ company() {
125
+ return this.hint("company");
126
+ }
127
+ jobTitle() {
128
+ return this.hint("jobTitle");
129
+ }
130
+ department() {
131
+ return this.hint("department");
132
+ }
133
+ currency() {
134
+ return this.hint("currency");
135
+ }
136
+ // Text
137
+ word() {
138
+ return this.hint("word");
139
+ }
140
+ slug() {
141
+ return this.hint("slug");
142
+ }
143
+ sentence() {
144
+ return this.hint("sentence");
145
+ }
146
+ paragraph() {
147
+ return this.hint("paragraph");
148
+ }
149
+ bio() {
150
+ return this.hint("bio");
151
+ }
152
+ // Visual
153
+ color() {
154
+ return this.hint("color");
155
+ }
156
+ hexColor() {
157
+ return this.hint("hexColor");
158
+ }
159
+ // Id
160
+ uuid() {
161
+ return this.hint("uuid");
162
+ }
163
+ };
164
+ var NumberFieldBuilder = class extends FieldBuilder {
165
+ constructor() {
166
+ super("number");
167
+ }
168
+ hint(h) {
169
+ this.def.rules.fakeHint = h;
170
+ return this;
171
+ }
172
+ price() {
173
+ return this.hint("price");
174
+ }
175
+ age() {
176
+ return this.hint("age");
177
+ }
178
+ rating() {
179
+ return this.hint("rating");
180
+ }
181
+ percent() {
182
+ return this.hint("percent");
183
+ }
184
+ lat() {
185
+ return this.hint("lat");
186
+ }
187
+ lng() {
188
+ return this.hint("lng");
189
+ }
190
+ year() {
191
+ return this.hint("year");
192
+ }
193
+ };
58
194
 
59
195
  // src/field/factories.ts
60
- var string = () => new FieldBuilder("string");
61
- var number = () => new FieldBuilder("number");
196
+ var string = () => new StringFieldBuilder();
197
+ var number = () => new NumberFieldBuilder();
62
198
  var boolean = () => new FieldBuilder("boolean");
63
199
  var uuid = () => new FieldBuilder("uuid");
64
200
  var datetime = () => new FieldBuilder("datetime");
65
201
  var enumField = (values) => new FieldBuilder("enum", { enumValues: values });
66
202
  var belongsTo = (entity2) => new FieldBuilder("belongsTo", { entity: entity2 });
67
203
  var hasMany = (entity2) => new FieldBuilder("hasMany", { entity: entity2 });
204
+ var object = (fields) => {
205
+ const objectFields = Object.fromEntries(Object.entries(fields).map(([k, v]) => [k, v.build()]));
206
+ return new FieldBuilder("object", { objectFields });
207
+ };
208
+ var array = (item, count) => {
209
+ return new FieldBuilder("array", { arrayItem: item.build(), arrayCount: count });
210
+ };
68
211
 
69
212
  // src/index.ts
70
- var __ffa_version = "0.6.0";
213
+ var __ffa_version = "0.16.0";
71
214
  export {
72
215
  __ffa_version,
216
+ array,
73
217
  belongsTo,
74
218
  boolean,
75
219
  datetime,
@@ -78,6 +222,7 @@ export {
78
222
  enumField,
79
223
  hasMany,
80
224
  number,
225
+ object,
81
226
  string,
82
227
  uuid
83
228
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config/defineConfig.ts","../src/entity/entity.ts","../src/field/FieldBuilder.ts","../src/field/factories.ts","../src/index.ts"],"sourcesContent":["import type { EntityDefinition } from '../field/types'\n\nexport interface ServerConfig {\n port: number\n cors?: boolean | { origin: string | string[] }\n persist?: boolean | string\n delay?: number | [number, number]\n}\n\nexport interface FfaConfig {\n server: ServerConfig\n entities: Record<string, EntityDefinition>\n}\n\nexport function defineConfig(config: FfaConfig): FfaConfig {\n return {\n server: config.server ?? { port: 3000 },\n entities: config.entities ?? {},\n }\n}\n","// src/entity/entity.ts\nexport function entity(fields: Record<string, any>, options?: { count?: number }) {\n const builtFields: Record<string, any> = {}\n\n for (const [key, value] of Object.entries(fields)) {\n builtFields[key] = value.build()\n }\n\n return {\n fields: builtFields,\n count: options?.count,\n }\n}\n","import { FieldDefinition, FieldRules, FieldType } from './types'\n\nexport class FieldBuilder {\n private def: FieldDefinition\n\n constructor(type: FieldType, extraRules?: Partial<FieldRules>) {\n this.def = {\n type,\n rules: { ...extraRules },\n }\n }\n\n required() {\n this.def.rules.required = true\n return this\n }\n\n optional() {\n this.def.rules.required = false\n return this\n }\n\n min(value: number) {\n this.def.rules.min = value\n return this\n }\n\n max(value: number) {\n this.def.rules.max = value\n return this\n }\n\n default(value: any) {\n this.def.rules.default = value\n return this\n }\n\n readonly() {\n this.def.rules.readonly = true\n return this\n }\n\n build(): FieldDefinition {\n return structuredClone(this.def)\n }\n}\n","import { FieldBuilder } from './FieldBuilder'\n\nexport const string = () => new FieldBuilder('string')\nexport const number = () => new FieldBuilder('number')\nexport const boolean = () => new FieldBuilder('boolean')\nexport const uuid = () => new FieldBuilder('uuid')\nexport const datetime = () => new FieldBuilder('datetime')\nexport const enumField = (values: [string, ...string[]]) => new FieldBuilder('enum', { enumValues: values })\nexport const belongsTo = (entity: string) => new FieldBuilder('belongsTo', { entity })\nexport const hasMany = (entity: string) => new FieldBuilder('hasMany', { entity })\n","// config\nexport { defineConfig } from './config/defineConfig'\nexport type { FfaConfig } from './config/defineConfig'\n\n// entity\nexport { entity } from './entity/entity'\n\n// field DSL\nexport { string, number, boolean, uuid, datetime, enumField, belongsTo, hasMany } from './field/factories'\n\nexport const __ffa_version = '0.6.0'\n"],"mappings":";AAcO,SAAS,aAAa,QAA8B;AACzD,SAAO;AAAA,IACL,QAAQ,OAAO,UAAU,EAAE,MAAM,IAAK;AAAA,IACtC,UAAU,OAAO,YAAY,CAAC;AAAA,EAChC;AACF;;;AClBO,SAAS,OAAO,QAA6B,SAA8B;AAChF,QAAM,cAAmC,CAAC;AAE1C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,gBAAY,GAAG,IAAI,MAAM,MAAM;AAAA,EACjC;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,OAAO,SAAS;AAAA,EAClB;AACF;;;ACVO,IAAM,eAAN,MAAmB;AAAA,EAChB;AAAA,EAER,YAAY,MAAiB,YAAkC;AAC7D,SAAK,MAAM;AAAA,MACT;AAAA,MACA,OAAO,EAAE,GAAG,WAAW;AAAA,IACzB;AAAA,EACF;AAAA,EAEA,WAAW;AACT,SAAK,IAAI,MAAM,WAAW;AAC1B,WAAO;AAAA,EACT;AAAA,EAEA,WAAW;AACT,SAAK,IAAI,MAAM,WAAW;AAC1B,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,OAAe;AACjB,SAAK,IAAI,MAAM,MAAM;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,OAAe;AACjB,SAAK,IAAI,MAAM,MAAM;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,OAAY;AAClB,SAAK,IAAI,MAAM,UAAU;AACzB,WAAO;AAAA,EACT;AAAA,EAEA,WAAW;AACT,SAAK,IAAI,MAAM,WAAW;AAC1B,WAAO;AAAA,EACT;AAAA,EAEA,QAAyB;AACvB,WAAO,gBAAgB,KAAK,GAAG;AAAA,EACjC;AACF;;;AC3CO,IAAM,SAAS,MAAM,IAAI,aAAa,QAAQ;AAC9C,IAAM,SAAS,MAAM,IAAI,aAAa,QAAQ;AAC9C,IAAM,UAAU,MAAM,IAAI,aAAa,SAAS;AAChD,IAAM,OAAO,MAAM,IAAI,aAAa,MAAM;AAC1C,IAAM,WAAW,MAAM,IAAI,aAAa,UAAU;AAClD,IAAM,YAAY,CAAC,WAAkC,IAAI,aAAa,QAAQ,EAAE,YAAY,OAAO,CAAC;AACpG,IAAM,YAAY,CAACA,YAAmB,IAAI,aAAa,aAAa,EAAE,QAAAA,QAAO,CAAC;AAC9E,IAAM,UAAU,CAACA,YAAmB,IAAI,aAAa,WAAW,EAAE,QAAAA,QAAO,CAAC;;;ACC1E,IAAM,gBAAgB;","names":["entity"]}
1
+ {"version":3,"sources":["../src/config/defineConfig.ts","../src/entity/entity.ts","../src/field/FieldBuilder.ts","../src/field/factories.ts","../src/index.ts"],"sourcesContent":["import type { EntityDefinition } from '../field/types'\n\nexport interface ServerConfig {\n port: number\n cors?: boolean | { origin: string | string[] }\n persist?: boolean | string\n delay?: number | [number, number]\n errorRate?: number\n}\n\nexport interface FfaConfig {\n server: ServerConfig\n entities: Record<string, EntityDefinition>\n}\n\nexport function defineConfig(config: FfaConfig): FfaConfig {\n return {\n server: config.server ?? { port: 3000 },\n entities: config.entities ?? {},\n }\n}\n","import type { MetaValue } from '../field/types'\n\nexport function entity(\n fields: Record<string, any>,\n options?: { count?: number; meta?: Record<string, MetaValue>; seed?: Record<string, unknown>[] },\n) {\n const builtFields: Record<string, any> = {}\n\n for (const [key, value] of Object.entries(fields)) {\n builtFields[key] = value.build()\n }\n\n return {\n fields: builtFields,\n count: options?.count,\n meta: options?.meta,\n seed: options?.seed,\n }\n}\n","import type { FieldDefinition, FieldRules, FieldType, FakeHint, StringFakeHint, NumberFakeHint } from './types'\n\n// ─── Base builder ────────────────────────────────────────────────────────────\n\nexport class FieldBuilder {\n protected def: FieldDefinition\n\n constructor(type: FieldType, extraRules?: Partial<FieldRules>) {\n this.def = { type, rules: { ...extraRules } }\n }\n\n required(): this {\n this.def.rules.required = true\n return this\n }\n\n optional(): this {\n this.def.rules.required = false\n return this\n }\n\n min(value: number): this {\n this.def.rules.min = value\n return this\n }\n\n max(value: number): this {\n this.def.rules.max = value\n return this\n }\n\n default(value: any): this {\n this.def.rules.default = value\n return this\n }\n\n readonly(): this {\n this.def.rules.readonly = true\n return this\n }\n\n /** Explicit faker hint — overrides smart field-name detection */\n fake(hint: FakeHint): this {\n this.def.rules.fakeHint = hint\n return this\n }\n\n build(): FieldDefinition {\n return structuredClone(this.def)\n }\n}\n\n// ─── String builder ──────────────────────────────────────────────────────────\n\nexport class StringFieldBuilder extends FieldBuilder {\n constructor() {\n super('string')\n }\n\n private hint(h: StringFakeHint): this {\n this.def.rules.fakeHint = h\n return this\n }\n\n // Internet\n email(): this { return this.hint('email') }\n url(): this { return this.hint('url') }\n domain(): this { return this.hint('domain') }\n ip(): this { return this.hint('ip') }\n username(): this { return this.hint('username') }\n\n // Media\n image(): this { return this.hint('image') }\n avatar(): this { return this.hint('avatar') }\n\n // Person\n firstName(): this { return this.hint('firstName') }\n lastName(): this { return this.hint('lastName') }\n fullName(): this { return this.hint('fullName') }\n\n // Contact\n phone(): this { return this.hint('phone') }\n\n // Location\n city(): this { return this.hint('city') }\n country(): this { return this.hint('country') }\n address(): this { return this.hint('address') }\n zip(): this { return this.hint('zip') }\n locale(): this { return this.hint('locale') }\n\n // Business\n company(): this { return this.hint('company') }\n jobTitle(): this { return this.hint('jobTitle') }\n department(): this { return this.hint('department') }\n currency(): this { return this.hint('currency') }\n\n // Text\n word(): this { return this.hint('word') }\n slug(): this { return this.hint('slug') }\n sentence(): this { return this.hint('sentence') }\n paragraph(): this { return this.hint('paragraph') }\n bio(): this { return this.hint('bio') }\n\n // Visual\n color(): this { return this.hint('color') }\n hexColor(): this { return this.hint('hexColor') }\n\n // Id\n uuid(): this { return this.hint('uuid') }\n}\n\n// ─── Number builder ──────────────────────────────────────────────────────────\n\nexport class NumberFieldBuilder extends FieldBuilder {\n constructor() {\n super('number')\n }\n\n private hint(h: NumberFakeHint): this {\n this.def.rules.fakeHint = h\n return this\n }\n\n price(): this { return this.hint('price') }\n age(): this { return this.hint('age') }\n rating(): this { return this.hint('rating') }\n percent(): this { return this.hint('percent') }\n lat(): this { return this.hint('lat') }\n lng(): this { return this.hint('lng') }\n year(): this { return this.hint('year') }\n}\n","import { FieldBuilder, StringFieldBuilder, NumberFieldBuilder } from './FieldBuilder'\n\nexport const string = (): StringFieldBuilder => new StringFieldBuilder()\nexport const number = (): NumberFieldBuilder => new NumberFieldBuilder()\nexport const boolean = () => new FieldBuilder('boolean')\nexport const uuid = () => new FieldBuilder('uuid')\nexport const datetime = () => new FieldBuilder('datetime')\nexport const enumField = (values: [string, ...string[]]) => new FieldBuilder('enum', { enumValues: values })\nexport const belongsTo = (entity: string) => new FieldBuilder('belongsTo', { entity })\nexport const hasMany = (entity: string) => new FieldBuilder('hasMany', { entity })\n\nexport const object = (fields: Record<string, FieldBuilder>): FieldBuilder => {\n const objectFields = Object.fromEntries(Object.entries(fields).map(([k, v]) => [k, v.build()]))\n return new FieldBuilder('object', { objectFields })\n}\n\nexport const array = (item: FieldBuilder, count?: [number, number]): FieldBuilder => {\n return new FieldBuilder('array', { arrayItem: item.build(), arrayCount: count })\n}\n","// config\nexport { defineConfig } from './config/defineConfig'\nexport type { FfaConfig } from './config/defineConfig'\n\n// entity\nexport { entity } from './entity/entity'\n\n// field DSL\nexport { string, number, boolean, uuid, datetime, enumField, belongsTo, hasMany, object, array } from './field/factories'\nexport type { FakeHint, StringFakeHint, NumberFakeHint, MetaFn, MetaValue } from './field/types'\n\nexport const __ffa_version = '0.16.0'\n"],"mappings":"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","names":["entity"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koltakov/ffa-core",
3
- "version": "0.6.0",
3
+ "version": "0.16.0",
4
4
  "description": "Instant mock REST API for frontend development",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -22,6 +22,8 @@
22
22
  "build": "tsup",
23
23
  "dev": "tsx src/cli.ts",
24
24
  "typecheck": "tsc --noEmit",
25
+ "test": "vitest run",
26
+ "test:watch": "vitest",
25
27
  "prepublishOnly": "npm run typecheck && npm run build"
26
28
  },
27
29
  "keywords": [
@@ -64,6 +66,7 @@
64
66
  "@types/node": "^25.3.3",
65
67
  "tsup": "^8.0.0",
66
68
  "tsx": "^4.21.0",
67
- "typescript": "^5.9.3"
69
+ "typescript": "^5.9.3",
70
+ "vitest": "^4.0.18"
68
71
  }
69
72
  }