@jsonapi-serde/server 1.0.0 → 1.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.
@@ -7,15 +7,15 @@ import { type SearchParamsInput } from "../http/index.js";
7
7
  *
8
8
  * Defines which related resources are allowed in an `include` request.
9
9
  */
10
- export type ParseQueryIncludeOptions<TInclude extends string> = {
10
+ export type ParseQueryIncludeOptions<TInclude extends readonly string[] | undefined> = {
11
11
  /**
12
12
  * Allowed include-paths (e.g., "author", "comments.author")
13
13
  *
14
14
  * Allowing "comments" automatically allows "comments.author".
15
15
  */
16
- allowed: TInclude[];
16
+ allowed: TInclude;
17
17
  /** Default include-paths if none are provided in the query */
18
- default?: string[];
18
+ default?: TInclude extends readonly string[] ? ParentPaths<TInclude[number]>[] : undefined;
19
19
  };
20
20
  /**
21
21
  * Represents a sortable field and its sort direction
@@ -38,41 +38,41 @@ export type Sort<TSort extends string> = SortField<TSort>[];
38
38
  /**
39
39
  * Options for the `sort` query parameter
40
40
  */
41
- export type ParseQuerySortOptions<TFields extends string> = {
41
+ export type ParseQuerySortOptions<TFields extends readonly string[] | undefined> = {
42
42
  /** List of field names that are allowed to be sorted */
43
- allowed: TFields[];
43
+ allowed: TFields;
44
44
  /** Default sorting order, if none is provided in the query */
45
- default?: SortField<TFields>[];
45
+ default?: TFields extends readonly string[] ? Sort<TFields[number]> : undefined;
46
46
  /** Whether multiple sort fields are allowed (comma-separated) */
47
47
  multiple?: boolean;
48
48
  };
49
- export type SparseFieldSets = Record<string, string[]>;
49
+ export type SparseFieldSets = Record<string, readonly string[]>;
50
50
  export type PartialSparseFieldSets<TFieldSets extends SparseFieldSets> = {
51
- [K in keyof TFieldSets]?: Partial<TFieldSets[K]>;
51
+ [K in keyof TFieldSets]?: TFieldSets[K][number][];
52
52
  };
53
53
  /**
54
54
  * Options for the `fields` (sparse fieldsets) query parameter
55
55
  *
56
56
  * Allows specifying which fields are allowed per resource type.
57
57
  */
58
- export type ParseQuerySparseFieldsetOptions<TAllowed extends Record<string, string[]>> = {
58
+ export type ParseQuerySparseFieldsetOptions<TAllowed extends SparseFieldSets | undefined> = {
59
59
  /** Allowed field names per resource type (e.g., { articles: ["title", "body"] }) */
60
60
  allowed: TAllowed;
61
61
  /** Default fieldsets to apply when the query omits some or all `fields` */
62
- default?: PartialSparseFieldSets<TAllowed>;
62
+ default?: TAllowed extends SparseFieldSets ? PartialSparseFieldSets<TAllowed> : undefined;
63
63
  };
64
64
  /**
65
65
  * Configuration object for creating a JSON:API query parser
66
66
  *
67
67
  * Omitting a property will disallow it in the query parameters.
68
68
  */
69
- export type ParseQueryOptions<TInclude extends string | undefined, TSortFields extends string | undefined, TSparseFieldSets extends SparseFieldSets | undefined, TFilterSchema extends $ZodType | undefined, TPageSchema extends $ZodType | undefined> = {
69
+ export type ParseQueryOptions<TInclude extends readonly string[] | undefined, TSortFields extends readonly string[] | undefined, TSparseFieldSets extends SparseFieldSets | undefined, TFilterSchema extends $ZodType | undefined, TPageSchema extends $ZodType | undefined> = {
70
70
  /** Configuration for `include` query param */
71
- include?: TInclude extends string ? ParseQueryIncludeOptions<TInclude> : undefined;
71
+ include?: ParseQueryIncludeOptions<TInclude>;
72
72
  /** Configuration for `sort` query param */
73
- sort?: TSortFields extends string ? ParseQuerySortOptions<TSortFields> : undefined;
73
+ sort?: ParseQuerySortOptions<TSortFields>;
74
74
  /** Configuration for `fields` query param */
75
- fields?: TSparseFieldSets extends SparseFieldSets ? ParseQuerySparseFieldsetOptions<TSparseFieldSets> : undefined;
75
+ fields?: ParseQuerySparseFieldsetOptions<TSparseFieldSets>;
76
76
  /** Zod schema for validating and parsing the `filter` query param */
77
77
  filter?: TFilterSchema;
78
78
  /** Zod schema for validating and parsing the `page` query param */
@@ -81,17 +81,17 @@ export type ParseQueryOptions<TInclude extends string | undefined, TSortFields e
81
81
  /**
82
82
  * Structured result returned by the query parser
83
83
  */
84
- export type ParseQueryResult<TInclude extends string | undefined, TSortFields extends string | undefined, TSparseFieldSets extends SparseFieldSets | undefined, TFilterSchema extends $ZodType | undefined, TPageSchema extends $ZodType | undefined> = {
85
- include: TInclude extends string ? ParentPaths<TInclude>[] : undefined;
86
- sort: TSortFields extends string ? Sort<TSortFields> : undefined;
87
- fields: TSparseFieldSets extends SparseFieldSets ? PartialSparseFieldSets<TSparseFieldSets> : undefined;
84
+ export type ParseQueryResult<TInclude extends readonly string[] | undefined, TSortFields extends readonly string[] | undefined, TSparseFieldSets extends SparseFieldSets | undefined, TFilterSchema extends $ZodType | undefined, TPageSchema extends $ZodType | undefined> = {
85
+ include: undefined extends TInclude ? undefined : TInclude extends readonly string[] ? ParentPaths<TInclude[number]>[] : undefined;
86
+ sort: undefined extends TSortFields ? undefined : TSortFields extends readonly string[] ? Sort<TSortFields[number]> : undefined;
87
+ fields: undefined extends TSparseFieldSets ? undefined : TSparseFieldSets extends SparseFieldSets ? PartialSparseFieldSets<TSparseFieldSets> : undefined;
88
88
  filter: TFilterSchema extends $ZodType ? z.output<TFilterSchema> : undefined;
89
89
  page: TPageSchema extends $ZodType ? z.output<TPageSchema> : undefined;
90
90
  };
91
91
  /**
92
92
  * A query parser that parses a JSON:API-style query string into a strongly typed object.
93
93
  */
94
- export type QueryParser<TInclude extends string | undefined, TSortFields extends string | undefined, TSparseFieldSets extends SparseFieldSets | undefined, TFilterSchema extends $ZodType | undefined, TPageSchema extends $ZodType | undefined> = (searchParams: SearchParamsInput) => ParseQueryResult<TInclude, TSortFields, TSparseFieldSets, TFilterSchema, TPageSchema>;
94
+ export type QueryParser<TInclude extends readonly string[] | undefined, TSortFields extends readonly string[] | undefined, TSparseFieldSets extends SparseFieldSets | undefined, TFilterSchema extends $ZodType | undefined, TPageSchema extends $ZodType | undefined> = (searchParams: SearchParamsInput) => ParseQueryResult<TInclude, TSortFields, TSparseFieldSets, TFilterSchema, TPageSchema>;
95
95
  /**
96
96
  * Creates a query parser for JSON:API-compliant query strings.
97
97
  *
@@ -113,4 +113,4 @@ export type QueryParser<TInclude extends string | undefined, TSortFields extends
113
113
  * const query = parsePostQuery("include=author&sort=-createdAt&fields[articles]=title,body");
114
114
  * ```
115
115
  */
116
- export declare const createQueryParser: <TInclude extends string | undefined, TSortFields extends string | undefined, TSparseFieldSets extends SparseFieldSets | undefined, TFilterSchema extends $ZodType | undefined, TPageSchema extends $ZodType | undefined>(options: ParseQueryOptions<TInclude, TSortFields, TSparseFieldSets, TFilterSchema, TPageSchema>) => QueryParser<NoInfer<TInclude>, NoInfer<TSortFields>, NoInfer<TSparseFieldSets>, NoInfer<TFilterSchema>, NoInfer<TPageSchema>>;
116
+ export declare const createQueryParser: <const TInclude extends readonly string[] | undefined, const TSortFields extends readonly string[] | undefined, const TSparseFieldSets extends SparseFieldSets | undefined, TFilterSchema extends $ZodType | undefined, TPageSchema extends $ZodType | undefined>(options: ParseQueryOptions<TInclude, TSortFields, TSparseFieldSets, TFilterSchema, TPageSchema>) => QueryParser<NoInfer<TInclude>, NoInfer<TSortFields>, NoInfer<TSparseFieldSets>, NoInfer<TFilterSchema>, NoInfer<TPageSchema>>;
@@ -116,13 +116,13 @@ const buildSparseFieldsetSchema = (options) => z.strictObject(Object.fromEntries
116
116
  */
117
117
  export const createQueryParser = (options) => {
118
118
  const schema = z.strictObject({
119
- include: options.include
119
+ include: options.include?.allowed
120
120
  ? buildIncludeSchema(options.include)
121
121
  : z.undefined({ error: "'include' parameter is not supported" }),
122
- sort: options.sort
122
+ sort: options.sort?.allowed
123
123
  ? buildSortSchema(options.sort)
124
124
  : z.undefined({ error: "'sort' parameter is not supported" }),
125
- fields: options.fields
125
+ fields: options.fields?.allowed
126
126
  ? buildSparseFieldsetSchema(options.fields)
127
127
  : z.undefined({ error: "'fields' parameter is not supported" }),
128
128
  filter: options.filter
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsonapi-serde/server",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Framework agnostic JSON:API serialization and deserialization",
5
5
  "type": "module",
6
6
  "author": "Ben Scholzen 'DASPRiD'",
@@ -55,6 +55,7 @@
55
55
  }
56
56
  },
57
57
  "devDependencies": {
58
+ "expect-type": "^1.2.1",
58
59
  "zod": "^3.25.42"
59
60
  },
60
61
  "peerDependencies": {