@jini-ai/cms 0.5.2 → 0.5.3

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 (205) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +14 -8
  3. package/dist/comments/errors.d.ts +23 -0
  4. package/dist/comments/errors.js +25 -0
  5. package/dist/comments/express/index.d.ts +2 -0
  6. package/dist/comments/express/index.js +2 -0
  7. package/dist/comments/express/submit-handler.d.ts +30 -0
  8. package/dist/comments/express/submit-handler.js +85 -0
  9. package/dist/comments/hooks.d.ts +39 -0
  10. package/dist/comments/hooks.js +41 -0
  11. package/dist/comments/index.d.ts +11 -0
  12. package/dist/comments/index.js +11 -0
  13. package/dist/comments/ingress.d.ts +57 -0
  14. package/dist/comments/ingress.js +173 -0
  15. package/dist/comments/module.d.ts +94 -0
  16. package/dist/comments/module.js +73 -0
  17. package/dist/comments/ports.d.ts +184 -0
  18. package/dist/comments/ports.js +2 -0
  19. package/dist/comments/repo.memory.d.ts +70 -0
  20. package/dist/comments/repo.memory.js +120 -0
  21. package/dist/comments/sanitize.d.ts +15 -0
  22. package/dist/comments/sanitize.js +31 -0
  23. package/dist/comments/spam.heuristic.d.ts +8 -0
  24. package/dist/comments/spam.heuristic.js +54 -0
  25. package/dist/comments/sql/index.d.ts +3 -0
  26. package/dist/comments/sql/index.js +3 -0
  27. package/dist/comments/sql/repo.d.ts +77 -0
  28. package/dist/comments/sql/repo.js +190 -0
  29. package/dist/comments/sql/repo.rows.d.ts +49 -0
  30. package/dist/comments/sql/repo.rows.js +71 -0
  31. package/dist/comments/types.d.ts +187 -0
  32. package/dist/comments/types.js +39 -0
  33. package/dist/comments/write-service.d.ts +121 -0
  34. package/dist/comments/write-service.js +144 -0
  35. package/dist/core/commands/command.d.ts +2 -9
  36. package/dist/core/commands/command.js +2 -9
  37. package/dist/core/index.d.ts +2 -1
  38. package/dist/core/index.js +1 -0
  39. package/dist/core/keyset-cursor.d.ts +25 -0
  40. package/dist/core/keyset-cursor.js +20 -0
  41. package/dist/core/ports.d.ts +30 -0
  42. package/dist/core/ports.js +0 -1
  43. package/dist/core/tools/args.d.ts +1 -46
  44. package/dist/core/tools/args.js +1 -44
  45. package/dist/media/index.d.ts +0 -3
  46. package/dist/media/index.js +1 -4
  47. package/dist/media/node.d.ts +5 -0
  48. package/dist/media/node.js +6 -0
  49. package/dist/redirects/capture.d.ts +80 -0
  50. package/dist/redirects/capture.js +66 -0
  51. package/dist/redirects/express/index.d.ts +27 -0
  52. package/dist/redirects/express/index.js +40 -0
  53. package/dist/redirects/hit-sink.d.ts +56 -0
  54. package/dist/redirects/hit-sink.js +44 -0
  55. package/dist/redirects/host-config/index.d.ts +40 -0
  56. package/dist/redirects/host-config/index.js +145 -0
  57. package/dist/redirects/index.d.ts +14 -0
  58. package/dist/redirects/index.js +14 -0
  59. package/dist/redirects/matcher.d.ts +58 -0
  60. package/dist/redirects/matcher.js +144 -0
  61. package/dist/redirects/order.d.ts +30 -0
  62. package/dist/redirects/order.js +26 -0
  63. package/dist/redirects/ports.d.ts +242 -0
  64. package/dist/redirects/ports.internal.d.ts +57 -0
  65. package/dist/redirects/ports.internal.js +14 -0
  66. package/dist/redirects/ports.js +2 -0
  67. package/dist/redirects/redirects.d.ts +226 -0
  68. package/dist/redirects/redirects.js +590 -0
  69. package/dist/redirects/referrer-alias.d.ts +31 -0
  70. package/dist/redirects/referrer-alias.js +33 -0
  71. package/dist/redirects/repo.memory.d.ts +51 -0
  72. package/dist/redirects/repo.memory.js +98 -0
  73. package/dist/redirects/reserved-destination.d.ts +58 -0
  74. package/dist/redirects/reserved-destination.js +59 -0
  75. package/dist/redirects/resolver.d.ts +100 -0
  76. package/dist/redirects/resolver.js +87 -0
  77. package/dist/redirects/spa/index.d.ts +30 -0
  78. package/dist/redirects/spa/index.js +27 -0
  79. package/dist/redirects/sql/index.d.ts +4 -0
  80. package/dist/redirects/sql/index.js +4 -0
  81. package/dist/redirects/sql/repo.d.ts +82 -0
  82. package/dist/redirects/sql/repo.js +143 -0
  83. package/dist/redirects/sql/repo.rows.d.ts +49 -0
  84. package/dist/redirects/sql/repo.rows.js +79 -0
  85. package/dist/redirects/sql/row-types.d.ts +34 -0
  86. package/dist/redirects/sql/row-types.js +2 -0
  87. package/dist/redirects/target-gate.d.ts +30 -0
  88. package/dist/redirects/target-gate.js +85 -0
  89. package/dist/redirects/types.d.ts +213 -0
  90. package/dist/redirects/types.js +42 -0
  91. package/dist/seo/absolute-url.d.ts +58 -0
  92. package/dist/seo/absolute-url.js +117 -0
  93. package/dist/seo/dom/index.d.ts +14 -0
  94. package/dist/seo/dom/index.js +52 -0
  95. package/dist/seo/errors.d.ts +35 -0
  96. package/dist/seo/errors.js +35 -0
  97. package/dist/seo/feed.d.ts +49 -0
  98. package/dist/seo/feed.js +61 -0
  99. package/dist/seo/index.d.ts +13 -0
  100. package/dist/seo/index.js +13 -0
  101. package/dist/seo/media.d.ts +57 -0
  102. package/dist/seo/media.js +134 -0
  103. package/dist/seo/page-head.d.ts +18 -0
  104. package/dist/seo/page-head.js +114 -0
  105. package/dist/seo/ports.d.ts +221 -0
  106. package/dist/seo/ports.js +27 -0
  107. package/dist/seo/seo.d.ts +73 -0
  108. package/dist/seo/seo.js +230 -0
  109. package/dist/seo/sitemap.d.ts +139 -0
  110. package/dist/seo/sitemap.js +217 -0
  111. package/dist/seo/types.d.ts +278 -0
  112. package/dist/seo/types.js +2 -0
  113. package/dist/seo/write-service.d.ts +79 -0
  114. package/dist/seo/write-service.js +273 -0
  115. package/dist/seo/xml-escape.d.ts +16 -0
  116. package/dist/seo/xml-escape.js +19 -0
  117. package/dist/settings/express/cms-adapter.d.ts +20 -0
  118. package/dist/settings/express/cms-adapter.js +124 -0
  119. package/dist/settings/express/contracts.d.ts +135 -0
  120. package/dist/settings/express/contracts.js +2 -0
  121. package/dist/settings/express/http.d.ts +10 -0
  122. package/dist/settings/express/http.js +211 -0
  123. package/dist/settings/express/index.d.ts +5 -0
  124. package/dist/settings/express/index.js +5 -0
  125. package/dist/settings/express/shared.d.ts +68 -0
  126. package/dist/settings/express/shared.js +54 -0
  127. package/dist/settings/express/stream.d.ts +24 -0
  128. package/dist/settings/express/stream.js +147 -0
  129. package/dist/settings/index.d.ts +3 -38
  130. package/dist/settings/index.js +3 -35
  131. package/dist/taxonomy/write-service.d.ts +2 -30
  132. package/dist/widgets/authorize-helper.d.ts +42 -0
  133. package/dist/widgets/authorize-helper.js +16 -0
  134. package/dist/widgets/concurrency.d.ts +12 -0
  135. package/dist/widgets/concurrency.js +44 -0
  136. package/dist/widgets/config-validation.d.ts +34 -0
  137. package/dist/widgets/config-validation.js +125 -0
  138. package/dist/widgets/embed-service.d.ts +133 -0
  139. package/dist/widgets/embed-service.js +460 -0
  140. package/dist/widgets/embed-validation.d.ts +23 -0
  141. package/dist/widgets/embed-validation.js +38 -0
  142. package/dist/widgets/entry-payload.d.ts +103 -0
  143. package/dist/widgets/entry-payload.js +160 -0
  144. package/dist/widgets/errors.d.ts +136 -0
  145. package/dist/widgets/errors.js +136 -0
  146. package/dist/widgets/host-ports.d.ts +149 -0
  147. package/dist/widgets/host-ports.js +2 -0
  148. package/dist/widgets/html/html-embeds.d.ts +247 -0
  149. package/dist/widgets/html/html-embeds.js +408 -0
  150. package/dist/widgets/html/index.d.ts +5 -0
  151. package/dist/widgets/html/index.js +4 -0
  152. package/dist/widgets/html/legacy-widget-markers.d.ts +8 -0
  153. package/dist/widgets/html/legacy-widget-markers.js +45 -0
  154. package/dist/widgets/html/resolve-html-page-embeds.d.ts +42 -0
  155. package/dist/widgets/html/resolve-html-page-embeds.js +57 -0
  156. package/dist/widgets/index.d.ts +20 -0
  157. package/dist/widgets/index.js +19 -0
  158. package/dist/widgets/markers/html-attributes.d.ts +98 -0
  159. package/dist/widgets/markers/html-attributes.js +216 -0
  160. package/dist/widgets/markers/index.d.ts +3 -0
  161. package/dist/widgets/markers/index.js +3 -0
  162. package/dist/widgets/markers/marker.d.ts +496 -0
  163. package/dist/widgets/markers/marker.js +780 -0
  164. package/dist/widgets/page-embed-types.d.ts +42 -0
  165. package/dist/widgets/page-embed-types.js +42 -0
  166. package/dist/widgets/ports.d.ts +142 -0
  167. package/dist/widgets/ports.js +2 -0
  168. package/dist/widgets/read-service.d.ts +81 -0
  169. package/dist/widgets/read-service.js +79 -0
  170. package/dist/widgets/region-area-service.d.ts +110 -0
  171. package/dist/widgets/region-area-service.js +180 -0
  172. package/dist/widgets/registry.d.ts +217 -0
  173. package/dist/widgets/registry.js +172 -0
  174. package/dist/widgets/repo.memory.d.ts +41 -0
  175. package/dist/widgets/repo.memory.js +48 -0
  176. package/dist/widgets/resolver-service.d.ts +209 -0
  177. package/dist/widgets/resolver-service.js +909 -0
  178. package/dist/widgets/resolvers/contact-form.d.ts +26 -0
  179. package/dist/widgets/resolvers/contact-form.js +54 -0
  180. package/dist/widgets/resolvers/create-core-resolvers.d.ts +34 -0
  181. package/dist/widgets/resolvers/create-core-resolvers.js +11 -0
  182. package/dist/widgets/resolvers/index.d.ts +65 -0
  183. package/dist/widgets/resolvers/index.js +155 -0
  184. package/dist/widgets/resolvers/menu.d.ts +42 -0
  185. package/dist/widgets/resolvers/menu.js +43 -0
  186. package/dist/widgets/resolvers/ports.d.ts +82 -0
  187. package/dist/widgets/resolvers/ports.js +2 -0
  188. package/dist/widgets/resolvers/recent-entries.d.ts +71 -0
  189. package/dist/widgets/resolvers/recent-entries.js +165 -0
  190. package/dist/widgets/resolvers/taxonomy.d.ts +12 -0
  191. package/dist/widgets/resolvers/taxonomy.js +34 -0
  192. package/dist/widgets/sql/index.d.ts +3 -0
  193. package/dist/widgets/sql/index.js +3 -0
  194. package/dist/widgets/sql/repo.d.ts +41 -0
  195. package/dist/widgets/sql/repo.js +82 -0
  196. package/dist/widgets/sql/tables.d.ts +13 -0
  197. package/dist/widgets/sql/tables.js +2 -0
  198. package/dist/widgets/types.d.ts +213 -0
  199. package/dist/widgets/types.js +17 -0
  200. package/dist/widgets/where-used.d.ts +41 -0
  201. package/dist/widgets/where-used.js +11 -0
  202. package/dist/widgets/write-service.d.ts +204 -0
  203. package/dist/widgets/write-service.js +332 -0
  204. package/dist/workspace/delete.d.ts +1 -1
  205. package/package.json +220 -11
@@ -0,0 +1,226 @@
1
+ /**
2
+ * @file THE `redirects` write chokepoint (SPEC-009 REQ-01/04/05/06/07/08/13/
3
+ * 14/22/26; ADR-PIPE-009 C-001..C-004).
4
+ *
5
+ * Purpose:
6
+ * `createRedirect`/`updateRedirect`/`tombstoneRedirect`/`importRedirects` —
7
+ * the single manual-write entry point for redirect rules. Validates the
8
+ * pattern (via `RedirectMatcher.validatePattern`), rejects unsafe targets —
9
+ * absolute ones against the origin allowlist and site-relative ones against
10
+ * the admin application's own URL space (write-path open-redirect oracle,
11
+ * REQ-08; see `assertTargetAllowed`) — collapses/rejects
12
+ * one-hop chains (INV-04), enforces the exact-match dedup rule
13
+ * (behavior.spec.md §5.1), and writes the record + its revision in one
14
+ * transaction via `ports.internal.ts`'s shared `insertRedirectAndRevision`
15
+ * (INV-01/INV-07 — no other file writes `redirects`/`redirect_revisions`).
16
+ *
17
+ * Architectural role:
18
+ * Feature logic. No Express/route code — route handlers (Phase 2) call these
19
+ * functions directly and map thrown typed errors to HTTP codes per
20
+ * errors.spec.md.
21
+ */
22
+ import { type Clock as ClockPort, type IdGenerator as IdGeneratorPort } from "@jini-ai/core/primitives";
23
+ import { type OutboxPort } from "../core/index.js";
24
+ import type { OriginRegistryPort } from "@jini-ai/http-kit/verified-origin";
25
+ import { type RedirectDbHandle } from "./ports.internal.js";
26
+ import type { RedirectMatcher, RedirectRepoPort } from "./ports.js";
27
+ import type { CreateRedirectInput, RedirectMatchType, RedirectRecord, RedirectStatusCode, UpdateRedirectInput } from "./types.js";
28
+ export declare const MIN_TARGET_LENGTH = 1;
29
+ export declare const MAX_TARGET_LENGTH = 2048;
30
+ export declare const MIN_PRIORITY = 0;
31
+ export declare const MAX_PRIORITY = 1000;
32
+ export declare const VALID_STATUS_CODES: readonly RedirectStatusCode[];
33
+ export declare const MAX_IMPORT_BATCH_SIZE = 500;
34
+ /**
35
+ * The removal primitive this domain is handed, rather than one it implements.
36
+ *
37
+ * Structurally typed ON PURPOSE — `features/redirects` imports nothing from `features/trash`, and
38
+ * must not. The composition root binds the real implementation (marker flip AND Trash index row, in
39
+ * one transaction) pre-bound to this domain's entity type. `display` is required so the two strings
40
+ * the Trash screen shows come from columns the caller already holds.
41
+ */
42
+ export type RemoveRedirectFn = (required: {
43
+ workspaceId: string;
44
+ id: string;
45
+ display: {
46
+ title: string;
47
+ subtitle?: string | null;
48
+ };
49
+ at: string;
50
+ expectedVersion: number | null;
51
+ actor: {
52
+ principalId: string;
53
+ pluginId?: string | null;
54
+ };
55
+ }) => Promise<{
56
+ ok: true;
57
+ version: number | null;
58
+ } | {
59
+ ok: false;
60
+ reason: "not-found" | "version-changed";
61
+ }>;
62
+ export interface RedirectsWriteDeps {
63
+ repo: RedirectRepoPort;
64
+ /** See {@link RemoveRedirectFn}. Replaces `tombstoneRedirect`'s own `status` write. */
65
+ remove: RemoveRedirectFn;
66
+ /**
67
+ * Whether this rule has a Trash index row (S7, web-high fix plan 2026-09-24) — the thing
68
+ * `tombstoneRedirect` creates and Trash restore/purge match on, and NOT the same thing as
69
+ * `status === "disabled"` (an ordinary toggle-off has no Trash row at all). Structurally typed,
70
+ * same discipline as {@link RemoveRedirectFn}: this domain imports nothing from `features/trash`.
71
+ */
72
+ isInTrash: (required: {
73
+ workspaceId: string;
74
+ id: string;
75
+ }) => Promise<boolean>;
76
+ /**
77
+ * Un-trashes this rule (S7). Mirrors `TrashPort.restore`'s outcome union structurally, again
78
+ * without importing `features/trash`. `"adapter-unavailable"` is not reachable for redirects (the
79
+ * composition root always registers an adapter for `REDIRECT_ENTITY_TYPE`), but is part of the
80
+ * union it mirrors.
81
+ */
82
+ restore: (required: {
83
+ workspaceId: string;
84
+ id: string;
85
+ at: string;
86
+ actor: {
87
+ principalId: string;
88
+ pluginId?: string | null;
89
+ };
90
+ }) => Promise<"restored" | "not-found" | "version-changed" | "adapter-unavailable">;
91
+ /** The shared, non-tx-opening write handle (Decision A) — used via `ports.internal.ts`. */
92
+ db: RedirectDbHandle;
93
+ /** Opens/commits/rolls back the chokepoint's own transaction around a write. */
94
+ transaction: <T>(fn: () => Promise<T>) => Promise<T>;
95
+ matcher: RedirectMatcher;
96
+ originRegistry: OriginRegistryPort;
97
+ /** First path segments reserved by the composing host; no product-policy default. */
98
+ reservedSegments: ReadonlySet<string>;
99
+ clock: ClockPort;
100
+ idGen: IdGeneratorPort;
101
+ outbox: OutboxPort;
102
+ }
103
+ /**
104
+ * The site-relative half of the write gate: routing's structural + reserved-path verdict, then the
105
+ * redirect oracle's own raw-character rule. The read path hands a relative location to that oracle
106
+ * by concatenation, so a target it refuses (a raw backslash, any whitespace) would be stored and
107
+ * never fire; refusing it here keeps write and read agreeing. Checked SECOND so the more specific
108
+ * routing reasons (off-origin, control character, reserved) keep their own wording — a bare
109
+ * backslash target is `ok` to `checkSiteRelativeTarget` (on this site, `\` really does resolve to
110
+ * `/`), so only this second check ever refuses it (t91 B2, 2026-09-16). Last, the exact target
111
+ * `back`, which Express serves as the visitor's `Referer` instead of a path (see
112
+ * `./referrer-alias.ts`; t91 review F1, 2026-09-16).
113
+ *
114
+ * Exported as THE check for any caller-chosen, site-relative `Location` (t91 open-redirect fix,
115
+ * 2026-09-16): `routes/site/store.ts`'s `returnTo` had its own `startsWith("/") && !startsWith("//")`
116
+ * copy, which `/\evil.example` walks straight through. A caller that needs a path-absolute value
117
+ * still checks `startsWith("/")` itself — this function also accepts relative references (`new`,
118
+ * `?x`), which stay on-site but resolve against the current URL.
119
+ *
120
+ * @param required.target - The untrusted reference exactly as received, before any `new URL()` parse. Anything
121
+ * that is not site-relative (an absolute or protocol-relative URL, `javascript:`) is refused too.
122
+ * @returns The reason clause, or `null` when the target is allowed.
123
+ * @complexity O(n) in the target length.
124
+ * @example siteRelativeTargetReason({ target: "/products", reservedSegments }, {}); // => null
125
+ * @example siteRelativeTargetReason({ target: "/\\evil.example", reservedSegments }, {}) !== null; // => true
126
+ */
127
+ export declare function siteRelativeTargetReason({ target, reservedSegments }: {
128
+ target: string;
129
+ reservedSegments: ReadonlySet<string>;
130
+ }, _optional?: Record<string, never>): string | null;
131
+ /**
132
+ * Pure precondition check mirroring every validator `createRedirect`/`updateRedirect` run, with NO
133
+ * write — `features/redirects/publish-content.ts`'s `precheck()` reuses this so the two can never
134
+ * drift onto different rulesets. Returns the refusal message a create/update against these exact
135
+ * fields would throw, or `null` when nothing would block.
136
+ *
137
+ * @param excludeId Mirrors {@link assertNoDuplicate}'s own parameter — the destination's own row id,
138
+ * when checking an update against itself.
139
+ * @complexity O(n) in `toTarget`'s length, plus the repo/origin reads each check makes — identical
140
+ * cost to `createRedirect`'s own validation pass, since this runs the exact same sequence.
141
+ */
142
+ export declare function checkRedirectFieldsWouldWrite({ deps, fields }: {
143
+ deps: RedirectsWriteDeps;
144
+ fields: {
145
+ workspaceId: string;
146
+ matchType: RedirectMatchType;
147
+ fromPattern: string;
148
+ toTarget: string;
149
+ statusCode: RedirectStatusCode;
150
+ priority: number;
151
+ };
152
+ }, { excludeId }?: {
153
+ excludeId?: string;
154
+ }): Promise<string | null>;
155
+ export interface CreateRedirectRequired {
156
+ deps: RedirectsWriteDeps;
157
+ input: CreateRedirectInput;
158
+ /**
159
+ * Provenance to stamp on the created record (REQ-01/26). Defaults to
160
+ * `'manual'`. `importRedirects` (C-004) passes `'import'` here — this is
161
+ * an internal parameter, not part of `CreateRedirectInput`'s public shape
162
+ * (an API caller never chooses their own provenance).
163
+ */
164
+ source?: "manual" | "import";
165
+ }
166
+ /** C-001: manual-create entry point (REQ-01). */
167
+ export declare function createRedirect(required: CreateRedirectRequired, _optional?: Record<string, never>): Promise<{
168
+ record: RedirectRecord;
169
+ }>;
170
+ export interface UpdateRedirectRequired {
171
+ deps: RedirectsWriteDeps;
172
+ input: UpdateRedirectInput;
173
+ }
174
+ /**
175
+ * C-002: symmetric chokepoint entry for updates (REQ-04). A disable-only update
176
+ * ({@link isDisableOnlyUpdate}) writes the status change without re-validating the unchanged fields
177
+ * — it stores the existing target as-is, with no one-hop collapse.
178
+ *
179
+ * S7 (web-high fix plan 2026-09-24): a rule with a Trash index row (`deps.isInTrash`, distinct from
180
+ * `status === "disabled"` — see {@link RedirectsWriteDeps.isInTrash}'s own doc) refuses every update
181
+ * EXCEPT a pure `status: "active"` PATCH ({@link isRestoreOnlyUpdate}), which restores it instead of
182
+ * editing a row the caller cannot see the current shape of.
183
+ *
184
+ * @throws {EntityNotLiveError} On a non-restore update to a rule in the Trash.
185
+ * @throws {RedirectConflictError} If the Trash row's version moved before the restore landed.
186
+ */
187
+ export declare function updateRedirect(required: UpdateRedirectRequired, _optional?: Record<string, never>): Promise<{
188
+ record: RedirectRecord;
189
+ }>;
190
+ export interface TombstoneRedirectRequired {
191
+ deps: RedirectsWriteDeps;
192
+ input: {
193
+ workspaceId: string;
194
+ id: string;
195
+ actorId: string;
196
+ pluginId?: string;
197
+ };
198
+ }
199
+ /** C-003: soft-delete (REQ-05). */
200
+ export declare function tombstoneRedirect(required: TombstoneRedirectRequired, _optional?: Record<string, never>): Promise<{
201
+ record: RedirectRecord;
202
+ }>;
203
+ export interface ImportRedirectsRequired {
204
+ deps: RedirectsWriteDeps;
205
+ input: {
206
+ workspaceId: string;
207
+ actorId: string;
208
+ rules: CreateRedirectInput[];
209
+ };
210
+ }
211
+ export interface ImportRedirectsFailure {
212
+ index: number;
213
+ code: string;
214
+ message: string;
215
+ }
216
+ /**
217
+ * C-004: batch-create reusing the same chokepoint, no bypass (REQ-26). Each
218
+ * item is processed independently through `createRedirect` — NOT one shared
219
+ * transaction across items (EC-08); a per-item failure does not abort
220
+ * already-written prior items.
221
+ */
222
+ export declare function importRedirects(required: ImportRedirectsRequired, _optional?: Record<string, never>): Promise<{
223
+ created: RedirectRecord[];
224
+ failed: ImportRedirectsFailure[];
225
+ }>;
226
+ //# sourceMappingURL=redirects.d.ts.map