@apso/cli 0.1.0 → 0.1.5
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/commands/server/scaffold.d.ts +1 -1
- package/dist/commands/server/scaffold.js +5 -5
- package/dist/lib/apsorc-parser.d.ts +27 -1
- package/dist/lib/apsorc-parser.js +97 -3
- package/dist/lib/controller.d.ts +8 -0
- package/dist/lib/controller.js +24 -9
- package/dist/lib/dto.d.ts +14 -7
- package/dist/lib/dto.js +61 -25
- package/dist/lib/entity.d.ts +9 -0
- package/dist/lib/entity.js +14 -4
- package/dist/lib/gql-dto.js +1 -1
- package/dist/lib/index-module.d.ts +11 -0
- package/dist/lib/index-module.js +11 -0
- package/dist/lib/module.d.ts +13 -1
- package/dist/lib/module.js +26 -10
- package/dist/lib/service.d.ts +9 -1
- package/dist/lib/service.js +22 -7
- package/dist/lib/templates/entities/entity-col-json.eta +1 -1
- package/dist/lib/templates/rest/dto-rest.eta +2 -2
- package/dist/lib/templates/rest/module-rest.eta +1 -1
- package/dist/lib/templates/rest/service-rest-spec.eta +38 -0
- package/dist/lib/utils/casing.d.ts +2 -1
- package/dist/lib/utils/casing.js +18 -8
- package/dist/lib/utils/field.js +1 -1
- package/dist/lib/utils/relationships/parse.d.ts +45 -1
- package/dist/lib/utils/relationships/parse.js +228 -79
- package/dist/lib/utils/relationships/parse.spec.d.ts +1 -0
- package/dist/lib/utils/relationships/parse.spec.js +229 -0
- package/dist/test-nested-relationships.d.ts +1 -0
- package/dist/test-nested-relationships.js +112 -0
- package/dist/tests/templates/entities/types/json-template.spec.js +2 -2
- package/dist/tests/utils/relationship-deduplication.spec.d.ts +1 -0
- package/dist/tests/utils/relationship-deduplication.spec.js +98 -0
- package/oclif.manifest.json +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const globals_1 = require("@jest/globals");
|
|
4
|
+
const parse_1 = require("./parse");
|
|
5
|
+
(0, globals_1.describe)('parseRelationships', () => {
|
|
6
|
+
// Mock console.warn to prevent test output clutter
|
|
7
|
+
(0, globals_1.beforeEach)(() => {
|
|
8
|
+
globals_1.jest.spyOn(console, 'warn').mockImplementation(() => { });
|
|
9
|
+
});
|
|
10
|
+
(0, globals_1.afterEach)(() => {
|
|
11
|
+
globals_1.jest.restoreAllMocks();
|
|
12
|
+
});
|
|
13
|
+
(0, globals_1.describe)('ManyToMany Relationships', () => {
|
|
14
|
+
(0, globals_1.it)('should parse a single bidirectional ManyToMany definition', () => {
|
|
15
|
+
const relationships = [
|
|
16
|
+
{
|
|
17
|
+
from: 'EntityA',
|
|
18
|
+
to: 'EntityB',
|
|
19
|
+
type: 'ManyToMany',
|
|
20
|
+
// eslint-disable-next-line camelcase
|
|
21
|
+
bi_directional: true,
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
const expected = {
|
|
25
|
+
EntityA: [
|
|
26
|
+
{
|
|
27
|
+
name: 'EntityB',
|
|
28
|
+
type: 'ManyToMany',
|
|
29
|
+
referenceName: 'EntityB',
|
|
30
|
+
join: true,
|
|
31
|
+
biDirectional: true,
|
|
32
|
+
joinTableName: undefined,
|
|
33
|
+
joinColumnName: undefined,
|
|
34
|
+
inverseJoinColumnName: undefined,
|
|
35
|
+
inverseReferenceName: 'EntityA', // PascalCase entity name
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
EntityB: [
|
|
39
|
+
{
|
|
40
|
+
name: 'EntityA',
|
|
41
|
+
type: 'ManyToMany',
|
|
42
|
+
referenceName: 'EntityA',
|
|
43
|
+
join: false,
|
|
44
|
+
biDirectional: true,
|
|
45
|
+
joinTableName: undefined,
|
|
46
|
+
joinColumnName: undefined,
|
|
47
|
+
inverseJoinColumnName: undefined,
|
|
48
|
+
inverseReferenceName: 'EntityB', // PascalCase entity name
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
const result = (0, parse_1.parseRelationships)(relationships);
|
|
53
|
+
(0, globals_1.expect)(result).toEqual(expected);
|
|
54
|
+
});
|
|
55
|
+
(0, globals_1.it)('should parse a single bidirectional ManyToMany with to_name', () => {
|
|
56
|
+
const relationships = [
|
|
57
|
+
{
|
|
58
|
+
from: 'User',
|
|
59
|
+
to: 'Group',
|
|
60
|
+
type: 'ManyToMany',
|
|
61
|
+
// eslint-disable-next-line camelcase
|
|
62
|
+
bi_directional: true,
|
|
63
|
+
// eslint-disable-next-line camelcase
|
|
64
|
+
to_name: 'userGroups',
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
const expected = {
|
|
68
|
+
User: [
|
|
69
|
+
{
|
|
70
|
+
name: 'Group',
|
|
71
|
+
type: 'ManyToMany',
|
|
72
|
+
referenceName: 'userGroups',
|
|
73
|
+
join: true,
|
|
74
|
+
biDirectional: true,
|
|
75
|
+
joinTableName: undefined,
|
|
76
|
+
joinColumnName: undefined,
|
|
77
|
+
inverseJoinColumnName: undefined,
|
|
78
|
+
inverseReferenceName: 'User', // PascalCase entity name
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
Group: [
|
|
82
|
+
{
|
|
83
|
+
name: 'User',
|
|
84
|
+
type: 'ManyToMany',
|
|
85
|
+
referenceName: 'User',
|
|
86
|
+
join: false,
|
|
87
|
+
biDirectional: true,
|
|
88
|
+
joinTableName: undefined,
|
|
89
|
+
joinColumnName: undefined,
|
|
90
|
+
inverseJoinColumnName: undefined,
|
|
91
|
+
inverseReferenceName: 'userGroups', // Preserved camelCase from to_name
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
};
|
|
95
|
+
const result = (0, parse_1.parseRelationships)(relationships);
|
|
96
|
+
(0, globals_1.expect)(result).toEqual(expected);
|
|
97
|
+
});
|
|
98
|
+
(0, globals_1.it)('should parse a unidirectional ManyToMany definition', () => {
|
|
99
|
+
const relationships = [
|
|
100
|
+
{
|
|
101
|
+
from: 'Post',
|
|
102
|
+
to: 'Tag',
|
|
103
|
+
type: 'ManyToMany',
|
|
104
|
+
// bi_directional is false or omitted
|
|
105
|
+
},
|
|
106
|
+
];
|
|
107
|
+
const expected = {
|
|
108
|
+
Post: [
|
|
109
|
+
{
|
|
110
|
+
name: 'Tag',
|
|
111
|
+
type: 'ManyToMany',
|
|
112
|
+
referenceName: 'Tag',
|
|
113
|
+
join: true,
|
|
114
|
+
biDirectional: false,
|
|
115
|
+
joinTableName: undefined,
|
|
116
|
+
joinColumnName: undefined,
|
|
117
|
+
inverseJoinColumnName: undefined,
|
|
118
|
+
inverseReferenceName: undefined, // Correct: No inverse name for unidirectional
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
// No entry expected for Tag
|
|
122
|
+
};
|
|
123
|
+
const result = (0, parse_1.parseRelationships)(relationships);
|
|
124
|
+
(0, globals_1.expect)(result).toEqual(expected);
|
|
125
|
+
});
|
|
126
|
+
(0, globals_1.it)('should handle join table details correctly', () => {
|
|
127
|
+
const relationships = [
|
|
128
|
+
{
|
|
129
|
+
from: 'Student',
|
|
130
|
+
to: 'Course',
|
|
131
|
+
type: 'ManyToMany',
|
|
132
|
+
// eslint-disable-next-line camelcase
|
|
133
|
+
bi_directional: true,
|
|
134
|
+
// UNUSED: eslint-disable-next-line camelcase
|
|
135
|
+
joinTableName: 'enrollments',
|
|
136
|
+
// UNUSED: eslint-disable-next-line camelcase
|
|
137
|
+
joinColumnName: 'student_id',
|
|
138
|
+
// UNUSED: eslint-disable-next-line camelcase
|
|
139
|
+
inverseJoinColumnName: 'course_id',
|
|
140
|
+
},
|
|
141
|
+
];
|
|
142
|
+
const expected = {
|
|
143
|
+
Student: [
|
|
144
|
+
{
|
|
145
|
+
name: 'Course',
|
|
146
|
+
type: 'ManyToMany',
|
|
147
|
+
referenceName: 'Course',
|
|
148
|
+
join: true,
|
|
149
|
+
biDirectional: true,
|
|
150
|
+
joinTableName: 'enrollments',
|
|
151
|
+
joinColumnName: 'student_id',
|
|
152
|
+
inverseJoinColumnName: 'course_id',
|
|
153
|
+
inverseReferenceName: 'Student', // PascalCase entity name
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
Course: [
|
|
157
|
+
{
|
|
158
|
+
name: 'Student',
|
|
159
|
+
type: 'ManyToMany',
|
|
160
|
+
referenceName: 'Student',
|
|
161
|
+
join: false,
|
|
162
|
+
biDirectional: true,
|
|
163
|
+
joinTableName: undefined,
|
|
164
|
+
joinColumnName: undefined,
|
|
165
|
+
inverseJoinColumnName: undefined,
|
|
166
|
+
inverseReferenceName: 'Course', // PascalCase entity name
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
};
|
|
170
|
+
const result = (0, parse_1.parseRelationships)(relationships);
|
|
171
|
+
(0, globals_1.expect)(result).toEqual(expected);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
(0, globals_1.describe)('Mixed Relationship Types', () => {
|
|
175
|
+
(0, globals_1.it)('should correctly parse ManyToMany alongside other types', () => {
|
|
176
|
+
const relationships = [
|
|
177
|
+
{
|
|
178
|
+
from: 'User',
|
|
179
|
+
to: 'Profile',
|
|
180
|
+
type: 'OneToOne',
|
|
181
|
+
// eslint-disable-next-line camelcase
|
|
182
|
+
bi_directional: true,
|
|
183
|
+
// eslint-disable-next-line camelcase
|
|
184
|
+
to_name: 'userProfile'
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
from: 'User',
|
|
188
|
+
to: 'Post',
|
|
189
|
+
type: 'OneToMany',
|
|
190
|
+
// eslint-disable-next-line camelcase
|
|
191
|
+
bi_directional: true // Implies ManyToOne on Post
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
from: 'Role',
|
|
195
|
+
to: 'User',
|
|
196
|
+
type: 'ManyToMany',
|
|
197
|
+
// eslint-disable-next-line camelcase
|
|
198
|
+
bi_directional: true
|
|
199
|
+
}
|
|
200
|
+
];
|
|
201
|
+
const result = (0, parse_1.parseRelationships)(relationships);
|
|
202
|
+
// Check User relationships
|
|
203
|
+
(0, globals_1.expect)(result.User).toHaveLength(3);
|
|
204
|
+
(0, globals_1.expect)(result.User).toContainEqual(globals_1.expect.objectContaining({ name: 'Profile', type: 'OneToOne', referenceName: 'userProfile', biDirectional: true, join: false })); // Expect preserved camelCase
|
|
205
|
+
(0, globals_1.expect)(result.User).toContainEqual(globals_1.expect.objectContaining({ name: 'Post', type: 'OneToMany', referenceName: 'Post', biDirectional: true })); // PascalCase entity name
|
|
206
|
+
(0, globals_1.expect)(result.User).toContainEqual(globals_1.expect.objectContaining({ name: 'Role', type: 'ManyToMany', referenceName: 'Role', biDirectional: true, join: false })); // PascalCase entity name
|
|
207
|
+
// Check Profile relationship
|
|
208
|
+
(0, globals_1.expect)(result.Profile).toHaveLength(1);
|
|
209
|
+
(0, globals_1.expect)(result.Profile).toContainEqual(globals_1.expect.objectContaining({
|
|
210
|
+
name: 'User',
|
|
211
|
+
type: 'OneToOne',
|
|
212
|
+
referenceName: 'User',
|
|
213
|
+
biDirectional: true,
|
|
214
|
+
join: true
|
|
215
|
+
}));
|
|
216
|
+
// Check Post relationship
|
|
217
|
+
(0, globals_1.expect)(result.Post).toHaveLength(1);
|
|
218
|
+
(0, globals_1.expect)(result.Post).toContainEqual(globals_1.expect.objectContaining({
|
|
219
|
+
name: 'User',
|
|
220
|
+
type: 'ManyToOne',
|
|
221
|
+
referenceName: 'User',
|
|
222
|
+
biDirectional: true
|
|
223
|
+
}));
|
|
224
|
+
// Check Role relationship
|
|
225
|
+
(0, globals_1.expect)(result.Role).toHaveLength(1);
|
|
226
|
+
(0, globals_1.expect)(result.Role).toContainEqual(globals_1.expect.objectContaining({ name: 'User', type: 'ManyToMany', referenceName: 'User', biDirectional: true, join: true })); // PascalCase entity name
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const relationships_1 = require("./lib/utils/relationships");
|
|
4
|
+
// Test case based on the diff showing camelCase issues
|
|
5
|
+
const relationshipMap = {
|
|
6
|
+
User: [
|
|
7
|
+
{
|
|
8
|
+
type: "ManyToOne",
|
|
9
|
+
name: "Workspace",
|
|
10
|
+
},
|
|
11
|
+
],
|
|
12
|
+
Workspace: [
|
|
13
|
+
{
|
|
14
|
+
type: "OneToMany",
|
|
15
|
+
name: "User",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
type: "OneToMany",
|
|
19
|
+
name: "WorkspaceUser",
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
WorkspaceUser: [
|
|
23
|
+
{
|
|
24
|
+
type: "ManyToOne",
|
|
25
|
+
name: "Workspace",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: "ManyToOne",
|
|
29
|
+
name: "User",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
type: "OneToMany",
|
|
33
|
+
name: "WorkspaceServiceUser",
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
WorkspaceServiceUser: [
|
|
37
|
+
{
|
|
38
|
+
type: "ManyToOne",
|
|
39
|
+
name: "WorkspaceUser",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
type: "ManyToOne",
|
|
43
|
+
name: "WorkspaceService",
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
WorkspaceService: [
|
|
47
|
+
{
|
|
48
|
+
type: "OneToMany",
|
|
49
|
+
name: "WorkspaceServiceUser",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
type: "OneToMany",
|
|
53
|
+
name: "WorkspaceServiceApiKey",
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
WorkspaceServiceApiKey: [
|
|
57
|
+
{
|
|
58
|
+
type: "ManyToOne",
|
|
59
|
+
name: "WorkspaceService",
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
};
|
|
63
|
+
// Run the test for User entity
|
|
64
|
+
console.log("Nested relationships for User:");
|
|
65
|
+
const userNestedRelationships = (0, relationships_1.getNestedRelationships)("User", relationshipMap);
|
|
66
|
+
userNestedRelationships.forEach(rel => console.log(` - ${rel}`));
|
|
67
|
+
// Run test for CustomerCard entity (similar to what's shown in the diff)
|
|
68
|
+
// Create a CustomerCard example with the pattern seen in the diff
|
|
69
|
+
const customerCardRelationshipMap = {
|
|
70
|
+
CustomerCard: [
|
|
71
|
+
{
|
|
72
|
+
type: "ManyToOne",
|
|
73
|
+
name: "User",
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
User: [
|
|
77
|
+
{
|
|
78
|
+
type: "OneToMany",
|
|
79
|
+
name: "Workspace",
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
Workspace: [
|
|
83
|
+
{
|
|
84
|
+
type: "OneToMany",
|
|
85
|
+
name: "WorkspaceUser",
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
type: "OneToMany",
|
|
89
|
+
name: "WorkspaceService",
|
|
90
|
+
}
|
|
91
|
+
],
|
|
92
|
+
WorkspaceService: [
|
|
93
|
+
{
|
|
94
|
+
type: "OneToMany",
|
|
95
|
+
name: "WorkspaceServiceApiKey",
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
WorkspaceServiceApiKey: [
|
|
99
|
+
{
|
|
100
|
+
type: "ManyToOne",
|
|
101
|
+
name: "WorkspaceService",
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
};
|
|
105
|
+
console.log("\nNested relationships for CustomerCard:");
|
|
106
|
+
const customerCardNestedRelationships = (0, relationships_1.getNestedRelationships)("CustomerCard", customerCardRelationshipMap);
|
|
107
|
+
customerCardNestedRelationships.forEach(rel => console.log(` - ${rel}`));
|
|
108
|
+
// Expected to see properly camelCased names like:
|
|
109
|
+
// - workspace.workspaceUsers
|
|
110
|
+
// - workspace.workspaceUsers.workspaceServiceUsers
|
|
111
|
+
// - workspace.workspaceUsers.workspaceServiceUsers.workspaceService
|
|
112
|
+
// - workspace.workspaceUsers.workspaceServiceUsers.workspaceService.workspaceServiceApiKeys
|
|
@@ -17,7 +17,7 @@ const globals_1 = require("@jest/globals");
|
|
|
17
17
|
nullable: false
|
|
18
18
|
},
|
|
19
19
|
assertions: [
|
|
20
|
-
{ type: 'contains', text: "@Column('
|
|
20
|
+
{ type: 'contains', text: "@Column('jsonb'" },
|
|
21
21
|
{ type: 'contains', text: 'nullable: false' },
|
|
22
22
|
{ type: 'contains', text: 'jsonData: JSON;' }
|
|
23
23
|
]
|
|
@@ -30,7 +30,7 @@ const globals_1 = require("@jest/globals");
|
|
|
30
30
|
nullable: true
|
|
31
31
|
},
|
|
32
32
|
assertions: [
|
|
33
|
-
{ type: 'contains', text: "@Column('
|
|
33
|
+
{ type: 'contains', text: "@Column('jsonb'" },
|
|
34
34
|
{ type: 'contains', text: 'nullable: true' },
|
|
35
35
|
{ type: 'contains', text: 'optionalJsonData: JSON;' }
|
|
36
36
|
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const globals_1 = require("@jest/globals");
|
|
4
|
+
const parse_1 = require("../../lib/utils/relationships/parse");
|
|
5
|
+
(0, globals_1.describe)("getRelationshipForTemplate deduplication", () => {
|
|
6
|
+
(0, globals_1.test)("should deduplicate ManyToMany relationships", () => {
|
|
7
|
+
// Mock entity name
|
|
8
|
+
const entityName = "CustomerCard";
|
|
9
|
+
// Mock relationships - simulating bidirectional ManyToMany where
|
|
10
|
+
// both sides are added to the relationships array for the same entity
|
|
11
|
+
const mockRelationships = [
|
|
12
|
+
// First ManyToMany relationship (non-join side)
|
|
13
|
+
{
|
|
14
|
+
name: "Subscription",
|
|
15
|
+
type: "ManyToMany",
|
|
16
|
+
referenceName: "subscriptions",
|
|
17
|
+
biDirectional: true,
|
|
18
|
+
join: false,
|
|
19
|
+
inverseReferenceName: "customercards"
|
|
20
|
+
},
|
|
21
|
+
// Duplicate relationship (join side) - similar to what happens in bidirectional ManyToMany
|
|
22
|
+
{
|
|
23
|
+
name: "Subscription",
|
|
24
|
+
type: "ManyToMany",
|
|
25
|
+
referenceName: "subscriptions",
|
|
26
|
+
biDirectional: true,
|
|
27
|
+
join: true,
|
|
28
|
+
inverseReferenceName: "customercards"
|
|
29
|
+
}
|
|
30
|
+
];
|
|
31
|
+
// Run the function
|
|
32
|
+
const result = (0, parse_1.getRelationshipForTemplate)(entityName, mockRelationships);
|
|
33
|
+
// Assertions
|
|
34
|
+
// 1. Should only have one relationship
|
|
35
|
+
(0, globals_1.expect)(result.length).toBe(1);
|
|
36
|
+
// 2. The remaining relationship should be the one with join=true
|
|
37
|
+
(0, globals_1.expect)(result[0].name).toBe("Subscription");
|
|
38
|
+
(0, globals_1.expect)(result[0].joinTable).toBe(true);
|
|
39
|
+
});
|
|
40
|
+
(0, globals_1.test)("should keep first relationship when reference names differ", () => {
|
|
41
|
+
// Mock entity name
|
|
42
|
+
const entityName = "User";
|
|
43
|
+
// Create mocked relationships with same target but different reference names
|
|
44
|
+
const mockRelationships = [
|
|
45
|
+
{
|
|
46
|
+
name: "Workspace",
|
|
47
|
+
type: "ManyToMany",
|
|
48
|
+
referenceName: "workspaces",
|
|
49
|
+
biDirectional: true,
|
|
50
|
+
join: true
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "Workspace",
|
|
54
|
+
type: "ManyToMany",
|
|
55
|
+
referenceName: "ownedWorkspaces",
|
|
56
|
+
biDirectional: true,
|
|
57
|
+
join: true
|
|
58
|
+
}
|
|
59
|
+
];
|
|
60
|
+
// Run the function
|
|
61
|
+
const result = (0, parse_1.getRelationshipForTemplate)(entityName, mockRelationships);
|
|
62
|
+
// Assertions
|
|
63
|
+
// New behavior: Both relationships with different referenceName should be kept
|
|
64
|
+
(0, globals_1.expect)(result.length).toBe(2);
|
|
65
|
+
const referenceNames = result.map(r => r.relationshipName || r.referenceName);
|
|
66
|
+
(0, globals_1.expect)(referenceNames).toContain("workspaces");
|
|
67
|
+
(0, globals_1.expect)(referenceNames).toContain("ownedWorkspaces");
|
|
68
|
+
});
|
|
69
|
+
(0, globals_1.test)("should prioritize owner side (join=true) when deduplicating", () => {
|
|
70
|
+
// Scenario based on real issue: two ManyToMany relationships to same entity
|
|
71
|
+
const entityName = "Tag";
|
|
72
|
+
// Create relationships where one has join=true and one has join=false (non-owning side)
|
|
73
|
+
const mockRelationships = [
|
|
74
|
+
{
|
|
75
|
+
name: "WorkspaceService",
|
|
76
|
+
type: "ManyToMany",
|
|
77
|
+
biDirectional: true,
|
|
78
|
+
join: false,
|
|
79
|
+
referenceName: "workspaceservices"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: "WorkspaceService",
|
|
83
|
+
type: "ManyToMany",
|
|
84
|
+
biDirectional: true,
|
|
85
|
+
join: true,
|
|
86
|
+
referenceName: "workspaceservices"
|
|
87
|
+
}
|
|
88
|
+
];
|
|
89
|
+
// Run the function
|
|
90
|
+
const result = (0, parse_1.getRelationshipForTemplate)(entityName, mockRelationships);
|
|
91
|
+
// Assertions
|
|
92
|
+
// Should only have one relationship
|
|
93
|
+
(0, globals_1.expect)(result.length).toBe(1);
|
|
94
|
+
// Should be the one with join=true
|
|
95
|
+
(0, globals_1.expect)(result[0].name).toBe("WorkspaceService");
|
|
96
|
+
(0, globals_1.expect)(result[0].joinTable).toBe(true); // joinTable corresponds to join
|
|
97
|
+
});
|
|
98
|
+
});
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apso/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Apso CLI",
|
|
5
5
|
"author": "Apso by Mavric - @mavric",
|
|
6
6
|
"bin": {
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"ts-jest": "^29.1.0",
|
|
57
57
|
"ts-node": "^10.9.1",
|
|
58
58
|
"tslib": "^2.5.0",
|
|
59
|
+
"typedoc": "^0.28.3",
|
|
59
60
|
"typescript": "^5"
|
|
60
61
|
},
|
|
61
62
|
"oclif": {
|
|
@@ -86,6 +87,7 @@
|
|
|
86
87
|
"test": "jest",
|
|
87
88
|
"test:watch": "jest --watch",
|
|
88
89
|
"test:cov": "jest --coverage",
|
|
90
|
+
"docs:generate": "typedoc src/lib/index.ts --out docs",
|
|
89
91
|
"version": "oclif readme && git add README.md"
|
|
90
92
|
},
|
|
91
93
|
"engines": {
|