ropegeo-common 1.10.0 → 1.10.2
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 +1 -1
- package/dist/models/api/params/routesParams.d.ts +9 -3
- package/dist/models/api/params/routesParams.d.ts.map +1 -1
- package/dist/models/api/params/routesParams.js +61 -23
- package/dist/models/filters/routeFilter.d.ts +7 -3
- package/dist/models/filters/routeFilter.d.ts.map +1 -1
- package/dist/models/filters/routeFilter.js +56 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,7 +105,7 @@ Helper tables use columns **Name**, **Description**, **Import**. Model tables ad
|
|
|
105
105
|
| `Q_ACA_WATER` | N/A | Query key for ACA water rating list. | `import { Q_ACA_WATER } from 'ropegeo-common/models'` |
|
|
106
106
|
| `Q_ACA_TIME` | N/A | Query key for ACA time rating list. | `import { Q_ACA_TIME } from 'ropegeo-common/models'` |
|
|
107
107
|
| `Q_ACA_RISK` | N/A | Query key for ACA risk rating list. | `import { Q_ACA_RISK } from 'ropegeo-common/models'` |
|
|
108
|
-
| `RoutesParams` | `PaginationParams` | Validated GET /routes params (region, source, route
|
|
108
|
+
| `RoutesParams` | `PaginationParams` | Validated GET /routes params (region, source, optional `route-types` pipe-list, difficulty, `limit`, `page`). | `import { RoutesParams } from 'ropegeo-common/models'` |
|
|
109
109
|
| `SearchParams` | `CursorPaginationParams` | Validated GET /search params including cursor pagination and difficulty. | `import { SearchParams } from 'ropegeo-common/models'` |
|
|
110
110
|
| `SearchOrder` | N/A | Search sort order (`similarity` \| `quality` \| `distance`). | `import type { SearchOrder } from 'ropegeo-common/models'` |
|
|
111
111
|
| `SearchParamsPosition` | N/A | `{ lat, lon }` for distance search. | `import type { SearchParamsPosition } from 'ropegeo-common/models'` |
|
|
@@ -7,6 +7,7 @@ import { DifficultyParams } from './difficultyParams';
|
|
|
7
7
|
* Validated params for getRoutes (GET /routes).
|
|
8
8
|
* Global request: no `region` query param. Region-scoped: `region` id required; optional `source`
|
|
9
9
|
* pipe-list (omit or empty = all sources). `source` must not appear without `region`.
|
|
10
|
+
* Optional `route-types` query param is a pipe-list of {@link RouteType} values (omit or empty = all types).
|
|
10
11
|
* Includes page-based `limit` and `page` (defaults {@link PaginationParams.DEFAULT_LIMIT} / {@link PaginationParams.DEFAULT_PAGE}).
|
|
11
12
|
*/
|
|
12
13
|
export declare class RoutesParams extends PaginationParams {
|
|
@@ -18,14 +19,15 @@ export declare class RoutesParams extends PaginationParams {
|
|
|
18
19
|
id: string;
|
|
19
20
|
source: PageDataSource[] | null;
|
|
20
21
|
} | null;
|
|
21
|
-
|
|
22
|
+
/** Null = no route-type filter; non-empty = allow-list (pipe-encoded in query strings as `route-types`). */
|
|
23
|
+
readonly routeTypes: RouteType[] | null;
|
|
22
24
|
readonly difficulty: DifficultyParams | null;
|
|
23
25
|
constructor(options: {
|
|
24
26
|
region: {
|
|
25
27
|
id: string;
|
|
26
28
|
source: PageDataSource[] | null;
|
|
27
29
|
} | null;
|
|
28
|
-
|
|
30
|
+
routeTypes?: RouteType[] | null;
|
|
29
31
|
difficulty?: DifficultyParams | null;
|
|
30
32
|
limit?: number;
|
|
31
33
|
page?: number;
|
|
@@ -39,6 +41,10 @@ export declare class RoutesParams extends PaginationParams {
|
|
|
39
41
|
private static parsePageQuery;
|
|
40
42
|
private static normalizeDifficulty;
|
|
41
43
|
private static parseRouteType;
|
|
44
|
+
/** Dedupes while preserving first-seen order; `null` / empty → `null`. */
|
|
45
|
+
private static normalizeRouteTypeList;
|
|
46
|
+
/** Pipe-separated tokens, same encoding as {@link RoutesParams.toQueryString}. */
|
|
47
|
+
private static parseRouteTypePipe;
|
|
42
48
|
private static parseSourcePipe;
|
|
43
49
|
private static parseSourceToken;
|
|
44
50
|
/**
|
|
@@ -48,7 +54,7 @@ export declare class RoutesParams extends PaginationParams {
|
|
|
48
54
|
static fromResult(result: unknown, requiredRegion?: boolean): RoutesParams;
|
|
49
55
|
private static paginationFromResult;
|
|
50
56
|
private static optionalPositiveInt;
|
|
51
|
-
private static
|
|
57
|
+
private static optionalRouteTypesFromResult;
|
|
52
58
|
private static optionalDifficultyFromResult;
|
|
53
59
|
private static coerceTrimmedString;
|
|
54
60
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routesParams.d.ts","sourceRoot":"","sources":["../../../../src/models/api/params/routesParams.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,mCAAmC,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAKtD
|
|
1
|
+
{"version":3,"file":"routesParams.d.ts","sourceRoot":"","sources":["../../../../src/models/api/params/routesParams.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,mCAAmC,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAKtD;;;;;;GAMG;AACH,qBAAa,YAAa,SAAQ,gBAAgB;IAC9C;;;OAGG;IACH,SAAgB,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/E,4GAA4G;IAC5G,SAAgB,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAC/C,SAAgB,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;gBAExC,OAAO,EAAE;QACjB,MAAM,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAA;SAAE,GAAG,IAAI,CAAC;QAC/D,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;QAChC,UAAU,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;QACrC,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB;IAkCD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY;IAUpC,kDAAkD;IAClD,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAclC,aAAa,IAAI,MAAM;IAevB,MAAM,CAAC,qBAAqB,CACxB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACtC,YAAY;IA0Cf,OAAO,CAAC,MAAM,CAAC,eAAe;IAiB9B,OAAO,CAAC,MAAM,CAAC,cAAc;IAY7B,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAOlC,OAAO,CAAC,MAAM,CAAC,cAAc;IAQ7B,0EAA0E;IAC1E,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAcrC,kFAAkF;IAClF,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAUjC,OAAO,CAAC,MAAM,CAAC,eAAe;IAS9B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAU/B;;;OAGG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,UAAQ,GAAG,YAAY;IAoFxE,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAkBnC,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAsBlC,OAAO,CAAC,MAAM,CAAC,4BAA4B;IAwB3C,OAAO,CAAC,MAAM,CAAC,4BAA4B;IAkB3C,OAAO,CAAC,MAAM,CAAC,mBAAmB;CAWrC"}
|
|
@@ -12,16 +12,14 @@ const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12
|
|
|
12
12
|
* Validated params for getRoutes (GET /routes).
|
|
13
13
|
* Global request: no `region` query param. Region-scoped: `region` id required; optional `source`
|
|
14
14
|
* pipe-list (omit or empty = all sources). `source` must not appear without `region`.
|
|
15
|
+
* Optional `route-types` query param is a pipe-list of {@link RouteType} values (omit or empty = all types).
|
|
15
16
|
* Includes page-based `limit` and `page` (defaults {@link PaginationParams.DEFAULT_LIMIT} / {@link PaginationParams.DEFAULT_PAGE}).
|
|
16
17
|
*/
|
|
17
18
|
class RoutesParams extends paginationParams_1.PaginationParams {
|
|
18
19
|
constructor(options) {
|
|
19
20
|
const limit = options.limit ?? paginationParams_1.PaginationParams.DEFAULT_LIMIT;
|
|
20
21
|
const page = options.page ?? paginationParams_1.PaginationParams.DEFAULT_PAGE;
|
|
21
|
-
const
|
|
22
|
-
if (routeType !== null && !Object.values(routeType_1.RouteType).includes(routeType)) {
|
|
23
|
-
throw new Error(`Invalid route type: ${JSON.stringify(routeType)}`);
|
|
24
|
-
}
|
|
22
|
+
const routeTypes = RoutesParams.normalizeRouteTypeList(options.routeTypes ?? null);
|
|
25
23
|
const diffRaw = options.difficulty ?? null;
|
|
26
24
|
const diff = diffRaw !== null && diffRaw.isActive() ? diffRaw : null;
|
|
27
25
|
const reg = options.region;
|
|
@@ -42,13 +40,13 @@ class RoutesParams extends paginationParams_1.PaginationParams {
|
|
|
42
40
|
}
|
|
43
41
|
super(limit, page);
|
|
44
42
|
this.region = regionNorm;
|
|
45
|
-
this.
|
|
43
|
+
this.routeTypes = routeTypes;
|
|
46
44
|
this.difficulty = diff;
|
|
47
45
|
}
|
|
48
46
|
withPage(page) {
|
|
49
47
|
return new RoutesParams({
|
|
50
48
|
region: this.region,
|
|
51
|
-
|
|
49
|
+
routeTypes: this.routeTypes,
|
|
52
50
|
difficulty: this.difficulty,
|
|
53
51
|
limit: this.limit,
|
|
54
52
|
page,
|
|
@@ -76,8 +74,8 @@ class RoutesParams extends paginationParams_1.PaginationParams {
|
|
|
76
74
|
p.set('source', this.region.source.join('|'));
|
|
77
75
|
}
|
|
78
76
|
}
|
|
79
|
-
if (this.
|
|
80
|
-
p.set('route-
|
|
77
|
+
if (this.routeTypes != null && this.routeTypes.length > 0) {
|
|
78
|
+
p.set('route-types', this.routeTypes.join('|'));
|
|
81
79
|
}
|
|
82
80
|
difficultyParams_1.DifficultyParams.appendToUrlSearchParams(p, this.difficulty);
|
|
83
81
|
return p.toString();
|
|
@@ -87,10 +85,10 @@ class RoutesParams extends paginationParams_1.PaginationParams {
|
|
|
87
85
|
const page = RoutesParams.parsePageQuery(q);
|
|
88
86
|
const regionRaw = (q.region ?? q.Region ?? '').trim();
|
|
89
87
|
const sourceRaw = (q.source ?? q.Source ?? '').trim();
|
|
90
|
-
const
|
|
91
|
-
const
|
|
88
|
+
const routeTypesStr = (q['route-types'] ?? q['Route-Types'] ?? '').trim();
|
|
89
|
+
const routeTypes = routeTypesStr === ''
|
|
92
90
|
? null
|
|
93
|
-
: RoutesParams.
|
|
91
|
+
: RoutesParams.parseRouteTypePipe(routeTypesStr);
|
|
94
92
|
const difficulty = RoutesParams.normalizeDifficulty(difficultyParams_1.DifficultyParams.fromQueryStringParams(q));
|
|
95
93
|
if (regionRaw === '') {
|
|
96
94
|
if (sourceRaw !== '') {
|
|
@@ -98,7 +96,7 @@ class RoutesParams extends paginationParams_1.PaginationParams {
|
|
|
98
96
|
}
|
|
99
97
|
return new RoutesParams({
|
|
100
98
|
region: null,
|
|
101
|
-
|
|
99
|
+
routeTypes,
|
|
102
100
|
difficulty,
|
|
103
101
|
limit,
|
|
104
102
|
page,
|
|
@@ -109,7 +107,7 @@ class RoutesParams extends paginationParams_1.PaginationParams {
|
|
|
109
107
|
: RoutesParams.parseSourcePipe(sourceRaw);
|
|
110
108
|
return new RoutesParams({
|
|
111
109
|
region: { id: regionRaw, source: sources },
|
|
112
|
-
|
|
110
|
+
routeTypes,
|
|
113
111
|
difficulty,
|
|
114
112
|
limit,
|
|
115
113
|
page,
|
|
@@ -149,7 +147,32 @@ class RoutesParams extends paginationParams_1.PaginationParams {
|
|
|
149
147
|
const exact = Object.values(routeType_1.RouteType).find((v) => v === value);
|
|
150
148
|
if (exact !== undefined)
|
|
151
149
|
return exact;
|
|
152
|
-
throw new Error(`Query parameter "route-
|
|
150
|
+
throw new Error(`Query parameter "route-types" must be one of: ${Object.values(routeType_1.RouteType).join(', ')}`);
|
|
151
|
+
}
|
|
152
|
+
/** Dedupes while preserving first-seen order; `null` / empty → `null`. */
|
|
153
|
+
static normalizeRouteTypeList(list) {
|
|
154
|
+
if (list == null || list.length === 0)
|
|
155
|
+
return null;
|
|
156
|
+
const out = [];
|
|
157
|
+
for (const t of list) {
|
|
158
|
+
if (!Object.values(routeType_1.RouteType).includes(t)) {
|
|
159
|
+
throw new Error(`Invalid route type: ${JSON.stringify(t)}`);
|
|
160
|
+
}
|
|
161
|
+
if (!out.includes(t))
|
|
162
|
+
out.push(t);
|
|
163
|
+
}
|
|
164
|
+
return out;
|
|
165
|
+
}
|
|
166
|
+
/** Pipe-separated tokens, same encoding as {@link RoutesParams.toQueryString}. */
|
|
167
|
+
static parseRouteTypePipe(raw) {
|
|
168
|
+
const parts = raw
|
|
169
|
+
.split('|')
|
|
170
|
+
.map((s) => s.trim())
|
|
171
|
+
.filter((s) => s.length > 0);
|
|
172
|
+
if (parts.length === 0)
|
|
173
|
+
return null;
|
|
174
|
+
const types = parts.map((p) => RoutesParams.parseRouteType(p));
|
|
175
|
+
return RoutesParams.normalizeRouteTypeList(types);
|
|
153
176
|
}
|
|
154
177
|
static parseSourcePipe(raw) {
|
|
155
178
|
const parts = raw
|
|
@@ -186,9 +209,15 @@ class RoutesParams extends paginationParams_1.PaginationParams {
|
|
|
186
209
|
if (requiredRegion) {
|
|
187
210
|
throw new Error('RoutesParams: region must be a non-null { id, source? } object when requiredRegion is true');
|
|
188
211
|
}
|
|
189
|
-
const
|
|
212
|
+
const routeTypes = RoutesParams.optionalRouteTypesFromResult(r);
|
|
190
213
|
const difficulty = RoutesParams.normalizeDifficulty(RoutesParams.optionalDifficultyFromResult(r));
|
|
191
|
-
return new RoutesParams({
|
|
214
|
+
return new RoutesParams({
|
|
215
|
+
region: null,
|
|
216
|
+
routeTypes,
|
|
217
|
+
difficulty,
|
|
218
|
+
limit,
|
|
219
|
+
page,
|
|
220
|
+
});
|
|
192
221
|
}
|
|
193
222
|
if (typeof raw !== 'object') {
|
|
194
223
|
throw new Error('RoutesParams.region must be an object or null, got: ' + typeof raw);
|
|
@@ -222,14 +251,14 @@ class RoutesParams extends paginationParams_1.PaginationParams {
|
|
|
222
251
|
else {
|
|
223
252
|
throw new Error('RoutesParams.region.source must be string, string[], or null');
|
|
224
253
|
}
|
|
225
|
-
const
|
|
254
|
+
const routeTypes = RoutesParams.optionalRouteTypesFromResult(r);
|
|
226
255
|
const difficulty = RoutesParams.normalizeDifficulty(RoutesParams.optionalDifficultyFromResult(r));
|
|
227
256
|
return new RoutesParams({
|
|
228
257
|
region: {
|
|
229
258
|
id: idStr,
|
|
230
259
|
source: RoutesParams.normalizeSourceList(sourceList),
|
|
231
260
|
},
|
|
232
|
-
|
|
261
|
+
routeTypes,
|
|
233
262
|
difficulty,
|
|
234
263
|
limit,
|
|
235
264
|
page,
|
|
@@ -256,14 +285,23 @@ class RoutesParams extends paginationParams_1.PaginationParams {
|
|
|
256
285
|
}
|
|
257
286
|
return v;
|
|
258
287
|
}
|
|
259
|
-
static
|
|
260
|
-
const v = r.
|
|
288
|
+
static optionalRouteTypesFromResult(r) {
|
|
289
|
+
const v = r.routeTypes ?? r['route-types'] ?? r.RouteTypes;
|
|
261
290
|
if (v === null || v === undefined || v === '')
|
|
262
291
|
return null;
|
|
263
|
-
if (typeof v
|
|
264
|
-
|
|
292
|
+
if (typeof v === 'string') {
|
|
293
|
+
return RoutesParams.parseRouteTypePipe(v);
|
|
294
|
+
}
|
|
295
|
+
if (Array.isArray(v)) {
|
|
296
|
+
const types = v.map((item, i) => {
|
|
297
|
+
if (typeof item !== 'string') {
|
|
298
|
+
throw new Error(`RoutesParams.routeTypes[${i}] must be a string`);
|
|
299
|
+
}
|
|
300
|
+
return RoutesParams.parseRouteType(item);
|
|
301
|
+
});
|
|
302
|
+
return RoutesParams.normalizeRouteTypeList(types);
|
|
265
303
|
}
|
|
266
|
-
|
|
304
|
+
throw new Error('RoutesParams.routeTypes must be a string, string[], or null');
|
|
267
305
|
}
|
|
268
306
|
static optionalDifficultyFromResult(r) {
|
|
269
307
|
const nested = r.difficulty ?? r.Difficulty;
|
|
@@ -9,15 +9,19 @@ import { DifficultyFilterOptions } from './difficultyFilterOptions';
|
|
|
9
9
|
export declare class RouteFilter {
|
|
10
10
|
source: PageDataSource[] | null;
|
|
11
11
|
regionId: string | null;
|
|
12
|
-
|
|
12
|
+
/** Null or empty = no route-type filter (all types). */
|
|
13
|
+
routeTypes: RouteType[] | null;
|
|
13
14
|
difficultyOptions: DifficultyFilterOptions | null;
|
|
14
|
-
constructor(source?: PageDataSource[] | null, regionId?: string | null,
|
|
15
|
+
constructor(source?: PageDataSource[] | null, regionId?: string | null, routeTypes?: RouteType[] | null, difficultyOptions?: DifficultyFilterOptions | null);
|
|
15
16
|
toRoutesParams(): RoutesParams;
|
|
16
17
|
toJSON(): Record<string, unknown>;
|
|
17
18
|
toString(): string;
|
|
18
19
|
static fromJsonString(json: string): RouteFilter;
|
|
19
20
|
static fromJSON(parsed: unknown): RouteFilter;
|
|
21
|
+
private static normalizeRouteTypesList;
|
|
22
|
+
/** Accepts `routeTypes` array or legacy singular `routeType` string. */
|
|
23
|
+
private static parseRouteTypesField;
|
|
24
|
+
private static parseRouteTypeToken;
|
|
20
25
|
private static parseSourceField;
|
|
21
|
-
private static parseRouteType;
|
|
22
26
|
}
|
|
23
27
|
//# sourceMappingURL=routeFilter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routeFilter.d.ts","sourceRoot":"","sources":["../../../src/models/filters/routeFilter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,0CAA0C,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEpE;;GAEG;AACH,qBAAa,WAAW;IACpB,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAChC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,
|
|
1
|
+
{"version":3,"file":"routeFilter.d.ts","sourceRoot":"","sources":["../../../src/models/filters/routeFilter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,0CAA0C,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEpE;;GAEG;AACH,qBAAa,WAAW;IACpB,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAChC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,wDAAwD;IACxD,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAC/B,iBAAiB,EAAE,uBAAuB,GAAG,IAAI,CAAC;gBAG9C,MAAM,GAAE,cAAc,EAAE,GAAG,IAAW,EACtC,QAAQ,GAAE,MAAM,GAAG,IAAW,EAC9B,UAAU,GAAE,SAAS,EAAE,GAAG,IAAW,EACrC,iBAAiB,GAAE,uBAAuB,GAAG,IAAW;IAQ5D,cAAc,IAAI,YAAY;IAwC9B,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAYjC,QAAQ,IAAI,MAAM;IAIlB,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW;IAYhD,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,WAAW;IAkB7C,OAAO,CAAC,MAAM,CAAC,uBAAuB;IActC,wEAAwE;IACxE,OAAO,CAAC,MAAM,CAAC,oBAAoB;IA0BnC,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAOlC,OAAO,CAAC,MAAM,CAAC,gBAAgB;CAmBlC"}
|
|
@@ -10,10 +10,10 @@ const difficultyFilterOptions_1 = require("./difficultyFilterOptions");
|
|
|
10
10
|
* Persisted explore / minimap route filter. Null fields mean “no constraint” on that axis.
|
|
11
11
|
*/
|
|
12
12
|
class RouteFilter {
|
|
13
|
-
constructor(source = null, regionId = null,
|
|
13
|
+
constructor(source = null, regionId = null, routeTypes = null, difficultyOptions = null) {
|
|
14
14
|
this.source = source;
|
|
15
15
|
this.regionId = regionId;
|
|
16
|
-
this.
|
|
16
|
+
this.routeTypes = RouteFilter.normalizeRouteTypesList(routeTypes);
|
|
17
17
|
this.difficultyOptions = difficultyOptions;
|
|
18
18
|
}
|
|
19
19
|
toRoutesParams() {
|
|
@@ -26,7 +26,9 @@ class RouteFilter {
|
|
|
26
26
|
}
|
|
27
27
|
return new routesParams_1.RoutesParams({
|
|
28
28
|
region: null,
|
|
29
|
-
|
|
29
|
+
routeTypes: this.routeTypes != null && this.routeTypes.length > 0
|
|
30
|
+
? [...this.routeTypes]
|
|
31
|
+
: null,
|
|
30
32
|
difficulty: this.difficultyOptions !== null
|
|
31
33
|
? this.difficultyOptions.toDifficultyParams()
|
|
32
34
|
: null,
|
|
@@ -37,7 +39,9 @@ class RouteFilter {
|
|
|
37
39
|
: [...this.source];
|
|
38
40
|
return new routesParams_1.RoutesParams({
|
|
39
41
|
region: { id: rid, source: src },
|
|
40
|
-
|
|
42
|
+
routeTypes: this.routeTypes != null && this.routeTypes.length > 0
|
|
43
|
+
? [...this.routeTypes]
|
|
44
|
+
: null,
|
|
41
45
|
difficulty: this.difficultyOptions !== null
|
|
42
46
|
? this.difficultyOptions.toDifficultyParams()
|
|
43
47
|
: null,
|
|
@@ -47,7 +51,7 @@ class RouteFilter {
|
|
|
47
51
|
return {
|
|
48
52
|
source: this.source,
|
|
49
53
|
regionId: this.regionId,
|
|
50
|
-
|
|
54
|
+
routeTypes: this.routeTypes,
|
|
51
55
|
difficultyOptions: this.difficultyOptions !== null
|
|
52
56
|
? this.difficultyOptions.toJSON()
|
|
53
57
|
: null,
|
|
@@ -75,14 +79,57 @@ class RouteFilter {
|
|
|
75
79
|
const regionId = o.regionId === null || o.regionId === undefined
|
|
76
80
|
? null
|
|
77
81
|
: String(o.regionId);
|
|
78
|
-
const
|
|
79
|
-
? null
|
|
80
|
-
: RouteFilter.parseRouteType(o.routeType);
|
|
82
|
+
const routeTypes = RouteFilter.parseRouteTypesField(o);
|
|
81
83
|
let difficultyOptions = null;
|
|
82
84
|
if (o.difficultyOptions != null && typeof o.difficultyOptions === 'object') {
|
|
83
85
|
difficultyOptions = difficultyFilterOptions_1.DifficultyFilterOptions.fromResult(o.difficultyOptions);
|
|
84
86
|
}
|
|
85
|
-
return new RouteFilter(source, regionId,
|
|
87
|
+
return new RouteFilter(source, regionId, routeTypes, difficultyOptions);
|
|
88
|
+
}
|
|
89
|
+
static normalizeRouteTypesList(list) {
|
|
90
|
+
if (list == null || list.length === 0)
|
|
91
|
+
return null;
|
|
92
|
+
const out = [];
|
|
93
|
+
for (const t of list) {
|
|
94
|
+
if (!Object.values(routeType_1.RouteType).includes(t)) {
|
|
95
|
+
throw new Error(`Invalid RouteType: ${JSON.stringify(t)}`);
|
|
96
|
+
}
|
|
97
|
+
if (!out.includes(t))
|
|
98
|
+
out.push(t);
|
|
99
|
+
}
|
|
100
|
+
return out;
|
|
101
|
+
}
|
|
102
|
+
/** Accepts `routeTypes` array or legacy singular `routeType` string. */
|
|
103
|
+
static parseRouteTypesField(o) {
|
|
104
|
+
const raw = o.routeTypes;
|
|
105
|
+
if (raw !== null && raw !== undefined) {
|
|
106
|
+
if (!Array.isArray(raw)) {
|
|
107
|
+
throw new Error('RouteFilter.routeTypes must be an array or null');
|
|
108
|
+
}
|
|
109
|
+
const types = raw.map((item, i) => {
|
|
110
|
+
if (typeof item !== 'string') {
|
|
111
|
+
throw new Error(`RouteFilter.routeTypes[${i}] must be a string`);
|
|
112
|
+
}
|
|
113
|
+
return RouteFilter.parseRouteTypeToken(item);
|
|
114
|
+
});
|
|
115
|
+
return RouteFilter.normalizeRouteTypesList(types);
|
|
116
|
+
}
|
|
117
|
+
const legacy = o.routeType;
|
|
118
|
+
if (legacy === null || legacy === undefined) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
if (typeof legacy !== 'string') {
|
|
122
|
+
throw new Error('RouteFilter.routeType must be a string or null');
|
|
123
|
+
}
|
|
124
|
+
return RouteFilter.normalizeRouteTypesList([
|
|
125
|
+
RouteFilter.parseRouteTypeToken(legacy),
|
|
126
|
+
]);
|
|
127
|
+
}
|
|
128
|
+
static parseRouteTypeToken(v) {
|
|
129
|
+
if (!Object.values(routeType_1.RouteType).includes(v)) {
|
|
130
|
+
throw new Error(`Invalid RouteType: ${JSON.stringify(v)}`);
|
|
131
|
+
}
|
|
132
|
+
return v;
|
|
86
133
|
}
|
|
87
134
|
static parseSourceField(v) {
|
|
88
135
|
if (v === null || v === undefined)
|
|
@@ -104,11 +151,5 @@ class RouteFilter {
|
|
|
104
151
|
}
|
|
105
152
|
return out.length === 0 ? null : out;
|
|
106
153
|
}
|
|
107
|
-
static parseRouteType(v) {
|
|
108
|
-
if (typeof v !== 'string' || !Object.values(routeType_1.RouteType).includes(v)) {
|
|
109
|
-
throw new Error(`Invalid RouteType: ${JSON.stringify(v)}`);
|
|
110
|
-
}
|
|
111
|
-
return v;
|
|
112
|
-
}
|
|
113
154
|
}
|
|
114
155
|
exports.RouteFilter = RouteFilter;
|