@crvouga/mockingbird-service-google-maps

中文文档
3.11.0发布于 2026/11/11MITTypeScriptES Module构建来源已验证近 30 天下载 1.6万

模拟 Google Places 自动完成 / 细节 / Find Place, Geocoding API, a Maps JavaScript (places) shim和地址验证 API(USPS CASS/DPV discriptions),在QA地址表之上,有Google状态代码和断层预设.

中文使用文档
文档目录11 节
  1. 安装
  2. 使用量
  3. 地址验证
  4. 路线
  5. 地址验证判决
  6. 企业
  7. 管理员(超过标准合同)
  8. 命名空间
  9. 测试
  10. 故意不模拟
  11. API 密码

@crvouga/ mockingbird-service-google-地图

本地模拟器。 真正的API合同. 部分 嘲笑鸟。 。 。 .

模拟 谷歌地图平台 显示我们的会员应用地址: 位置 自动完成, Place 细节并从文本中查找位置( JSON 网络服务), Geocoding API, (单位:千美元) 地图 JavaScript API shim (单位:千美元)/maps/api/js?libraries=places) 揭露 google.maps.places.* 财务报告和审定财务报表 google.maps.Geocoder 在相同数据上 地址 验证 API (单位:千美元)POST /v1:validateAddress,并附有USPS CASS/DPV数据),用于服务器侧船到 检查。 答案来自一个机构 匹配我们的 QA 设置, 因此地址步骤等待 5 s 的 Google 预测( 然后) 回到手动输入)立即解决,决定性地解决.

  • 行动范围: 支助
  • Google 没有针对这些端点发布 OpenAPI 文档 : openapi.yaml 手写 从Google的文档形状 和我们消费者读的字段。 以下地址验证 页:1 REST 参考文献 财务报告和审定财务报表 ValidationResult。 。 。 .

安装

npm install -D @crvouga/mockingbird-service-google-maps

仅限无害环境管理。 节点 22或 Bun 1.2. 无土生属地. 给它服务 npx mockingbird-google-maps serve, (中文(简体) ), createServer 从 ./server (节点),或 createRuntime 与任何获取服务器.

使用量

应用程序硬码 https://maps.googleapis.com (接缝) G-Y1级: 用于 M/lib/ui/address-autocomplete/address-autocomplete-native-rest.tsx, (中文(简体) ), M/features/bloodwork/shared/lab-finder/use-geocoded-address.ts 财务报告和审定财务报表 M/lib/ui/google-maps/load-google-maps-script.ts) (中文(简体) ). 在它降落之前 将宿主重写成模拟者 在堆栈的网盘中( t)stack-web-dist.ts),至于后霍格语. PLACES_KEY 可以是任何非空的 字符串,除非限制键.

npx mockingbird-google-maps serve --port 8814 --api-key "$PLACES_KEY"
import { Client, PlaceAutocompleteType } from "@googlemaps/google-maps-services-js"
import { createRuntime } from "@crvouga/mockingbird-service-google-maps"

// The Maps client your application already uses. Only its HTTP layer changes: axios's
// fetch adapter reaches the emulator in this process instead of maps.googleapis.com.
const emulator = createRuntime()
const maps = new Client({
  config: {
    adapter: "fetch",
    env: { fetch: (url: string | URL | Request, init?: RequestInit) => emulator.fetch(new Request(url, init)) },
  },
})

const { data } = await maps.placeAutocomplete({
  params: { input: "1625 N Central", types: PlaceAutocompleteType.address, components: ["country:us"], key: "k" },
})
const details = await maps.placeDetails({
  params: { place_id: data.predictions[0]?.place_id ?? "", fields: ["address_component"], key: "k" },
})
// details.data.result.address_components → 1625 / N Central Ave / Phoenix / AZ / 85004

// Test control: make the next two autocomplete calls fail, as QA's manual-entry fallback expects.
emulator.applyPreset("autocomplete_over_query_limit", "default", { count: 2 })

地址验证

谷歌服务它来自不同的主机, https://addressvalidation.googleapis.com; 路径 不相撞,所以一个仿真器服务于两者。 指向服务器端客户端的地址验证基址 在模拟器上(或 <emulator>/__admin/ns/<namespace>),键为 ?key= (或 X-Goog-Api-Key) (中文(简体) ).

import { AddressValidationClient } from "@googlemaps/addressvalidation"
import { createServer } from "@crvouga/mockingbird-service-google-maps/server"

const server = await createServer()
const { hostname, port } = new URL(server.url)

// The application's client, in REST mode. Only the endpoint changes.
const client = new AddressValidationClient({
  fallback: true,
  protocol: "http",
  apiEndpoint: hostname,
  port: Number(port),
  apiKey: "k",
})
const [{ result }] = await client.validateAddress({
  address: {
    regionCode: "US",
    addressLines: ["1625 N Central Ave"],
    locality: "Phoenix",
    administrativeArea: "AZ",
    postalCode: "85004",
  },
  enableUspsCass: true,
})
// result.verdict → PREMISE / addressComplete; result.uspsData.dpvConfirmation → "Y"

// Test control: force the USPS "not deliverable" answer on the next call.
server.runtime.applyPreset("address_validation_dpv_n", "default", { count: 1 })

await client.close()
await server.close()

网上装入 <emulator>/maps/api/js?key=…&libraries=places 和Google的应用程序一样 脚本;shim调回模拟器的 REST 端点在同一来源和命名空间上.

路线

每个网络服务的答案是 HTTP 200 (韩语) 与谷歌的 status (单位:千美元)OK, (中文(简体) ), ZERO_RESULTS, (中文(简体) ), INVALID_REQUEST, (中文(简体) ), NOT_FOUND, (中文(简体) ), REQUEST_DENIED, (中文(简体) ), OVER_QUERY_LIMIT, (中文(简体) ), UNKNOWN_ERROR并且,为了 错误,谷歌 error_messageB. 答复 access-control-allow-origin: * 所以,嘘 从浏览器工作.

路线行为
GET /maps/api/place/autocomplete/jsoninput (必须,其他 INVALID_REQUEST, (中文(简体) ), types, (中文(简体) ), components=country:us, (中文(简体) ), sessiontoken。 。 。 . predictions[] 与 description, (中文(简体) ), place_id, (中文(简体) ), reference, (中文(简体) ), structured_formatting{main_text, main_text_matched_substrings, secondary_text}, (中文(简体) ), terms, (中文(简体) ), types, (中文(简体) ), matched_substrings; 最多为 5. 以符号前缀相匹配(街道、城市、州、ZIP); "<number> <street> <corpus city>[ <ST>][ <ZIP>]" 实值 已合成 在那一行的城市/州/ZIP(QA模糊搜索). 没什么 ZERO_RESULTS; 一个非 美国 components → ZERO_RESULTS。 。 。 .
GET /maps/api/place/details/jsonplace_id (必须), fields (荣誉: address_component 仅返回 address_components页:1 INVALID_REQUEST, (中文(简体) ), sessiontoken。 。 。 . result 与 address_components (单位:千美元)street_number, (中文(简体) ), route, (中文(简体) ), locality, (中文(简体) ), administrative_area_level_2, (中文(简体) ), administrative_area_level_1 长/短, country, (中文(简体) ), postal_code, (中文(简体) ), formatted_address, (中文(简体) ), geometry{location, viewport}, (中文(简体) ), place_id, (中文(简体) ), types, (中文(简体) ), name, (中文(简体) ), url, (中文(简体) ), vicinity。未知编号 NOT_FOUND。 。 。 .
GET /maps/api/geocode/jsonaddress, (中文(简体) ), place_id 或者说 components=postal_code:… (无) INVALID_REQUEST) (中文(简体) ). results[0] 与 address_components, (中文(简体) ), formatted_address, (中文(简体) ), geometry{location, location_type, viewport}, (中文(简体) ), place_id, (中文(简体) ), types完整地址:"line1, city, ST zip"解决其行或合成地址; 赤裸的ZIP或 "City, ST" 至 ZIP 中间体; 没有可移动城市的街道是 ZERO_RESULTS。 。 。 .
GET /maps/api/place/findplacefromtext/jsoninput + 键 inputtype=textquery (次数) INVALID_REQUEST, (中文(简体) ), fields (默认 : place_id 仅作为谷歌). 先是地理编码,然后是比较松散的自动完成匹配, 所以它找到我们的地理编码回落需要什么.
POST /v1:validateAddress地址验证(见下文)。 谷歌云 API:错误为 HTTP 4xx/5xx 与 {"error": {code, message, status}},而不是200与 status。 。 。 .
GET /maps/api/js嘘text/javascript: google.maps.places.AutocompleteService#getPlacePredictions, (中文(简体) ), PlacesService#getDetails 编号 : #findPlaceFromQuery, (中文(简体) ), AutocompleteSessionToken, (中文(简体) ), PlacesServiceStatus, (中文(简体) ), google.maps.Geocoder#geocode, (中文(简体) ), GeocoderStatus, (中文(简体) ), LatLng (单位:千美元)lat()编号 :lng(), (中文(简体) ), LatLngBounds, (中文(简体) ), importLibrary。回电和承诺(以 MapsRequestError 在不给回话时错误。 电话 window[callback] 页:1 &callback=,以及 window.gm_authFailure() 当密钥被拒绝时.

地址验证判决

正如Google发送的 false 删除布尔和空列表 (无) unconfirmedComponentTypes: []) (中文(简体) ). result 携带 verdict (单位:千美元)inputGranularity, (中文(简体) ), validationGranularity, (中文(简体) ), geocodeGranularity, (中文(简体) ), addressComplete, (中文(简体) ), has*Components, (中文(简体) ), possibleNextAction, (中文(简体) ), address (单位:千美元)formattedAddress, (中文(简体) ), postalAddress, (中文(简体) ), addressComponents 与 confirmationLevel 编号 : inferred 编号 : replaced, (中文(简体) ), missingComponentTypes, (中文(简体) ), unconfirmedComponentTypes, (中文(简体) ), geocode (单位:千美元)location, (中文(简体) ), placeId, (中文(简体) ), placeTypes和,美国 地址:, uspsData (单位:千美元)standardizedAddress, (中文(简体) ), dpvConfirmation, (中文(简体) ), dpvFootnote, (中文(简体) ), postOfficeCity编号 :State, (中文(简体) ), errorMessage, (中文(简体) ), cassProcessed 何时 enableUspsCass) (中文(简体) ). 每一个答案 有一个 responseId,发送一个组件地址(1行+可选单元2行), locality, (中文(简体) ), administrativeArea, (中文(简体) ), postalCode或所有的东西 addressLines。 。 。 .

投入判决
实体行( A)1625 N Central Ave, Phoenix AZ 8504; 拼出单词(North, (中文(简体) ), Avenue匹配( r)PREMISE完整地说, ACCEPT,DPV Y· ; postalAddress 以确定性ZIP+4(85004-NNNN(中文(简体) )
<number> <street> 在一个城市里合成, 至于自动完成 : PREMISE, (中文(简体) ), ACCEPT,DPV Y,街道USPS缩略语(Maple Street → Maple St(中文(简体) )
单发点行上的单元(… Building A, (中文(简体) ), Apt 4(中文(简体) )PREMISE完整地说, CONFIRM, (中文(简体) ), subpremise 未证实,DPV Y
无房号(N Central Ave) 在一个实体城市ROUTE, (中文(简体) ), FIX, (中文(简体) ), missingComponentTypes: ["street_number"],无 DPV 代码
一个城市/ZIP 保护令没有OTHER, (中文(简体) ), FIX,不可置放的组件未经证实,DPV N
对城市不利的ZIP(或对ZIP不利的城市)已替换 : hasReplacedComponents, (中文(简体) ), CONFIRM,在 postalAddress
一行为 validation.multiUnit无单位 : CONFIRM_ADD_SUBPREMISES, (中文(简体) ), missingComponentTypes: ["subpremise"],DPV D中的单位 validation.units (或任何,何时) units 缺席 : SUB_PREMISE, (中文(简体) ), ACCEPT, (中文(简体) ), Y。另一个单位: PREMISE, (中文(简体) ), CONFIRM, (中文(简体) ), subpremise 未证实,DPV S
一行为 validation.uspsErrorMessageuspsData: {errorMessage} 没有 DPV 代码
没有 address空无 addressLines,一个未知字段,非JSON,超过280个字符,或者 enableUspsCass 外部 US编号 :PR400个 INVALID_ARGUMENT
无密钥403 (韩语) PERMISSION_DENIED "请求缺少有效的API密钥"
外部键 settings.keys400个 INVALID_ARGUMENT "API密钥无效. 请通过有效的 API 密钥。” (reason: API_KEY_INVALID),因为谷歌回答一个未知的密钥; address_validation_denied 在未启用 API 的情况下给出密钥的 403

企业

59个地址:每行质量保证 ROUTING_ZIP_CORPUS (单位:千美元)packages/qa/src/world/gen/addresses.ts, (中文(简体) ), + DC, IDs),包括 凤凰AZ演示成员 (单位:千美元)ADDRESS_AT_HOME_PHLEBOTOMY:1625 N Central Ave, Phoenix, AZ 85004)等 (中文(简体) ) packages/app/src/test-addresses 成员,加 ADDRESS_AT_HOME_PHLEBOTOMY_2 (501 N 5th St.) (英语). 每一个都有其真正的县和城市的坐标. 位置标识是稳定的(ChIJ… 用于行; 合成地址获得一个 Ei… 正如Google自己的地址代号一样 细节不需要存储状态). GET /__admin/health 报告尸体.

管理员(超过标准合同)

路线效果
GET /__admin/corpus命名空间的地址( 海关优先) 和自定义计数 .
PUT /__admin/corpus{addresses: [{line1, city, state, zip, id?, county?, lat?, lng?, validation?}]} 替换名称空间的自定义地址(在内建主体之上). validation 该行的 Pins 地址验证 : {granularity?, addressComplete?, possibleNextAction?, dpvConfirmation?: "Y"|"N"|"S"|"D", unconfirmedComponentTypes?, uspsErrorMessage?, multiUnit?, units?}。 。 。 .
DELETE /__admin/corpus放弃自定义地址 .
GET/PUT /__admin/settings{keys?: string[], publicUrl?: string | null}。 。 。 . keys 限制已接受的 API 密钥( 其他获得) REQUEST_DENIED "提供的 API 密钥无效";缺失的密钥总是这样". publicUrl jS Shim在与请求不同时(重写代理).

错误预设( E)POST /__admin/faults {"preset": "<name>", "count"?: n}· ; GET /__admin/faults/presets: over_query_limit, (中文(简体) ), request_denied, (中文(简体) ), unknown_error, (中文(简体) ), zero_results (每个网络服务,HTTP 200) 以该地位, geocode_zero_results (行使我们的发现地倒置), autocomplete_over_query_limit (其中两张是手动输入的), server_error (HTTP 500), (韩语), slow (6 s,过去QA的5 s等),, script_unavailable (JS加载器回答503,所以) 剧本 onerror (见A/C.5/49/70,附件)。 只用于地址验证 : address_validation_denied (403) (中文(简体) ) PERMISSION_DENIED,没有启用 API 的密钥, address_validation_unavailable (503个) UNAVAILABLE, (中文(简体) ), address_validation_slow (3 s, 超过2.5 s的结账超时), address_validation_no_verdict (200个) {"result": {}}:不是谷歌发送的东西 客户端的防御分支)和 address_validation_dpv_n (日内瓦) N) (中文(简体) ). GET /__admin/metrics 计数 ValidateAddress 独自一人.

命名空间

x-mockingbird-namespace页:1 /__admin/ns/<name> 前缀在基址上(JS Shim服务于 前缀通过它回调),或 API 密钥: PUT /__admin/credentials {"credentials": {"<PLACES_KEY>": "<namespace>"}} (单位:千美元) key 查询 参数,或 X-Goog-Api-Key 用于地址验证,是证书。 请求日记 记录操作、状态、解决 placeId 编辑 sessionToken,用于 ValidateAddress 解析的方块行 id (addressRowId和判决等级 (单位:千美元)ACCEPT/Y, (中文(简体) ), FIX/N;从未输入过地址.

测试

  • google-maps.property.test.ts:所有四种网络服务随机行走的自我均等(每一种) 和故意不同的情况 逮到他们了.
  • google-maps.acceptance.test.ts驱动器 test/consumer.ts我们的港口 address-autocomplete-native-rest.tsx (URL建设者,解说者,两相相克相克相克相克相克相克相克相克相克相克相克相克相克相克相克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克 手动输入开关, parse-place-details.ts, (中文(简体) ), address-autocomplete-web.tsx 财务报告和审定财务报表 use-geocoded-address.ts (原始内容存档于2018-03-21) (通过在假窗口评价的shim). 也曾在HTTP服役.
  • google-maps.address-validation.acceptance.test.ts: 每个地址验证判决等级, 400/403 信封、命名空间、日记和每个预设,通过 test/consumer.ts是因为 测试失败的开口船对评估(non-2xx,无判决 = 无法使用;USPS) 错误,颗粒性,不完整, FIX编号 :CONFIRM_ADD_SUBPREMISES,批判性未经证实 组件,除DPV Y编号 :S ——拒绝). 自我平等包括: ValidateAddress。 。 。 .
  • 没有 SDK 滴入测试: 本地使用 plain fetch,而网页 SDK 是谷歌的托管 剧本,shim取而代之.
  • bun scripts/parity.ts: 现场对等 maps.googleapis.com (和 addressvalidation.googleapis.com 页:1 ValidateAddress与 GOOGLE_MAPS_API_KEY (env / (中文(简体) ) .env.local; 必须启用地址验证 键);2号出口没有它.

故意不模拟

  • 案卷以外的地址:只有案卷行和街道合成了案卷城市 决心。 添加更多内容 PUT /__admin/corpus。 。 。 .
  • Google的路线扩展(N Central Ave • 长名 North Central Avenue: long_name 重复了字母拼写,所以QA的一行一回转。 生活平等将显示这种差异.
  • 映射图( O)google.maps.Map、标记、平板、静态地图、新地点 API (单位:千美元)places.googleapis.com, (中文(简体) ), Place 班级, AutocompleteSuggestion),倒转地理编码 (单位:千美元)latlng=, (中文(简体) ), locationbias编号 :radius,以及超过预设的计费/配额.
  • 会话计费语义:接受并刊出符文,仅此而已.
  • 地址验证 validateAddress数字 : provideValidationFeedback, (中文(简体) ), previousResponseId 锁链, languageOptions 财务报告和审定财务报表 sessionToken (接受、忽视), metadata (业务/住宅/业务包厢), englishLatinAddress区域(无 enableUspsCass 他们得到一个 FIX 回答和无 uspsData; Google 验证了许多国家). ZIP+4位数, dpvFootnote 编码和USPS记录的其余部分(载货路线、交货) 点,县FIPS...) 被合成或省略:比较判决类和DPV代码,而不是 这些.

API 密码

导出仁爱说明
GoogleMapsAPI类进程模拟器 : fetch(request), (中文(简体) ), reset(), (中文(简体) ), corpus(), (中文(简体) ), state选项: sqlite, (中文(简体) ), now, (中文(简体) ), namespace, (中文(简体) ), publicNamespace, (中文(简体) ), corpus, (中文(简体) ), settings。 。 。 .
createRuntime函数全面服务合同的仿真器(保健、管理、命名空间、证书、预设和日记)。 选项 : corpus, (中文(简体) ), settings, (中文(简体) ), clock, (中文(简体) ), seed, (中文(简体) ), adminKey, (中文(简体) ), onLog。 。 。 .
GOOGLE_MAPS_PRESETS对象每个命名的断层预设.
GOOGLE_MAPS_NAMESPACE字符串服务名称, "google-maps"。 。 。 .
keyCredential函数这个 key 查询参数(或 X-Goog-Api-Key 请求头 (API 密钥映射到命名空间) .
DEFAULT_CORPUS, (中文(简体) ), PHOENIX_DEMO_ADDRESS, (中文(简体) ), STATE_NAMES数值地址表,凤凰城演示成员行,以及状态名称 administrative_area_level_1。 。 。 .
corpusPlaceId函数尸体行的固定位置.
mapsJavaScript函数绘制地图 JavaScript shim {base, key, authFailed, callback}。 。 。 .
normalize函数用于匹配的地址正常化 .
MISSING_KEY_MESSAGE, (中文(简体) ), INVALID_KEY_MESSAGE字符串谷歌的音乐 error_message 缺少 / 拒绝 密钥 .
MISSING_API_KEY_MESSAGE, (中文(简体) ), INVALID_API_KEY_MESSAGE字符串地址验证 error.message 缺少(403)/无效(400)密钥.
document, (中文(简体) ), operationIds, (中文(简体) ), supportedOperationIds数值OpenAPI合同及其操作代号.
createServer, (中文(简体) ), serveTarget, (中文(简体) ), DEFAULT_PORT (单位:千美元)./server(中文(简体) )节点服务过来 node:http; 数据 serve CLI目标(--api-key, (中文(简体) ), --public-url; 第8814号口.

部分 嘲笑鸟。 。 。 .

版本与发布记录

@crvouga/mockingbird-service-google-maps 共发布 43 个版本,首次发布于 2026/09/23;过去 12 个月发布了 43 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.11.0latest2026/11/11今天
3.10.92026/11/038 天前
3.10.82026/11/038 天前
3.10.72026/11/038 天前
3.10.62026/11/038 天前
3.10.52026/11/038 天前

关于 @crvouga/mockingbird-service-google-maps 的常见问题

@crvouga/mockingbird-service-google-maps 是什么?

模拟 Google Places 自动完成 / 细节 / Find Place, Geocoding API, a Maps JavaScript (places) shim和地址验证 API(USPS CASS/DPV discriptions),在QA地址表之上,有Google状态代码和断层预设.

如何安装 @crvouga/mockingbird-service-google-maps?

在项目目录运行 npm install @crvouga/mockingbird-service-google-maps,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 mockingbird-google-maps,可以用 npx mockingbird-google-maps 直接运行。

@crvouga/mockingbird-service-google-maps 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@crvouga/mockingbird-service-google-maps 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@crvouga/mockingbird-service-google-maps 可以商用吗?

@crvouga/mockingbird-service-google-maps 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@crvouga/mockingbird-service-google-maps 的下载量有多少?

根据 npm 官方下载统计,@crvouga/mockingbird-service-google-maps 在 2026/10/11 – 2026/11/09 这 30 天内被下载 16,377 次,日均约 546 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@crvouga/mockingbird-service-google-maps 还在维护吗?

最新版本 3.11.0 发布于 2026/11/11(今天);至今共发布 43 个版本,其中过去 12 个月发布了 43 个;首次发布于 2026/09/23。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。