@terreno/api 0.0.4 → 0.0.11-beta.1
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/CLAUDE.md +107 -0
- package/bunfig.toml +3 -2
- package/dist/api.d.ts +6 -17
- package/dist/api.js +44 -68
- package/dist/api.test.js +2051 -166
- package/dist/expressServer.d.ts +2 -2
- package/dist/openApi.d.ts +7 -7
- package/dist/openApiBuilder.d.ts +3 -3
- package/dist/permissions.d.ts +2 -2
- package/dist/permissions.js +17 -25
- package/dist/transformers.d.ts +4 -4
- package/dist/utils.test.js +169 -7
- package/package.json +3 -2
- package/src/api.test.ts +1736 -142
- package/src/api.ts +22 -64
- package/src/example.ts +2 -2
- package/src/expressServer.ts +2 -2
- package/src/openApi.test.ts +4 -4
- package/src/openApi.ts +7 -7
- package/src/openApiBuilder.test.ts +2 -2
- package/src/openApiBuilder.ts +4 -4
- package/src/permissions.ts +4 -14
- package/src/transformers.ts +4 -4
- package/src/utils.test.ts +189 -9
package/src/utils.test.ts
CHANGED
|
@@ -1,14 +1,194 @@
|
|
|
1
|
-
import {describe, expect, it} from "bun:test";
|
|
1
|
+
import {describe, expect, it, spyOn} from "bun:test";
|
|
2
|
+
import mongoose from "mongoose";
|
|
2
3
|
|
|
3
|
-
import {isValidObjectId} from "./utils";
|
|
4
|
+
import {checkModelsStrict, isValidObjectId} from "./utils";
|
|
4
5
|
|
|
5
6
|
describe("utils", () => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
describe("isValidObjectId", () => {
|
|
8
|
+
it("checks valid ObjectIds", () => {
|
|
9
|
+
expect(isValidObjectId("62c44da0003d9f8ee8cc925c")).toBe(true);
|
|
10
|
+
expect(isValidObjectId("620000000000000000000000")).toBe(true);
|
|
11
|
+
// Mongoose's builtin "ObjectId.isValid" will falsely say this is an ObjectId.
|
|
12
|
+
expect(isValidObjectId("1234567890ab")).toBe(false);
|
|
13
|
+
expect(isValidObjectId("microsoft123")).toBe(false);
|
|
14
|
+
expect(isValidObjectId("62c44da0003d9f8ee8cc925x")).toBe(false);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe("checkModelsStrict", () => {
|
|
19
|
+
it("throws error when toObject.virtuals is not true", () => {
|
|
20
|
+
// Create a schema without toObject.virtuals
|
|
21
|
+
const testSchema = new mongoose.Schema({name: String});
|
|
22
|
+
testSchema.set("strict", "throw");
|
|
23
|
+
// Not setting toObject.virtuals
|
|
24
|
+
|
|
25
|
+
if (mongoose.models.ToObjectTestModel) {
|
|
26
|
+
delete mongoose.models.ToObjectTestModel;
|
|
27
|
+
}
|
|
28
|
+
mongoose.model("ToObjectTestModel", testSchema);
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
// This should throw because ToObjectTestModel doesn't have toObject.virtuals
|
|
32
|
+
expect(() => checkModelsStrict()).toThrow("toObject.virtuals not set to true");
|
|
33
|
+
} finally {
|
|
34
|
+
delete mongoose.models.ToObjectTestModel;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("throws error when toJSON.virtuals is not true", () => {
|
|
39
|
+
// Create a schema with toObject.virtuals but without toJSON.virtuals
|
|
40
|
+
const testSchema = new mongoose.Schema({name: String});
|
|
41
|
+
testSchema.set("toObject", {virtuals: true});
|
|
42
|
+
testSchema.set("strict", "throw");
|
|
43
|
+
// Not setting toJSON.virtuals
|
|
44
|
+
|
|
45
|
+
if (mongoose.models.ToJsonTestModel) {
|
|
46
|
+
delete mongoose.models.ToJsonTestModel;
|
|
47
|
+
}
|
|
48
|
+
mongoose.model("ToJsonTestModel", testSchema);
|
|
49
|
+
|
|
50
|
+
// Use spyOn to intercept modelNames and return only our test model
|
|
51
|
+
const spy = spyOn(mongoose, "modelNames").mockReturnValue(["ToJsonTestModel"]);
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
expect(() => checkModelsStrict()).toThrow("toJSON.virtuals not set to true");
|
|
55
|
+
} finally {
|
|
56
|
+
spy.mockRestore();
|
|
57
|
+
delete mongoose.models.ToJsonTestModel;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("throws error when strict mode is not set to throw", () => {
|
|
62
|
+
// Create a schema with virtuals but without strict mode
|
|
63
|
+
const testSchema = new mongoose.Schema({name: String});
|
|
64
|
+
testSchema.set("toObject", {virtuals: true});
|
|
65
|
+
testSchema.set("toJSON", {virtuals: true});
|
|
66
|
+
// Not setting strict to "throw"
|
|
67
|
+
|
|
68
|
+
if (mongoose.models.StrictTestModel) {
|
|
69
|
+
delete mongoose.models.StrictTestModel;
|
|
70
|
+
}
|
|
71
|
+
mongoose.model("StrictTestModel", testSchema);
|
|
72
|
+
|
|
73
|
+
const spy = spyOn(mongoose, "modelNames").mockReturnValue(["StrictTestModel"]);
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
expect(() => checkModelsStrict()).toThrow("is not set to strict mode");
|
|
77
|
+
} finally {
|
|
78
|
+
spy.mockRestore();
|
|
79
|
+
delete mongoose.models.StrictTestModel;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("passes when all checks pass", () => {
|
|
84
|
+
// Create a properly configured schema
|
|
85
|
+
const testSchema = new mongoose.Schema({name: String});
|
|
86
|
+
testSchema.set("toObject", {virtuals: true});
|
|
87
|
+
testSchema.set("toJSON", {virtuals: true});
|
|
88
|
+
testSchema.set("strict", "throw");
|
|
89
|
+
|
|
90
|
+
if (mongoose.models.GoodTestModel) {
|
|
91
|
+
delete mongoose.models.GoodTestModel;
|
|
92
|
+
}
|
|
93
|
+
mongoose.model("GoodTestModel", testSchema);
|
|
94
|
+
|
|
95
|
+
const spy = spyOn(mongoose, "modelNames").mockReturnValue(["GoodTestModel"]);
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
expect(() => checkModelsStrict()).not.toThrow();
|
|
99
|
+
} finally {
|
|
100
|
+
spy.mockRestore();
|
|
101
|
+
delete mongoose.models.GoodTestModel;
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("skips strict mode check for ignored models", () => {
|
|
106
|
+
// Create a properly configured model
|
|
107
|
+
const goodSchema = new mongoose.Schema({name: String});
|
|
108
|
+
goodSchema.set("toObject", {virtuals: true});
|
|
109
|
+
goodSchema.set("toJSON", {virtuals: true});
|
|
110
|
+
goodSchema.set("strict", "throw");
|
|
111
|
+
|
|
112
|
+
if (mongoose.models.GoodModel) {
|
|
113
|
+
delete mongoose.models.GoodModel;
|
|
114
|
+
}
|
|
115
|
+
mongoose.model("GoodModel", goodSchema);
|
|
116
|
+
|
|
117
|
+
// Create a model without strict mode that we'll ignore
|
|
118
|
+
const badSchema = new mongoose.Schema({name: String});
|
|
119
|
+
badSchema.set("toObject", {virtuals: true});
|
|
120
|
+
badSchema.set("toJSON", {virtuals: true});
|
|
121
|
+
// Not setting strict - should fail unless ignored
|
|
122
|
+
|
|
123
|
+
if (mongoose.models.IgnoredModel) {
|
|
124
|
+
delete mongoose.models.IgnoredModel;
|
|
125
|
+
}
|
|
126
|
+
mongoose.model("IgnoredModel", badSchema);
|
|
127
|
+
|
|
128
|
+
const spy = spyOn(mongoose, "modelNames").mockReturnValue(["GoodModel", "IgnoredModel"]);
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
// Without ignoring, should throw for IgnoredModel
|
|
132
|
+
expect(() => checkModelsStrict()).toThrow("is not set to strict mode");
|
|
133
|
+
|
|
134
|
+
// With ignoring IgnoredModel, should pass
|
|
135
|
+
expect(() => checkModelsStrict(["IgnoredModel"])).not.toThrow();
|
|
136
|
+
} finally {
|
|
137
|
+
spy.mockRestore();
|
|
138
|
+
delete mongoose.models.GoodModel;
|
|
139
|
+
delete mongoose.models.IgnoredModel;
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it("handles multiple models and validates all", () => {
|
|
144
|
+
// Create three properly configured models
|
|
145
|
+
const schema1 = new mongoose.Schema({name: String});
|
|
146
|
+
schema1.set("toObject", {virtuals: true});
|
|
147
|
+
schema1.set("toJSON", {virtuals: true});
|
|
148
|
+
schema1.set("strict", "throw");
|
|
149
|
+
|
|
150
|
+
const schema2 = new mongoose.Schema({value: Number});
|
|
151
|
+
schema2.set("toObject", {virtuals: true});
|
|
152
|
+
schema2.set("toJSON", {virtuals: true});
|
|
153
|
+
schema2.set("strict", "throw");
|
|
154
|
+
|
|
155
|
+
const schema3 = new mongoose.Schema({active: Boolean});
|
|
156
|
+
schema3.set("toObject", {virtuals: true});
|
|
157
|
+
schema3.set("toJSON", {virtuals: true});
|
|
158
|
+
schema3.set("strict", "throw");
|
|
159
|
+
|
|
160
|
+
if (mongoose.models.MultiModel1) delete mongoose.models.MultiModel1;
|
|
161
|
+
if (mongoose.models.MultiModel2) delete mongoose.models.MultiModel2;
|
|
162
|
+
if (mongoose.models.MultiModel3) delete mongoose.models.MultiModel3;
|
|
163
|
+
|
|
164
|
+
mongoose.model("MultiModel1", schema1);
|
|
165
|
+
mongoose.model("MultiModel2", schema2);
|
|
166
|
+
mongoose.model("MultiModel3", schema3);
|
|
167
|
+
|
|
168
|
+
const spy = spyOn(mongoose, "modelNames").mockReturnValue([
|
|
169
|
+
"MultiModel1",
|
|
170
|
+
"MultiModel2",
|
|
171
|
+
"MultiModel3",
|
|
172
|
+
]);
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
expect(() => checkModelsStrict()).not.toThrow();
|
|
176
|
+
} finally {
|
|
177
|
+
spy.mockRestore();
|
|
178
|
+
delete mongoose.models.MultiModel1;
|
|
179
|
+
delete mongoose.models.MultiModel2;
|
|
180
|
+
delete mongoose.models.MultiModel3;
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it("handles empty model list", () => {
|
|
185
|
+
const spy = spyOn(mongoose, "modelNames").mockReturnValue([]);
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
expect(() => checkModelsStrict()).not.toThrow();
|
|
189
|
+
} finally {
|
|
190
|
+
spy.mockRestore();
|
|
191
|
+
}
|
|
192
|
+
});
|
|
13
193
|
});
|
|
14
194
|
});
|