@terreno/api 0.13.2 → 0.14.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/__tests__/versionCheckPlugin.test.js +53 -3
- package/dist/api.arrayOperations.test.js +1 -0
- package/dist/api.asyncHandler.test.d.ts +1 -0
- package/dist/api.asyncHandler.test.js +236 -0
- package/dist/api.d.ts +15 -4
- package/dist/api.errors.test.js +1 -0
- package/dist/api.hooks.test.js +1 -0
- package/dist/api.js +153 -104
- package/dist/api.query.test.js +1 -0
- package/dist/api.test.js +174 -0
- package/dist/auth.d.ts +10 -5
- package/dist/auth.js +163 -90
- package/dist/auth.test.js +159 -0
- package/dist/betterAuthApp.test.js +1 -0
- package/dist/betterAuthSetup.d.ts +5 -6
- package/dist/betterAuthSetup.js +17 -14
- package/dist/betterAuthSetup.test.js +1 -0
- package/dist/config.d.ts +48 -0
- package/dist/config.js +248 -0
- package/dist/config.test.d.ts +1 -0
- package/dist/config.test.js +328 -0
- package/dist/configuration.test.js +1 -0
- package/dist/configurationApp.d.ts +1 -1
- package/dist/configurationApp.js +17 -13
- package/dist/configurationPlugin.test.js +1 -0
- package/dist/consentApp.test.js +1 -0
- package/dist/envConfigurationPlugin.d.ts +2 -0
- package/dist/envConfigurationPlugin.js +173 -0
- package/dist/envConfigurationPlugin.test.d.ts +1 -0
- package/dist/envConfigurationPlugin.test.js +322 -0
- package/dist/errors.d.ts +18 -7
- package/dist/errors.js +106 -10
- package/dist/errors.test.js +16 -1
- package/dist/example.js +16 -7
- package/dist/expressServer.d.ts +10 -9
- package/dist/expressServer.js +62 -53
- package/dist/expressServer.test.js +53 -2
- package/dist/githubAuth.d.ts +2 -1
- package/dist/githubAuth.js +41 -26
- package/dist/githubAuth.test.js +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/logger.d.ts +1 -1
- package/dist/logger.js +42 -20
- package/dist/models/versionConfig.d.ts +2 -0
- package/dist/models/versionConfig.js +8 -0
- package/dist/notifiers/googleChatNotifier.js +14 -16
- package/dist/notifiers/googleChatNotifier.test.js +1 -0
- package/dist/notifiers/slackNotifier.js +16 -14
- package/dist/notifiers/slackNotifier.test.js +41 -3
- package/dist/notifiers/zoomNotifier.js +7 -10
- package/dist/notifiers/zoomNotifier.test.js +1 -0
- package/dist/openApi.d.ts +1 -1
- package/dist/openApi.test.js +1 -0
- package/dist/openApiBuilder.d.ts +39 -6
- package/dist/openApiBuilder.js +1 -31
- package/dist/openApiBuilder.test.js +1 -0
- package/dist/openApiValidator.js +1 -0
- package/dist/openApiValidator.test.js +65 -0
- package/dist/permissions.d.ts +4 -4
- package/dist/permissions.js +67 -65
- package/dist/permissions.middleware.test.js +1 -0
- package/dist/permissions.test.js +1 -0
- package/dist/plugins.d.ts +5 -5
- package/dist/plugins.js +18 -9
- package/dist/plugins.test.js +1 -1
- package/dist/populate.d.ts +15 -8
- package/dist/populate.js +23 -24
- package/dist/populate.test.js +1 -0
- package/dist/realtime/changeStreamWatcher.d.ts +73 -0
- package/dist/realtime/changeStreamWatcher.js +720 -0
- package/dist/realtime/index.d.ts +6 -0
- package/dist/realtime/index.js +27 -0
- package/dist/realtime/queryMatcher.d.ts +14 -0
- package/dist/realtime/queryMatcher.js +250 -0
- package/dist/realtime/queryStore.d.ts +37 -0
- package/dist/realtime/queryStore.js +195 -0
- package/dist/realtime/realtime.test.d.ts +10 -0
- package/dist/realtime/realtime.test.js +2158 -0
- package/dist/realtime/realtimeApp.d.ts +93 -0
- package/dist/realtime/realtimeApp.js +560 -0
- package/dist/realtime/registry.d.ts +40 -0
- package/dist/realtime/registry.js +38 -0
- package/dist/realtime/socketUser.d.ts +10 -0
- package/dist/realtime/socketUser.js +17 -0
- package/dist/realtime/types.d.ts +100 -0
- package/dist/realtime/types.js +2 -0
- package/dist/requestContext.d.ts +37 -0
- package/dist/requestContext.js +344 -0
- package/dist/requestContext.test.d.ts +1 -0
- package/dist/requestContext.test.js +241 -0
- package/dist/terrenoApp.d.ts +8 -0
- package/dist/terrenoApp.js +50 -13
- package/dist/terrenoApp.test.js +194 -21
- package/dist/terrenoPlugin.d.ts +11 -0
- package/dist/tests/bunSetup.js +1 -0
- package/dist/tests.js +1 -1
- package/dist/transformers.d.ts +2 -2
- package/dist/transformers.js +5 -3
- package/dist/transformers.test.js +90 -0
- package/dist/types/consentResponse.d.ts +6 -3
- package/dist/versionCheckPlugin.d.ts +2 -0
- package/dist/versionCheckPlugin.js +18 -12
- package/package.json +4 -2
- package/src/__tests__/versionCheckPlugin.test.ts +37 -3
- package/src/api.arrayOperations.test.ts +1 -0
- package/src/api.asyncHandler.test.ts +177 -0
- package/src/api.errors.test.ts +1 -0
- package/src/api.hooks.test.ts +1 -0
- package/src/api.query.test.ts +1 -0
- package/src/api.test.ts +132 -0
- package/src/api.ts +199 -84
- package/src/auth.test.ts +160 -0
- package/src/auth.ts +120 -50
- package/src/betterAuthApp.test.ts +1 -0
- package/src/betterAuthSetup.test.ts +1 -0
- package/src/betterAuthSetup.ts +46 -19
- package/src/config.test.ts +255 -0
- package/src/config.ts +206 -0
- package/src/configuration.test.ts +1 -0
- package/src/configurationApp.ts +59 -24
- package/src/configurationPlugin.test.ts +1 -0
- package/src/consentApp.test.ts +1 -0
- package/src/envConfigurationPlugin.test.ts +143 -0
- package/src/envConfigurationPlugin.ts +100 -0
- package/src/errors.test.ts +19 -1
- package/src/errors.ts +94 -20
- package/src/example.ts +46 -21
- package/src/express.d.ts +18 -1
- package/src/expressServer.test.ts +50 -2
- package/src/expressServer.ts +80 -50
- package/src/githubAuth.test.ts +1 -0
- package/src/githubAuth.ts +59 -38
- package/src/index.ts +4 -0
- package/src/logger.ts +47 -17
- package/src/models/versionConfig.ts +13 -2
- package/src/notifiers/googleChatNotifier.test.ts +1 -0
- package/src/notifiers/googleChatNotifier.ts +7 -9
- package/src/notifiers/slackNotifier.test.ts +29 -3
- package/src/notifiers/slackNotifier.ts +9 -7
- package/src/notifiers/zoomNotifier.test.ts +1 -0
- package/src/notifiers/zoomNotifier.ts +8 -11
- package/src/openApi.test.ts +1 -0
- package/src/openApi.ts +4 -4
- package/src/openApiBuilder.test.ts +1 -0
- package/src/openApiBuilder.ts +14 -11
- package/src/openApiValidator.test.ts +59 -0
- package/src/openApiValidator.ts +3 -2
- package/src/permissions.middleware.test.ts +1 -0
- package/src/permissions.test.ts +1 -0
- package/src/permissions.ts +30 -25
- package/src/plugins.test.ts +1 -1
- package/src/plugins.ts +21 -14
- package/src/populate.test.ts +1 -0
- package/src/populate.ts +44 -36
- package/src/realtime/changeStreamWatcher.ts +568 -0
- package/src/realtime/index.ts +34 -0
- package/src/realtime/queryMatcher.ts +179 -0
- package/src/realtime/queryStore.ts +132 -0
- package/src/realtime/realtime.test.ts +1755 -0
- package/src/realtime/realtimeApp.ts +478 -0
- package/src/realtime/registry.ts +64 -0
- package/src/realtime/socketUser.ts +25 -0
- package/src/realtime/types.ts +112 -0
- package/src/requestContext.test.ts +196 -0
- package/src/requestContext.ts +368 -0
- package/src/terrenoApp.test.ts +137 -11
- package/src/terrenoApp.ts +64 -17
- package/src/terrenoPlugin.ts +12 -0
- package/src/tests/bunSetup.ts +1 -0
- package/src/tests.ts +7 -2
- package/src/transformers.test.ts +70 -2
- package/src/transformers.ts +15 -7
- package/src/types/consentResponse.ts +8 -10
- package/src/versionCheckPlugin.ts +15 -7
package/src/populate.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import isArray from "lodash/isArray";
|
|
2
|
-
import type {Document} from "mongoose";
|
|
2
|
+
import type {Document, Schema} from "mongoose";
|
|
3
3
|
import m2s from "mongoose-to-swagger";
|
|
4
4
|
|
|
5
5
|
import {APIError} from "./errors";
|
|
@@ -8,7 +8,19 @@ const m2sOptions = {
|
|
|
8
8
|
props: ["readOnly", "required", "enum", "default"],
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
interface OpenApiSchemaNode {
|
|
12
|
+
description?: string;
|
|
13
|
+
items?: OpenApiSchemaNode;
|
|
14
|
+
properties?: Record<string, OpenApiSchemaNode>;
|
|
15
|
+
type?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface SchemaPathInfo {
|
|
19
|
+
instance: string;
|
|
20
|
+
schema?: Schema;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface PopulatePath {
|
|
12
24
|
// Mongoose style path population.
|
|
13
25
|
// "ownerId" // populates the User that matches `ownerId`
|
|
14
26
|
// "ownerId.organizationId" Nested. Populates the User that matches `ownerId`, as well as their organization.
|
|
@@ -17,28 +29,25 @@ export type PopulatePath = {
|
|
|
17
29
|
// If not provided and path is provided, will use the path and optionally fields to
|
|
18
30
|
// automatically generate the types. If only generatePathFields is provided, the type will be
|
|
19
31
|
// any.
|
|
20
|
-
openApiComponent?:
|
|
32
|
+
openApiComponent?: string;
|
|
21
33
|
// An array of strings to filter on the populated objects, following Mongoose's select
|
|
22
34
|
// rules. If each field starts a preceding "-", will act as a block list and only remove those
|
|
23
35
|
// fields. If each field does not start with a "-", will act as an allow list and only
|
|
24
36
|
// return those fields.
|
|
25
37
|
fields?: string[];
|
|
26
|
-
}
|
|
38
|
+
}
|
|
27
39
|
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
// If no keys are provided, it returns the original object.
|
|
31
|
-
// The function recursively traverses the object structure to handle nested properties.
|
|
32
|
-
const filterKeys = (obj: Record<string, any>, keysToKeep?: string[]): Record<string, any> => {
|
|
40
|
+
// Keeps only the specified dot-notation keys from an object.
|
|
41
|
+
const filterKeys = (obj: Record<string, unknown>, keysToKeep?: string[]): Record<string, unknown> => {
|
|
33
42
|
if (!keysToKeep) {
|
|
34
43
|
return obj;
|
|
35
44
|
}
|
|
36
45
|
|
|
37
|
-
const result: Record<string,
|
|
46
|
+
const result: Record<string, unknown> = {};
|
|
38
47
|
|
|
39
48
|
const filterNestedKeys = (
|
|
40
|
-
currentObj: Record<string,
|
|
41
|
-
currentResult: Record<string,
|
|
49
|
+
currentObj: Record<string, unknown>,
|
|
50
|
+
currentResult: Record<string, unknown>,
|
|
42
51
|
remainingKeys: string[]
|
|
43
52
|
) => {
|
|
44
53
|
const currentKey = remainingKeys[0];
|
|
@@ -52,7 +61,7 @@ const filterKeys = (obj: Record<string, any>, keysToKeep?: string[]): Record<str
|
|
|
52
61
|
if (!currentResult[firstKey]) {
|
|
53
62
|
currentResult[firstKey] = {};
|
|
54
63
|
}
|
|
55
|
-
filterNestedKeys(currentObj[firstKey], currentResult[firstKey], [
|
|
64
|
+
filterNestedKeys(currentObj[firstKey] as Record<string, unknown>, currentResult[firstKey] as Record<string, unknown>, [
|
|
56
65
|
rest.join("."),
|
|
57
66
|
...remainingKeys.slice(1),
|
|
58
67
|
]);
|
|
@@ -73,7 +82,7 @@ const filterKeys = (obj: Record<string, any>, keysToKeep?: string[]): Record<str
|
|
|
73
82
|
|
|
74
83
|
// Helper function to get the path in the OpenAPI schema, so we can swap out the type for the
|
|
75
84
|
// populated model component or generated type.
|
|
76
|
-
|
|
85
|
+
const getPathInSchema = (schema: OpenApiSchemaNode, path: string): string => {
|
|
77
86
|
const keys = path.split(".");
|
|
78
87
|
let currentSchema = schema;
|
|
79
88
|
let fullPath = "";
|
|
@@ -94,52 +103,50 @@ function getPathInSchema(schema: any, path: string): string {
|
|
|
94
103
|
// If we're at the last key and it's an array, we don't need to add anything
|
|
95
104
|
break;
|
|
96
105
|
} else {
|
|
97
|
-
throw new
|
|
106
|
+
throw new APIError({status: 500, title: `Path ${path} not found in schema at key ${key}`});
|
|
98
107
|
}
|
|
99
108
|
}
|
|
100
109
|
|
|
101
110
|
return fullPath;
|
|
102
|
-
}
|
|
111
|
+
};
|
|
103
112
|
|
|
104
|
-
//
|
|
105
|
-
|
|
106
|
-
// OpenAPI properties so they use an empty schema (accepts any type) instead
|
|
107
|
-
// of the `{type: "object", properties: {}}` that mongoose-to-swagger emits.
|
|
108
|
-
export const fixMixedFields = (schema: any, properties: Record<string, any>): void => {
|
|
113
|
+
// Corrects Mixed-type fields in OpenAPI properties so they accept any value.
|
|
114
|
+
export const fixMixedFields = (schema: Schema | null, properties: Record<string, OpenApiSchemaNode> | Record<string, unknown> | null): void => {
|
|
109
115
|
if (!properties || !schema) {
|
|
110
116
|
return;
|
|
111
117
|
}
|
|
112
118
|
|
|
113
|
-
|
|
114
|
-
|
|
119
|
+
const props = properties as Record<string, OpenApiSchemaNode>;
|
|
120
|
+
for (const key of Object.keys(props)) {
|
|
121
|
+
const schemaPath = schema.path(key) as unknown as SchemaPathInfo | undefined;
|
|
115
122
|
if (!schemaPath) {
|
|
116
123
|
continue;
|
|
117
124
|
}
|
|
118
125
|
|
|
119
126
|
// Direct Mixed field
|
|
120
127
|
if (schemaPath.instance === "Mixed") {
|
|
121
|
-
|
|
128
|
+
props[key] = {description: props[key]?.description};
|
|
122
129
|
continue;
|
|
123
130
|
}
|
|
124
131
|
|
|
125
132
|
// Array of sub-documents — check each sub-field for Mixed
|
|
126
|
-
if (
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
fixMixedFields(schemaPath.schema, properties[key].items.properties);
|
|
133
|
+
if (schemaPath.instance === "Array" && schemaPath.schema) {
|
|
134
|
+
const itemProperties = props[key]?.items?.properties;
|
|
135
|
+
if (itemProperties) {
|
|
136
|
+
fixMixedFields(schemaPath.schema, itemProperties);
|
|
137
|
+
}
|
|
132
138
|
}
|
|
133
139
|
}
|
|
134
140
|
};
|
|
135
141
|
|
|
136
|
-
export
|
|
142
|
+
export const getOpenApiSpecForModel = (
|
|
143
|
+
// biome-ignore lint/suspicious/noExplicitAny: noExplicitAny: Mongoose Model param uses deep internal APIs (schema.path().options.ref, schema.virtuals, schema.childSchemas, db.model) that are not exposed in public type definitions
|
|
137
144
|
model: any,
|
|
138
145
|
{
|
|
139
146
|
populatePaths,
|
|
140
147
|
extraModelProperties,
|
|
141
148
|
}: {populatePaths?: PopulatePath[]; extraModelProperties?: Record<string, unknown>} = {}
|
|
142
|
-
): {properties: Record<string, unknown>; required: string[]} {
|
|
149
|
+
): {properties: Record<string, unknown>; required: string[]} => {
|
|
143
150
|
const modelSwagger = m2s(model, {
|
|
144
151
|
props: ["required", "enum"],
|
|
145
152
|
});
|
|
@@ -241,19 +248,20 @@ export function getOpenApiSpecForModel(
|
|
|
241
248
|
properties: {...modelSwagger.properties, ...extraModelProperties},
|
|
242
249
|
required: modelSwagger.required ?? [],
|
|
243
250
|
};
|
|
244
|
-
}
|
|
251
|
+
};
|
|
245
252
|
|
|
246
253
|
// Helper function to unpopulate a document that has been populated.
|
|
247
254
|
// This is helpful for supporting backwards compatibility. E.g. you use populatePaths
|
|
248
255
|
// to populate a document but if the version header for the request is below the version
|
|
249
256
|
// that the populatePath was added, we remove the population and just return the _id.
|
|
250
|
-
export
|
|
257
|
+
export const unpopulate = <T>(doc: Document<T>, path: string): Document<T> => {
|
|
251
258
|
if (!path) {
|
|
252
259
|
throw new APIError({status: 500, title: "path is required for unpopulate"});
|
|
253
260
|
}
|
|
254
261
|
const pathParts = path.split(".");
|
|
255
262
|
|
|
256
263
|
// Recursive because we need to support nested paths.
|
|
264
|
+
// biome-ignore lint/suspicious/noExplicitAny: noExplicitAny: recursive document traversal uses bracket-notation indexing on arbitrary nested document shapes that Mongoose Document types do not expose
|
|
257
265
|
const recursiveUnpopulate = (current: any, parts: string[]): any => {
|
|
258
266
|
const part = parts[0];
|
|
259
267
|
|
|
@@ -266,7 +274,7 @@ export function unpopulate<T>(doc: Document<T>, path: string): Document<T> {
|
|
|
266
274
|
// Base case: we've reached the last part of the path
|
|
267
275
|
if (Array.isArray(current[part])) {
|
|
268
276
|
// If the field is an array, recursively unpopulate each element
|
|
269
|
-
current[part] = current[part].map((item
|
|
277
|
+
current[part] = current[part].map((item) => {
|
|
270
278
|
return item?._id ? item._id : item;
|
|
271
279
|
});
|
|
272
280
|
} else if (current[part]?._id) {
|
|
@@ -288,4 +296,4 @@ export function unpopulate<T>(doc: Document<T>, path: string): Document<T> {
|
|
|
288
296
|
};
|
|
289
297
|
|
|
290
298
|
return recursiveUnpopulate(doc, pathParts);
|
|
291
|
-
}
|
|
299
|
+
};
|