@cookbook/urlkit 1.0.0 → 1.1.0
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 +7 -2
- package/dist/{compile-path-wQfWAzOh.js → compile-path-COU1uxXm.js} +28 -41
- package/dist/{compile-path-wQfWAzOh.js.map → compile-path-COU1uxXm.js.map} +1 -1
- package/dist/{compile-static-search-Cq3uaLe8.js → compile-static-search-CCwJuNC3.js} +2 -2
- package/dist/{compile-static-search-Cq3uaLe8.js.map → compile-static-search-CCwJuNC3.js.map} +1 -1
- package/dist/{create-url-contract-BYKPM9bn.js → create-url-contract-DAU3UCJ6.js} +2 -2
- package/dist/{create-url-contract-BYKPM9bn.js.map → create-url-contract-DAU3UCJ6.js.map} +1 -1
- package/dist/index.js +4 -4
- package/dist/router-runtime.js +5 -5
- package/dist/static.js +3 -3
- package/dist/url/contracts.d.ts +1 -1
- package/package.json +37 -5
package/README.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# @cookbook/urlkit
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@cookbook/urlkit)
|
|
4
|
+
[](https://www.npmjs.com/package/@cookbook/urlkit)
|
|
5
|
+
[](https://bundlephobia.com/package/@cookbook/urlkit)
|
|
6
|
+
[](https://github.com/the-cookbook/urlkit/actions/workflows/ci.yml)
|
|
7
|
+
|
|
3
8
|
Framework-agnostic typed URL contracts for parsing, validating, normalizing, matching, and building URL state.
|
|
4
9
|
|
|
5
10
|
URLKit owns typed URL state: path params, search params, hash fragments, request parsing, URL normalization, matching, and href building. It sits between `@cookbook/pathkit` and higher-level router packages, but it does not define routes, route IDs, route trees, loaders, middleware, React hooks, components, or framework adapters.
|
|
@@ -176,7 +181,7 @@ ArticleUrl.build({ params: { slug: 'post-1' } });
|
|
|
176
181
|
// ArticleUrl.build({ pathname: '/articles/post-1' });
|
|
177
182
|
```
|
|
178
183
|
|
|
179
|
-
Path params are inferred from the pattern. Built-in `int` and `
|
|
184
|
+
Path params are inferred from the pattern. Built-in `int`, `decimal` and `range` path constraints parse to numbers in standalone `url(...)` contracts.
|
|
180
185
|
|
|
181
186
|
```ts
|
|
182
187
|
const UserUrl = url({ path: '/users/{id:int}' });
|
|
@@ -187,7 +192,7 @@ const user = UserUrl.parse('/users/42');
|
|
|
187
192
|
|
|
188
193
|
### Custom path constraints
|
|
189
194
|
|
|
190
|
-
URLKit re-exports PathKit's `createConstraint` and provides global registration helpers for reusable path constraints. Custom constraints infer `string` params by default; built-in `int` and `
|
|
195
|
+
URLKit re-exports PathKit's `createConstraint` and provides global registration helpers for reusable path constraints. Custom constraints infer `string` params by default; built-in `int`, `decimal` and `range` still infer `number`.
|
|
191
196
|
|
|
192
197
|
```ts
|
|
193
198
|
import { createConstraint, registerPathConstraint, url } from '@cookbook/urlkit';
|
|
@@ -1027,19 +1027,6 @@ function isSearchSchema(input) {
|
|
|
1027
1027
|
return typeof input === 'object' && input !== null && !Array.isArray(input);
|
|
1028
1028
|
}
|
|
1029
1029
|
|
|
1030
|
-
function getPathParamKind(segment) {
|
|
1031
|
-
switch (segment.constraint) {
|
|
1032
|
-
case 'int':
|
|
1033
|
-
return 'int';
|
|
1034
|
-
case 'number':
|
|
1035
|
-
return 'number';
|
|
1036
|
-
case 'regex':
|
|
1037
|
-
return 'regex';
|
|
1038
|
-
default:
|
|
1039
|
-
return 'string';
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
1030
|
function assertPathMatchFailure(pattern, pathname, segments) {
|
|
1044
1031
|
const pathnameSegments = splitPath(pathname);
|
|
1045
1032
|
if (pathnameSegments.length !== segments.length) {
|
|
@@ -1049,6 +1036,7 @@ function assertPathMatchFailure(pattern, pathname, segments) {
|
|
|
1049
1036
|
const segment = segments[index];
|
|
1050
1037
|
const pathnameSegment = pathnameSegments[index];
|
|
1051
1038
|
if (!segment || pathnameSegment === undefined) {
|
|
1039
|
+
console.log('ERROR', segment);
|
|
1052
1040
|
throwPathMismatch(pattern, pathname);
|
|
1053
1041
|
}
|
|
1054
1042
|
if (segment.kind === 'literal') {
|
|
@@ -1066,46 +1054,31 @@ function assertPathMatchFailure(pattern, pathname, segments) {
|
|
|
1066
1054
|
throwPathMismatch(pattern, pathname);
|
|
1067
1055
|
}
|
|
1068
1056
|
function splitPath(pathname) {
|
|
1069
|
-
if (pathname
|
|
1057
|
+
if (!pathname) {
|
|
1070
1058
|
return Object.freeze([]);
|
|
1071
1059
|
}
|
|
1072
1060
|
const normalized = pathname.startsWith('/') ? pathname.slice(1) : pathname;
|
|
1073
|
-
if (normalized
|
|
1061
|
+
if (!normalized) {
|
|
1074
1062
|
return Object.freeze([]);
|
|
1075
1063
|
}
|
|
1076
1064
|
return Object.freeze(normalized.split('/'));
|
|
1077
1065
|
}
|
|
1078
1066
|
function isValidPathParamSegment(segment, value) {
|
|
1079
|
-
if (value
|
|
1067
|
+
if (!value || !segment.constraint) {
|
|
1080
1068
|
return false;
|
|
1081
1069
|
}
|
|
1082
|
-
const
|
|
1083
|
-
if (
|
|
1084
|
-
return
|
|
1085
|
-
}
|
|
1086
|
-
if (kind === 'number') {
|
|
1087
|
-
return /^-?(?:\d+(?:\.\d+)?|\.\d+)$/.test(value) && Number.isFinite(Number(value));
|
|
1070
|
+
const constraint = getConstraint(segment.constraint);
|
|
1071
|
+
if (!constraint) {
|
|
1072
|
+
return false;
|
|
1088
1073
|
}
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
}
|
|
1094
|
-
return new RegExp(`^(?:${params})$`).test(value);
|
|
1074
|
+
try {
|
|
1075
|
+
constraint(segment.name, value, segment.constraintParams ?? '');
|
|
1076
|
+
console.log(constraint, segment, value);
|
|
1077
|
+
return true;
|
|
1095
1078
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
if (!constraint) {
|
|
1099
|
-
return false;
|
|
1100
|
-
}
|
|
1101
|
-
try {
|
|
1102
|
-
return new RegExp(`^(?:${constraint.toRegExp(segment.constraintParams ?? '')})$`).test(value);
|
|
1103
|
-
}
|
|
1104
|
-
catch {
|
|
1105
|
-
return false;
|
|
1106
|
-
}
|
|
1079
|
+
catch {
|
|
1080
|
+
return false;
|
|
1107
1081
|
}
|
|
1108
|
-
return true;
|
|
1109
1082
|
}
|
|
1110
1083
|
function throwPathMismatch(pattern, pathname) {
|
|
1111
1084
|
throw new UrlKitError('path-mismatch', `Pathname "${pathname}" does not match pattern "${pattern}".`, {
|
|
@@ -1113,6 +1086,20 @@ function throwPathMismatch(pattern, pathname) {
|
|
|
1113
1086
|
});
|
|
1114
1087
|
}
|
|
1115
1088
|
|
|
1089
|
+
function getPathParamKind(segment) {
|
|
1090
|
+
switch (segment.constraint) {
|
|
1091
|
+
case 'int':
|
|
1092
|
+
return 'int';
|
|
1093
|
+
case 'decimal':
|
|
1094
|
+
case 'range':
|
|
1095
|
+
return 'number';
|
|
1096
|
+
case 'regex':
|
|
1097
|
+
return 'regex';
|
|
1098
|
+
default:
|
|
1099
|
+
return 'string';
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1116
1103
|
function coercePathParam(segment, value, paramsMode) {
|
|
1117
1104
|
if (paramsMode === 'raw') {
|
|
1118
1105
|
return value;
|
|
@@ -1315,4 +1302,4 @@ function compilePathPattern(pattern) {
|
|
|
1315
1302
|
}
|
|
1316
1303
|
|
|
1317
1304
|
export { UrlKitError as U, compilePath as a, boolean as b, compileSearchSchema as c, date as d, enumOf as e, registerPathConstraints as f, handleRuntimeSchemaAbsence as g, hasPathConstraint as h, int as i, createSchemaValueError as j, createRuntimeSchemaValueContext as k, compileRuntimeSchemaValue as l, createRuntimeSchemaBuilder as m, number as n, normalizeRuntimeSchemaValue as o, getRuntimeSchemaInternals as p, runtimeSchemaSymbol as q, registerPathConstraint as r, string as s, compileRuntimeSchema as t, normalizeCompiledRuntimeSchemaValue as u, compileStaticHashDescriptor as v, parseUnixSeconds as w, parseUnixMs as x, parseDateTime as y, parseDate as z };
|
|
1318
|
-
//# sourceMappingURL=compile-path-
|
|
1305
|
+
//# sourceMappingURL=compile-path-COU1uxXm.js.map
|