@mailwoman/api 8.6.0 → 9.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/out/schema.d.ts CHANGED
@@ -6,9 +6,9 @@
6
6
  * Zod wire schemas for the native `/v1` surface. Unlike the drop-ins (photon, nominatim,
7
7
  * libpostal), nothing here is a vendor contract — this surface is ours to design, so request
8
8
  * bodies are REQUIRED and validator-enforced (no legacy tolerance to preserve). A `defaultHook`
9
- * on the app (wired in Task 3) maps validation failures through the shared `APIErrorSchema`
10
- * envelope (`apiError(c, 400, "invalid request body", <zod summary>)`) — the documented pattern
11
- * boundary from phase 2: where no legacy contract exists, the validator MAY speak, but only in
9
+ * on the app maps validation failures through the shared `APIErrorSchema` envelope
10
+ * (`apiError(c, 400, "invalid request body", <zod summary>)`) — the pattern boundary every
11
+ * surface holds to: where no legacy contract exists, the validator MAY speak, but only in
12
12
  * our envelope.
13
13
  *
14
14
  * `APIErrorSchema` itself is owned by `@mailwoman/api-kit` (plumbing shared by every native
@@ -29,6 +29,20 @@ export declare const InputModeSchema: z.ZodEnum<{
29
29
  fragmented: "fragmented";
30
30
  formatted: "formatted";
31
31
  }>;
32
+ /**
33
+ * Longest accepted `address`, in characters.
34
+ *
35
+ * Sized against what the model can actually read, not against a guess at abuse. The classifier's window is 128
36
+ * SentencePiece pieces — roughly 330 characters of address text — and everything past it is truncated before inference,
37
+ * so input beyond this bound cannot influence a result. The margin over that window leaves room for scripts that
38
+ * tokenize denser than Latin, and for the department-and-division prefixes web forms concatenate.
39
+ *
40
+ * The bound exists because preprocessing is linear but not free: a 1 MB body costs ~1.7 s across normalize, query-shape
41
+ * and the phrase grouper, and Node runs them on the one thread every other request is waiting on. A cap here is cheaper
42
+ * than fairness plumbing, and rejecting is more honest than accepting a body whose tail the parser will silently
43
+ * discard.
44
+ */
45
+ export declare const MAX_ADDRESS_LENGTH = 1024;
32
46
  /**
33
47
  * `POST /v1/parse` request body.
34
48
  */
@@ -85,12 +99,39 @@ export declare const GeocodeRequestSchema: z.ZodObject<{
85
99
  */
86
100
  export declare const GeocodeOutcomeSchema: z.ZodObject<{
87
101
  input: z.ZodString;
102
+ components: z.ZodRecord<z.ZodEnum<{
103
+ country: "country";
104
+ region: "region";
105
+ locality: "locality";
106
+ dependent_locality: "dependent_locality";
107
+ postcode: "postcode";
108
+ subregion: "subregion";
109
+ house_number: "house_number";
110
+ street: "street";
111
+ street_prefix: "street_prefix";
112
+ street_prefix_particle: "street_prefix_particle";
113
+ street_suffix: "street_suffix";
114
+ intersection_a: "intersection_a";
115
+ intersection_b: "intersection_b";
116
+ unit: "unit";
117
+ venue: "venue";
118
+ attention: "attention";
119
+ po_box: "po_box";
120
+ cedex: "cedex";
121
+ prefecture: "prefecture";
122
+ municipality: "municipality";
123
+ district: "district";
124
+ block: "block";
125
+ sub_block: "sub_block";
126
+ building_number: "building_number";
127
+ building_name: "building_name";
128
+ }> & z.core.$partial, z.ZodString>;
88
129
  lat: z.ZodNullable<z.ZodNumber>;
89
130
  lon: z.ZodNullable<z.ZodNumber>;
90
131
  resolution_tier: z.ZodEnum<{
132
+ street: "street";
91
133
  address_point: "address_point";
92
134
  interpolated: "interpolated";
93
- street: "street";
94
135
  admin: "admin";
95
136
  }>;
96
137
  uncertainty_m: z.ZodNullable<z.ZodNumber>;
@@ -101,6 +142,7 @@ export declare const GeocodeOutcomeSchema: z.ZodObject<{
101
142
  street: z.ZodNullable<z.ZodString>;
102
143
  venue: z.ZodNullable<z.ZodString>;
103
144
  dependent_locality: z.ZodNullable<z.ZodString>;
145
+ unit: z.ZodNullable<z.ZodString>;
104
146
  countryCode: z.ZodNullable<z.ZodString>;
105
147
  hierarchy: z.ZodArray<z.ZodObject<{
106
148
  tag: z.ZodString;
@@ -118,6 +160,32 @@ export declare const GeocodeOutcomeSchema: z.ZodObject<{
118
160
  countryCode: z.ZodNullable<z.ZodString>;
119
161
  placeID: z.ZodOptional<z.ZodString>;
120
162
  }, z.core.$strip>>;
163
+ postcode_country_scope: z.ZodNullable<z.ZodString>;
164
+ intent_markers: z.ZodArray<z.ZodObject<{
165
+ kind: z.ZodEnum<{
166
+ intersection: "intersection";
167
+ po_box: "po_box";
168
+ postcode_only: "postcode_only";
169
+ locality_only: "locality_only";
170
+ structured_address: "structured_address";
171
+ landmark: "landmark";
172
+ poi_query: "poi_query";
173
+ vague: "vague";
174
+ bare_toponym: "bare_toponym";
175
+ route_pair: "route_pair";
176
+ near_me: "near_me";
177
+ poi_category: "poi_category";
178
+ }>;
179
+ code: z.ZodEnum<{
180
+ poi_category: "poi_category";
181
+ declared_ambiguity: "declared_ambiguity";
182
+ declared_fork: "declared_fork";
183
+ focus_point_required: "focus_point_required";
184
+ }>;
185
+ mechanism: z.ZodString;
186
+ message: z.ZodString;
187
+ evidence: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
188
+ }, z.core.$strip>>;
121
189
  }, z.core.$loose>;
122
190
  /**
123
191
  * `POST /v1/batch` request body.
@@ -135,12 +203,39 @@ export declare const BatchRequestSchema: z.ZodObject<{
135
203
  export declare const BatchResponseSchema: z.ZodObject<{
136
204
  results: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
137
205
  input: z.ZodString;
206
+ components: z.ZodRecord<z.ZodEnum<{
207
+ country: "country";
208
+ region: "region";
209
+ locality: "locality";
210
+ dependent_locality: "dependent_locality";
211
+ postcode: "postcode";
212
+ subregion: "subregion";
213
+ house_number: "house_number";
214
+ street: "street";
215
+ street_prefix: "street_prefix";
216
+ street_prefix_particle: "street_prefix_particle";
217
+ street_suffix: "street_suffix";
218
+ intersection_a: "intersection_a";
219
+ intersection_b: "intersection_b";
220
+ unit: "unit";
221
+ venue: "venue";
222
+ attention: "attention";
223
+ po_box: "po_box";
224
+ cedex: "cedex";
225
+ prefecture: "prefecture";
226
+ municipality: "municipality";
227
+ district: "district";
228
+ block: "block";
229
+ sub_block: "sub_block";
230
+ building_number: "building_number";
231
+ building_name: "building_name";
232
+ }> & z.core.$partial, z.ZodString>;
138
233
  lat: z.ZodNullable<z.ZodNumber>;
139
234
  lon: z.ZodNullable<z.ZodNumber>;
140
235
  resolution_tier: z.ZodEnum<{
236
+ street: "street";
141
237
  address_point: "address_point";
142
238
  interpolated: "interpolated";
143
- street: "street";
144
239
  admin: "admin";
145
240
  }>;
146
241
  uncertainty_m: z.ZodNullable<z.ZodNumber>;
@@ -151,6 +246,7 @@ export declare const BatchResponseSchema: z.ZodObject<{
151
246
  street: z.ZodNullable<z.ZodString>;
152
247
  venue: z.ZodNullable<z.ZodString>;
153
248
  dependent_locality: z.ZodNullable<z.ZodString>;
249
+ unit: z.ZodNullable<z.ZodString>;
154
250
  countryCode: z.ZodNullable<z.ZodString>;
155
251
  hierarchy: z.ZodArray<z.ZodObject<{
156
252
  tag: z.ZodString;
@@ -168,6 +264,32 @@ export declare const BatchResponseSchema: z.ZodObject<{
168
264
  countryCode: z.ZodNullable<z.ZodString>;
169
265
  placeID: z.ZodOptional<z.ZodString>;
170
266
  }, z.core.$strip>>;
267
+ postcode_country_scope: z.ZodNullable<z.ZodString>;
268
+ intent_markers: z.ZodArray<z.ZodObject<{
269
+ kind: z.ZodEnum<{
270
+ intersection: "intersection";
271
+ po_box: "po_box";
272
+ postcode_only: "postcode_only";
273
+ locality_only: "locality_only";
274
+ structured_address: "structured_address";
275
+ landmark: "landmark";
276
+ poi_query: "poi_query";
277
+ vague: "vague";
278
+ bare_toponym: "bare_toponym";
279
+ route_pair: "route_pair";
280
+ near_me: "near_me";
281
+ poi_category: "poi_category";
282
+ }>;
283
+ code: z.ZodEnum<{
284
+ poi_category: "poi_category";
285
+ declared_ambiguity: "declared_ambiguity";
286
+ declared_fork: "declared_fork";
287
+ focus_point_required: "focus_point_required";
288
+ }>;
289
+ mechanism: z.ZodString;
290
+ message: z.ZodString;
291
+ evidence: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
292
+ }, z.core.$strip>>;
171
293
  }, z.core.$loose>, z.ZodObject<{
172
294
  input: z.ZodString;
173
295
  error: z.ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAA;AAErC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAEnD;;GAEG;AACH;;;;GAIG;AACH,eAAO,MAAM,eAAe;;;EAA2D,CAAA;AAEvF;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;iBAMN,CAAA;AAEzB;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;iBAA6E,CAAA;AAE9G;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;iBAON,CAAA;AAEzB;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;iBAKN,CAAA;AAiC3B;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqBN,CAAA;AAE3B;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;iBAQN,CAAA;AAYzB;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAIN,CAAA;AAE1B;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;iBAKN,CAAA;AAE3B;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;iBAIN,CAAA;AAQ5B;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;iBAMN,CAAA;AAE1B;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;iBAKN,CAAA;AAE3B;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;iBAMN,CAAA"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAA;AAErC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAEnD;;GAEG;AACH;;;;GAIG;AACH,eAAO,MAAM,eAAe;;;EAA2D,CAAA;AAEvF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,OAAO,CAAA;AAEtC;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;iBAMN,CAAA;AAEzB;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;iBAA6E,CAAA;AAE9G;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;iBAON,CAAA;AAEzB;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;iBAKN,CAAA;AAuG3B;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+BN,CAAA;AAE3B;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;iBAUN,CAAA;AAYzB;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAIN,CAAA;AAE1B;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;iBAKN,CAAA;AAE3B;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;iBAIN,CAAA;AAQ5B;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;iBAMN,CAAA;AAE1B;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;iBAKN,CAAA;AAE3B;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;iBAMN,CAAA"}
package/out/schema.js CHANGED
@@ -6,9 +6,9 @@
6
6
  * Zod wire schemas for the native `/v1` surface. Unlike the drop-ins (photon, nominatim,
7
7
  * libpostal), nothing here is a vendor contract — this surface is ours to design, so request
8
8
  * bodies are REQUIRED and validator-enforced (no legacy tolerance to preserve). A `defaultHook`
9
- * on the app (wired in Task 3) maps validation failures through the shared `APIErrorSchema`
10
- * envelope (`apiError(c, 400, "invalid request body", <zod summary>)`) — the documented pattern
11
- * boundary from phase 2: where no legacy contract exists, the validator MAY speak, but only in
9
+ * on the app maps validation failures through the shared `APIErrorSchema` envelope
10
+ * (`apiError(c, 400, "invalid request body", <zod summary>)`) — the pattern boundary every
11
+ * surface holds to: where no legacy contract exists, the validator MAY speak, but only in
12
12
  * our envelope.
13
13
  *
14
14
  * `APIErrorSchema` itself is owned by `@mailwoman/api-kit` (plumbing shared by every native
@@ -26,12 +26,26 @@ export { APIErrorSchema } from "@mailwoman/api-kit";
26
26
  * `/v1/batch` defaults to `formatted` (batch rows are the record register by nature).
27
27
  */
28
28
  export const InputModeSchema = z.enum(["fragmented", "formatted"]).openapi("InputMode");
29
+ /**
30
+ * Longest accepted `address`, in characters.
31
+ *
32
+ * Sized against what the model can actually read, not against a guess at abuse. The classifier's window is 128
33
+ * SentencePiece pieces — roughly 330 characters of address text — and everything past it is truncated before inference,
34
+ * so input beyond this bound cannot influence a result. The margin over that window leaves room for scripts that
35
+ * tokenize denser than Latin, and for the department-and-division prefixes web forms concatenate.
36
+ *
37
+ * The bound exists because preprocessing is linear but not free: a 1 MB body costs ~1.7 s across normalize, query-shape
38
+ * and the phrase grouper, and Node runs them on the one thread every other request is waiting on. A cap here is cheaper
39
+ * than fairness plumbing, and rejecting is more honest than accepting a body whose tail the parser will silently
40
+ * discard.
41
+ */
42
+ export const MAX_ADDRESS_LENGTH = 1024;
29
43
  /**
30
44
  * `POST /v1/parse` request body.
31
45
  */
32
46
  export const ParseRequestSchema = z
33
47
  .object({
34
- address: z.string(),
48
+ address: z.string().max(MAX_ADDRESS_LENGTH),
35
49
  debug: z.boolean().optional(),
36
50
  input_mode: InputModeSchema.optional(),
37
51
  })
@@ -58,7 +72,7 @@ export const ParseOutcomeSchema = z
58
72
  */
59
73
  export const GeocodeRequestSchema = z
60
74
  .object({
61
- address: z.string(),
75
+ address: z.string().max(MAX_ADDRESS_LENGTH),
62
76
  input_mode: InputModeSchema.optional(),
63
77
  })
64
78
  .openapi("GeocodeRequest");
@@ -91,6 +105,71 @@ const GeocodeCandidateSchema = z
91
105
  placeID: z.string().optional(),
92
106
  })
93
107
  .openapi("GeocodeCandidate");
108
+ /**
109
+ * Canonical parsed-component map carried by `GeocodeResult.components`. Spelled out at this engine-agnostic API
110
+ * boundary for the same reason the result schema is hand-modeled; the compile-time drift pin in
111
+ * `mailwoman/test/api-schema-drift.test.ts` catches any mismatch with the real `ComponentTag`-keyed result type.
112
+ */
113
+ const GeocodeComponentsSchema = z.partialRecord(z.enum([
114
+ "country",
115
+ "region",
116
+ "locality",
117
+ "dependent_locality",
118
+ "postcode",
119
+ "subregion",
120
+ "house_number",
121
+ "street",
122
+ "street_prefix",
123
+ "street_prefix_particle",
124
+ "street_suffix",
125
+ "intersection_a",
126
+ "intersection_b",
127
+ "unit",
128
+ "venue",
129
+ "attention",
130
+ "po_box",
131
+ "cedex",
132
+ "prefecture",
133
+ "municipality",
134
+ "district",
135
+ "block",
136
+ "sub_block",
137
+ "building_number",
138
+ "building_name",
139
+ ]), z.string());
140
+ /**
141
+ * One `GeocodeOutcome.intent_markers` entry — an advisory the ROAD_TO_V9 §4 intent vocabulary raised about the QUERY.
142
+ * Mirrors `QueryIntentMarker` (`core/pipeline/types.ts`).
143
+ *
144
+ * `evidence` is deliberately open (`z.record`): each `code` carries its own measurement — a dominance margin, a pair of
145
+ * interpretations, a taxonomy id — and flattening those into one closed shape would either lose the numbers or invent
146
+ * fields that do not apply. `code` is the discriminator a client branches on.
147
+ */
148
+ const QueryIntentMarkerSchema = z
149
+ .object({
150
+ // Spelled out rather than `z.string()` so `mailwoman/test/api-schema-drift.test.ts`'s schema-too-wide direction
151
+ // keeps biting: a new `QueryKind` that never reaches this list is a documented contract that has quietly stopped
152
+ // describing the real one.
153
+ kind: z.enum([
154
+ "postcode_only",
155
+ "locality_only",
156
+ "structured_address",
157
+ "intersection",
158
+ "po_box",
159
+ "landmark",
160
+ "poi_query",
161
+ "vague",
162
+ "bare_toponym",
163
+ "route_pair",
164
+ "near_me",
165
+ "poi_category",
166
+ ]),
167
+ code: z.enum(["declared_ambiguity", "declared_fork", "focus_point_required", "poi_category"]),
168
+ mechanism: z.string(),
169
+ message: z.string(),
170
+ evidence: z.record(z.string(), z.unknown()).optional(),
171
+ })
172
+ .openapi("QueryIntentMarker");
94
173
  /**
95
174
  * `POST /v1/geocode` response — a hand-modeled mirror of `GeocodeResult`'s wire shape (`mailwoman/geocode-core.ts`),
96
175
  * `.loose()` so a field the engine adds that this schema doesn't yet know about still rides through undocumented rather
@@ -104,6 +183,7 @@ const GeocodeCandidateSchema = z
104
183
  export const GeocodeOutcomeSchema = z
105
184
  .object({
106
185
  input: z.string(),
186
+ components: GeocodeComponentsSchema,
107
187
  lat: z.number().nullable(),
108
188
  lon: z.number().nullable(),
109
189
  resolution_tier: z.enum(["address_point", "interpolated", "street", "admin"]),
@@ -117,9 +197,18 @@ export const GeocodeOutcomeSchema = z
117
197
  venue: z.string().nullable(),
118
198
  // The parsed dependent-locality span (parse view; `hierarchy` is the resolved view).
119
199
  dependent_locality: z.string().nullable(),
200
+ // The parsed unit / sub-venue span (parse view) — "Terminal 5", "Suite 300".
201
+ unit: z.string().nullable(),
120
202
  countryCode: z.string().nullable(),
121
203
  hierarchy: z.array(GeocodeHierarchyEntrySchema),
122
204
  candidates: z.array(GeocodeCandidateSchema),
205
+ // #42: the country the postcode-country coherence pass scoped the walk to, or null. Non-null ONLY when it
206
+ // OVERRODE the request's country prior — so a caller who asked for US and got an FR answer can see which
207
+ // evidence bought the change instead of reading it as a bug.
208
+ postcode_country_scope: z.string().nullable(),
209
+ // ROAD_TO_V9 §4: query-intent advisories. Always present; empty means the vocabulary looked and had nothing to
210
+ // say. Advisory ONLY — no marker changed which answer won, and a client is free to ignore the array entirely.
211
+ intent_markers: z.array(QueryIntentMarkerSchema),
123
212
  })
124
213
  .loose()
125
214
  .openapi("GeocodeOutcome");
@@ -128,7 +217,9 @@ export const GeocodeOutcomeSchema = z
128
217
  */
129
218
  export const BatchRequestSchema = z
130
219
  .object({
131
- addresses: z.array(z.string()),
220
+ // Per-ROW, not just per-request: the row cap (`batchMax`, default 500) bounds how many addresses arrive,
221
+ // and this bounds how large each may be. Without both, one request is 500 unbounded bodies.
222
+ addresses: z.array(z.string().max(MAX_ADDRESS_LENGTH)),
132
223
  /**
133
224
  * Register override for every row. DEFAULT `"formatted"` — batch rows are the record register by nature.
134
225
  */
package/out/schema.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../schema.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mailwoman/api",
3
- "version": "8.6.0",
3
+ "version": "9.1.0",
4
4
  "description": "The native Mailwoman HTTP API — engine-agnostic /v1 surface (parse, geocode, batch, resolve, format) with health, metrics, and an emitted OpenAPI document.",
5
5
  "license": "AGPL-3.0-only OR LicenseRef-Commercial",
6
6
  "repository": {
@@ -43,10 +43,10 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@hono/zod-openapi": "^1.5.1",
46
- "@mailwoman/api-kit": "8.6.0",
47
- "@mailwoman/core": "8.6.0",
48
- "@mailwoman/formatter": "8.6.0",
49
- "hono": "^4.12.32",
46
+ "@mailwoman/api-kit": "9.1.0",
47
+ "@mailwoman/core": "9.1.0",
48
+ "@mailwoman/formatter": "9.1.0",
49
+ "hono": "^4.13.0",
50
50
  "zod": "^4.4.3"
51
51
  }
52
52
  }
package/schema.ts CHANGED
@@ -6,9 +6,9 @@
6
6
  * Zod wire schemas for the native `/v1` surface. Unlike the drop-ins (photon, nominatim,
7
7
  * libpostal), nothing here is a vendor contract — this surface is ours to design, so request
8
8
  * bodies are REQUIRED and validator-enforced (no legacy tolerance to preserve). A `defaultHook`
9
- * on the app (wired in Task 3) maps validation failures through the shared `APIErrorSchema`
10
- * envelope (`apiError(c, 400, "invalid request body", <zod summary>)`) — the documented pattern
11
- * boundary from phase 2: where no legacy contract exists, the validator MAY speak, but only in
9
+ * on the app maps validation failures through the shared `APIErrorSchema` envelope
10
+ * (`apiError(c, 400, "invalid request body", <zod summary>)`) — the pattern boundary every
11
+ * surface holds to: where no legacy contract exists, the validator MAY speak, but only in
12
12
  * our envelope.
13
13
  *
14
14
  * `APIErrorSchema` itself is owned by `@mailwoman/api-kit` (plumbing shared by every native
@@ -30,12 +30,27 @@ export { APIErrorSchema } from "@mailwoman/api-kit"
30
30
  */
31
31
  export const InputModeSchema = z.enum(["fragmented", "formatted"]).openapi("InputMode")
32
32
 
33
+ /**
34
+ * Longest accepted `address`, in characters.
35
+ *
36
+ * Sized against what the model can actually read, not against a guess at abuse. The classifier's window is 128
37
+ * SentencePiece pieces — roughly 330 characters of address text — and everything past it is truncated before inference,
38
+ * so input beyond this bound cannot influence a result. The margin over that window leaves room for scripts that
39
+ * tokenize denser than Latin, and for the department-and-division prefixes web forms concatenate.
40
+ *
41
+ * The bound exists because preprocessing is linear but not free: a 1 MB body costs ~1.7 s across normalize, query-shape
42
+ * and the phrase grouper, and Node runs them on the one thread every other request is waiting on. A cap here is cheaper
43
+ * than fairness plumbing, and rejecting is more honest than accepting a body whose tail the parser will silently
44
+ * discard.
45
+ */
46
+ export const MAX_ADDRESS_LENGTH = 1024
47
+
33
48
  /**
34
49
  * `POST /v1/parse` request body.
35
50
  */
36
51
  export const ParseRequestSchema = z
37
52
  .object({
38
- address: z.string(),
53
+ address: z.string().max(MAX_ADDRESS_LENGTH),
39
54
  debug: z.boolean().optional(),
40
55
  input_mode: InputModeSchema.optional(),
41
56
  })
@@ -65,7 +80,7 @@ export const ParseOutcomeSchema = z
65
80
  */
66
81
  export const GeocodeRequestSchema = z
67
82
  .object({
68
- address: z.string(),
83
+ address: z.string().max(MAX_ADDRESS_LENGTH),
69
84
  input_mode: InputModeSchema.optional(),
70
85
  })
71
86
  .openapi("GeocodeRequest")
@@ -101,6 +116,76 @@ const GeocodeCandidateSchema = z
101
116
  })
102
117
  .openapi("GeocodeCandidate")
103
118
 
119
+ /**
120
+ * Canonical parsed-component map carried by `GeocodeResult.components`. Spelled out at this engine-agnostic API
121
+ * boundary for the same reason the result schema is hand-modeled; the compile-time drift pin in
122
+ * `mailwoman/test/api-schema-drift.test.ts` catches any mismatch with the real `ComponentTag`-keyed result type.
123
+ */
124
+ const GeocodeComponentsSchema = z.partialRecord(
125
+ z.enum([
126
+ "country",
127
+ "region",
128
+ "locality",
129
+ "dependent_locality",
130
+ "postcode",
131
+ "subregion",
132
+ "house_number",
133
+ "street",
134
+ "street_prefix",
135
+ "street_prefix_particle",
136
+ "street_suffix",
137
+ "intersection_a",
138
+ "intersection_b",
139
+ "unit",
140
+ "venue",
141
+ "attention",
142
+ "po_box",
143
+ "cedex",
144
+ "prefecture",
145
+ "municipality",
146
+ "district",
147
+ "block",
148
+ "sub_block",
149
+ "building_number",
150
+ "building_name",
151
+ ]),
152
+ z.string()
153
+ )
154
+
155
+ /**
156
+ * One `GeocodeOutcome.intent_markers` entry — an advisory the ROAD_TO_V9 §4 intent vocabulary raised about the QUERY.
157
+ * Mirrors `QueryIntentMarker` (`core/pipeline/types.ts`).
158
+ *
159
+ * `evidence` is deliberately open (`z.record`): each `code` carries its own measurement — a dominance margin, a pair of
160
+ * interpretations, a taxonomy id — and flattening those into one closed shape would either lose the numbers or invent
161
+ * fields that do not apply. `code` is the discriminator a client branches on.
162
+ */
163
+ const QueryIntentMarkerSchema = z
164
+ .object({
165
+ // Spelled out rather than `z.string()` so `mailwoman/test/api-schema-drift.test.ts`'s schema-too-wide direction
166
+ // keeps biting: a new `QueryKind` that never reaches this list is a documented contract that has quietly stopped
167
+ // describing the real one.
168
+ kind: z.enum([
169
+ "postcode_only",
170
+ "locality_only",
171
+ "structured_address",
172
+ "intersection",
173
+ "po_box",
174
+ "landmark",
175
+ "poi_query",
176
+ "vague",
177
+ "bare_toponym",
178
+ "route_pair",
179
+ "near_me",
180
+ "poi_category",
181
+ ]),
182
+ code: z.enum(["declared_ambiguity", "declared_fork", "focus_point_required", "poi_category"]),
183
+ mechanism: z.string(),
184
+ message: z.string(),
185
+ evidence: z.record(z.string(), z.unknown()).optional(),
186
+ })
187
+ .openapi("QueryIntentMarker")
188
+
104
189
  /**
105
190
  * `POST /v1/geocode` response — a hand-modeled mirror of `GeocodeResult`'s wire shape (`mailwoman/geocode-core.ts`),
106
191
  * `.loose()` so a field the engine adds that this schema doesn't yet know about still rides through undocumented rather
@@ -114,6 +199,7 @@ const GeocodeCandidateSchema = z
114
199
  export const GeocodeOutcomeSchema = z
115
200
  .object({
116
201
  input: z.string(),
202
+ components: GeocodeComponentsSchema,
117
203
  lat: z.number().nullable(),
118
204
  lon: z.number().nullable(),
119
205
  resolution_tier: z.enum(["address_point", "interpolated", "street", "admin"]),
@@ -127,9 +213,18 @@ export const GeocodeOutcomeSchema = z
127
213
  venue: z.string().nullable(),
128
214
  // The parsed dependent-locality span (parse view; `hierarchy` is the resolved view).
129
215
  dependent_locality: z.string().nullable(),
216
+ // The parsed unit / sub-venue span (parse view) — "Terminal 5", "Suite 300".
217
+ unit: z.string().nullable(),
130
218
  countryCode: z.string().nullable(),
131
219
  hierarchy: z.array(GeocodeHierarchyEntrySchema),
132
220
  candidates: z.array(GeocodeCandidateSchema),
221
+ // #42: the country the postcode-country coherence pass scoped the walk to, or null. Non-null ONLY when it
222
+ // OVERRODE the request's country prior — so a caller who asked for US and got an FR answer can see which
223
+ // evidence bought the change instead of reading it as a bug.
224
+ postcode_country_scope: z.string().nullable(),
225
+ // ROAD_TO_V9 §4: query-intent advisories. Always present; empty means the vocabulary looked and had nothing to
226
+ // say. Advisory ONLY — no marker changed which answer won, and a client is free to ignore the array entirely.
227
+ intent_markers: z.array(QueryIntentMarkerSchema),
133
228
  })
134
229
  .loose()
135
230
  .openapi("GeocodeOutcome")
@@ -139,7 +234,9 @@ export const GeocodeOutcomeSchema = z
139
234
  */
140
235
  export const BatchRequestSchema = z
141
236
  .object({
142
- addresses: z.array(z.string()),
237
+ // Per-ROW, not just per-request: the row cap (`batchMax`, default 500) bounds how many addresses arrive,
238
+ // and this bounds how large each may be. Without both, one request is 500 unbounded bodies.
239
+ addresses: z.array(z.string().max(MAX_ADDRESS_LENGTH)),
143
240
  /**
144
241
  * Register override for every row. DEFAULT `"formatted"` — batch rows are the record register by nature.
145
242
  */