domma-cms 0.33.0 → 0.33.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.
@@ -119,7 +119,7 @@
119
119
  <div class="form-group">
120
120
  <label class="form-label" for="tryit-query">Extra query string (optional)</label>
121
121
  <input type="text" class="form-input" id="tryit-query" placeholder="nation=France&status=published">
122
- <p class="text-muted" style="font-size:.8rem;margin:.25rem 0 0;">Applied as extra filters <em>on top of</em> the definition's own filters (which always win). Only fields this endpoint returns can be filtered; <code>page</code>, <code>limit</code>, <code>sort</code>, <code>order</code>, <code>search</code> are reserved. Operators work too e.g. <code>title_contains=cup</code>.</p>
122
+ <p class="text-muted" style="font-size:.8rem;margin:.25rem 0 0;">Applied as extra filters <em>on top of</em> the definition's own filters (which always win). Only fields this endpoint returns can be filtered; operators work too — e.g. <code>title_contains=cup</code>. <code>page</code>, <code>limit</code>, <code>sort</code> and <code>order</code> control pagination/sort instead (<code>limit</code> is capped at the endpoint's own limit); <code>search</code> is reserved.</p>
123
123
  </div>
124
124
  <button class="btn btn-primary" id="tryit-send" style="width:100%;"><span data-icon="play"></span> Send</button>
125
125
  <div id="tryit-result" style="display:none;margin-top:.75rem;">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-cms",
3
- "version": "0.33.0",
3
+ "version": "0.33.1",
4
4
  "description": "File-based CMS powered by Domma and Fastify. Run npx domma-cms my-site to create a new project.",
5
5
  "type": "module",
6
6
  "main": "server/server.js",
@@ -452,15 +452,35 @@ function collectAdHocFilter(query, exposed, declaredFields) {
452
452
  */
453
453
  export async function executeEndpoint(def, params, query) {
454
454
  const q = query || {};
455
+ const exposed = await exposedFieldSet(def);
455
456
  const declared = substituteFilter(def.filter, params, q);
456
457
  const declaredFields = new Set(Object.keys(def.filter || {}).map(k => parseFilterKey(k).field));
457
- const adhoc = collectAdHocFilter(q, await exposedFieldSet(def), declaredFields);
458
+ const adhoc = collectAdHocFilter(q, exposed, declaredFields);
458
459
  const filter = {...adhoc, ...declared}; // declared wins on any key collision
460
+
461
+ // Envelope controls — the reserved query keys tune pagination and sort
462
+ // rather than filter (list mode only). The definition's own limit is the
463
+ // ceiling: a caller may page/shrink within it but never pull more than the
464
+ // endpoint intends; sort is restricted to exposed fields.
465
+ let page = 1;
466
+ let limit = Number.isInteger(def.limit) ? def.limit : 50;
467
+ let sort = def.sort || 'createdAt';
468
+ let order = ORDERS.includes(def.order) ? def.order : 'desc';
469
+ if (def.mode !== 'single') {
470
+ const cap = limit > 0 ? limit : 500;
471
+ const qLimit = Number.parseInt(q.limit, 10);
472
+ if (Number.isInteger(qLimit) && qLimit >= 1) limit = Math.min(qLimit, cap);
473
+ const qPage = Number.parseInt(q.page, 10);
474
+ if (Number.isInteger(qPage) && qPage >= 1) page = qPage;
475
+ if (q.order === 'asc' || q.order === 'desc') order = q.order;
476
+ if (typeof q.sort === 'string' && q.sort && exposed.has(q.sort.split('.')[0])) sort = q.sort;
477
+ }
478
+
459
479
  const result = await listEntries(def.collection, {
460
- page: 1,
461
- limit: def.mode === 'single' ? 1 : (def.limit ?? 50),
462
- sort: def.sort || 'createdAt',
463
- order: def.order || 'desc',
480
+ page,
481
+ limit: def.mode === 'single' ? 1 : limit,
482
+ sort,
483
+ order,
464
484
  filter: Object.keys(filter).length ? filter : undefined
465
485
  });
466
486
  if (def.mode === 'single') return result.entries[0] || null;