@famgia/omnify 0.1.2 → 0.1.3

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
@@ -178,6 +178,35 @@ function Component() {
178
178
  - Node.js >= 16
179
179
  - TypeScript >= 5.0 (peer dependency)
180
180
 
181
+ ## Development
182
+
183
+ ### Running Tests
184
+
185
+ ```bash
186
+ # Run all tests
187
+ npm test
188
+
189
+ # Run tests in watch mode
190
+ npm run test:watch
191
+
192
+ # Run tests with coverage
193
+ npm run test:coverage
194
+ ```
195
+
196
+ ### Test Coverage
197
+
198
+ The package includes comprehensive tests for:
199
+ - Type mapping (Omnify types to TypeScript)
200
+ - Enum generation
201
+ - Model generation
202
+ - Context generation with helper methods
203
+
204
+ Current coverage:
205
+ - Statements: ~70%
206
+ - Branches: ~40%
207
+ - Functions: ~80%
208
+ - Lines: ~70%
209
+
181
210
  ## License
182
211
 
183
212
  MIT
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=contextGenerator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contextGenerator.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/generators/contextGenerator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const contextGenerator_1 = require("../../generators/contextGenerator");
4
+ describe('contextGenerator', () => {
5
+ describe('generateEnumContextFile', () => {
6
+ const mockEnums = [
7
+ {
8
+ objectName: 'User',
9
+ propertyName: 'status',
10
+ values: [
11
+ { value: 'ACTIVE', label: 'Active' },
12
+ { value: 'INACTIVE', label: 'Inactive' },
13
+ ],
14
+ },
15
+ {
16
+ objectName: 'User',
17
+ propertyName: 'role',
18
+ values: [
19
+ { value: 'ADMIN', label: 'Administrator' },
20
+ { value: 'USER', label: 'User' },
21
+ ],
22
+ },
23
+ ];
24
+ it('should generate context with EnumOptions interface', () => {
25
+ const output = (0, contextGenerator_1.generateEnumContextFile)(mockEnums);
26
+ expect(output).toContain("'use client';");
27
+ expect(output).toContain('// Auto-generated by @omnifyjp/omnify');
28
+ expect(output).toContain('export interface EnumOptions {');
29
+ expect(output).toContain('status: Record<string, string>;');
30
+ expect(output).toContain('role: Record<string, string>;');
31
+ expect(output).toContain('prefectures: Record<string, string>;');
32
+ });
33
+ it('should generate STATIC_ENUMS object', () => {
34
+ const output = (0, contextGenerator_1.generateEnumContextFile)(mockEnums);
35
+ expect(output).toContain('const STATIC_ENUMS: EnumOptions = {');
36
+ expect(output).toContain('status: {');
37
+ expect(output).toContain("ACTIVE: 'Active'");
38
+ expect(output).toContain("INACTIVE: 'Inactive'");
39
+ expect(output).toContain('role: {');
40
+ expect(output).toContain("ADMIN: 'Administrator'");
41
+ expect(output).toContain("USER: 'User'");
42
+ });
43
+ it('should include all 47 prefectures', () => {
44
+ const output = (0, contextGenerator_1.generateEnumContextFile)(mockEnums);
45
+ expect(output).toContain('prefectures: {');
46
+ expect(output).toContain("'1': '北海道'");
47
+ expect(output).toContain("'13': '東京都'");
48
+ expect(output).toContain("'47': '沖縄県'");
49
+ });
50
+ it('should generate EnumsContextType with helper methods', () => {
51
+ const output = (0, contextGenerator_1.generateEnumContextFile)(mockEnums);
52
+ expect(output).toContain('interface EnumsContextType {');
53
+ expect(output).toContain('enums: EnumOptions | null;');
54
+ expect(output).toContain('loading: boolean;');
55
+ expect(output).toContain('error: Error | null;');
56
+ expect(output).toContain('getLabel: (enumKey: keyof EnumOptions, value: string | number) => string | undefined;');
57
+ expect(output).toContain('getValue: (enumKey: keyof EnumOptions, label: string) => string | undefined;');
58
+ expect(output).toContain('getOptions: (enumKey: keyof EnumOptions) => { value: string; label: string }[];');
59
+ });
60
+ it('should generate EnumsProvider component', () => {
61
+ const output = (0, contextGenerator_1.generateEnumContextFile)(mockEnums);
62
+ expect(output).toContain('export function EnumsProvider({ children }: { children: ReactNode })');
63
+ expect(output).toContain('const [enums] = useState<EnumOptions>(STATIC_ENUMS);');
64
+ expect(output).toContain('<EnumsContext.Provider');
65
+ });
66
+ it('should generate getLabel helper method', () => {
67
+ const output = (0, contextGenerator_1.generateEnumContextFile)(mockEnums);
68
+ expect(output).toContain('const getLabel = (enumKey: keyof EnumOptions, value: string | number): string | undefined => {');
69
+ expect(output).toContain('if (!enums) return undefined;');
70
+ expect(output).toContain('const enumData = enums[enumKey];');
71
+ expect(output).toContain('return enumData[String(value)];');
72
+ });
73
+ it('should generate getValue helper method', () => {
74
+ const output = (0, contextGenerator_1.generateEnumContextFile)(mockEnums);
75
+ expect(output).toContain('const getValue = (enumKey: keyof EnumOptions, label: string): string | undefined => {');
76
+ expect(output).toContain('return Object.entries(enumData).find(([_, l]) => l === label)?.[0];');
77
+ });
78
+ it('should generate getOptions helper method', () => {
79
+ const output = (0, contextGenerator_1.generateEnumContextFile)(mockEnums);
80
+ expect(output).toContain('const getOptions = (enumKey: keyof EnumOptions): { value: string; label: string }[] => {');
81
+ expect(output).toContain('return Object.entries(enumData).map(([value, label]) => ({ value, label }));');
82
+ });
83
+ it('should generate useEnums hook', () => {
84
+ const output = (0, contextGenerator_1.generateEnumContextFile)(mockEnums);
85
+ expect(output).toContain('export function useEnums(): EnumsContextType {');
86
+ expect(output).toContain('const context = useContext(EnumsContext);');
87
+ expect(output).toContain("throw new Error('useEnums must be used within an EnumsProvider');");
88
+ });
89
+ it('should handle empty enums array', () => {
90
+ const output = (0, contextGenerator_1.generateEnumContextFile)([]);
91
+ expect(output).toContain('export interface EnumOptions {');
92
+ expect(output).toContain('prefectures: Record<string, string>;');
93
+ expect(output).toContain('const STATIC_ENUMS: EnumOptions = {');
94
+ });
95
+ });
96
+ });
97
+ //# sourceMappingURL=contextGenerator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contextGenerator.test.js","sourceRoot":"","sources":["../../../src/__tests__/generators/contextGenerator.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=enumGenerator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enumGenerator.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/generators/enumGenerator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const enumGenerator_1 = require("../../generators/enumGenerator");
4
+ describe('enumGenerator', () => {
5
+ const mockSchema = {
6
+ User: {
7
+ name: 'User',
8
+ table: 'users',
9
+ properties: {
10
+ id: {
11
+ type: 'Id',
12
+ objectName: 'User',
13
+ propertyName: 'id',
14
+ displayName: 'ID',
15
+ description: null,
16
+ primary: true,
17
+ },
18
+ status: {
19
+ type: 'Enum',
20
+ enum: [
21
+ { value: 'ACTIVE', label: 'Active' },
22
+ { value: 'INACTIVE', label: 'Inactive' },
23
+ ],
24
+ objectName: 'User',
25
+ propertyName: 'status',
26
+ displayName: 'Status',
27
+ description: null,
28
+ },
29
+ role: {
30
+ type: 'Enum',
31
+ enum: [
32
+ { value: 'ADMIN', label: 'Administrator' },
33
+ { value: 'USER', label: 'User' },
34
+ ],
35
+ objectName: 'User',
36
+ propertyName: 'role',
37
+ displayName: 'Role',
38
+ description: null,
39
+ },
40
+ },
41
+ },
42
+ };
43
+ describe('extractEnums', () => {
44
+ it('should extract all enums from schema', () => {
45
+ const enums = (0, enumGenerator_1.extractEnums)(mockSchema);
46
+ expect(enums).toHaveLength(2);
47
+ expect(enums[0].objectName).toBe('User');
48
+ expect(enums[0].propertyName).toBe('status');
49
+ expect(enums[0].values).toHaveLength(2);
50
+ expect(enums[1].propertyName).toBe('role');
51
+ });
52
+ it('should handle schema with no enums', () => {
53
+ const schemaWithoutEnums = {
54
+ User: {
55
+ name: 'User',
56
+ table: 'users',
57
+ properties: {
58
+ id: {
59
+ type: 'Id',
60
+ objectName: 'User',
61
+ propertyName: 'id',
62
+ displayName: 'ID',
63
+ description: null,
64
+ },
65
+ name: {
66
+ type: 'String',
67
+ objectName: 'User',
68
+ propertyName: 'name',
69
+ displayName: 'Name',
70
+ description: null,
71
+ },
72
+ },
73
+ },
74
+ };
75
+ const enums = (0, enumGenerator_1.extractEnums)(schemaWithoutEnums);
76
+ expect(enums).toHaveLength(0);
77
+ });
78
+ });
79
+ describe('generateEnumTypesFile', () => {
80
+ it('should generate enums TypeScript file', () => {
81
+ const enums = (0, enumGenerator_1.extractEnums)(mockSchema);
82
+ const output = (0, enumGenerator_1.generateEnumTypesFile)(enums);
83
+ expect(output).toContain('// Auto-generated by @omnifyjp/omnify');
84
+ expect(output).toContain('export type User_status');
85
+ expect(output).toContain("| 'ACTIVE'");
86
+ expect(output).toContain("| 'INACTIVE'");
87
+ expect(output).toContain('export type User_role');
88
+ expect(output).toContain("| 'ADMIN'");
89
+ expect(output).toContain("| 'USER'");
90
+ });
91
+ it('should generate empty file for no enums', () => {
92
+ const output = (0, enumGenerator_1.generateEnumTypesFile)([]);
93
+ expect(output).toContain('// Auto-generated by @omnifyjp/omnify');
94
+ expect(output).not.toContain('export type');
95
+ });
96
+ });
97
+ describe('generateEnumOptionsFile', () => {
98
+ it('should generate enum options file', () => {
99
+ const enums = (0, enumGenerator_1.extractEnums)(mockSchema);
100
+ const output = (0, enumGenerator_1.generateEnumOptionsFile)(enums);
101
+ expect(output).toContain('// Auto-generated by @omnifyjp/omnify');
102
+ expect(output).toContain('export const statusOptions = {');
103
+ expect(output).toContain("ACTIVE: 'Active'");
104
+ expect(output).toContain("INACTIVE: 'Inactive'");
105
+ expect(output).toContain('export const roleOptions = {');
106
+ expect(output).toContain("ADMIN: 'Administrator'");
107
+ expect(output).toContain("USER: 'User'");
108
+ });
109
+ });
110
+ });
111
+ //# sourceMappingURL=enumGenerator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enumGenerator.test.js","sourceRoot":"","sources":["../../../src/__tests__/generators/enumGenerator.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=modelGenerator.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelGenerator.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/generators/modelGenerator.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const modelGenerator_1 = require("../../generators/modelGenerator");
4
+ describe('modelGenerator', () => {
5
+ describe('generateModelFile', () => {
6
+ it('should generate basic model interface', () => {
7
+ const object = {
8
+ name: 'User',
9
+ table: 'users',
10
+ label: 'User',
11
+ properties: {
12
+ id: {
13
+ type: 'Id',
14
+ objectName: 'User',
15
+ propertyName: 'id',
16
+ displayName: 'ID',
17
+ description: null,
18
+ primary: true,
19
+ },
20
+ name: {
21
+ type: 'String',
22
+ objectName: 'User',
23
+ propertyName: 'name',
24
+ displayName: 'Name',
25
+ description: null,
26
+ },
27
+ email: {
28
+ type: 'Email',
29
+ objectName: 'User',
30
+ propertyName: 'email',
31
+ displayName: 'Email',
32
+ description: null,
33
+ },
34
+ },
35
+ };
36
+ const output = (0, modelGenerator_1.generateModelFile)('User', object);
37
+ expect(output).toContain('// Auto-generated by @omnifyjp/omnify');
38
+ expect(output).toContain('export interface User {');
39
+ expect(output).toContain('id: number; // ID');
40
+ expect(output).toContain('name: string; // Name');
41
+ expect(output).toContain('email: string; // Email');
42
+ });
43
+ it('should handle nullable fields', () => {
44
+ const object = {
45
+ name: 'User',
46
+ table: 'users',
47
+ properties: {
48
+ id: {
49
+ type: 'Id',
50
+ objectName: 'User',
51
+ propertyName: 'id',
52
+ displayName: 'ID',
53
+ description: null,
54
+ },
55
+ bio: {
56
+ type: 'Text',
57
+ nullable: true,
58
+ objectName: 'User',
59
+ propertyName: 'bio',
60
+ displayName: 'Bio',
61
+ description: null,
62
+ },
63
+ },
64
+ };
65
+ const output = (0, modelGenerator_1.generateModelFile)('User', object);
66
+ expect(output).toContain('bio?: string | null;');
67
+ });
68
+ it('should handle enum fields', () => {
69
+ const object = {
70
+ name: 'User',
71
+ table: 'users',
72
+ properties: {
73
+ id: {
74
+ type: 'Id',
75
+ objectName: 'User',
76
+ propertyName: 'id',
77
+ displayName: 'ID',
78
+ description: null,
79
+ },
80
+ status: {
81
+ type: 'Enum',
82
+ enum: [
83
+ { value: 'ACTIVE', label: 'Active' },
84
+ { value: 'INACTIVE', label: 'Inactive' },
85
+ ],
86
+ objectName: 'User',
87
+ propertyName: 'status',
88
+ displayName: 'Status',
89
+ description: null,
90
+ },
91
+ },
92
+ };
93
+ const output = (0, modelGenerator_1.generateModelFile)('User', object);
94
+ expect(output).toContain('status: User_status;');
95
+ });
96
+ it('should generate clean output', () => {
97
+ const object = {
98
+ name: 'TestModel',
99
+ table: 'test_models',
100
+ properties: {
101
+ id: {
102
+ type: 'Id',
103
+ objectName: 'TestModel',
104
+ propertyName: 'id',
105
+ displayName: 'ID',
106
+ description: null,
107
+ },
108
+ },
109
+ };
110
+ const output = (0, modelGenerator_1.generateModelFile)('TestModel', object);
111
+ expect(output).not.toContain('undefined');
112
+ expect(output).not.toContain('[object Object]');
113
+ });
114
+ });
115
+ });
116
+ //# sourceMappingURL=modelGenerator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelGenerator.test.js","sourceRoot":"","sources":["../../../src/__tests__/generators/modelGenerator.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=typeMapper.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typeMapper.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/utils/typeMapper.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const typeMapper_1 = require("../../utils/typeMapper");
4
+ describe('typeMapper', () => {
5
+ describe('mapOmnifyTypeToTypeScript', () => {
6
+ it('should map String types correctly', () => {
7
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('String')).toBe('string');
8
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('Text')).toBe('string');
9
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('Email')).toBe('string');
10
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('LongText')).toBe('string');
11
+ });
12
+ it('should map numeric types correctly', () => {
13
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('Int')).toBe('number');
14
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('BigInt')).toBe('number');
15
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('Float')).toBe('number');
16
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('Id')).toBe('number');
17
+ });
18
+ it('should map Boolean types correctly', () => {
19
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('Boolean')).toBe('boolean');
20
+ });
21
+ it('should map date/time types correctly', () => {
22
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('Date')).toBe('string');
23
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('Timestamp')).toBe('string');
24
+ });
25
+ it('should map JSON types correctly', () => {
26
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('Json')).toBe('Record<string, any>');
27
+ });
28
+ it('should map File types correctly', () => {
29
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('File')).toBe('string');
30
+ });
31
+ it('should handle nullable types', () => {
32
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('String', true)).toBe('string | null');
33
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('Int', true)).toBe('number | null');
34
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('Boolean', true)).toBe('boolean | null');
35
+ });
36
+ it('should return "any" for unknown types', () => {
37
+ expect((0, typeMapper_1.mapOmnifyTypeToTypeScript)('UnknownType')).toBe('any');
38
+ });
39
+ });
40
+ });
41
+ //# sourceMappingURL=typeMapper.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typeMapper.test.js","sourceRoot":"","sources":["../../../src/__tests__/utils/typeMapper.test.ts"],"names":[],"mappings":";;AAAA,uDAAmE;AAEnE,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IACxB,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACvC,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YACzC,MAAM,CAAC,IAAA,sCAAyB,EAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC3D,MAAM,CAAC,IAAA,sCAAyB,EAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzD,MAAM,CAAC,IAAA,sCAAyB,EAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC1D,MAAM,CAAC,IAAA,sCAAyB,EAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC1C,MAAM,CAAC,IAAA,sCAAyB,EAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACxD,MAAM,CAAC,IAAA,sCAAyB,EAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC3D,MAAM,CAAC,IAAA,sCAAyB,EAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC1D,MAAM,CAAC,IAAA,sCAAyB,EAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC1C,MAAM,CAAC,IAAA,sCAAyB,EAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC5C,MAAM,CAAC,IAAA,sCAAyB,EAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzD,MAAM,CAAC,IAAA,sCAAyB,EAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACvC,MAAM,CAAC,IAAA,sCAAyB,EAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACvC,MAAM,CAAC,IAAA,sCAAyB,EAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACpC,MAAM,CAAC,IAAA,sCAAyB,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACxE,MAAM,CAAC,IAAA,sCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACrE,MAAM,CAAC,IAAA,sCAAyB,EAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC9E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC7C,MAAM,CAAC,IAAA,sCAAyB,EAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@famgia/omnify",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Convert Omnify schema-lock.json to TypeScript models and enums",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -9,6 +9,9 @@
9
9
  },
10
10
  "scripts": {
11
11
  "build": "tsc",
12
+ "test": "jest",
13
+ "test:watch": "jest --watch",
14
+ "test:coverage": "jest --coverage",
12
15
  "prepublishOnly": "npm run build"
13
16
  },
14
17
  "keywords": [
@@ -34,7 +37,10 @@
34
37
  "node": ">=16.0.0"
35
38
  },
36
39
  "devDependencies": {
37
- "@types/node": "^20.0.0",
40
+ "@types/jest": "^30.0.0",
41
+ "@types/node": "^20.19.24",
42
+ "jest": "^30.2.0",
43
+ "ts-jest": "^29.4.5",
38
44
  "typescript": "^5.0.0"
39
45
  },
40
46
  "dependencies": {