@cookbook/urlkit 1.0.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.
Files changed (157) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +707 -0
  3. package/dist/compile-path-wQfWAzOh.js +1318 -0
  4. package/dist/compile-path-wQfWAzOh.js.map +1 -0
  5. package/dist/compile-static-search-Cq3uaLe8.js +238 -0
  6. package/dist/compile-static-search-Cq3uaLe8.js.map +1 -0
  7. package/dist/contracts.d.ts +107 -0
  8. package/dist/create-url-contract-BYKPM9bn.js +1751 -0
  9. package/dist/create-url-contract-BYKPM9bn.js.map +1 -0
  10. package/dist/date/contracts.d.ts +5 -0
  11. package/dist/date/parse-custom-date.d.ts +7 -0
  12. package/dist/date/parse-date-time.d.ts +6 -0
  13. package/dist/date/parse-date.d.ts +6 -0
  14. package/dist/date/parse-unix-ms.d.ts +6 -0
  15. package/dist/date/parse-unix-seconds.d.ts +6 -0
  16. package/dist/date/serialize-custom-date.d.ts +7 -0
  17. package/dist/date/serialize-date-time.d.ts +6 -0
  18. package/dist/date/serialize-date.d.ts +6 -0
  19. package/dist/date/serialize-unix-ms.d.ts +6 -0
  20. package/dist/date/serialize-unix-seconds.d.ts +6 -0
  21. package/dist/errors/contracts.d.ts +5 -0
  22. package/dist/errors/url-kit-error.d.ts +8 -0
  23. package/dist/hash/build-hash.d.ts +4 -0
  24. package/dist/hash/compile-hash-descriptor.d.ts +2 -0
  25. package/dist/hash/compile-normalized-hash-descriptor.d.ts +2 -0
  26. package/dist/hash/compile-runtime-hash-descriptor.d.ts +3 -0
  27. package/dist/hash/compile-static-hash-descriptor.d.ts +3 -0
  28. package/dist/hash/contracts.d.ts +21 -0
  29. package/dist/hash/copy-normalized-hash-descriptor.d.ts +2 -0
  30. package/dist/hash/create-hash.d.ts +5 -0
  31. package/dist/hash/hash-fragment.d.ts +2 -0
  32. package/dist/hash/is-normalized-hash-descriptor.d.ts +2 -0
  33. package/dist/hash/normalize-hash.d.ts +3 -0
  34. package/dist/hash/parse-hash.d.ts +3 -0
  35. package/dist/hash/validate-normalized-hash-value.d.ts +5 -0
  36. package/dist/index.d.ts +21 -0
  37. package/dist/index.js +73 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/router-runtime.d.ts +12 -0
  40. package/dist/router-runtime.js +214 -0
  41. package/dist/router-runtime.js.map +1 -0
  42. package/dist/runtime/build-route-search.d.ts +22 -0
  43. package/dist/runtime/compile-cached-static-search.d.ts +3 -0
  44. package/dist/runtime/contracts.d.ts +7 -0
  45. package/dist/runtime/create-route-url-contract.d.ts +15 -0
  46. package/dist/runtime/parse-route-search.d.ts +12 -0
  47. package/dist/schema/array.d.ts +9 -0
  48. package/dist/schema/boolean.d.ts +4 -0
  49. package/dist/schema/compile-runtime-schema-value.d.ts +6 -0
  50. package/dist/schema/compile-runtime-schema.d.ts +2 -0
  51. package/dist/schema/contracts.d.ts +87 -0
  52. package/dist/schema/create-schema-builder.d.ts +2 -0
  53. package/dist/schema/create-schema-value-error.d.ts +3 -0
  54. package/dist/schema/date-time.d.ts +4 -0
  55. package/dist/schema/date.d.ts +14 -0
  56. package/dist/schema/enum-of.d.ts +7 -0
  57. package/dist/schema/get-runtime-schema-internals.d.ts +2 -0
  58. package/dist/schema/handle-runtime-schema-absence.d.ts +6 -0
  59. package/dist/schema/int.d.ts +4 -0
  60. package/dist/schema/is-runtime-schema-kind.d.ts +2 -0
  61. package/dist/schema/normalize-compiled-runtime-schema-value.d.ts +3 -0
  62. package/dist/schema/normalize-runtime-schema-value.d.ts +2 -0
  63. package/dist/schema/number.d.ts +4 -0
  64. package/dist/schema/object.d.ts +20 -0
  65. package/dist/schema/parse-compiled-runtime-schema-value.d.ts +3 -0
  66. package/dist/schema/parse-runtime-schema-value.d.ts +2 -0
  67. package/dist/schema/runtime-schema-symbol.d.ts +5 -0
  68. package/dist/schema/runtime-schema-value-context.d.ts +2 -0
  69. package/dist/schema/safe-runtime-schema-value.d.ts +4 -0
  70. package/dist/schema/serialize-compiled-runtime-schema-value.d.ts +3 -0
  71. package/dist/schema/serialize-runtime-schema-value.d.ts +2 -0
  72. package/dist/schema/string.d.ts +4 -0
  73. package/dist/search/append-object-search-entries.d.ts +4 -0
  74. package/dist/search/append-raw-search-value.d.ts +2 -0
  75. package/dist/search/append-search-entry.d.ts +3 -0
  76. package/dist/search/are-search-values-equal.d.ts +1 -0
  77. package/dist/search/assert-object-search-collisions.d.ts +2 -0
  78. package/dist/search/build-compiled-search.d.ts +3 -0
  79. package/dist/search/build-raw-search.d.ts +2 -0
  80. package/dist/search/build-schema-search.d.ts +3 -0
  81. package/dist/search/build-search.d.ts +6 -0
  82. package/dist/search/collect-object-search-paths.d.ts +2 -0
  83. package/dist/search/compile-search-schema.d.ts +2 -0
  84. package/dist/search/contracts.d.ts +73 -0
  85. package/dist/search/copy-raw-search-params.d.ts +2 -0
  86. package/dist/search/copy-unknown-structured-search.d.ts +2 -0
  87. package/dist/search/create-search-params.d.ts +1 -0
  88. package/dist/search/create-search.d.ts +4 -0
  89. package/dist/search/delete-search-field-raw-keys.d.ts +2 -0
  90. package/dist/search/filter-raw-search.d.ts +3 -0
  91. package/dist/search/find-object-search-raw-value.d.ts +2 -0
  92. package/dist/search/has-search-field-raw-value.d.ts +2 -0
  93. package/dist/search/is-runtime-search-field.d.ts +2 -0
  94. package/dist/search/join-search-strings.d.ts +1 -0
  95. package/dist/search/normalize-compiled-search.d.ts +3 -0
  96. package/dist/search/normalize-search-build-value.d.ts +2 -0
  97. package/dist/search/normalize-search-field-default.d.ts +2 -0
  98. package/dist/search/normalize-search-field-type.d.ts +2 -0
  99. package/dist/search/object-search-key.d.ts +4 -0
  100. package/dist/search/object-search-path-key.d.ts +2 -0
  101. package/dist/search/object-search-raw-key-path.d.ts +1 -0
  102. package/dist/search/omit-search.d.ts +1 -0
  103. package/dist/search/parse-array-search-value.d.ts +4 -0
  104. package/dist/search/parse-compiled-search.d.ts +2 -0
  105. package/dist/search/parse-object-search-value.d.ts +4 -0
  106. package/dist/search/parse-partial-compiled-search.d.ts +6 -0
  107. package/dist/search/parse-partial-schema-search.d.ts +6 -0
  108. package/dist/search/parse-raw-search.d.ts +2 -0
  109. package/dist/search/parse-search-field-value.d.ts +2 -0
  110. package/dist/search/parse-search.d.ts +5 -0
  111. package/dist/search/patch-search.d.ts +6 -0
  112. package/dist/search/pick-search.d.ts +1 -0
  113. package/dist/search/replace-search.d.ts +5 -0
  114. package/dist/search/search-array-format.d.ts +3 -0
  115. package/dist/search/search-entries.d.ts +4 -0
  116. package/dist/search/serialize-search-build-value.d.ts +2 -0
  117. package/dist/search/serialize-search-entries.d.ts +3 -0
  118. package/dist/static/compile-static-hash.d.ts +3 -0
  119. package/dist/static/compile-static-search.d.ts +3 -0
  120. package/dist/static/compile-static-url.d.ts +3 -0
  121. package/dist/static/contracts.d.ts +81 -0
  122. package/dist/static/create-static-search-schema.d.ts +3 -0
  123. package/dist/static/normalize-static-search-default.d.ts +2 -0
  124. package/dist/static/static-search-field-kind.d.ts +4 -0
  125. package/dist/static.d.ts +7 -0
  126. package/dist/static.js +55 -0
  127. package/dist/static.js.map +1 -0
  128. package/dist/url/assert-path-match-failure.d.ts +2 -0
  129. package/dist/url/build-compiled-url.d.ts +3 -0
  130. package/dist/url/build-url.d.ts +3 -0
  131. package/dist/url/coerce-path-param.d.ts +2 -0
  132. package/dist/url/compile-path.d.ts +2 -0
  133. package/dist/url/compile-runtime-url-descriptor.d.ts +2 -0
  134. package/dist/url/compile-url-descriptor.d.ts +13 -0
  135. package/dist/url/contracts.d.ts +91 -0
  136. package/dist/url/create-unsupported-url-method.d.ts +1 -0
  137. package/dist/url/create-url-contract.d.ts +3 -0
  138. package/dist/url/create-url.d.ts +2 -0
  139. package/dist/url/filter-compiled-url-search.d.ts +4 -0
  140. package/dist/url/format-parsed-url.d.ts +2 -0
  141. package/dist/url/match-url.d.ts +3 -0
  142. package/dist/url/normalize-compiled-url.d.ts +3 -0
  143. package/dist/url/normalize-path-build-params.d.ts +1 -0
  144. package/dist/url/normalize-url.d.ts +3 -0
  145. package/dist/url/parse-compiled-url.d.ts +3 -0
  146. package/dist/url/parse-path-pattern.d.ts +2 -0
  147. package/dist/url/parse-request.d.ts +2 -0
  148. package/dist/url/parse-url.d.ts +6 -0
  149. package/dist/url/patch-compiled-url-search.d.ts +3 -0
  150. package/dist/url/path-constraints.d.ts +5 -0
  151. package/dist/url/path-param-kind.d.ts +3 -0
  152. package/dist/url/path-segment.d.ts +11 -0
  153. package/dist/url/register-urlkit-path-constraints.d.ts +1 -0
  154. package/dist/url/replace-compiled-url-search.d.ts +3 -0
  155. package/dist/url/resolve-url-unknown-search.d.ts +3 -0
  156. package/dist/url/url-state-brand.d.ts +7 -0
  157. package/package.json +73 -0
package/dist/static.js ADDED
@@ -0,0 +1,55 @@
1
+ import { a as compilePath, U as UrlKitError } from './compile-path-wQfWAzOh.js';
2
+ export { h as hasPathConstraint, r as registerPathConstraint, f as registerPathConstraints } from './compile-path-wQfWAzOh.js';
3
+ export { createConstraint } from '@cookbook/pathkit/constraints';
4
+ import { c as compileStaticHash, a as compileStaticSearch } from './compile-static-search-Cq3uaLe8.js';
5
+ import '@cookbook/pathkit/compile';
6
+ import '@cookbook/pathkit/match';
7
+
8
+ function compileStaticUrl(descriptor, options = {}) {
9
+ assertStaticUrlDescriptor(descriptor);
10
+ const mode = Object.prototype.hasOwnProperty.call(descriptor, 'path') ? 'path' : 'pathless';
11
+ const normalized = {
12
+ mode,
13
+ pattern: mode === 'path' ? descriptor.path : undefined,
14
+ ...(mode === 'path' && descriptor.path !== undefined
15
+ ? {
16
+ path: compilePath(descriptor.path, {
17
+ params: 'parsed',
18
+ ...(options.pathConstraints ? { pathConstraints: options.pathConstraints } : {}),
19
+ }),
20
+ }
21
+ : {}),
22
+ ...(Object.prototype.hasOwnProperty.call(descriptor, 'search')
23
+ ? { search: compileStaticSearch(descriptor.search ?? {}) }
24
+ : {}),
25
+ ...(Object.prototype.hasOwnProperty.call(descriptor, 'hash') && descriptor.hash !== undefined
26
+ ? { hash: compileStaticHash(descriptor.hash) }
27
+ : {}),
28
+ };
29
+ return Object.freeze(normalized);
30
+ }
31
+ function assertStaticUrlDescriptor(input) {
32
+ if (!isRecord(input)) {
33
+ throw new UrlKitError('invalid-descriptor', 'Static URL descriptor must be an object.', {
34
+ path: [],
35
+ });
36
+ }
37
+ if (Object.prototype.hasOwnProperty.call(input, 'path') && typeof input.path !== 'string') {
38
+ throw new UrlKitError('invalid-descriptor', 'Static URL descriptor path must be a string.', {
39
+ path: ['path'],
40
+ });
41
+ }
42
+ if (Object.prototype.hasOwnProperty.call(input, 'search') &&
43
+ input.search !== undefined &&
44
+ !isRecord(input.search)) {
45
+ throw new UrlKitError('invalid-descriptor', 'Static URL descriptor search must be an object.', {
46
+ path: ['search'],
47
+ });
48
+ }
49
+ }
50
+ function isRecord(input) {
51
+ return typeof input === 'object' && input !== null && !Array.isArray(input);
52
+ }
53
+
54
+ export { compileStaticHash, compileStaticSearch, compileStaticUrl };
55
+ //# sourceMappingURL=static.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static.js","sources":["../src/static/compile-static-url.ts"],"sourcesContent":["import { UrlKitError } from '../errors/url-kit-error.js';\nimport type { NormalizedUrlDescriptor } from '../url/contracts.js';\nimport type {\n CompileStaticUrlOptions,\n StaticUrlDescriptor,\n StaticUrlModeFromDescriptor,\n} from './contracts.js';\nimport { compilePath } from '../url/compile-path.js';\nimport { compileStaticHash } from './compile-static-hash.js';\nimport { compileStaticSearch } from './compile-static-search.js';\n\nexport function compileStaticUrl<Descriptor extends StaticUrlDescriptor>(\n descriptor: Descriptor,\n options: CompileStaticUrlOptions = {},\n): NormalizedUrlDescriptor<StaticUrlModeFromDescriptor<Descriptor>> {\n assertStaticUrlDescriptor(descriptor);\n\n const mode = Object.prototype.hasOwnProperty.call(descriptor, 'path') ? 'path' : 'pathless';\n const normalized = {\n mode,\n pattern: mode === 'path' ? descriptor.path : undefined,\n ...(mode === 'path' && descriptor.path !== undefined\n ? {\n path: compilePath(descriptor.path, {\n params: 'parsed',\n ...(options.pathConstraints ? { pathConstraints: options.pathConstraints } : {}),\n }),\n }\n : {}),\n ...(Object.prototype.hasOwnProperty.call(descriptor, 'search')\n ? { search: compileStaticSearch(descriptor.search ?? {}) }\n : {}),\n ...(Object.prototype.hasOwnProperty.call(descriptor, 'hash') && descriptor.hash !== undefined\n ? { hash: compileStaticHash(descriptor.hash) }\n : {}),\n } as NormalizedUrlDescriptor<StaticUrlModeFromDescriptor<Descriptor>>;\n\n return Object.freeze(normalized);\n}\n\nfunction assertStaticUrlDescriptor(input: unknown): asserts input is StaticUrlDescriptor {\n if (!isRecord(input)) {\n throw new UrlKitError('invalid-descriptor', 'Static URL descriptor must be an object.', {\n path: [],\n });\n }\n\n if (Object.prototype.hasOwnProperty.call(input, 'path') && typeof input.path !== 'string') {\n throw new UrlKitError('invalid-descriptor', 'Static URL descriptor path must be a string.', {\n path: ['path'],\n });\n }\n\n if (\n Object.prototype.hasOwnProperty.call(input, 'search') &&\n input.search !== undefined &&\n !isRecord(input.search)\n ) {\n throw new UrlKitError('invalid-descriptor', 'Static URL descriptor search must be an object.', {\n path: ['search'],\n });\n }\n}\n\nfunction isRecord(input: unknown): input is Record<string, unknown> {\n return typeof input === 'object' && input !== null && !Array.isArray(input);\n}\n"],"names":[],"mappings":";;;;;;;SAWgB,gBAAgB,CAC9B,UAAsB,EACtB,UAAmC,EAAE,EAAA;IAErC,yBAAyB,CAAC,UAAU,CAAC;IAErC,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,MAAM,GAAG,UAAU;AAC3F,IAAA,MAAM,UAAU,GAAG;QACjB,IAAI;AACJ,QAAA,OAAO,EAAE,IAAI,KAAK,MAAM,GAAG,UAAU,CAAC,IAAI,GAAG,SAAS;QACtD,IAAI,IAAI,KAAK,MAAM,IAAI,UAAU,CAAC,IAAI,KAAK;AACzC,cAAE;AACE,gBAAA,IAAI,EAAE,WAAW,CAAC,UAAU,CAAC,IAAI,EAAE;AACjC,oBAAA,MAAM,EAAE,QAAQ;AAChB,oBAAA,IAAI,OAAO,CAAC,eAAe,GAAG,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC;iBACjF,CAAC;AACH;cACD,EAAE,CAAC;AACP,QAAA,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ;AAC3D,cAAE,EAAE,MAAM,EAAE,mBAAmB,CAAC,UAAU,CAAC,MAAM,IAAI,EAAE,CAAC;cACtD,EAAE,CAAC;AACP,QAAA,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,UAAU,CAAC,IAAI,KAAK;cAChF,EAAE,IAAI,EAAE,iBAAiB,CAAC,UAAU,CAAC,IAAI,CAAC;cAC1C,EAAE,CAAC;KAC4D;AAErE,IAAA,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;AAClC;AAEA,SAAS,yBAAyB,CAAC,KAAc,EAAA;AAC/C,IAAA,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AACpB,QAAA,MAAM,IAAI,WAAW,CAAC,oBAAoB,EAAE,0CAA0C,EAAE;AACtF,YAAA,IAAI,EAAE,EAAE;AACT,SAAA,CAAC;IACJ;IAEA,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE;AACzF,QAAA,MAAM,IAAI,WAAW,CAAC,oBAAoB,EAAE,8CAA8C,EAAE;YAC1F,IAAI,EAAE,CAAC,MAAM,CAAC;AACf,SAAA,CAAC;IACJ;IAEA,IACE,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC;QACrD,KAAK,CAAC,MAAM,KAAK,SAAS;AAC1B,QAAA,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EACvB;AACA,QAAA,MAAM,IAAI,WAAW,CAAC,oBAAoB,EAAE,iDAAiD,EAAE;YAC7F,IAAI,EAAE,CAAC,QAAQ,CAAC;AACjB,SAAA,CAAC;IACJ;AACF;AAEA,SAAS,QAAQ,CAAC,KAAc,EAAA;AAC9B,IAAA,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;AAC7E;;;;"}
@@ -0,0 +1,2 @@
1
+ import type { ParsedPathSegment } from './path-segment.js';
2
+ export declare function assertPathMatchFailure(pattern: string, pathname: string, segments: readonly ParsedPathSegment[]): never;
@@ -0,0 +1,3 @@
1
+ import type { BuildUrlOptions, UrlBuildInput } from '../contracts.js';
2
+ import type { CompiledUrlDescriptor } from './compile-url-descriptor.js';
3
+ export declare function buildCompiledUrl<Mode extends 'path' | 'pathless', Params, Search, Hash, SearchInput = Partial<Search>, HashInput = Hash>(input: UrlBuildInput<Mode, Params, Search, Hash, SearchInput, HashInput>, compiled: CompiledUrlDescriptor<Mode>, options?: BuildUrlOptions): string;
@@ -0,0 +1,3 @@
1
+ import type { BuildUrlOptions, UrlBuildInput, UrlMode } from '../contracts.js';
2
+ import type { CompiledUrlDescriptor } from './compile-url-descriptor.js';
3
+ export declare function buildUrl<Mode extends UrlMode, Params, Search, Hash>(input: UrlBuildInput<Mode, Params, Search, Hash>, compiled: CompiledUrlDescriptor<Mode>, options?: BuildUrlOptions): string;
@@ -0,0 +1,2 @@
1
+ import type { ParsedPathParamSegment } from './path-segment.js';
2
+ export declare function coercePathParam(segment: ParsedPathParamSegment, value: string, paramsMode: 'raw' | 'parsed'): string | number;
@@ -0,0 +1,2 @@
1
+ import type { CompiledPath, CompilePathOptions } from './contracts.js';
2
+ export declare function compilePath<Pattern extends string>(pattern: Pattern, options?: CompilePathOptions): CompiledPath<Pattern>;
@@ -0,0 +1,2 @@
1
+ import type { CreateUrlOptions, NormalizedUrlDescriptor, RuntimeUrlDescriptor, UrlModeFromRuntimeDescriptor } from './contracts.js';
2
+ export declare function compileRuntimeUrlDescriptor<Descriptor extends RuntimeUrlDescriptor>(descriptor: Descriptor, options?: CreateUrlOptions): NormalizedUrlDescriptor<UrlModeFromRuntimeDescriptor<Descriptor>>;
@@ -0,0 +1,13 @@
1
+ import type { CompiledHashDescriptor } from '../hash/contracts.js';
2
+ import type { CompiledSearchSchema, RuntimeSearchSchema } from '../search/contracts.js';
3
+ import type { UrlMode } from '../contracts.js';
4
+ import type { CompiledPath, NormalizedUrlDescriptor } from './contracts.js';
5
+ export interface CompiledUrlDescriptor<Mode extends UrlMode = UrlMode> {
6
+ readonly mode: Mode;
7
+ readonly pattern: Mode extends 'path' ? string : undefined;
8
+ readonly path: Mode extends 'path' ? CompiledPath : undefined;
9
+ readonly searchSchema?: RuntimeSearchSchema;
10
+ readonly search?: CompiledSearchSchema;
11
+ readonly hash?: CompiledHashDescriptor;
12
+ }
13
+ export declare function compileUrlDescriptor<Mode extends UrlMode>(descriptor: NormalizedUrlDescriptor<Mode>): CompiledUrlDescriptor<Mode>;
@@ -0,0 +1,91 @@
1
+ import type { BuildHashArguments, BuildSearchOptions, BuildUrlOptions, EmptyParams, NormalizeUrlOptions, NormalizeUrlState, ParseRequestOptions, ParseUrlOptions, PatchSearchOptions, PathBuildMethod, PathConstraintMap, SearchInputArgument, UrlBuildInput, UrlMode, UrlNormalizeInput, UrlRequestInput, UrlSafeNormalizeResult, UrlSafeParseResult, UrlState, SearchArrayFormat, UnknownSearchBehavior } from '../contracts.js';
2
+ import type { HashSchema, NormalizedHashDescriptor } from '../hash/contracts.js';
3
+ import type { InferRuntimeSearch, InferRuntimeSearchBuildInput, RuntimeSearchSchema } from '../search/contracts.js';
4
+ import type { InferRuntimeSchemaDescriptor, InferRuntimeSchemaValue } from '../schema/contracts.js';
5
+ export interface NormalizedUrlDescriptor<Mode extends UrlMode = UrlMode> {
6
+ readonly mode: Mode;
7
+ readonly pattern: Mode extends 'path' ? string : undefined;
8
+ readonly path?: Mode extends 'path' ? CompiledPath : undefined;
9
+ readonly search?: RuntimeSearchSchema;
10
+ readonly hash?: NormalizedHashDescriptor;
11
+ }
12
+ export interface RuntimeUrlDescriptor {
13
+ readonly path?: string;
14
+ readonly search?: RuntimeSearchSchema;
15
+ readonly hash?: HashSchema;
16
+ }
17
+ export interface CreateUrlOptions {
18
+ readonly unknownSearch?: UnknownSearchBehavior;
19
+ readonly arrayFormat?: SearchArrayFormat;
20
+ readonly pathConstraints?: PathConstraintMap;
21
+ }
22
+ export interface CreateUrlContractOptions extends CreateUrlOptions {
23
+ }
24
+ export interface UrlContract<Mode extends UrlMode, Pathname, Params, Search, Hash, SearchInput = Partial<Search>, HashInput = Hash> {
25
+ readonly pattern: Mode extends 'path' ? string : undefined;
26
+ parse(input: string | URL, options?: ParseUrlOptions): UrlState<Pathname, Params, Search, Hash>;
27
+ safeParse(input: string | URL, options?: ParseUrlOptions): UrlSafeParseResult<Pathname, Params, Search, Hash>;
28
+ parseRequest(input: Request | UrlRequestInput, options?: ParseRequestOptions): UrlState<Pathname, Params, Search, Hash>;
29
+ safeParseRequest(input: Request | UrlRequestInput, options?: ParseRequestOptions): UrlSafeParseResult<Pathname, Params, Search, Hash>;
30
+ normalize<const Input extends UrlNormalizeInput<Mode, Params, Search, Hash, SearchInput, HashInput>>(input: Input & UrlNormalizeInput<Mode, Params, Search, Hash, SearchInput, HashInput>, options?: NormalizeUrlOptions): NormalizeUrlState<Mode, Pathname, Params, Search, Hash, Input>;
31
+ safeNormalize<const Input extends UrlNormalizeInput<Mode, Params, Search, Hash, SearchInput, HashInput>>(input: Input & UrlNormalizeInput<Mode, Params, Search, Hash, SearchInput, HashInput>, options?: NormalizeUrlOptions): UrlSafeNormalizeResult<Mode, Pathname, Params, Search, Hash, Input>;
32
+ build(input: UrlBuildInput<Mode, Params, Search, Hash, SearchInput, HashInput> | UrlState<Pathname, Params, Search, Hash>, options?: BuildUrlOptions): string;
33
+ match(input: string | URL, options?: ParseUrlOptions): boolean;
34
+ readonly parsePathname: Mode extends 'path' ? (pathname: string) => Params : never;
35
+ readonly buildPath: Mode extends 'path' ? PathBuildMethod<Params> : never;
36
+ parseSearch(input: string | URLSearchParams, options?: ParseUrlOptions): Search;
37
+ parseHash(input: unknown): Hash;
38
+ buildSearch(search: SearchInputArgument<SearchInput>, options?: BuildSearchOptions): string;
39
+ buildHash(...args: BuildHashArguments<HashInput>): string;
40
+ withSearch(input: string | URL, search: Partial<Search>, options?: PatchSearchOptions): string;
41
+ replaceSearch(input: string | URL, search: SearchInput, options?: BuildSearchOptions): string;
42
+ omitSearch(input: string | URL, keys: readonly string[], options?: BuildSearchOptions): string;
43
+ pickSearch(input: string | URL, keys: readonly string[], options?: BuildSearchOptions): string;
44
+ }
45
+ export interface CompilePathOptions {
46
+ readonly params?: 'raw' | 'parsed';
47
+ readonly pathConstraints?: PathConstraintMap;
48
+ }
49
+ export interface CompiledPath<Pattern extends string = string, Params = ParamsFromPattern<Pattern>> {
50
+ readonly pattern: Pattern;
51
+ parsePathname(pathname: string): Params;
52
+ buildPath: PathBuildMethod<Params>;
53
+ }
54
+ export type UrlModeFromRuntimeDescriptor<Descriptor> = Descriptor extends {
55
+ readonly path: string;
56
+ } ? 'path' : 'pathless';
57
+ export type PathnameFromRuntimeDescriptor<Descriptor> = Descriptor extends {
58
+ readonly path: infer Pattern extends string;
59
+ } ? PathnameFromPattern<Pattern> : string;
60
+ export type ParamsFromRuntimeDescriptor<Descriptor> = Descriptor extends {
61
+ readonly path: infer Pattern extends string;
62
+ } ? ParamsFromPattern<Pattern> : EmptyParams;
63
+ export type SearchFromRuntimeDescriptor<Descriptor> = Descriptor extends {
64
+ readonly search: infer Search extends RuntimeSearchSchema;
65
+ } ? InferRuntimeSearch<Search> : EmptyParams;
66
+ export type SearchBuildInputFromRuntimeDescriptor<Descriptor> = Descriptor extends {
67
+ readonly search: infer Search extends RuntimeSearchSchema;
68
+ } ? InferRuntimeSearchBuildInput<Search> : EmptyParams;
69
+ export type HashFromRuntimeDescriptor<Descriptor> = Descriptor extends {
70
+ readonly hash: infer Schema;
71
+ } ? Schema extends HashSchema ? InferRuntimeSchemaValue<Schema> : never : undefined;
72
+ export type HashBuildInputFromRuntimeDescriptor<Descriptor> = Descriptor extends {
73
+ readonly hash: infer Schema;
74
+ } ? Schema extends HashSchema ? HashBuildInputFromRuntimeSchema<Schema> : never : undefined;
75
+ export type HashBuildInputFromRuntimeSchema<Schema extends HashSchema> = InferRuntimeSchemaDescriptor<Schema> extends {
76
+ readonly presence: 'required';
77
+ } ? InferRuntimeSchemaValue<Schema> : InferRuntimeSchemaValue<Schema> | undefined;
78
+ export type RawParamsFromPattern<Pattern extends string> = Simplify<ExtractRawPathParams<Pattern>>;
79
+ type ExtractRawPathParams<Pattern extends string> = Pattern extends `${string}{${infer Token}}${infer Rest}` ? RawParamFromToken<Token> & ExtractRawPathParams<Rest> : {};
80
+ type RawParamFromToken<Token extends string> = Token extends `*${infer Name}` ? Readonly<Record<CleanPathParamName<Name>, string>> : Token extends `${infer Name}:${string}` ? Readonly<Record<CleanPathParamName<Name>, string>> : Readonly<Record<CleanPathParamName<Token>, string>>;
81
+ export type PathnameFromPattern<Pattern extends string> = Pattern extends `${infer Before}{${infer Param}}${infer After}` ? `${Before}${PathParamValue<Param>}${PathnameFromPattern<After>}` : Pattern;
82
+ export type ParamsFromPattern<Pattern extends string> = Simplify<ExtractPathParams<Pattern>>;
83
+ type ExtractPathParams<Pattern extends string> = Pattern extends `${string}{${infer Token}}${infer Rest}` ? ParamFromToken<Token> & ExtractPathParams<Rest> : {};
84
+ type ParamFromToken<Token extends string> = Token extends `*${infer Name}` ? Readonly<Record<CleanPathParamName<Name>, string>> : Token extends `${infer Name}:${infer Constraint}` ? Readonly<Record<CleanPathParamName<Name>, PathParamValueFromConstraint<Constraint>>> : Readonly<Record<CleanPathParamName<Token>, string>>;
85
+ type CleanPathParamName<Name extends string> = Name extends `${infer Clean}?` ? Clean : Name;
86
+ type PathParamValue<Param extends string> = Param extends `${string}:${infer Constraint}` ? PathParamValueFromConstraint<Constraint> : string;
87
+ type PathParamValueFromConstraint<Constraint extends string> = Constraint extends 'int' ? number : Constraint extends 'number' ? number : Constraint extends `regex(${string})` ? string : string;
88
+ type Simplify<Value> = {
89
+ readonly [Key in keyof Value]: Value[Key];
90
+ } & {};
91
+ export {};
@@ -0,0 +1 @@
1
+ export declare function createUnsupportedUrlMethod(name: string): (...args: readonly unknown[]) => never;
@@ -0,0 +1,3 @@
1
+ import type { EmptyParams } from '../contracts.js';
2
+ import type { CreateUrlContractOptions, NormalizedUrlDescriptor, UrlContract } from './contracts.js';
3
+ export declare function createUrlContract<Mode extends 'path' | 'pathless', Pathname = Mode extends 'path' ? string : string, Params = Mode extends 'path' ? Record<string, string | number> : EmptyParams, Search = Record<string, unknown>, Hash = string | undefined, SearchInput = Partial<Search>, HashInput = Hash>(descriptor: NormalizedUrlDescriptor<Mode>, options?: CreateUrlContractOptions): UrlContract<Mode, Pathname, Params, Search, Hash, SearchInput, HashInput>;
@@ -0,0 +1,2 @@
1
+ import type { CreateUrlOptions, HashBuildInputFromRuntimeDescriptor, HashFromRuntimeDescriptor, ParamsFromRuntimeDescriptor, PathnameFromRuntimeDescriptor, RuntimeUrlDescriptor, SearchBuildInputFromRuntimeDescriptor, SearchFromRuntimeDescriptor, UrlContract, UrlModeFromRuntimeDescriptor } from './contracts.js';
2
+ export declare function url<const Descriptor extends RuntimeUrlDescriptor>(descriptor: Descriptor, options?: CreateUrlOptions): UrlContract<UrlModeFromRuntimeDescriptor<Descriptor>, PathnameFromRuntimeDescriptor<Descriptor>, ParamsFromRuntimeDescriptor<Descriptor>, SearchFromRuntimeDescriptor<Descriptor>, HashFromRuntimeDescriptor<Descriptor>, SearchBuildInputFromRuntimeDescriptor<Descriptor>, HashBuildInputFromRuntimeDescriptor<Descriptor>>;
@@ -0,0 +1,4 @@
1
+ import type { BuildSearchOptions } from '../contracts.js';
2
+ import type { CompiledUrlDescriptor } from './compile-url-descriptor.js';
3
+ export declare function omitCompiledUrlSearch(input: string | URL, keys: readonly string[], _compiled: CompiledUrlDescriptor, options?: BuildSearchOptions): string;
4
+ export declare function pickCompiledUrlSearch(input: string | URL, keys: readonly string[], _compiled: CompiledUrlDescriptor, options?: BuildSearchOptions): string;
@@ -0,0 +1,2 @@
1
+ import type { ParsedUrlInput } from './parse-url.js';
2
+ export declare function formatParsedUrl(input: ParsedUrlInput, search: string): string;
@@ -0,0 +1,3 @@
1
+ import type { ParseUrlOptions, UnknownSearchBehavior } from '../contracts.js';
2
+ import type { CompiledUrlDescriptor } from './compile-url-descriptor.js';
3
+ export declare function matchCompiledUrl(input: string | URL, compiled: CompiledUrlDescriptor, unknownSearch: UnknownSearchBehavior, options?: Pick<ParseUrlOptions, 'arrayFormat'>): boolean;
@@ -0,0 +1,3 @@
1
+ import type { NormalizeUrlState, UnknownSearchBehavior } from '../contracts.js';
2
+ import type { CompiledUrlDescriptor } from './compile-url-descriptor.js';
3
+ export declare function normalizeCompiledUrl<Mode extends 'path' | 'pathless', Pathname, Params, Search, Hash, Input>(input: Input, compiled: CompiledUrlDescriptor<Mode>, unknownSearch: UnknownSearchBehavior): NormalizeUrlState<Mode, Pathname, Params, Search, Hash, Input>;
@@ -0,0 +1 @@
1
+ export declare function normalizePathBuildParams(params: unknown): Record<string, string | number | boolean>;
@@ -0,0 +1,3 @@
1
+ import type { NormalizeUrlState, UnknownSearchBehavior } from '../contracts.js';
2
+ import type { CompiledUrlDescriptor } from './compile-url-descriptor.js';
3
+ export declare function normalizeUrl<Mode extends 'path' | 'pathless', Pathname, Params, Search, Hash, Input>(input: Input, compiled: CompiledUrlDescriptor<Mode>, unknownSearch: UnknownSearchBehavior): NormalizeUrlState<Mode, Pathname, Params, Search, Hash, Input>;
@@ -0,0 +1,3 @@
1
+ import type { ParseUrlOptions, UrlState, UnknownSearchBehavior } from '../contracts.js';
2
+ import type { CompiledUrlDescriptor } from './compile-url-descriptor.js';
3
+ export declare function parseCompiledUrl<Pathname, Params, Search, Hash>(input: string | URL, compiled: CompiledUrlDescriptor, unknownSearch: UnknownSearchBehavior, options?: Pick<ParseUrlOptions, 'arrayFormat'>): UrlState<Pathname, Params, Search, Hash>;
@@ -0,0 +1,2 @@
1
+ import type { ParsedPathSegment } from './path-segment.js';
2
+ export declare function parsePathPattern(pattern: string): readonly ParsedPathSegment[];
@@ -0,0 +1,2 @@
1
+ import type { ParseRequestOptions, UrlRequestInput } from '../contracts.js';
2
+ export declare function resolveRequestUrlInput(input: Request | UrlRequestInput, options?: ParseRequestOptions): string | URL;
@@ -0,0 +1,6 @@
1
+ export interface ParsedUrlInput {
2
+ readonly pathname: string;
3
+ readonly searchParams: URLSearchParams;
4
+ readonly hash: string;
5
+ }
6
+ export declare function parseUrl(input: string | URL): ParsedUrlInput;
@@ -0,0 +1,3 @@
1
+ import type { PatchSearchOptions } from '../contracts.js';
2
+ import type { CompiledUrlDescriptor } from './compile-url-descriptor.js';
3
+ export declare function patchCompiledUrlSearch(input: string | URL, patch: Record<string, unknown>, compiled: CompiledUrlDescriptor, options?: PatchSearchOptions): string;
@@ -0,0 +1,5 @@
1
+ import type { ConstraintValidation } from '@cookbook/pathkit';
2
+ import type { PathConstraintMap, RegisterPathConstraintOptions } from '../contracts.js';
3
+ export declare function registerPathConstraint(name: string, constraint: ConstraintValidation, options?: RegisterPathConstraintOptions): void;
4
+ export declare function registerPathConstraints(constraints: PathConstraintMap, options?: RegisterPathConstraintOptions): void;
5
+ export declare function hasPathConstraint(name: string): boolean;
@@ -0,0 +1,3 @@
1
+ import type { ParsedPathParamSegment } from './path-segment.js';
2
+ export type PathParamKind = 'string' | 'int' | 'number' | 'regex';
3
+ export declare function getPathParamKind(segment: ParsedPathParamSegment): PathParamKind;
@@ -0,0 +1,11 @@
1
+ export interface ParsedPathLiteralSegment {
2
+ readonly kind: 'literal';
3
+ readonly value: string;
4
+ }
5
+ export interface ParsedPathParamSegment {
6
+ readonly kind: 'param';
7
+ readonly name: string;
8
+ readonly constraint?: string;
9
+ readonly constraintParams?: string;
10
+ }
11
+ export type ParsedPathSegment = ParsedPathLiteralSegment | ParsedPathParamSegment;
@@ -0,0 +1 @@
1
+ export declare function registerUrlKitPathConstraints(): void;
@@ -0,0 +1,3 @@
1
+ import type { BuildSearchOptions } from '../contracts.js';
2
+ import type { CompiledUrlDescriptor } from './compile-url-descriptor.js';
3
+ export declare function replaceCompiledUrlSearch(input: string | URL, next: Record<string, unknown>, compiled: CompiledUrlDescriptor, options?: BuildSearchOptions): string;
@@ -0,0 +1,3 @@
1
+ import type { UnknownSearchBehavior, UnknownSearchParams } from '../contracts.js';
2
+ import type { RawSearchParams } from '../search/contracts.js';
3
+ export declare function resolveUrlUnknownSearch(rawSearch: RawSearchParams, behavior: UnknownSearchBehavior): UnknownSearchParams | undefined;
@@ -0,0 +1,7 @@
1
+ declare const URL_STATE_BRAND: unique symbol;
2
+ export interface BrandedUrlState {
3
+ readonly [URL_STATE_BRAND]: true;
4
+ }
5
+ export declare function markUrlState<State extends object>(state: State): State & BrandedUrlState;
6
+ export declare function isUrlState(input: unknown): input is BrandedUrlState;
7
+ export {};
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@cookbook/urlkit",
3
+ "version": "1.0.0",
4
+ "description": "Framework-agnostic typed URL contract library for parsing, validating, normalizing, matching, and building URL state.",
5
+ "license": "MIT",
6
+ "author": "The Cookbook",
7
+ "homepage": "https://github.com/the-cookbook/urlkit#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/the-cookbook/urlkit.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/the-cookbook/urlkit/issues"
14
+ },
15
+ "type": "module",
16
+ "sideEffects": false,
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "exports": {
21
+ ".": {
22
+ "types": "./dist/index.d.ts",
23
+ "import": "./dist/index.js"
24
+ },
25
+ "./static": {
26
+ "types": "./dist/static.d.ts",
27
+ "import": "./dist/static.js"
28
+ },
29
+ "./router-runtime": {
30
+ "types": "./dist/router-runtime.d.ts",
31
+ "import": "./dist/router-runtime.js"
32
+ }
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "README.md"
37
+ ],
38
+ "devDependencies": {
39
+ "@changesets/cli": "^2.31.0",
40
+ "@commitlint/cli": "21.0.2",
41
+ "@commitlint/config-conventional": "21.0.2",
42
+ "@eslint/js": "10.0.1",
43
+ "@rollup/plugin-typescript": "^12.1.4",
44
+ "eslint": "10.4.1",
45
+ "eslint-config-prettier": "10.1.8",
46
+ "husky": "9.1.7",
47
+ "lint-staged": "17.0.7",
48
+ "prettier": "3.8.3",
49
+ "rollup": "^4.61.0",
50
+ "tslib": "^2.8.1",
51
+ "typescript": "^5.8.3",
52
+ "typescript-eslint": "8.60.1",
53
+ "vitest": "^4.1.8"
54
+ },
55
+ "dependencies": {
56
+ "@cookbook/pathkit": "^0.2.1"
57
+ },
58
+ "scripts": {
59
+ "clean": "rm -rf dist coverage",
60
+ "build": "pnpm run clean && rollup -c && tsc -p tsconfig.build.json",
61
+ "typecheck": "tsc --noEmit",
62
+ "test": "vitest run",
63
+ "test:watch": "vitest",
64
+ "coverage": "vitest run --coverage",
65
+ "lint": "eslint .",
66
+ "lint:fix": "eslint . --fix",
67
+ "format": "prettier --write .",
68
+ "format:check": "prettier --check .",
69
+ "changeset": "changeset",
70
+ "version-package": "changeset version",
71
+ "release": "pnpm run typecheck && pnpm test && pnpm run build && changeset publish"
72
+ }
73
+ }