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 +18 -0
- package/dist/adapter/metal-orm/index.d.ts +1 -1
- package/dist/adapter/metal-orm/types.d.ts +23 -0
- package/package.json +3 -1
- package/src/adapter/metal-orm/index.ts +3 -0
- package/src/adapter/metal-orm/types.ts +25 -0
- package/tests/typecheck/query-params.typecheck.ts +42 -0
- package/tsconfig.typecheck.json +8 -0
- package/vitest.config.ts +47 -7
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.
|
|
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;
|
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
|
-
|
|
7
|
-
|
|
8
|
-
poolOptions: {
|
|
9
|
-
forks: {
|
|
10
|
-
singleFork: true
|
|
11
|
-
}
|
|
12
|
-
}
|
|
51
|
+
pool: "threads",
|
|
52
|
+
include: ["src/**/*.test.ts", "tests/**/*.test.ts"]
|
|
13
53
|
}
|
|
14
54
|
});
|