fusion-framework 1.2.4 → 1.2.6

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.
Binary file
Binary file
Binary file
Binary file
package/index.js CHANGED
@@ -134,7 +134,7 @@ header.fingerprint = () =>
134
134
  : {
135
135
  'X-Powered-By': 'Fusion Framework',
136
136
  'X-Framework': 'Fusion',
137
- ['X-Fusion-Version']: '1.2.4',
137
+ ['X-Fusion-Version']: '1.2.6',
138
138
  }
139
139
 
140
140
  function isThenable(value) {
@@ -208,6 +208,26 @@ class FusionBaseApi {
208
208
  if (keys.length) out.headers = { ...headers }
209
209
  return out
210
210
  }
211
+
212
+ pagination({
213
+ page,
214
+ pageSize,
215
+ offset,
216
+ defaultPageSize = 20,
217
+ maxPageSize = 100,
218
+ } = {}) {
219
+ const query = { ...(this.query || {}) }
220
+ if (page != null) query.page = String(page)
221
+ if (pageSize != null) query.page_size = String(pageSize)
222
+ if (offset != null) query.offset = String(offset)
223
+ return parsePagination(query, { defaultPageSize, maxPageSize })
224
+ }
225
+
226
+ paginated(items, total, params = null, { page, pageSize, status = 200, headers } = {}) {
227
+ const p = params ?? this.pagination({ page, pageSize })
228
+ const body = paginatedBody(items, total, p)
229
+ return this.response(body, status, headers || {})
230
+ }
211
231
  }
212
232
 
213
233
  function apiResourceName(cls) {
@@ -259,10 +279,13 @@ function resolveHandlerRoute(classBasePath, template, className, methodName) {
259
279
  }
260
280
 
261
281
  function httpRoute(method, route, options = {}) {
282
+ // tags unset → inherit class route tags; tags: [] clears; tags: [...] overrides.
283
+ const tagsSet = Object.prototype.hasOwnProperty.call(options, 'tags')
262
284
  const meta = {
263
285
  method: String(method).toLowerCase(),
264
286
  template: route,
265
- tags: Array.isArray(options.tags) ? options.tags : [],
287
+ tagsSet,
288
+ tags: tagsSet ? (Array.isArray(options.tags) ? options.tags : []) : null,
266
289
  desc: options.desc ?? null,
267
290
  title: options.title ?? null,
268
291
  deprecated: !!options.deprecated,
@@ -274,6 +297,15 @@ function httpRoute(method, route, options = {}) {
274
297
  return wrap
275
298
  }
276
299
 
300
+ function mergeSwagger(methodSwagger, classSwagger) {
301
+ return {
302
+ tags: methodSwagger.tagsSet ? methodSwagger.tags : classSwagger.tags,
303
+ description: methodSwagger.desc ?? classSwagger.description,
304
+ title: methodSwagger.title ?? classSwagger.title,
305
+ deprecated: !!(methodSwagger.deprecated || classSwagger.deprecated),
306
+ }
307
+ }
308
+
277
309
  function httpGet(route, options = {}) {
278
310
  return httpRoute('get', route, options)
279
311
  }
@@ -311,12 +343,7 @@ function collectRouteSlots(ApiClass, classBasePath, classSwagger) {
311
343
  path: resolveHandlerRoute(classBasePath, meta.template, className, key),
312
344
  httpMethod: meta.method,
313
345
  handlerMethod: key,
314
- swagger: {
315
- tags: meta.tags,
316
- description: meta.desc,
317
- title: meta.title,
318
- deprecated: meta.deprecated,
319
- },
346
+ swagger: mergeSwagger(meta, classSwagger),
320
347
  })
321
348
  }
322
349
 
@@ -810,7 +837,12 @@ function swaggerUiHtml(swagger, openapiUrl, primaryName = null) {
810
837
  const showUrlInput = swagger.navbar?.showUrlInput !== false
811
838
  const hideUrlCss =
812
839
  navbarEnabled && !showUrlInput
813
- ? `<style>.topbar form { display: none !important; }</style>`
840
+ ? `<style>
841
+ .swagger-ui .topbar .download-url-wrapper input[type=text],
842
+ .swagger-ui .topbar .download-url-wrapper .download-url-button {
843
+ display: none !important;
844
+ }
845
+ </style>`
814
846
  : ''
815
847
  const standaloneScript = navbarEnabled
816
848
  ? `<script src="https://unpkg.com/swagger-ui-dist/swagger-ui-standalone-preset.js"></script>`
@@ -961,6 +993,18 @@ function pathToFileUrl(filePath) {
961
993
  return require('url').pathToFileURL(resolved).href
962
994
  }
963
995
 
996
+ function parsePagination(query, { defaultPageSize = 20, maxPageSize = 100 } = {}) {
997
+ try {
998
+ return native.parsePagination(query, defaultPageSize, maxPageSize)
999
+ } catch (err) {
1000
+ throw new HTTPException(400, err?.message || 'invalid pagination')
1001
+ }
1002
+ }
1003
+
1004
+ function paginatedBody(items, total, params) {
1005
+ return native.paginatedBody(items, total, params)
1006
+ }
1007
+
964
1008
  const route = router
965
1009
 
966
1010
  module.exports = {
@@ -994,6 +1038,8 @@ module.exports = {
994
1038
  frameworkHeaders,
995
1039
  runMiddlewareChain,
996
1040
  coerceParam,
1041
+ parsePagination,
1042
+ paginatedBody,
997
1043
  getHttpMethods: () => HTTP_METHODS,
998
1044
  apiResourceNameJs: native.apiResourceNameJs,
999
1045
  resolveRoutePathJs: native.resolveRoutePathJs,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fusion-framework",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "description": "Class-based HTTP framework for Node.js, powered by a shared Rust core via N-API",
5
5
  "keywords": [
6
6
  "http",