adorn-api 1.1.12 → 1.1.13

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/README.md CHANGED
@@ -639,6 +639,24 @@ export class UserController {
639
639
 
640
640
  The `listConfig` object contains: `filterMappings`, `sortableColumns`, `defaultSortBy`, `defaultSortDirection`, `defaultPageSize`, `maxPageSize`, `sortByKey`, and `sortDirectionKey`.
641
641
 
642
+ ### Type-Only Query Interfaces
643
+
644
+ For consumer projects that need pure TypeScript interfaces (without creating extra DTO classes), Adorn exports:
645
+ - `PaginationQueryParams`
646
+ - `SortingQueryParams`
647
+ - `PagedQueryParams`
648
+
649
+ ```typescript
650
+ import type { PagedQueryParams } from "adorn-api";
651
+
652
+ interface CaixaEntradaQueryDto extends PagedQueryParams {
653
+ usuarioId?: number;
654
+ lido?: boolean;
655
+ }
656
+ ```
657
+
658
+ `sortDirection` is the official typed sort field (`"asc" | "desc"`). `sortOrder` remains parser compatibility for legacy/external clients.
659
+
642
660
  ### `BaseService.list` Before/After (Boilerplate Reduction)
643
661
 
644
662
  Before:
@@ -11,4 +11,4 @@ export { createMetalDtoOverrides, type CreateMetalDtoOverridesOptions } from "./
11
11
  export { createErrorDtoClass, StandardErrorDto, SimpleErrorDto, BasicErrorDto } from "./error-dtos";
12
12
  export { withSession, parseIdOrThrow, compactUpdates, applyInput, getEntityOrThrow } from "./utils";
13
13
  export { validateEntityMetadata, hasValidEntityMetadata } from "./field-builder";
14
- export type { MetalDtoMode, MetalDtoOptions, MetalDtoTarget, PaginationConfig, PaginationOptions, ParsedPagination, Filter, FilterMapping, FilterFieldMapping, FilterFieldPath, FilterFieldPathArray, FilterFieldInput, RelationQuantifier, ParseFilterOptions, ParseSortOptions, ParsedSort, SortDirection, CrudListSortTerm, RunPagedListOptions, ExecuteCrudListOptions, CrudPagedResponse, ListConfig, PagedQueryDtoOptions, PagedResponseDtoOptions, PagedFilterQueryDtoOptions, FilterFieldDef, MetalCrudQueryFilterDef, MetalCrudSortableColumns, MetalCrudOptionsQueryOptions, MetalCrudQueryOptions, MetalCrudStandardErrorsOptions, MetalCrudDtoOptions, MetalCrudDtoClassOptions, MetalCrudDtoDecorators, MetalCrudDtoClasses, MetalCrudDtoClassNameKey, MetalCrudDtoClassNames, CrudControllerService, CrudControllerServiceInput, CreateCrudControllerOptions, RouteErrorsDecorator, NestedCreateDtoOptions, MetalTreeDtoClassOptions, MetalTreeDtoClasses, MetalTreeDtoClassNames, MetalTreeListEntryOptions, ErrorDtoOptions, CreateSessionFn } from "./types";
14
+ export type { MetalDtoMode, MetalDtoOptions, MetalDtoTarget, PaginationConfig, PaginationOptions, ParsedPagination, PaginationQueryParams, Filter, FilterMapping, FilterFieldMapping, FilterFieldPath, FilterFieldPathArray, FilterFieldInput, RelationQuantifier, ParseFilterOptions, ParseSortOptions, ParsedSort, SortDirection, SortingQueryParams, PagedQueryParams, CrudListSortTerm, RunPagedListOptions, ExecuteCrudListOptions, CrudPagedResponse, ListConfig, PagedQueryDtoOptions, PagedResponseDtoOptions, PagedFilterQueryDtoOptions, FilterFieldDef, MetalCrudQueryFilterDef, MetalCrudSortableColumns, MetalCrudOptionsQueryOptions, MetalCrudQueryOptions, MetalCrudStandardErrorsOptions, MetalCrudDtoOptions, MetalCrudDtoClassOptions, MetalCrudDtoDecorators, MetalCrudDtoClasses, MetalCrudDtoClassNameKey, MetalCrudDtoClassNames, CrudControllerService, CrudControllerServiceInput, CreateCrudControllerOptions, RouteErrorsDecorator, NestedCreateDtoOptions, MetalTreeDtoClassOptions, MetalTreeDtoClasses, MetalTreeDtoClassNames, MetalTreeListEntryOptions, ErrorDtoOptions, CreateSessionFn } from "./types";
@@ -56,6 +56,15 @@ export interface ParsedPagination {
56
56
  /** Page size */
57
57
  pageSize: number;
58
58
  }
59
+ /**
60
+ * Pagination query params for consumer-side TypeScript interfaces.
61
+ */
62
+ export interface PaginationQueryParams {
63
+ /** Page number */
64
+ page?: number;
65
+ /** Page size */
66
+ pageSize?: number;
67
+ }
59
68
  /**
60
69
  * Filter field mapping.
61
70
  */
@@ -108,6 +117,20 @@ export interface ParseFilterOptions<T = Record<string, unknown>> {
108
117
  * Sort direction.
109
118
  */
110
119
  export type SortDirection = "asc" | "desc";
120
+ /**
121
+ * Sorting query params for consumer-side TypeScript interfaces.
122
+ */
123
+ export interface SortingQueryParams {
124
+ /** Requested sort key */
125
+ sortBy?: string;
126
+ /** Sort direction */
127
+ sortDirection?: SortDirection;
128
+ }
129
+ /**
130
+ * Combined pagination + sorting query params.
131
+ */
132
+ export interface PagedQueryParams extends PaginationQueryParams, SortingQueryParams {
133
+ }
111
134
  /**
112
135
  * Sort parsing options.
113
136
  */
package/package.json CHANGED
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "name": "adorn-api",
3
- "version": "1.1.12",
3
+ "version": "1.1.13",
4
4
  "description": "Decorator-first web framework with OpenAPI 3.1 schema generation.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
8
8
  "build": "tsc -p tsconfig.json",
9
+ "pretest": "npm run build",
9
10
  "dev": "tsx examples/basic/index.ts",
10
11
  "test": "vitest run",
11
12
  "test:watch": "vitest",
13
+ "typecheck:tests": "tsc -p tsconfig.typecheck.json --noEmit",
12
14
  "example": "node scripts/run-example.js",
13
15
  "check": "tsc -p tsconfig.json --noEmit && npm test",
14
16
  "lint": "eslint . --ext .ts,.tsx,.js"
@@ -78,6 +78,7 @@ export type {
78
78
  PaginationConfig,
79
79
  PaginationOptions,
80
80
  ParsedPagination,
81
+ PaginationQueryParams,
81
82
  Filter,
82
83
  FilterMapping,
83
84
  FilterFieldMapping,
@@ -89,6 +90,8 @@ export type {
89
90
  ParseSortOptions,
90
91
  ParsedSort,
91
92
  SortDirection,
93
+ SortingQueryParams,
94
+ PagedQueryParams,
92
95
  CrudListSortTerm,
93
96
  RunPagedListOptions,
94
97
  ExecuteCrudListOptions,
@@ -74,6 +74,16 @@ export interface ParsedPagination {
74
74
  pageSize: number;
75
75
  }
76
76
 
77
+ /**
78
+ * Pagination query params for consumer-side TypeScript interfaces.
79
+ */
80
+ export interface PaginationQueryParams {
81
+ /** Page number */
82
+ page?: number;
83
+ /** Page size */
84
+ pageSize?: number;
85
+ }
86
+
77
87
  /**
78
88
  * Filter field mapping.
79
89
  */
@@ -155,6 +165,21 @@ export interface ParseFilterOptions<T = Record<string, unknown>> {
155
165
  */
156
166
  export type SortDirection = "asc" | "desc";
157
167
 
168
+ /**
169
+ * Sorting query params for consumer-side TypeScript interfaces.
170
+ */
171
+ export interface SortingQueryParams {
172
+ /** Requested sort key */
173
+ sortBy?: string;
174
+ /** Sort direction */
175
+ sortDirection?: SortDirection;
176
+ }
177
+
178
+ /**
179
+ * Combined pagination + sorting query params.
180
+ */
181
+ export interface PagedQueryParams extends PaginationQueryParams, SortingQueryParams {}
182
+
158
183
  /**
159
184
  * Sort parsing options.
160
185
  */
@@ -0,0 +1,42 @@
1
+ import type {
2
+ PagedQueryParams,
3
+ PaginationQueryParams,
4
+ SortDirection,
5
+ SortingQueryParams
6
+ } from "../../src/index";
7
+
8
+ type Assert<T extends true> = T;
9
+ type IsEqual<A, B> =
10
+ (<T>() => T extends A ? 1 : 2) extends
11
+ (<T>() => T extends B ? 1 : 2)
12
+ ? true
13
+ : false;
14
+
15
+ type _SortDirectionMatchesPublicType = Assert<
16
+ IsEqual<SortingQueryParams["sortDirection"], SortDirection | undefined>
17
+ >;
18
+
19
+ const paginationOnly: PaginationQueryParams = {
20
+ page: 1,
21
+ pageSize: 25
22
+ };
23
+
24
+ const sortingOnly: SortingQueryParams = {
25
+ sortBy: "createdAt",
26
+ sortDirection: "desc"
27
+ };
28
+
29
+ const pagedWithSorting: PagedQueryParams = {
30
+ page: paginationOnly.page,
31
+ pageSize: paginationOnly.pageSize,
32
+ sortBy: sortingOnly.sortBy,
33
+ sortDirection: "asc"
34
+ };
35
+
36
+ // @ts-expect-error sortDirection accepts only "asc" | "desc"
37
+ const invalidSorting: SortingQueryParams = { sortDirection: "ASC" };
38
+
39
+ void paginationOnly;
40
+ void sortingOnly;
41
+ void pagedWithSorting;
42
+ void invalidSorting;
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "rootDir": ".",
5
+ "noEmit": true
6
+ },
7
+ "include": ["src/**/*.ts", "tests/typecheck/**/*.ts"]
8
+ }
package/vitest.config.ts CHANGED
@@ -1,14 +1,54 @@
1
+ import path from "node:path";
2
+ import fs from "node:fs";
3
+ import * as ts from "typescript";
1
4
  import { defineConfig } from "vitest/config";
2
5
 
6
+ function transpileSourcePlugin() {
7
+ return {
8
+ name: "transpile-source",
9
+ enforce: "pre",
10
+ load(id: string) {
11
+ const cleanId = id.split(/[?#]/)[0];
12
+ const normalizedId = cleanId.split(path.sep).join("/");
13
+ if (
14
+ !normalizedId.includes("/src/") &&
15
+ !normalizedId.includes("/examples/") &&
16
+ !normalizedId.includes("/tests/")
17
+ ) {
18
+ return undefined;
19
+ }
20
+ if (!normalizedId.endsWith(".ts") && !normalizedId.endsWith(".tsx")) {
21
+ return undefined;
22
+ }
23
+
24
+ const code = fs.readFileSync(cleanId, "utf8");
25
+ const result = ts.transpileModule(code, {
26
+ compilerOptions: {
27
+ target: ts.ScriptTarget.ES2022,
28
+ module: ts.ModuleKind.ESNext,
29
+ moduleResolution: ts.ModuleResolutionKind.Node,
30
+ experimentalDecorators: false,
31
+ emitDecoratorMetadata: false,
32
+ useDefineForClassFields: true,
33
+ esModuleInterop: true,
34
+ sourceMap: true
35
+ },
36
+ fileName: cleanId
37
+ });
38
+
39
+ return {
40
+ code: result.outputText,
41
+ map: result.sourceMapText ? JSON.parse(result.sourceMapText) : undefined
42
+ };
43
+ }
44
+ };
45
+ }
46
+
3
47
  export default defineConfig({
48
+ plugins: [transpileSourcePlugin()],
4
49
  test: {
5
50
  environment: "node",
6
- include: ["src/**/*.test.ts", "tests/**/*.test.ts"],
7
- pool: "forks",
8
- poolOptions: {
9
- forks: {
10
- singleFork: true
11
- }
12
- }
51
+ pool: "threads",
52
+ include: ["src/**/*.test.ts", "tests/**/*.test.ts"]
13
53
  }
14
54
  });