@terreno/api 0.0.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.
Files changed (119) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +170 -0
  3. package/biome.jsonc +22 -0
  4. package/bunfig.toml +4 -0
  5. package/dist/api.d.ts +227 -0
  6. package/dist/api.js +1024 -0
  7. package/dist/api.test.d.ts +1 -0
  8. package/dist/api.test.js +2143 -0
  9. package/dist/auth.d.ts +50 -0
  10. package/dist/auth.js +512 -0
  11. package/dist/auth.test.d.ts +1 -0
  12. package/dist/auth.test.js +778 -0
  13. package/dist/errors.d.ts +75 -0
  14. package/dist/errors.js +216 -0
  15. package/dist/example.d.ts +1 -0
  16. package/dist/example.js +118 -0
  17. package/dist/expressServer.d.ts +35 -0
  18. package/dist/expressServer.js +436 -0
  19. package/dist/index.d.ts +14 -0
  20. package/dist/index.js +30 -0
  21. package/dist/logger.d.ts +23 -0
  22. package/dist/logger.js +249 -0
  23. package/dist/middleware.d.ts +10 -0
  24. package/dist/middleware.js +52 -0
  25. package/dist/notifiers/googleChatNotifier.d.ts +5 -0
  26. package/dist/notifiers/googleChatNotifier.js +130 -0
  27. package/dist/notifiers/googleChatNotifier.test.d.ts +1 -0
  28. package/dist/notifiers/googleChatNotifier.test.js +260 -0
  29. package/dist/notifiers/index.d.ts +3 -0
  30. package/dist/notifiers/index.js +19 -0
  31. package/dist/notifiers/slackNotifier.d.ts +5 -0
  32. package/dist/notifiers/slackNotifier.js +130 -0
  33. package/dist/notifiers/slackNotifier.test.d.ts +1 -0
  34. package/dist/notifiers/slackNotifier.test.js +259 -0
  35. package/dist/notifiers/zoomNotifier.d.ts +34 -0
  36. package/dist/notifiers/zoomNotifier.js +181 -0
  37. package/dist/notifiers/zoomNotifier.test.d.ts +1 -0
  38. package/dist/notifiers/zoomNotifier.test.js +370 -0
  39. package/dist/openApi.d.ts +60 -0
  40. package/dist/openApi.js +441 -0
  41. package/dist/openApi.test.d.ts +1 -0
  42. package/dist/openApi.test.js +445 -0
  43. package/dist/openApiBuilder.d.ts +419 -0
  44. package/dist/openApiBuilder.js +424 -0
  45. package/dist/openApiBuilder.test.d.ts +1 -0
  46. package/dist/openApiBuilder.test.js +509 -0
  47. package/dist/openApiEtag.d.ts +7 -0
  48. package/dist/openApiEtag.js +38 -0
  49. package/dist/permissions.d.ts +26 -0
  50. package/dist/permissions.js +331 -0
  51. package/dist/permissions.test.d.ts +1 -0
  52. package/dist/permissions.test.js +413 -0
  53. package/dist/plugins.d.ts +67 -0
  54. package/dist/plugins.js +315 -0
  55. package/dist/plugins.test.d.ts +1 -0
  56. package/dist/plugins.test.js +639 -0
  57. package/dist/populate.d.ts +14 -0
  58. package/dist/populate.js +315 -0
  59. package/dist/populate.test.d.ts +1 -0
  60. package/dist/populate.test.js +133 -0
  61. package/dist/response.d.ts +0 -0
  62. package/dist/response.js +1 -0
  63. package/dist/tests/bunSetup.d.ts +1 -0
  64. package/dist/tests/bunSetup.js +297 -0
  65. package/dist/tests/index.d.ts +1 -0
  66. package/dist/tests/index.js +17 -0
  67. package/dist/tests.d.ts +99 -0
  68. package/dist/tests.js +273 -0
  69. package/dist/transformers.d.ts +25 -0
  70. package/dist/transformers.js +217 -0
  71. package/dist/transformers.test.d.ts +1 -0
  72. package/dist/transformers.test.js +370 -0
  73. package/dist/utils.d.ts +11 -0
  74. package/dist/utils.js +143 -0
  75. package/dist/utils.test.d.ts +1 -0
  76. package/dist/utils.test.js +14 -0
  77. package/index.ts +1 -0
  78. package/package.json +88 -0
  79. package/src/__snapshots__/openApi.test.ts.snap +4814 -0
  80. package/src/__snapshots__/openApiBuilder.test.ts.snap +1485 -0
  81. package/src/api.test.ts +1661 -0
  82. package/src/api.ts +1036 -0
  83. package/src/auth.test.ts +550 -0
  84. package/src/auth.ts +408 -0
  85. package/src/errors.ts +225 -0
  86. package/src/example.ts +99 -0
  87. package/src/express.d.ts +5 -0
  88. package/src/expressServer.ts +387 -0
  89. package/src/index.ts +14 -0
  90. package/src/logger.ts +190 -0
  91. package/src/middleware.ts +18 -0
  92. package/src/notifiers/googleChatNotifier.test.ts +114 -0
  93. package/src/notifiers/googleChatNotifier.ts +47 -0
  94. package/src/notifiers/index.ts +3 -0
  95. package/src/notifiers/slackNotifier.test.ts +113 -0
  96. package/src/notifiers/slackNotifier.ts +55 -0
  97. package/src/notifiers/zoomNotifier.test.ts +207 -0
  98. package/src/notifiers/zoomNotifier.ts +111 -0
  99. package/src/openApi.test.ts +331 -0
  100. package/src/openApi.ts +494 -0
  101. package/src/openApiBuilder.test.ts +442 -0
  102. package/src/openApiBuilder.ts +636 -0
  103. package/src/openApiEtag.ts +40 -0
  104. package/src/permissions.test.ts +219 -0
  105. package/src/permissions.ts +228 -0
  106. package/src/plugins.test.ts +390 -0
  107. package/src/plugins.ts +289 -0
  108. package/src/populate.test.ts +65 -0
  109. package/src/populate.ts +258 -0
  110. package/src/response.ts +0 -0
  111. package/src/tests/bunSetup.ts +234 -0
  112. package/src/tests/index.ts +1 -0
  113. package/src/tests.ts +218 -0
  114. package/src/transformers.test.ts +202 -0
  115. package/src/transformers.ts +170 -0
  116. package/src/utils.test.ts +14 -0
  117. package/src/utils.ts +47 -0
  118. package/tsconfig.json +60 -0
  119. package/types.d.ts +17 -0
@@ -0,0 +1,424 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __read = (this && this.__read) || function (o, n) {
14
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
15
+ if (!m) return o;
16
+ var i = m.call(o), r, ar = [], e;
17
+ try {
18
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
19
+ }
20
+ catch (error) { e = { error: error }; }
21
+ finally {
22
+ try {
23
+ if (r && !r.done && (m = i["return"])) m.call(i);
24
+ }
25
+ finally { if (e) throw e.error; }
26
+ }
27
+ return ar;
28
+ };
29
+ var __importDefault = (this && this.__importDefault) || function (mod) {
30
+ return (mod && mod.__esModule) ? mod : { "default": mod };
31
+ };
32
+ Object.defineProperty(exports, "__esModule", { value: true });
33
+ exports.OpenApiMiddlewareBuilder = void 0;
34
+ exports.createOpenApiBuilder = createOpenApiBuilder;
35
+ /**
36
+ * OpenAPI Middleware Builder
37
+ *
38
+ * This module provides a fluent builder pattern for constructing OpenAPI middleware
39
+ * for Express routes that don't directly map to Mongoose models. It allows you to
40
+ * define custom API documentation with full control over request/response schemas.
41
+ *
42
+ * @packageDocumentation
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * import {createOpenApiBuilder} from "./openApiBuilder";
47
+ *
48
+ * // Create middleware with custom documentation
49
+ * const middleware = createOpenApiBuilder(options)
50
+ * .withTags(["users"])
51
+ * .withSummary("Get user statistics")
52
+ * .withDescription("Returns aggregated statistics for the current user")
53
+ * .withQueryParameter("period", {type: "string"}, {
54
+ * description: "Time period for statistics",
55
+ * required: false,
56
+ * })
57
+ * .withResponse<{count: number; average: number}>(200, {
58
+ * count: {type: "number", description: "Total count"},
59
+ * average: {type: "number", description: "Average value"},
60
+ * })
61
+ * .build();
62
+ *
63
+ * router.get("/stats", middleware, statsHandler);
64
+ * ```
65
+ */
66
+ var merge_1 = __importDefault(require("lodash/merge"));
67
+ var logger_1 = require("./logger");
68
+ var openApi_1 = require("./openApi");
69
+ /**
70
+ * A fluent builder for constructing OpenAPI middleware.
71
+ *
72
+ * This class provides a chainable API for defining OpenAPI documentation
73
+ * for Express routes. It supports defining tags, summaries, descriptions,
74
+ * request bodies, responses, and parameters.
75
+ *
76
+ * The builder pattern allows for flexible, readable configuration that
77
+ * produces middleware compatible with the express-openapi-validator library.
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * const middleware = new OpenApiMiddlewareBuilder(options)
82
+ * .withTags(["users"])
83
+ * .withSummary("Create a new user")
84
+ * .withRequestBody<{name: string; email: string}>({
85
+ * name: {type: "string", required: true},
86
+ * email: {type: "string", format: "email", required: true},
87
+ * })
88
+ * .withResponse<{id: string; name: string}>(201, {
89
+ * id: {type: "string"},
90
+ * name: {type: "string"},
91
+ * })
92
+ * .build();
93
+ * ```
94
+ */
95
+ var OpenApiMiddlewareBuilder = /** @class */ (function () {
96
+ /**
97
+ * Creates a new OpenApiMiddlewareBuilder instance.
98
+ *
99
+ * @param options - Router options containing the OpenAPI path configuration
100
+ */
101
+ function OpenApiMiddlewareBuilder(options) {
102
+ this.options = options;
103
+ this.config = {
104
+ responses: {},
105
+ };
106
+ }
107
+ /**
108
+ * Sets the tags for the OpenAPI operation.
109
+ *
110
+ * Tags are used to group operations in the API documentation.
111
+ *
112
+ * @param tags - Array of tag names
113
+ * @returns The builder instance for chaining
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * builder.withTags(["users", "authentication"]);
118
+ * ```
119
+ */
120
+ OpenApiMiddlewareBuilder.prototype.withTags = function (tags) {
121
+ this.config.tags = tags;
122
+ return this;
123
+ };
124
+ /**
125
+ * Sets the summary for the OpenAPI operation.
126
+ *
127
+ * The summary is a brief description shown in API documentation listings.
128
+ *
129
+ * @param summary - Short description of the operation
130
+ * @returns The builder instance for chaining
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * builder.withSummary("Get user by ID");
135
+ * ```
136
+ */
137
+ OpenApiMiddlewareBuilder.prototype.withSummary = function (summary) {
138
+ this.config.summary = summary;
139
+ return this;
140
+ };
141
+ /**
142
+ * Sets the description for the OpenAPI operation.
143
+ *
144
+ * The description provides detailed information about the operation,
145
+ * including usage notes, examples, and caveats.
146
+ *
147
+ * @param description - Detailed description of the operation
148
+ * @returns The builder instance for chaining
149
+ *
150
+ * @example
151
+ * ```typescript
152
+ * builder.withDescription("Retrieves a user by their unique identifier. Returns 404 if not found.");
153
+ * ```
154
+ */
155
+ OpenApiMiddlewareBuilder.prototype.withDescription = function (description) {
156
+ this.config.description = description;
157
+ return this;
158
+ };
159
+ /**
160
+ * Sets the request body schema for the OpenAPI operation.
161
+ *
162
+ * Properties marked with `required: true` will be added to the schema's
163
+ * required array automatically.
164
+ *
165
+ * @typeParam T - Type representing the request body structure
166
+ * @param schema - Object mapping property names to their OpenAPI schema definitions
167
+ * @param options - Optional configuration for the request body
168
+ * @param options.required - Whether the request body itself is required (default: true)
169
+ * @param options.mediaType - Media type for the request body (default: "application/json")
170
+ * @returns The builder instance for chaining
171
+ *
172
+ * @example
173
+ * ```typescript
174
+ * builder.withRequestBody<{name: string; age: number}>({
175
+ * name: {type: "string", description: "User name", required: true},
176
+ * age: {type: "number", description: "User age"},
177
+ * });
178
+ * ```
179
+ */
180
+ OpenApiMiddlewareBuilder.prototype.withRequestBody = function (schema, options) {
181
+ var _c;
182
+ var _d, _e;
183
+ var required = Object.entries(schema)
184
+ .filter(function (_c) {
185
+ var _d = __read(_c, 2), _ = _d[0], prop = _d[1];
186
+ return prop.required;
187
+ })
188
+ .map(function (_c) {
189
+ var _d = __read(_c, 2), key = _d[0], _ = _d[1];
190
+ return key;
191
+ });
192
+ this.config.requestBody = {
193
+ content: (_c = {},
194
+ _c[(_d = options === null || options === void 0 ? void 0 : options.mediaType) !== null && _d !== void 0 ? _d : "application/json"] = {
195
+ schema: {
196
+ properties: schema,
197
+ required: required.length > 0 ? required : undefined,
198
+ type: "object",
199
+ },
200
+ },
201
+ _c),
202
+ required: (_e = options === null || options === void 0 ? void 0 : options.required) !== null && _e !== void 0 ? _e : true,
203
+ };
204
+ return this;
205
+ };
206
+ /**
207
+ * Adds a response definition to the OpenAPI operation.
208
+ *
209
+ * Can accept either an object schema or a simple string description
210
+ * for responses without a body (e.g., 204 No Content).
211
+ *
212
+ * @typeParam T - Type representing the response body structure
213
+ * @param statusCode - HTTP status code for this response
214
+ * @param schema - Either an object schema or a description string
215
+ * @param options - Optional configuration for the response
216
+ * @param options.description - Description of the response (default: "Success")
217
+ * @param options.mediaType - Media type for the response (default: "application/json")
218
+ * @returns The builder instance for chaining
219
+ *
220
+ * @example
221
+ * ```typescript
222
+ * // Response with body
223
+ * builder.withResponse<{id: string}>(200, {
224
+ * id: {type: "string", description: "Created resource ID"},
225
+ * }, {description: "Resource created successfully"});
226
+ *
227
+ * // Response without body
228
+ * builder.withResponse(204, "No content");
229
+ * ```
230
+ */
231
+ OpenApiMiddlewareBuilder.prototype.withResponse = function (statusCode, schema, options) {
232
+ var _c;
233
+ var _d, _e;
234
+ if (typeof schema === "string") {
235
+ this.config.responses[statusCode] = {
236
+ description: schema,
237
+ };
238
+ }
239
+ else {
240
+ this.config.responses[statusCode] = {
241
+ content: (_c = {},
242
+ _c[(_d = options === null || options === void 0 ? void 0 : options.mediaType) !== null && _d !== void 0 ? _d : "application/json"] = {
243
+ schema: {
244
+ properties: schema,
245
+ type: "object",
246
+ },
247
+ },
248
+ _c),
249
+ description: (_e = options === null || options === void 0 ? void 0 : options.description) !== null && _e !== void 0 ? _e : "Success",
250
+ };
251
+ }
252
+ return this;
253
+ };
254
+ /**
255
+ * Adds an array response definition to the OpenAPI operation.
256
+ *
257
+ * Use this method when the response is an array of objects rather
258
+ * than a single object.
259
+ *
260
+ * @typeParam T - Type representing the structure of each array item
261
+ * @param statusCode - HTTP status code for this response
262
+ * @param itemSchema - Schema for each item in the response array
263
+ * @param options - Optional configuration for the response
264
+ * @param options.description - Description of the response (default: "Success")
265
+ * @param options.mediaType - Media type for the response (default: "application/json")
266
+ * @returns The builder instance for chaining
267
+ *
268
+ * @example
269
+ * ```typescript
270
+ * builder.withArrayResponse<{id: string; name: string}>(200, {
271
+ * id: {type: "string"},
272
+ * name: {type: "string"},
273
+ * }, {description: "List of users"});
274
+ * ```
275
+ */
276
+ OpenApiMiddlewareBuilder.prototype.withArrayResponse = function (statusCode, itemSchema, options) {
277
+ var _c;
278
+ var _d, _e;
279
+ this.config.responses[statusCode] = {
280
+ content: (_c = {},
281
+ _c[(_d = options === null || options === void 0 ? void 0 : options.mediaType) !== null && _d !== void 0 ? _d : "application/json"] = {
282
+ schema: {
283
+ items: {
284
+ properties: itemSchema,
285
+ type: "object",
286
+ },
287
+ type: "array",
288
+ },
289
+ },
290
+ _c),
291
+ description: (_e = options === null || options === void 0 ? void 0 : options.description) !== null && _e !== void 0 ? _e : "Success",
292
+ };
293
+ return this;
294
+ };
295
+ /**
296
+ * Adds a query parameter to the OpenAPI operation.
297
+ *
298
+ * Query parameters are passed in the URL query string (e.g., `?limit=10`).
299
+ *
300
+ * @param name - Name of the query parameter
301
+ * @param schema - Schema defining the parameter's type and format
302
+ * @param options - Optional configuration for the parameter
303
+ * @param options.required - Whether the parameter is required (default: false)
304
+ * @param options.description - Human-readable description of the parameter
305
+ * @returns The builder instance for chaining
306
+ *
307
+ * @example
308
+ * ```typescript
309
+ * builder.withQueryParameter("limit", {type: "number"}, {
310
+ * required: false,
311
+ * description: "Maximum number of results to return",
312
+ * });
313
+ * ```
314
+ */
315
+ OpenApiMiddlewareBuilder.prototype.withQueryParameter = function (name, schema, options) {
316
+ var _c;
317
+ if (!this.config.parameters) {
318
+ this.config.parameters = [];
319
+ }
320
+ this.config.parameters.push({
321
+ description: options === null || options === void 0 ? void 0 : options.description,
322
+ in: "query",
323
+ name: name,
324
+ required: (_c = options === null || options === void 0 ? void 0 : options.required) !== null && _c !== void 0 ? _c : false,
325
+ schema: schema,
326
+ });
327
+ return this;
328
+ };
329
+ /**
330
+ * Adds a path parameter to the OpenAPI operation.
331
+ *
332
+ * Path parameters are embedded in the URL path (e.g., `/users/:id`).
333
+ * Path parameters are always required per OpenAPI specification.
334
+ *
335
+ * @param name - Name of the path parameter (must match the route parameter)
336
+ * @param schema - Schema defining the parameter's type and format
337
+ * @param options - Optional configuration for the parameter
338
+ * @param options.description - Human-readable description of the parameter
339
+ * @returns The builder instance for chaining
340
+ *
341
+ * @example
342
+ * ```typescript
343
+ * builder.withPathParameter("id", {type: "string", format: "uuid"}, {
344
+ * description: "Unique identifier of the user",
345
+ * });
346
+ * ```
347
+ */
348
+ OpenApiMiddlewareBuilder.prototype.withPathParameter = function (name, schema, options) {
349
+ if (!this.config.parameters) {
350
+ this.config.parameters = [];
351
+ }
352
+ this.config.parameters.push({
353
+ description: options === null || options === void 0 ? void 0 : options.description,
354
+ in: "path",
355
+ name: name,
356
+ required: true,
357
+ schema: schema,
358
+ });
359
+ return this;
360
+ };
361
+ /**
362
+ * Builds and returns the OpenAPI middleware.
363
+ *
364
+ * This method finalizes the configuration and returns Express middleware
365
+ * that integrates with the OpenAPI documentation system. If no OpenAPI
366
+ * path is configured in options, returns a no-op middleware.
367
+ *
368
+ * Default error responses (400, 401, 403, 404, 405) are automatically
369
+ * merged with the configured responses.
370
+ *
371
+ * @returns Express middleware function for OpenAPI documentation
372
+ *
373
+ * @example
374
+ * ```typescript
375
+ * const middleware = builder
376
+ * .withTags(["users"])
377
+ * .withResponse(200, {id: {type: "string"}})
378
+ * .build();
379
+ *
380
+ * router.get("/users/:id", middleware, getUserHandler);
381
+ * ```
382
+ */
383
+ OpenApiMiddlewareBuilder.prototype.build = function () {
384
+ var _c, _d, _e;
385
+ var noop = function (_a, _b, next) { return next(); };
386
+ if (!((_c = this.options.openApi) === null || _c === void 0 ? void 0 : _c.path)) {
387
+ logger_1.logger.debug("No options.openApi provided, skipping OpenApiMiddleware");
388
+ return noop;
389
+ }
390
+ return this.options.openApi.path((0, merge_1.default)(__assign(__assign({}, this.config), { responses: __assign(__assign({}, this.config.responses), openApi_1.defaultOpenApiErrorResponses) }), (_e = (_d = this.options.openApiOverwrite) === null || _d === void 0 ? void 0 : _d.get) !== null && _e !== void 0 ? _e : {}));
391
+ };
392
+ return OpenApiMiddlewareBuilder;
393
+ }());
394
+ exports.OpenApiMiddlewareBuilder = OpenApiMiddlewareBuilder;
395
+ /**
396
+ * Creates a new OpenAPI middleware builder.
397
+ *
398
+ * This is the recommended entry point for creating custom OpenAPI middleware.
399
+ * It returns a fluent builder that allows you to chain configuration methods.
400
+ *
401
+ * @param options - Router options containing the OpenAPI configuration
402
+ * @returns A new OpenApiMiddlewareBuilder instance
403
+ *
404
+ * @example
405
+ * ```typescript
406
+ * import {createOpenApiBuilder} from "./openApiBuilder";
407
+ *
408
+ * const statsMiddleware = createOpenApiBuilder(options)
409
+ * .withTags(["analytics"])
410
+ * .withSummary("Get usage statistics")
411
+ * .withQueryParameter("startDate", {type: "string", format: "date"})
412
+ * .withQueryParameter("endDate", {type: "string", format: "date"})
413
+ * .withResponse<{totalUsers: number; activeUsers: number}>(200, {
414
+ * totalUsers: {type: "number", description: "Total registered users"},
415
+ * activeUsers: {type: "number", description: "Users active in period"},
416
+ * })
417
+ * .build();
418
+ *
419
+ * router.get("/analytics/stats", statsMiddleware, getStatsHandler);
420
+ * ```
421
+ */
422
+ function createOpenApiBuilder(options) {
423
+ return new OpenApiMiddlewareBuilder(options);
424
+ }
@@ -0,0 +1 @@
1
+ export {};