@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,419 @@
1
+ import type { modelRouterOptions } from "./api";
2
+ /**
3
+ * Defines a property within an OpenAPI schema.
4
+ *
5
+ * This type represents the structure of individual properties in request bodies,
6
+ * response objects, and nested schemas. It supports primitive types, arrays,
7
+ * nested objects, and additional properties for map-like structures.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * // Simple string property
12
+ * const nameProperty: OpenApiSchemaProperty = {
13
+ * type: "string",
14
+ * description: "User's full name",
15
+ * };
16
+ *
17
+ * // Array of objects
18
+ * const itemsProperty: OpenApiSchemaProperty = {
19
+ * type: "array",
20
+ * items: {
21
+ * type: "object",
22
+ * properties: {
23
+ * id: {type: "string"},
24
+ * value: {type: "number"},
25
+ * },
26
+ * },
27
+ * };
28
+ *
29
+ * // Object with additional properties (map/dictionary)
30
+ * const metadataProperty: OpenApiSchemaProperty = {
31
+ * type: "object",
32
+ * additionalProperties: {type: "string"},
33
+ * };
34
+ * ```
35
+ */
36
+ export type OpenApiSchemaProperty = {
37
+ /** The JSON Schema type (e.g., "string", "number", "boolean", "object", "array") */
38
+ type: string;
39
+ /** Human-readable description of the property */
40
+ description?: string;
41
+ /** Format hint for the type (e.g., "date-time", "email", "uri", "uuid") */
42
+ format?: string;
43
+ /** Schema for array items when type is "array" */
44
+ items?: OpenApiSchemaProperty;
45
+ /** Nested properties when type is "object" */
46
+ properties?: Record<string, OpenApiSchemaProperty>;
47
+ /** Schema for additional properties or boolean to allow/disallow them */
48
+ additionalProperties?: OpenApiSchemaProperty | boolean;
49
+ /** Whether this property is required in the parent object */
50
+ required?: boolean;
51
+ };
52
+ /**
53
+ * Defines the top-level schema for request bodies and responses.
54
+ *
55
+ * This type represents complete object schemas used in OpenAPI operations,
56
+ * typically for request bodies and response content.
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * const userSchema: OpenApiSchema = {
61
+ * type: "object",
62
+ * properties: {
63
+ * id: {type: "string"},
64
+ * name: {type: "string"},
65
+ * email: {type: "string", format: "email"},
66
+ * },
67
+ * required: ["id", "name"],
68
+ * };
69
+ * ```
70
+ */
71
+ export type OpenApiSchema = {
72
+ /** The JSON Schema type (typically "object" or "array") */
73
+ type: string;
74
+ /** Property definitions for object types */
75
+ properties?: Record<string, OpenApiSchemaProperty>;
76
+ /** List of required property names */
77
+ required?: string[];
78
+ /** Schema for array items when type is "array" */
79
+ items?: OpenApiSchemaProperty;
80
+ /** Schema for additional properties or boolean to allow/disallow them */
81
+ additionalProperties?: OpenApiSchemaProperty | boolean;
82
+ };
83
+ /**
84
+ * Defines a parameter in an OpenAPI operation.
85
+ *
86
+ * Parameters can be passed via query string, path segments, or headers.
87
+ * Path parameters are always required by OpenAPI specification.
88
+ *
89
+ * @example
90
+ * ```typescript
91
+ * // Query parameter
92
+ * const limitParam: OpenApiParameter = {
93
+ * in: "query",
94
+ * name: "limit",
95
+ * required: false,
96
+ * schema: {type: "number"},
97
+ * description: "Maximum number of results",
98
+ * };
99
+ *
100
+ * // Path parameter
101
+ * const idParam: OpenApiParameter = {
102
+ * in: "path",
103
+ * name: "id",
104
+ * required: true,
105
+ * schema: {type: "string"},
106
+ * description: "Resource identifier",
107
+ * };
108
+ * ```
109
+ */
110
+ export type OpenApiParameter = {
111
+ /** Location of the parameter */
112
+ in: "query" | "path" | "header";
113
+ /** Name of the parameter */
114
+ name: string;
115
+ /** Whether the parameter is required (path params are always required) */
116
+ required?: boolean;
117
+ /** Schema defining the parameter's type and format */
118
+ schema: OpenApiSchemaProperty;
119
+ /** Human-readable description of the parameter */
120
+ description?: string;
121
+ };
122
+ /**
123
+ * Defines a response in an OpenAPI operation.
124
+ *
125
+ * Responses include a description and optionally content with a schema
126
+ * for the response body.
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * const successResponse: OpenApiResponse = {
131
+ * description: "Successfully retrieved user",
132
+ * content: {
133
+ * "application/json": {
134
+ * schema: {
135
+ * type: "object",
136
+ * properties: {
137
+ * id: {type: "string"},
138
+ * name: {type: "string"},
139
+ * },
140
+ * },
141
+ * },
142
+ * },
143
+ * };
144
+ * ```
145
+ */
146
+ export type OpenApiResponse = {
147
+ /** Human-readable description of the response */
148
+ description: string;
149
+ /** Content definitions keyed by media type */
150
+ content?: {
151
+ [mediaType: string]: {
152
+ schema: OpenApiSchema;
153
+ };
154
+ };
155
+ };
156
+ /**
157
+ * A fluent builder for constructing OpenAPI middleware.
158
+ *
159
+ * This class provides a chainable API for defining OpenAPI documentation
160
+ * for Express routes. It supports defining tags, summaries, descriptions,
161
+ * request bodies, responses, and parameters.
162
+ *
163
+ * The builder pattern allows for flexible, readable configuration that
164
+ * produces middleware compatible with the express-openapi-validator library.
165
+ *
166
+ * @example
167
+ * ```typescript
168
+ * const middleware = new OpenApiMiddlewareBuilder(options)
169
+ * .withTags(["users"])
170
+ * .withSummary("Create a new user")
171
+ * .withRequestBody<{name: string; email: string}>({
172
+ * name: {type: "string", required: true},
173
+ * email: {type: "string", format: "email", required: true},
174
+ * })
175
+ * .withResponse<{id: string; name: string}>(201, {
176
+ * id: {type: "string"},
177
+ * name: {type: "string"},
178
+ * })
179
+ * .build();
180
+ * ```
181
+ */
182
+ export declare class OpenApiMiddlewareBuilder {
183
+ /** Router options containing OpenAPI configuration */
184
+ private options;
185
+ /** Accumulated OpenAPI configuration from builder methods */
186
+ private config;
187
+ /**
188
+ * Creates a new OpenApiMiddlewareBuilder instance.
189
+ *
190
+ * @param options - Router options containing the OpenAPI path configuration
191
+ */
192
+ constructor(options: Partial<modelRouterOptions<any>>);
193
+ /**
194
+ * Sets the tags for the OpenAPI operation.
195
+ *
196
+ * Tags are used to group operations in the API documentation.
197
+ *
198
+ * @param tags - Array of tag names
199
+ * @returns The builder instance for chaining
200
+ *
201
+ * @example
202
+ * ```typescript
203
+ * builder.withTags(["users", "authentication"]);
204
+ * ```
205
+ */
206
+ withTags(tags: string[]): this;
207
+ /**
208
+ * Sets the summary for the OpenAPI operation.
209
+ *
210
+ * The summary is a brief description shown in API documentation listings.
211
+ *
212
+ * @param summary - Short description of the operation
213
+ * @returns The builder instance for chaining
214
+ *
215
+ * @example
216
+ * ```typescript
217
+ * builder.withSummary("Get user by ID");
218
+ * ```
219
+ */
220
+ withSummary(summary: string): this;
221
+ /**
222
+ * Sets the description for the OpenAPI operation.
223
+ *
224
+ * The description provides detailed information about the operation,
225
+ * including usage notes, examples, and caveats.
226
+ *
227
+ * @param description - Detailed description of the operation
228
+ * @returns The builder instance for chaining
229
+ *
230
+ * @example
231
+ * ```typescript
232
+ * builder.withDescription("Retrieves a user by their unique identifier. Returns 404 if not found.");
233
+ * ```
234
+ */
235
+ withDescription(description: string): this;
236
+ /**
237
+ * Sets the request body schema for the OpenAPI operation.
238
+ *
239
+ * Properties marked with `required: true` will be added to the schema's
240
+ * required array automatically.
241
+ *
242
+ * @typeParam T - Type representing the request body structure
243
+ * @param schema - Object mapping property names to their OpenAPI schema definitions
244
+ * @param options - Optional configuration for the request body
245
+ * @param options.required - Whether the request body itself is required (default: true)
246
+ * @param options.mediaType - Media type for the request body (default: "application/json")
247
+ * @returns The builder instance for chaining
248
+ *
249
+ * @example
250
+ * ```typescript
251
+ * builder.withRequestBody<{name: string; age: number}>({
252
+ * name: {type: "string", description: "User name", required: true},
253
+ * age: {type: "number", description: "User age"},
254
+ * });
255
+ * ```
256
+ */
257
+ withRequestBody<T extends Record<string, any>>(schema: {
258
+ [K in keyof T]: OpenApiSchemaProperty;
259
+ }, options?: {
260
+ required?: boolean;
261
+ mediaType?: string;
262
+ }): this;
263
+ /**
264
+ * Adds a response definition to the OpenAPI operation.
265
+ *
266
+ * Can accept either an object schema or a simple string description
267
+ * for responses without a body (e.g., 204 No Content).
268
+ *
269
+ * @typeParam T - Type representing the response body structure
270
+ * @param statusCode - HTTP status code for this response
271
+ * @param schema - Either an object schema or a description string
272
+ * @param options - Optional configuration for the response
273
+ * @param options.description - Description of the response (default: "Success")
274
+ * @param options.mediaType - Media type for the response (default: "application/json")
275
+ * @returns The builder instance for chaining
276
+ *
277
+ * @example
278
+ * ```typescript
279
+ * // Response with body
280
+ * builder.withResponse<{id: string}>(200, {
281
+ * id: {type: "string", description: "Created resource ID"},
282
+ * }, {description: "Resource created successfully"});
283
+ *
284
+ * // Response without body
285
+ * builder.withResponse(204, "No content");
286
+ * ```
287
+ */
288
+ withResponse<T extends Record<string, any>>(statusCode: number, schema: {
289
+ [K in keyof T]: OpenApiSchemaProperty;
290
+ } | string, options?: {
291
+ description?: string;
292
+ mediaType?: string;
293
+ }): this;
294
+ /**
295
+ * Adds an array response definition to the OpenAPI operation.
296
+ *
297
+ * Use this method when the response is an array of objects rather
298
+ * than a single object.
299
+ *
300
+ * @typeParam T - Type representing the structure of each array item
301
+ * @param statusCode - HTTP status code for this response
302
+ * @param itemSchema - Schema for each item in the response array
303
+ * @param options - Optional configuration for the response
304
+ * @param options.description - Description of the response (default: "Success")
305
+ * @param options.mediaType - Media type for the response (default: "application/json")
306
+ * @returns The builder instance for chaining
307
+ *
308
+ * @example
309
+ * ```typescript
310
+ * builder.withArrayResponse<{id: string; name: string}>(200, {
311
+ * id: {type: "string"},
312
+ * name: {type: "string"},
313
+ * }, {description: "List of users"});
314
+ * ```
315
+ */
316
+ withArrayResponse<T extends Record<string, any>>(statusCode: number, itemSchema: {
317
+ [K in keyof T]: OpenApiSchemaProperty;
318
+ }, options?: {
319
+ description?: string;
320
+ mediaType?: string;
321
+ }): this;
322
+ /**
323
+ * Adds a query parameter to the OpenAPI operation.
324
+ *
325
+ * Query parameters are passed in the URL query string (e.g., `?limit=10`).
326
+ *
327
+ * @param name - Name of the query parameter
328
+ * @param schema - Schema defining the parameter's type and format
329
+ * @param options - Optional configuration for the parameter
330
+ * @param options.required - Whether the parameter is required (default: false)
331
+ * @param options.description - Human-readable description of the parameter
332
+ * @returns The builder instance for chaining
333
+ *
334
+ * @example
335
+ * ```typescript
336
+ * builder.withQueryParameter("limit", {type: "number"}, {
337
+ * required: false,
338
+ * description: "Maximum number of results to return",
339
+ * });
340
+ * ```
341
+ */
342
+ withQueryParameter(name: string, schema: OpenApiSchemaProperty, options?: {
343
+ required?: boolean;
344
+ description?: string;
345
+ }): this;
346
+ /**
347
+ * Adds a path parameter to the OpenAPI operation.
348
+ *
349
+ * Path parameters are embedded in the URL path (e.g., `/users/:id`).
350
+ * Path parameters are always required per OpenAPI specification.
351
+ *
352
+ * @param name - Name of the path parameter (must match the route parameter)
353
+ * @param schema - Schema defining the parameter's type and format
354
+ * @param options - Optional configuration for the parameter
355
+ * @param options.description - Human-readable description of the parameter
356
+ * @returns The builder instance for chaining
357
+ *
358
+ * @example
359
+ * ```typescript
360
+ * builder.withPathParameter("id", {type: "string", format: "uuid"}, {
361
+ * description: "Unique identifier of the user",
362
+ * });
363
+ * ```
364
+ */
365
+ withPathParameter(name: string, schema: OpenApiSchemaProperty, options?: {
366
+ description?: string;
367
+ }): this;
368
+ /**
369
+ * Builds and returns the OpenAPI middleware.
370
+ *
371
+ * This method finalizes the configuration and returns Express middleware
372
+ * that integrates with the OpenAPI documentation system. If no OpenAPI
373
+ * path is configured in options, returns a no-op middleware.
374
+ *
375
+ * Default error responses (400, 401, 403, 404, 405) are automatically
376
+ * merged with the configured responses.
377
+ *
378
+ * @returns Express middleware function for OpenAPI documentation
379
+ *
380
+ * @example
381
+ * ```typescript
382
+ * const middleware = builder
383
+ * .withTags(["users"])
384
+ * .withResponse(200, {id: {type: "string"}})
385
+ * .build();
386
+ *
387
+ * router.get("/users/:id", middleware, getUserHandler);
388
+ * ```
389
+ */
390
+ build(): any;
391
+ }
392
+ /**
393
+ * Creates a new OpenAPI middleware builder.
394
+ *
395
+ * This is the recommended entry point for creating custom OpenAPI middleware.
396
+ * It returns a fluent builder that allows you to chain configuration methods.
397
+ *
398
+ * @param options - Router options containing the OpenAPI configuration
399
+ * @returns A new OpenApiMiddlewareBuilder instance
400
+ *
401
+ * @example
402
+ * ```typescript
403
+ * import {createOpenApiBuilder} from "./openApiBuilder";
404
+ *
405
+ * const statsMiddleware = createOpenApiBuilder(options)
406
+ * .withTags(["analytics"])
407
+ * .withSummary("Get usage statistics")
408
+ * .withQueryParameter("startDate", {type: "string", format: "date"})
409
+ * .withQueryParameter("endDate", {type: "string", format: "date"})
410
+ * .withResponse<{totalUsers: number; activeUsers: number}>(200, {
411
+ * totalUsers: {type: "number", description: "Total registered users"},
412
+ * activeUsers: {type: "number", description: "Users active in period"},
413
+ * })
414
+ * .build();
415
+ *
416
+ * router.get("/analytics/stats", statsMiddleware, getStatsHandler);
417
+ * ```
418
+ */
419
+ export declare function createOpenApiBuilder(options: Partial<modelRouterOptions<any>>): OpenApiMiddlewareBuilder;