googlemaps-kit 0.3.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +231 -26
- package/dist/advanced/http.d.ts +4 -4
- package/dist/advanced/http.d.ts.map +1 -1
- package/dist/advanced/http.js +4 -4
- package/dist/advanced/http.js.map +1 -1
- package/dist/advanced/parsers.d.ts +9 -4
- package/dist/advanced/parsers.d.ts.map +1 -1
- package/dist/advanced/parsers.js +6 -3
- package/dist/advanced/parsers.js.map +1 -1
- package/dist/advanced/rpc.d.ts +12 -12
- package/dist/advanced/rpc.d.ts.map +1 -1
- package/dist/advanced/rpc.js +10 -10
- package/dist/advanced/rpc.js.map +1 -1
- package/dist/advanced/services.d.ts +18 -7
- package/dist/advanced/services.d.ts.map +1 -1
- package/dist/advanced/services.js +18 -7
- package/dist/advanced/services.js.map +1 -1
- package/dist/advanced/utils.d.ts +3 -3
- package/dist/advanced/utils.d.ts.map +1 -1
- package/dist/advanced/utils.js +3 -3
- package/dist/advanced/utils.js.map +1 -1
- package/dist/advanced.d.ts +46 -9
- package/dist/advanced.d.ts.map +1 -1
- package/dist/advanced.js +13 -6
- package/dist/advanced.js.map +1 -1
- package/dist/auth/auth-status.js +2 -2
- package/dist/auth/auth-status.js.map +1 -1
- package/dist/auth/maps-tokens.js +1 -1
- package/dist/auth/session.d.ts.map +1 -1
- package/dist/auth/session.js +17 -2
- package/dist/auth/session.js.map +1 -1
- package/dist/cli/args.d.ts +21 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +97 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/format.d.ts.map +1 -1
- package/dist/cli/format.js +18 -27
- package/dist/cli/format.js.map +1 -1
- package/dist/cli/output.d.ts +19 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +82 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/run.d.ts +131 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +384 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/tui/app.d.ts +48 -0
- package/dist/cli/tui/app.d.ts.map +1 -0
- package/dist/cli/tui/app.js +461 -0
- package/dist/cli/tui/app.js.map +1 -0
- package/dist/cli/tui/styles.d.ts +11 -0
- package/dist/cli/tui/styles.d.ts.map +1 -0
- package/dist/cli/tui/styles.js +17 -0
- package/dist/cli/tui/styles.js.map +1 -0
- package/dist/cli.d.ts +1 -10
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +196 -206
- package/dist/cli.js.map +1 -1
- package/dist/client/gmaps-client.d.ts +8 -3
- package/dist/client/gmaps-client.d.ts.map +1 -1
- package/dist/client/gmaps-client.js +43 -5
- package/dist/client/gmaps-client.js.map +1 -1
- package/dist/client/http-client.d.ts.map +1 -1
- package/dist/client/http-client.js +11 -9
- package/dist/client/http-client.js.map +1 -1
- package/dist/client/intent.d.ts +1 -1
- package/dist/client/intent.d.ts.map +1 -1
- package/dist/client/intent.js +22 -5
- package/dist/client/intent.js.map +1 -1
- package/dist/client/maps-tools.d.ts +13 -1
- package/dist/client/maps-tools.d.ts.map +1 -1
- package/dist/client/maps-tools.js +44 -0
- package/dist/client/maps-tools.js.map +1 -1
- package/dist/client/namespaces.d.ts +84 -10
- package/dist/client/namespaces.d.ts.map +1 -1
- package/dist/client/namespaces.js +119 -11
- package/dist/client/namespaces.js.map +1 -1
- package/dist/client/place-enrichment.js +1 -1
- package/dist/client/place-enrichment.js.map +1 -1
- package/dist/index.d.ts +46 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/known-surfaces.d.ts +134 -2
- package/dist/known-surfaces.d.ts.map +1 -1
- package/dist/known-surfaces.js +134 -2
- package/dist/known-surfaces.js.map +1 -1
- package/dist/parsers/batch-url.d.ts +10 -1
- package/dist/parsers/batch-url.d.ts.map +1 -1
- package/dist/parsers/batch-url.js +30 -2
- package/dist/parsers/batch-url.js.map +1 -1
- package/dist/parsers/boq-reviews.d.ts +8 -1
- package/dist/parsers/boq-reviews.d.ts.map +1 -1
- package/dist/parsers/boq-reviews.js +50 -8
- package/dist/parsers/boq-reviews.js.map +1 -1
- package/dist/parsers/categories.d.ts.map +1 -1
- package/dist/parsers/categories.js +13 -10
- package/dist/parsers/categories.js.map +1 -1
- package/dist/parsers/directions.d.ts +18 -2
- package/dist/parsers/directions.d.ts.map +1 -1
- package/dist/parsers/directions.js +232 -18
- package/dist/parsers/directions.js.map +1 -1
- package/dist/parsers/geocode.d.ts +20 -2
- package/dist/parsers/geocode.d.ts.map +1 -1
- package/dist/parsers/geocode.js +110 -6
- package/dist/parsers/geocode.js.map +1 -1
- package/dist/parsers/knowledge.js +1 -1
- package/dist/parsers/knowledge.js.map +1 -1
- package/dist/parsers/lists.d.ts.map +1 -1
- package/dist/parsers/lists.js +29 -12
- package/dist/parsers/lists.js.map +1 -1
- package/dist/parsers/local-posts.d.ts.map +1 -1
- package/dist/parsers/local-posts.js +97 -12
- package/dist/parsers/local-posts.js.map +1 -1
- package/dist/parsers/mobility.d.ts +42 -0
- package/dist/parsers/mobility.d.ts.map +1 -0
- package/dist/parsers/mobility.js +130 -0
- package/dist/parsers/mobility.js.map +1 -0
- package/dist/parsers/panorama.d.ts +0 -1
- package/dist/parsers/panorama.d.ts.map +1 -1
- package/dist/parsers/panorama.js +117 -14
- package/dist/parsers/panorama.js.map +1 -1
- package/dist/parsers/photos.d.ts.map +1 -1
- package/dist/parsers/photos.js +15 -8
- package/dist/parsers/photos.js.map +1 -1
- package/dist/parsers/place-attributes.d.ts +12 -3
- package/dist/parsers/place-attributes.d.ts.map +1 -1
- package/dist/parsers/place-attributes.js +48 -2
- package/dist/parsers/place-attributes.js.map +1 -1
- package/dist/parsers/place-extended.d.ts +163 -0
- package/dist/parsers/place-extended.d.ts.map +1 -0
- package/dist/parsers/place-extended.js +741 -0
- package/dist/parsers/place-extended.js.map +1 -0
- package/dist/parsers/place.d.ts +15 -1
- package/dist/parsers/place.d.ts.map +1 -1
- package/dist/parsers/place.js +16 -5
- package/dist/parsers/place.js.map +1 -1
- package/dist/parsers/popular-times.d.ts +35 -0
- package/dist/parsers/popular-times.d.ts.map +1 -0
- package/dist/parsers/popular-times.js +149 -0
- package/dist/parsers/popular-times.js.map +1 -0
- package/dist/parsers/reveal.d.ts +1 -1
- package/dist/parsers/reveal.d.ts.map +1 -1
- package/dist/parsers/reveal.js +3 -2
- package/dist/parsers/reveal.js.map +1 -1
- package/dist/parsers/reviews.d.ts +17 -2
- package/dist/parsers/reviews.d.ts.map +1 -1
- package/dist/parsers/reviews.js +73 -1
- package/dist/parsers/reviews.js.map +1 -1
- package/dist/parsers/search.d.ts +17 -2
- package/dist/parsers/search.d.ts.map +1 -1
- package/dist/parsers/search.js +125 -7
- package/dist/parsers/search.js.map +1 -1
- package/dist/parsers/shared.d.ts +4 -0
- package/dist/parsers/shared.d.ts.map +1 -1
- package/dist/parsers/shared.js +10 -2
- package/dist/parsers/shared.js.map +1 -1
- package/dist/parsers/suggest.d.ts.map +1 -1
- package/dist/parsers/suggest.js +45 -6
- package/dist/parsers/suggest.js.map +1 -1
- package/dist/parsers/tiles.d.ts +13 -0
- package/dist/parsers/tiles.d.ts.map +1 -1
- package/dist/parsers/tiles.js +64 -0
- package/dist/parsers/tiles.js.map +1 -1
- package/dist/parsers/traffic.d.ts +9 -1
- package/dist/parsers/traffic.d.ts.map +1 -1
- package/dist/parsers/traffic.js +129 -2
- package/dist/parsers/traffic.js.map +1 -1
- package/dist/parsers/transit.d.ts +4 -2
- package/dist/parsers/transit.d.ts.map +1 -1
- package/dist/parsers/transit.js +385 -3
- package/dist/parsers/transit.js.map +1 -1
- package/dist/parsers/viewport.d.ts +20 -0
- package/dist/parsers/viewport.d.ts.map +1 -0
- package/dist/parsers/viewport.js +139 -0
- package/dist/parsers/viewport.js.map +1 -0
- package/dist/rpc/batch-execute.js +3 -3
- package/dist/rpc/batch-execute.js.map +1 -1
- package/dist/rpc/batch-request-builders.d.ts +12 -14
- package/dist/rpc/batch-request-builders.d.ts.map +1 -1
- package/dist/rpc/batch-request-builders.js +49 -17
- package/dist/rpc/batch-request-builders.js.map +1 -1
- package/dist/rpc/batch-rpc.js +1 -1
- package/dist/rpc/batch-services.d.ts +2 -0
- package/dist/rpc/batch-services.d.ts.map +1 -1
- package/dist/rpc/batch-services.js +4 -0
- package/dist/rpc/batch-services.js.map +1 -1
- package/dist/rpc/{descriptor-registry.d.ts → descriptors.d.ts} +29 -4
- package/dist/rpc/descriptors.d.ts.map +1 -0
- package/dist/rpc/{app-options.js → descriptors.js} +89 -5
- package/dist/rpc/descriptors.js.map +1 -0
- package/dist/rpc/earth-rocktree.d.ts +174 -0
- package/dist/rpc/earth-rocktree.d.ts.map +1 -0
- package/dist/rpc/earth-rocktree.js +468 -0
- package/dist/rpc/earth-rocktree.js.map +1 -0
- package/dist/rpc/feature-pb.d.ts +86 -0
- package/dist/rpc/feature-pb.d.ts.map +1 -0
- package/dist/rpc/feature-pb.js +112 -0
- package/dist/rpc/feature-pb.js.map +1 -0
- package/dist/rpc/feature-rpc.d.ts +15 -0
- package/dist/rpc/feature-rpc.d.ts.map +1 -1
- package/dist/rpc/feature-rpc.js +44 -0
- package/dist/rpc/feature-rpc.js.map +1 -1
- package/dist/rpc/maps-runtime.js +1 -1
- package/dist/rpc/panorama-pb.d.ts +3 -0
- package/dist/rpc/panorama-pb.d.ts.map +1 -1
- package/dist/rpc/panorama-pb.js +35 -3
- package/dist/rpc/panorama-pb.js.map +1 -1
- package/dist/rpc/pb-builders.d.ts +21 -1
- package/dist/rpc/pb-builders.d.ts.map +1 -1
- package/dist/rpc/pb-builders.js +62 -4
- package/dist/rpc/pb-builders.js.map +1 -1
- package/dist/rpc/photos-pb.d.ts +28 -1
- package/dist/rpc/photos-pb.d.ts.map +1 -1
- package/dist/rpc/photos-pb.js +96 -0
- package/dist/rpc/photos-pb.js.map +1 -1
- package/dist/rpc/rpc-methods.d.ts +0 -2
- package/dist/rpc/rpc-methods.d.ts.map +1 -1
- package/dist/rpc/rpc-methods.js +0 -38
- package/dist/rpc/rpc-methods.js.map +1 -1
- package/dist/rpc/search-filters.d.ts +0 -12
- package/dist/rpc/search-filters.d.ts.map +1 -1
- package/dist/rpc/search-filters.js +1 -11
- package/dist/rpc/search-filters.js.map +1 -1
- package/dist/rpc/tile-builders.d.ts +136 -0
- package/dist/rpc/tile-builders.d.ts.map +1 -0
- package/dist/rpc/tile-builders.js +172 -0
- package/dist/rpc/tile-builders.js.map +1 -0
- package/dist/rpc/xsrf-bootstrap.d.ts +0 -2
- package/dist/rpc/xsrf-bootstrap.d.ts.map +1 -1
- package/dist/rpc/xsrf-bootstrap.js +2 -2
- package/dist/rpc/xsrf-bootstrap.js.map +1 -1
- package/dist/services/ask-maps.d.ts +45 -5
- package/dist/services/ask-maps.d.ts.map +1 -1
- package/dist/services/ask-maps.js +148 -21
- package/dist/services/ask-maps.js.map +1 -1
- package/dist/services/directions.d.ts +17 -1
- package/dist/services/directions.d.ts.map +1 -1
- package/dist/services/directions.js +32 -0
- package/dist/services/directions.js.map +1 -1
- package/dist/services/distance-matrix.d.ts +1 -1
- package/dist/services/distance-matrix.d.ts.map +1 -1
- package/dist/services/distance-matrix.js +1 -1
- package/dist/services/distance-matrix.js.map +1 -1
- package/dist/services/elevation.d.ts +1 -1
- package/dist/services/elevation.d.ts.map +1 -1
- package/dist/services/elevation.js +3 -2
- package/dist/services/elevation.js.map +1 -1
- package/dist/services/geocode.d.ts +16 -0
- package/dist/services/geocode.d.ts.map +1 -1
- package/dist/services/geocode.js +90 -0
- package/dist/services/geocode.js.map +1 -1
- package/dist/services/lists.d.ts +7 -1
- package/dist/services/lists.d.ts.map +1 -1
- package/dist/services/lists.js +45 -1
- package/dist/services/lists.js.map +1 -1
- package/dist/services/map-3d.d.ts +66 -0
- package/dist/services/map-3d.d.ts.map +1 -0
- package/dist/services/map-3d.js +658 -0
- package/dist/services/map-3d.js.map +1 -0
- package/dist/services/map-layers.d.ts +33 -0
- package/dist/services/map-layers.d.ts.map +1 -0
- package/dist/services/map-layers.js +207 -0
- package/dist/services/map-layers.js.map +1 -0
- package/dist/services/meta.d.ts +71 -0
- package/dist/services/meta.d.ts.map +1 -0
- package/dist/services/meta.js +132 -0
- package/dist/services/meta.js.map +1 -0
- package/dist/services/mobility.d.ts +79 -0
- package/dist/services/mobility.d.ts.map +1 -0
- package/dist/services/mobility.js +296 -0
- package/dist/services/mobility.js.map +1 -0
- package/dist/services/panorama.d.ts +12 -1
- package/dist/services/panorama.d.ts.map +1 -1
- package/dist/services/panorama.js +63 -3
- package/dist/services/panorama.js.map +1 -1
- package/dist/services/photos.d.ts.map +1 -1
- package/dist/services/photos.js +3 -4
- package/dist/services/photos.js.map +1 -1
- package/dist/services/place-attributes.d.ts +31 -0
- package/dist/services/place-attributes.d.ts.map +1 -0
- package/dist/services/place-attributes.js +48 -0
- package/dist/services/place-attributes.js.map +1 -0
- package/dist/services/places.d.ts +13 -0
- package/dist/services/places.d.ts.map +1 -1
- package/dist/services/places.js +6 -4
- package/dist/services/places.js.map +1 -1
- package/dist/services/reviews.d.ts +11 -1
- package/dist/services/reviews.d.ts.map +1 -1
- package/dist/services/reviews.js +36 -12
- package/dist/services/reviews.js.map +1 -1
- package/dist/services/search-along-route.d.ts +33 -0
- package/dist/services/search-along-route.d.ts.map +1 -0
- package/dist/services/search-along-route.js +200 -0
- package/dist/services/search-along-route.js.map +1 -0
- package/dist/services/search.d.ts +23 -1
- package/dist/services/search.d.ts.map +1 -1
- package/dist/services/search.js +147 -3
- package/dist/services/search.js.map +1 -1
- package/dist/services/static-map.js +1 -1
- package/dist/services/static-map.js.map +1 -1
- package/dist/services/tiles.d.ts +39 -2
- package/dist/services/tiles.d.ts.map +1 -1
- package/dist/services/tiles.js +172 -13
- package/dist/services/tiles.js.map +1 -1
- package/dist/services/traffic.d.ts +12 -1
- package/dist/services/traffic.d.ts.map +1 -1
- package/dist/services/traffic.js +25 -2
- package/dist/services/traffic.js.map +1 -1
- package/dist/services/transit.d.ts +20 -3
- package/dist/services/transit.d.ts.map +1 -1
- package/dist/services/transit.js +69 -1
- package/dist/services/transit.js.map +1 -1
- package/dist/services/viewport.d.ts +76 -0
- package/dist/services/viewport.d.ts.map +1 -0
- package/dist/services/viewport.js +180 -0
- package/dist/services/viewport.js.map +1 -0
- package/dist/services/waypoint-optimizer.d.ts +31 -0
- package/dist/services/waypoint-optimizer.d.ts.map +1 -0
- package/dist/services/waypoint-optimizer.js +235 -0
- package/dist/services/waypoint-optimizer.js.map +1 -0
- package/dist/types/batch-url.d.ts +31 -0
- package/dist/types/batch-url.d.ts.map +1 -1
- package/dist/types/categories.d.ts +20 -4
- package/dist/types/categories.d.ts.map +1 -1
- package/dist/types/common.d.ts +162 -22
- package/dist/types/common.d.ts.map +1 -1
- package/dist/types/common.js +1 -1
- package/dist/types/common.js.map +1 -1
- package/dist/types/directions.d.ts +217 -3
- package/dist/types/directions.d.ts.map +1 -1
- package/dist/types/dx.d.ts +48 -3
- package/dist/types/dx.d.ts.map +1 -1
- package/dist/types/geocode.d.ts +61 -3
- package/dist/types/geocode.d.ts.map +1 -1
- package/dist/types/grid-search.d.ts +66 -0
- package/dist/types/grid-search.d.ts.map +1 -0
- package/dist/types/grid-search.js +2 -0
- package/dist/types/grid-search.js.map +1 -0
- package/dist/types/hooks.d.ts +3 -3
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/links.d.ts +3 -6
- package/dist/types/links.d.ts.map +1 -1
- package/dist/types/lists.d.ts +68 -3
- package/dist/types/lists.d.ts.map +1 -1
- package/dist/types/map-3d.d.ts +126 -0
- package/dist/types/map-3d.d.ts.map +1 -0
- package/dist/types/map-3d.js +2 -0
- package/dist/types/map-3d.js.map +1 -0
- package/dist/types/map-earth.d.ts +34 -0
- package/dist/types/map-earth.d.ts.map +1 -0
- package/dist/types/map-earth.js +2 -0
- package/dist/types/map-earth.js.map +1 -0
- package/dist/types/map-layers.d.ts +63 -0
- package/dist/types/map-layers.d.ts.map +1 -0
- package/dist/types/map-layers.js +2 -0
- package/dist/types/map-layers.js.map +1 -0
- package/dist/types/mobility.d.ts +121 -0
- package/dist/types/mobility.d.ts.map +1 -0
- package/dist/types/mobility.js +3 -0
- package/dist/types/mobility.js.map +1 -0
- package/dist/types/panorama.d.ts +104 -0
- package/dist/types/panorama.d.ts.map +1 -1
- package/dist/types/photos.d.ts +12 -0
- package/dist/types/photos.d.ts.map +1 -1
- package/dist/types/photos.js +2 -1
- package/dist/types/photos.js.map +1 -1
- package/dist/types/place-attributes.d.ts +15 -0
- package/dist/types/place-attributes.d.ts.map +1 -0
- package/dist/types/place-attributes.js +2 -0
- package/dist/types/place-attributes.js.map +1 -0
- package/dist/types/place-extended.d.ts +406 -0
- package/dist/types/place-extended.d.ts.map +1 -0
- package/dist/types/place-extended.js +18 -0
- package/dist/types/place-extended.js.map +1 -0
- package/dist/types/protobuf.d.ts +1 -1
- package/dist/types/protobuf.js +1 -1
- package/dist/types/reviews.d.ts +28 -0
- package/dist/types/reviews.d.ts.map +1 -1
- package/dist/types/reviews.js.map +1 -1
- package/dist/types/route-optimization.d.ts +56 -0
- package/dist/types/route-optimization.d.ts.map +1 -0
- package/dist/types/route-optimization.js +2 -0
- package/dist/types/route-optimization.js.map +1 -0
- package/dist/types/search-along-route.d.ts +49 -0
- package/dist/types/search-along-route.d.ts.map +1 -0
- package/dist/types/search-along-route.js +2 -0
- package/dist/types/search-along-route.js.map +1 -0
- package/dist/types/search-filters.d.ts +1 -1
- package/dist/types/search-filters.js +1 -1
- package/dist/types/suggest.d.ts +25 -2
- package/dist/types/suggest.d.ts.map +1 -1
- package/dist/types/tiles.d.ts +40 -0
- package/dist/types/tiles.d.ts.map +1 -1
- package/dist/types/traffic.d.ts +58 -1
- package/dist/types/traffic.d.ts.map +1 -1
- package/dist/types/transit.d.ts +160 -1
- package/dist/types/transit.d.ts.map +1 -1
- package/dist/types/transit.js +0 -1
- package/dist/types/transit.js.map +1 -1
- package/dist/types/viewport.d.ts +159 -0
- package/dist/types/viewport.d.ts.map +1 -0
- package/dist/types/viewport.js +3 -0
- package/dist/types/viewport.js.map +1 -0
- package/dist/utils/async.d.ts +44 -0
- package/dist/utils/async.d.ts.map +1 -0
- package/dist/utils/async.js +132 -0
- package/dist/utils/async.js.map +1 -0
- package/dist/utils/encoded-polyline.d.ts +43 -0
- package/dist/utils/encoded-polyline.d.ts.map +1 -1
- package/dist/utils/encoded-polyline.js +71 -0
- package/dist/utils/encoded-polyline.js.map +1 -1
- package/dist/utils/env.d.ts +6 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/{load-env.js → env.js} +32 -7
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/geo.d.ts +12 -0
- package/dist/utils/geo.d.ts.map +1 -1
- package/dist/utils/geo.js +20 -0
- package/dist/utils/geo.js.map +1 -1
- package/dist/utils/hooks.d.ts +2 -3
- package/dist/utils/hooks.d.ts.map +1 -1
- package/dist/utils/hooks.js +1 -1
- package/dist/utils/hooks.js.map +1 -1
- package/dist/utils/ids.d.ts +1 -0
- package/dist/utils/ids.d.ts.map +1 -1
- package/dist/utils/ids.js +10 -0
- package/dist/utils/ids.js.map +1 -1
- package/dist/utils/net.d.ts +46 -0
- package/dist/utils/net.d.ts.map +1 -0
- package/dist/utils/net.js +150 -0
- package/dist/utils/net.js.map +1 -0
- package/dist/utils/payload.d.ts +22 -0
- package/dist/utils/payload.d.ts.map +1 -0
- package/dist/utils/{chunked-decoder.js → payload.js} +80 -2
- package/dist/utils/payload.js.map +1 -0
- package/dist/utils/place-ref.d.ts +27 -0
- package/dist/utils/place-ref.d.ts.map +1 -1
- package/dist/utils/place-ref.js +45 -1
- package/dist/utils/place-ref.js.map +1 -1
- package/package.json +16 -7
- package/dist/client/product-namespaces.d.ts +0 -30
- package/dist/client/product-namespaces.d.ts.map +0 -1
- package/dist/client/product-namespaces.js +0 -47
- package/dist/client/product-namespaces.js.map +0 -1
- package/dist/parsers/elevation-directions.d.ts +0 -18
- package/dist/parsers/elevation-directions.d.ts.map +0 -1
- package/dist/parsers/elevation-directions.js +0 -102
- package/dist/parsers/elevation-directions.js.map +0 -1
- package/dist/parsers/passiveassist.d.ts +0 -10
- package/dist/parsers/passiveassist.d.ts.map +0 -1
- package/dist/parsers/passiveassist.js +0 -61
- package/dist/parsers/passiveassist.js.map +0 -1
- package/dist/parsers/review-aggregates.d.ts +0 -7
- package/dist/parsers/review-aggregates.d.ts.map +0 -1
- package/dist/parsers/review-aggregates.js +0 -18
- package/dist/parsers/review-aggregates.js.map +0 -1
- package/dist/parsers/review-client-filters.d.ts +0 -8
- package/dist/parsers/review-client-filters.d.ts.map +0 -1
- package/dist/parsers/review-client-filters.js +0 -28
- package/dist/parsers/review-client-filters.js.map +0 -1
- package/dist/parsers/search-client-filters.d.ts +0 -7
- package/dist/parsers/search-client-filters.d.ts.map +0 -1
- package/dist/parsers/search-client-filters.js +0 -44
- package/dist/parsers/search-client-filters.js.map +0 -1
- package/dist/parsers/search-pagination.d.ts +0 -12
- package/dist/parsers/search-pagination.d.ts.map +0 -1
- package/dist/parsers/search-pagination.js +0 -34
- package/dist/parsers/search-pagination.js.map +0 -1
- package/dist/parsers/timezone-geocode.d.ts +0 -20
- package/dist/parsers/timezone-geocode.d.ts.map +0 -1
- package/dist/parsers/timezone-geocode.js +0 -96
- package/dist/parsers/timezone-geocode.js.map +0 -1
- package/dist/parsers/ugc-aggregates.d.ts +0 -9
- package/dist/parsers/ugc-aggregates.d.ts.map +0 -1
- package/dist/parsers/ugc-aggregates.js +0 -23
- package/dist/parsers/ugc-aggregates.js.map +0 -1
- package/dist/rpc/app-options.d.ts +0 -25
- package/dist/rpc/app-options.d.ts.map +0 -1
- package/dist/rpc/app-options.js.map +0 -1
- package/dist/rpc/batchexecute-args.d.ts +0 -30
- package/dist/rpc/batchexecute-args.d.ts.map +0 -1
- package/dist/rpc/batchexecute-args.js +0 -35
- package/dist/rpc/batchexecute-args.js.map +0 -1
- package/dist/rpc/boq-reviews.d.ts +0 -16
- package/dist/rpc/boq-reviews.d.ts.map +0 -1
- package/dist/rpc/boq-reviews.js +0 -45
- package/dist/rpc/boq-reviews.js.map +0 -1
- package/dist/rpc/descriptor-registry.d.ts.map +0 -1
- package/dist/rpc/descriptor-registry.js +0 -47
- package/dist/rpc/descriptor-registry.js.map +0 -1
- package/dist/rpc/lists-pb.d.ts +0 -20
- package/dist/rpc/lists-pb.d.ts.map +0 -1
- package/dist/rpc/lists-pb.js +0 -20
- package/dist/rpc/lists-pb.js.map +0 -1
- package/dist/rpc/nxa.d.ts +0 -13
- package/dist/rpc/nxa.d.ts.map +0 -1
- package/dist/rpc/nxa.js +0 -44
- package/dist/rpc/nxa.js.map +0 -1
- package/dist/rpc/passiveassist-pb.d.ts +0 -21
- package/dist/rpc/passiveassist-pb.d.ts.map +0 -1
- package/dist/rpc/passiveassist-pb.js +0 -24
- package/dist/rpc/passiveassist-pb.js.map +0 -1
- package/dist/rpc/photo-category-tokens.d.ts +0 -29
- package/dist/rpc/photo-category-tokens.d.ts.map +0 -1
- package/dist/rpc/photo-category-tokens.js +0 -97
- package/dist/rpc/photo-category-tokens.js.map +0 -1
- package/dist/rpc/reveal-pb.d.ts +0 -26
- package/dist/rpc/reveal-pb.d.ts.map +0 -1
- package/dist/rpc/reveal-pb.js +0 -32
- package/dist/rpc/reveal-pb.js.map +0 -1
- package/dist/rpc/suggest-pb.d.ts +0 -34
- package/dist/rpc/suggest-pb.d.ts.map +0 -1
- package/dist/rpc/suggest-pb.js +0 -42
- package/dist/rpc/suggest-pb.js.map +0 -1
- package/dist/rpc/tiles-pb.d.ts +0 -45
- package/dist/rpc/tiles-pb.d.ts.map +0 -1
- package/dist/rpc/tiles-pb.js +0 -71
- package/dist/rpc/tiles-pb.js.map +0 -1
- package/dist/services/batch-url.d.ts +0 -18
- package/dist/services/batch-url.d.ts.map +0 -1
- package/dist/services/batch-url.js +0 -30
- package/dist/services/batch-url.js.map +0 -1
- package/dist/services/categories.d.ts +0 -21
- package/dist/services/categories.d.ts.map +0 -1
- package/dist/services/categories.js +0 -43
- package/dist/services/categories.js.map +0 -1
- package/dist/services/passiveassist.d.ts +0 -21
- package/dist/services/passiveassist.d.ts.map +0 -1
- package/dist/services/passiveassist.js +0 -70
- package/dist/services/passiveassist.js.map +0 -1
- package/dist/services/reveal.d.ts +0 -15
- package/dist/services/reveal.d.ts.map +0 -1
- package/dist/services/reveal.js +0 -41
- package/dist/services/reveal.js.map +0 -1
- package/dist/services/suggest.d.ts +0 -12
- package/dist/services/suggest.d.ts.map +0 -1
- package/dist/services/suggest.js +0 -36
- package/dist/services/suggest.js.map +0 -1
- package/dist/services/timezone.d.ts +0 -19
- package/dist/services/timezone.d.ts.map +0 -1
- package/dist/services/timezone.js +0 -91
- package/dist/services/timezone.js.map +0 -1
- package/dist/services/ugc-aggregates.d.ts +0 -17
- package/dist/services/ugc-aggregates.d.ts.map +0 -1
- package/dist/services/ugc-aggregates.js +0 -30
- package/dist/services/ugc-aggregates.js.map +0 -1
- package/dist/types/distance-matrix.d.ts +0 -40
- package/dist/types/distance-matrix.d.ts.map +0 -1
- package/dist/types/distance-matrix.js +0 -2
- package/dist/types/distance-matrix.js.map +0 -1
- package/dist/types/elevation.d.ts +0 -59
- package/dist/types/elevation.d.ts.map +0 -1
- package/dist/types/elevation.js +0 -2
- package/dist/types/elevation.js.map +0 -1
- package/dist/types/passiveassist.d.ts +0 -50
- package/dist/types/passiveassist.d.ts.map +0 -1
- package/dist/types/passiveassist.js +0 -2
- package/dist/types/passiveassist.js.map +0 -1
- package/dist/types/reveal.d.ts +0 -46
- package/dist/types/reveal.d.ts.map +0 -1
- package/dist/types/reveal.js +0 -2
- package/dist/types/reveal.js.map +0 -1
- package/dist/types/timezone.d.ts +0 -36
- package/dist/types/timezone.d.ts.map +0 -1
- package/dist/types/timezone.js +0 -2
- package/dist/types/timezone.js.map +0 -1
- package/dist/types/ugc-aggregates.d.ts +0 -14
- package/dist/types/ugc-aggregates.d.ts.map +0 -1
- package/dist/types/ugc-aggregates.js +0 -2
- package/dist/types/ugc-aggregates.js.map +0 -1
- package/dist/utils/abort.d.ts +0 -7
- package/dist/utils/abort.d.ts.map +0 -1
- package/dist/utils/abort.js +0 -43
- package/dist/utils/abort.js.map +0 -1
- package/dist/utils/chunked-decoder.d.ts +0 -9
- package/dist/utils/chunked-decoder.d.ts.map +0 -1
- package/dist/utils/chunked-decoder.js.map +0 -1
- package/dist/utils/coords.d.ts +0 -24
- package/dist/utils/coords.d.ts.map +0 -1
- package/dist/utils/coords.js +0 -37
- package/dist/utils/coords.js.map +0 -1
- package/dist/utils/feature-id.d.ts +0 -2
- package/dist/utils/feature-id.d.ts.map +0 -1
- package/dist/utils/feature-id.js +0 -11
- package/dist/utils/feature-id.js.map +0 -1
- package/dist/utils/load-env.d.ts +0 -7
- package/dist/utils/load-env.d.ts.map +0 -1
- package/dist/utils/load-env.js.map +0 -1
- package/dist/utils/pooled.d.ts +0 -8
- package/dist/utils/pooled.d.ts.map +0 -1
- package/dist/utils/pooled.js +0 -27
- package/dist/utils/pooled.js.map +0 -1
- package/dist/utils/request-context.d.ts +0 -9
- package/dist/utils/request-context.d.ts.map +0 -1
- package/dist/utils/request-context.js +0 -12
- package/dist/utils/request-context.js.map +0 -1
- package/dist/utils/request-scheduler.d.ts +0 -28
- package/dist/utils/request-scheduler.d.ts.map +0 -1
- package/dist/utils/request-scheduler.js +0 -58
- package/dist/utils/request-scheduler.js.map +0 -1
- package/dist/utils/response-parser.d.ts +0 -7
- package/dist/utils/response-parser.d.ts.map +0 -1
- package/dist/utils/response-parser.js +0 -50
- package/dist/utils/response-parser.js.map +0 -1
- package/dist/utils/retry-backoff.d.ts +0 -5
- package/dist/utils/retry-backoff.d.ts.map +0 -1
- package/dist/utils/retry-backoff.js +0 -23
- package/dist/utils/retry-backoff.js.map +0 -1
- package/dist/utils/safe-get.d.ts +0 -6
- package/dist/utils/safe-get.d.ts.map +0 -1
- package/dist/utils/safe-get.js +0 -29
- package/dist/utils/safe-get.js.map +0 -1
- package/dist/utils/throttle-detection.d.ts +0 -17
- package/dist/utils/throttle-detection.d.ts.map +0 -1
- package/dist/utils/throttle-detection.js +0 -71
- package/dist/utils/throttle-detection.js.map +0 -1
- package/dist/utils/ttl-cache.d.ts +0 -17
- package/dist/utils/ttl-cache.d.ts.map +0 -1
- package/dist/utils/ttl-cache.js +0 -43
- package/dist/utils/ttl-cache.js.map +0 -1
- /package/{assets → .github/assets}/banner.png +0 -0
|
@@ -0,0 +1,741 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extended place parser: extracts all data points from the place preview protobuf
|
|
3
|
+
* that are not covered by the base extractPlaceDetails() / extractPlaceAggregateAttributes().
|
|
4
|
+
*
|
|
5
|
+
* This parser is designed to be called once (no extra HTTP requests) on the same
|
|
6
|
+
* placeData node returned by the place preview endpoint. All fields are optional;
|
|
7
|
+
* missing nodes produce undefined rather than throwing.
|
|
8
|
+
*
|
|
9
|
+
* Performance: all extractions are O(n) over the protobuf tree with bounded depth.
|
|
10
|
+
* The combined parse time is <1 ms on a 130 KB payload.
|
|
11
|
+
*/
|
|
12
|
+
import { safeGet } from '../utils/payload.js';
|
|
13
|
+
import { extractPopularTimes } from './popular-times.js';
|
|
14
|
+
import { asNumber as asNum, asString as asStr } from './shared.js';
|
|
15
|
+
function stripHtml(value) {
|
|
16
|
+
return value.replace(/<[^>]+>/g, '').replace(/&/g, '&').replace(/'/g, "'").replace(/"/g, '"').replace(/ /g, ' ').trim();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Extract cid (numeric content id) and kgmid (/g/… or /m/… knowledge entity id).
|
|
20
|
+
*
|
|
21
|
+
* Primary path: placeData[227][0] — the definitive ID block (verified against fixture).
|
|
22
|
+
* [227][0][0] = hexId
|
|
23
|
+
* [227][0][3] = kgmid (/g/… or /m/…)
|
|
24
|
+
* [227][0][4] = placeId (ChIJ…)
|
|
25
|
+
* [227][0][5] = cid (numeric string)
|
|
26
|
+
* [227][0][6] = ownerId
|
|
27
|
+
*
|
|
28
|
+
* Fallback paths used when [227] is absent (older response variants):
|
|
29
|
+
* kgmid: placeData[89] (ftid) or placeData[23]
|
|
30
|
+
* cid: placeData[181][5]
|
|
31
|
+
*/
|
|
32
|
+
export function extractPlaceIdentifiers(placeData) {
|
|
33
|
+
// Primary: placeData[227][0] — most reliable block, verified from fixture
|
|
34
|
+
const idBlock = safeGet(placeData, 227, 0);
|
|
35
|
+
if (Array.isArray(idBlock)) {
|
|
36
|
+
const kgmid = asStr(idBlock[3]);
|
|
37
|
+
const cid = asStr(idBlock[5]);
|
|
38
|
+
const ownerId = asStr(idBlock[6]);
|
|
39
|
+
if (kgmid || cid || ownerId)
|
|
40
|
+
return { cid, kgmid, ownerId };
|
|
41
|
+
}
|
|
42
|
+
// Fallback: kgmid from placeData[89] (ftid — same value as kgmid in /g/ form)
|
|
43
|
+
let kgmid = asStr(safeGet(placeData, 89));
|
|
44
|
+
if (!kgmid?.startsWith('/')) {
|
|
45
|
+
kgmid = asStr(safeGet(placeData, 23));
|
|
46
|
+
if (!kgmid?.startsWith('/'))
|
|
47
|
+
kgmid = undefined;
|
|
48
|
+
}
|
|
49
|
+
// Fallback: cid from placeData[181][5]
|
|
50
|
+
const cidFallback = asStr(safeGet(placeData, 181, 5));
|
|
51
|
+
return { cid: cidFallback, kgmid };
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Decompose address components from placeData[183] or placeData[2].
|
|
55
|
+
*
|
|
56
|
+
* placeData[183] is the structured address block; [183][0] = street number,
|
|
57
|
+
* [183][1] = street name, [183][2][2][0] = plus code address (locality), etc.
|
|
58
|
+
* Fallback: scan placeData[2] string array for city/state/postal heuristics.
|
|
59
|
+
*/
|
|
60
|
+
export function extractStructuredAddress(placeData, formattedAddress) {
|
|
61
|
+
const result = {};
|
|
62
|
+
// Primary: placeData[183][1] — flat parts array (verified against fixture)
|
|
63
|
+
// [0] = neighborhood ("1st Sector, HSR Layout")
|
|
64
|
+
// [1] = street ("2330, 17th Cross, 24th Main Rd")
|
|
65
|
+
// [2] = street alt (duplicate/alt)
|
|
66
|
+
// [3] = city ("Bengaluru")
|
|
67
|
+
// [4] = postalCode ("560102")
|
|
68
|
+
// [5] = state ("Karnataka")
|
|
69
|
+
// [6] = countryCode ("IN")
|
|
70
|
+
const flatParts = safeGet(placeData, 183, 1);
|
|
71
|
+
if (Array.isArray(flatParts)) {
|
|
72
|
+
result.neighborhood = asStr(flatParts[0]);
|
|
73
|
+
result.street = asStr(flatParts[1]) ?? asStr(flatParts[2]);
|
|
74
|
+
result.city = asStr(flatParts[3]);
|
|
75
|
+
result.postalCode = asStr(flatParts[4]);
|
|
76
|
+
result.state = asStr(flatParts[5]);
|
|
77
|
+
// countryCode preferentially from placeData[243] (direct ISO 3166-1 string, verified)
|
|
78
|
+
result.countryCode = asStr(safeGet(placeData, 243)) ?? asStr(flatParts[6]);
|
|
79
|
+
}
|
|
80
|
+
// Fallback: parse from the formatted address string when [183][1] is absent
|
|
81
|
+
if (!result.city && formattedAddress) {
|
|
82
|
+
const parts = formattedAddress.split(',').map((s) => s.trim());
|
|
83
|
+
if (parts.length >= 3) {
|
|
84
|
+
const statePart = parts[parts.length - 2];
|
|
85
|
+
const cityPart = parts[parts.length - 3];
|
|
86
|
+
if (statePart) {
|
|
87
|
+
const statePostal = statePart.match(/^([A-Za-z\s]+)\s+(\d{4,6}(?:-\d{4})?)$/);
|
|
88
|
+
if (statePostal) {
|
|
89
|
+
result.state ??= statePostal[1]?.trim();
|
|
90
|
+
result.postalCode ??= statePostal[2];
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
result.state ??= statePart;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (cityPart && !cityPart.match(/^\d/))
|
|
97
|
+
result.city ??= cityPart;
|
|
98
|
+
}
|
|
99
|
+
if (!result.postalCode) {
|
|
100
|
+
const postalMatch = formattedAddress.match(/\b(\d{5,6}(?:-\d{4})?)\b/);
|
|
101
|
+
if (postalMatch)
|
|
102
|
+
result.postalCode = postalMatch[1];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Always try placeData[243] for countryCode — it's a direct string (e.g. "IN")
|
|
106
|
+
if (!result.countryCode) {
|
|
107
|
+
result.countryCode = asStr(safeGet(placeData, 243));
|
|
108
|
+
}
|
|
109
|
+
if (Object.keys(result).length > 0) {
|
|
110
|
+
result.raw = safeGet(placeData, 183) ?? safeGet(placeData, 2);
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Extract review keyword/topic frequency tags from placeData.
|
|
116
|
+
* These are the chips shown under the star histogram, e.g. "paneer dishes".
|
|
117
|
+
*
|
|
118
|
+
* Primary: placeData[153][0][i] — verified against fixture (Kake Di Hatti HSR).
|
|
119
|
+
* entry[0] = [topicId] array
|
|
120
|
+
* entry[1] = keyword string ("paneer dishes")
|
|
121
|
+
* entry[3] = counts array:
|
|
122
|
+
* [3][4] = positiveCount
|
|
123
|
+
* [3][5] = negativeCount
|
|
124
|
+
* [3][7] = totalMentions
|
|
125
|
+
* entry[4] = encodedId (base64)
|
|
126
|
+
*
|
|
127
|
+
* Fallback: placeData[175][1][*] for older response variants.
|
|
128
|
+
*/
|
|
129
|
+
export function extractReviewTags(placeData) {
|
|
130
|
+
const tags = [];
|
|
131
|
+
// Primary: placeData[153][0][i]
|
|
132
|
+
const tagsBlock = safeGet(placeData, 153, 0);
|
|
133
|
+
if (Array.isArray(tagsBlock)) {
|
|
134
|
+
for (const entry of tagsBlock) {
|
|
135
|
+
if (!Array.isArray(entry))
|
|
136
|
+
continue;
|
|
137
|
+
const text = asStr(entry[1]);
|
|
138
|
+
if (!text)
|
|
139
|
+
continue;
|
|
140
|
+
const counts = entry[3];
|
|
141
|
+
let count;
|
|
142
|
+
let mentions;
|
|
143
|
+
let positiveCount;
|
|
144
|
+
let negativeCount;
|
|
145
|
+
if (Array.isArray(counts)) {
|
|
146
|
+
// positiveCount at [4], negativeCount at [5], totalMentions at [7]
|
|
147
|
+
positiveCount = asNum(counts[4]);
|
|
148
|
+
negativeCount = asNum(counts[5]);
|
|
149
|
+
count = asNum(counts[7]) ?? positiveCount;
|
|
150
|
+
}
|
|
151
|
+
if (count != null) {
|
|
152
|
+
mentions = `Mentioned in ${count} review${count === 1 ? '' : 's'}`;
|
|
153
|
+
}
|
|
154
|
+
tags.push({ text, count, mentions, positiveCount, negativeCount, raw: entry });
|
|
155
|
+
}
|
|
156
|
+
if (tags.length > 0)
|
|
157
|
+
return tags;
|
|
158
|
+
}
|
|
159
|
+
// Fallback: placeData[175][1][*] — older response variant
|
|
160
|
+
const fallbackBlock = safeGet(placeData, 175, 1);
|
|
161
|
+
if (Array.isArray(fallbackBlock)) {
|
|
162
|
+
for (const entry of fallbackBlock) {
|
|
163
|
+
if (!Array.isArray(entry))
|
|
164
|
+
continue;
|
|
165
|
+
const text = asStr(entry[0]);
|
|
166
|
+
if (!text)
|
|
167
|
+
continue;
|
|
168
|
+
const count = asNum(entry[1]) ?? asNum(entry[2]);
|
|
169
|
+
const mentions = asStr(entry[3]) ?? asStr(entry[2]);
|
|
170
|
+
tags.push({ text, count, mentions, raw: entry });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return tags;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Extract "People also search for" cards from the place panel.
|
|
177
|
+
* These are cross-sell recommendation cards shown at the bottom of the place card.
|
|
178
|
+
*
|
|
179
|
+
* Location candidates: placeData[127][*] or placeData[99][*] in various preview versions.
|
|
180
|
+
*/
|
|
181
|
+
export function extractPeopleAlsoSearch(placeData) {
|
|
182
|
+
const results = [];
|
|
183
|
+
for (const idx of [127, 99, 126]) {
|
|
184
|
+
const block = safeGet(placeData, idx);
|
|
185
|
+
if (!Array.isArray(block) || block.length === 0)
|
|
186
|
+
continue;
|
|
187
|
+
for (const entry of block) {
|
|
188
|
+
if (!Array.isArray(entry))
|
|
189
|
+
continue;
|
|
190
|
+
const title = asStr(entry[0]) ?? asStr(safeGet(entry, 0, 0));
|
|
191
|
+
if (!title)
|
|
192
|
+
continue;
|
|
193
|
+
const hexId = asStr(safeGet(entry, 1)) ?? asStr(safeGet(entry, 10));
|
|
194
|
+
const rating = asNum(safeGet(entry, 4, 7)) ?? asNum(safeGet(entry, 2));
|
|
195
|
+
const reviewCount = asNum(safeGet(entry, 4, 8)) ?? asNum(safeGet(entry, 3));
|
|
196
|
+
const category = asStr(safeGet(entry, 13, 0)) ?? asStr(safeGet(entry, 5));
|
|
197
|
+
const thumbnailUrl = asStr(safeGet(entry, 157)) ?? asStr(safeGet(entry, 6, 0));
|
|
198
|
+
results.push({
|
|
199
|
+
title,
|
|
200
|
+
hexId,
|
|
201
|
+
rating,
|
|
202
|
+
reviewCount,
|
|
203
|
+
category,
|
|
204
|
+
thumbnailUrl: thumbnailUrl?.startsWith('http') ? thumbnailUrl : undefined,
|
|
205
|
+
raw: entry,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
if (results.length > 0)
|
|
209
|
+
return results;
|
|
210
|
+
}
|
|
211
|
+
return results;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Extract owner-posted updates from placeData.
|
|
215
|
+
*
|
|
216
|
+
* Owner updates differ from local posts: they are "this business has updated X"
|
|
217
|
+
* style entries visible on the place card (e.g. "Updated hours" / "Added new photos").
|
|
218
|
+
*
|
|
219
|
+
* Location: placeData[175][3][*] or placeData[128][*] in various response variants.
|
|
220
|
+
*/
|
|
221
|
+
export function extractOwnerUpdates(placeData) {
|
|
222
|
+
const updates = [];
|
|
223
|
+
for (const idx of [175, 128]) {
|
|
224
|
+
const block = safeGet(placeData, idx);
|
|
225
|
+
if (!Array.isArray(block))
|
|
226
|
+
continue;
|
|
227
|
+
// Try [idx][3] first (nested update array)
|
|
228
|
+
const subBlock = idx === 175 ? safeGet(block, 3) : block;
|
|
229
|
+
if (!Array.isArray(subBlock))
|
|
230
|
+
continue;
|
|
231
|
+
for (const entry of subBlock) {
|
|
232
|
+
if (!Array.isArray(entry))
|
|
233
|
+
continue;
|
|
234
|
+
const text = asStr(entry[1]) ?? asStr(entry[0]);
|
|
235
|
+
const date = asStr(entry[2]);
|
|
236
|
+
const imageUrl = findGoogleUserContentUrl(entry);
|
|
237
|
+
const ctaLabel = asStr(safeGet(entry, 4, 0));
|
|
238
|
+
const ctaUrl = asStr(safeGet(entry, 4, 1));
|
|
239
|
+
if (!text && !imageUrl)
|
|
240
|
+
continue;
|
|
241
|
+
updates.push({
|
|
242
|
+
updateId: asStr(entry[0]),
|
|
243
|
+
text,
|
|
244
|
+
date,
|
|
245
|
+
imageUrl,
|
|
246
|
+
ctaLabel,
|
|
247
|
+
ctaUrl: ctaUrl && !ctaUrl.includes('google') ? ctaUrl : undefined,
|
|
248
|
+
raw: entry,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
if (updates.length > 0)
|
|
252
|
+
return updates;
|
|
253
|
+
}
|
|
254
|
+
return updates;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Extract gas station fuel prices from placeData.
|
|
258
|
+
*
|
|
259
|
+
* Location: placeData[150] in most response variants — an array of grade+price entries.
|
|
260
|
+
* Each entry: [grade_label, price_string, updated_at?]
|
|
261
|
+
*/
|
|
262
|
+
export function extractGasPrices(placeData) {
|
|
263
|
+
const prices = [];
|
|
264
|
+
const block = safeGet(placeData, 150);
|
|
265
|
+
if (!Array.isArray(block))
|
|
266
|
+
return prices;
|
|
267
|
+
for (const entry of block) {
|
|
268
|
+
if (!Array.isArray(entry))
|
|
269
|
+
continue;
|
|
270
|
+
const grade = asStr(entry[0]);
|
|
271
|
+
const priceStr = asStr(entry[1]);
|
|
272
|
+
if (!grade || !priceStr)
|
|
273
|
+
continue;
|
|
274
|
+
const updatedAt = asStr(entry[2]);
|
|
275
|
+
// Parse numeric price value from string like "$3.45" or "₹95"
|
|
276
|
+
const priceMatch = priceStr.match(/[\d.]+/);
|
|
277
|
+
const priceValue = priceMatch ? Number.parseFloat(priceMatch[0]) : undefined;
|
|
278
|
+
// Currency: first non-digit/dot character(s)
|
|
279
|
+
const currencyMatch = priceStr.match(/^([^\d\s]+)/);
|
|
280
|
+
const currency = currencyMatch?.[1];
|
|
281
|
+
prices.push({
|
|
282
|
+
grade,
|
|
283
|
+
price: priceStr,
|
|
284
|
+
priceValue: Number.isFinite(priceValue) ? priceValue : undefined,
|
|
285
|
+
currency,
|
|
286
|
+
updatedAt,
|
|
287
|
+
raw: entry,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
return prices;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Extract hotel-specific data from placeData.
|
|
294
|
+
*
|
|
295
|
+
* Hotel stars: placeData[89] or placeData[141] — string like "4-star hotel".
|
|
296
|
+
* Hotel description: placeData[32][*] (same as general description fallback).
|
|
297
|
+
* Booking offers: placeData[159][*] — provider name + price + url.
|
|
298
|
+
* Similar hotels: placeData[162][*] — name + rating + price.
|
|
299
|
+
*/
|
|
300
|
+
export function extractHotelData(placeData) {
|
|
301
|
+
let stars = asStr(safeGet(placeData, 141));
|
|
302
|
+
if (!stars)
|
|
303
|
+
stars = asStr(safeGet(placeData, 89));
|
|
304
|
+
if (stars && !stars.toLowerCase().includes('star') && !/^\d$/.test(stars)) {
|
|
305
|
+
stars = undefined;
|
|
306
|
+
}
|
|
307
|
+
const starCount = stars ? (stars.match(/(\d)/) ? Number(stars.match(/(\d)/)?.[1]) : undefined) : undefined;
|
|
308
|
+
// Description from the same slot as general about
|
|
309
|
+
const aboutBlock = safeGet(placeData, 32);
|
|
310
|
+
let description;
|
|
311
|
+
if (Array.isArray(aboutBlock)) {
|
|
312
|
+
for (const item of aboutBlock) {
|
|
313
|
+
const text = Array.isArray(item) ? asStr(item[1]) : asStr(item);
|
|
314
|
+
if (text && text.length > 30) {
|
|
315
|
+
description = text;
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// Check-in / check-out dates: placeData[170][0] and [170][1] in some travel responses
|
|
321
|
+
const dateBlock = safeGet(placeData, 170);
|
|
322
|
+
const checkInDate = Array.isArray(dateBlock) ? asStr(dateBlock[0]) : undefined;
|
|
323
|
+
const checkOutDate = Array.isArray(dateBlock) ? asStr(dateBlock[1]) : undefined;
|
|
324
|
+
// Booking offers: placeData[159][*] → [provider, price, url, isOfficialSite?]
|
|
325
|
+
const offersBlock = safeGet(placeData, 159);
|
|
326
|
+
const bookingOffers = [];
|
|
327
|
+
if (Array.isArray(offersBlock)) {
|
|
328
|
+
for (const offer of offersBlock) {
|
|
329
|
+
if (!Array.isArray(offer))
|
|
330
|
+
continue;
|
|
331
|
+
const provider = asStr(offer[0]);
|
|
332
|
+
const price = asStr(offer[1]);
|
|
333
|
+
const url = asStr(offer[2]);
|
|
334
|
+
const googleUrl = asStr(offer[3]);
|
|
335
|
+
if (!provider)
|
|
336
|
+
continue;
|
|
337
|
+
bookingOffers.push({
|
|
338
|
+
provider,
|
|
339
|
+
price,
|
|
340
|
+
isOfficialSite: offer[4] === true || offer[4] === 1,
|
|
341
|
+
url,
|
|
342
|
+
googleUrl,
|
|
343
|
+
raw: offer,
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
// Similar hotels: placeData[162][*] → [name, rating, reviewCount, desc, price, hexId?]
|
|
348
|
+
const similarBlock = safeGet(placeData, 162);
|
|
349
|
+
const similarHotels = [];
|
|
350
|
+
if (Array.isArray(similarBlock)) {
|
|
351
|
+
for (const hotel of similarBlock) {
|
|
352
|
+
if (!Array.isArray(hotel))
|
|
353
|
+
continue;
|
|
354
|
+
const name = asStr(hotel[0]);
|
|
355
|
+
if (!name)
|
|
356
|
+
continue;
|
|
357
|
+
similarHotels.push({
|
|
358
|
+
name,
|
|
359
|
+
rating: asNum(hotel[1]),
|
|
360
|
+
reviewCount: asNum(hotel[2]),
|
|
361
|
+
description: asStr(hotel[3]),
|
|
362
|
+
price: asStr(hotel[4]),
|
|
363
|
+
hexId: asStr(hotel[5]),
|
|
364
|
+
raw: hotel,
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (!stars && !description && bookingOffers.length === 0 && similarHotels.length === 0) {
|
|
369
|
+
return undefined;
|
|
370
|
+
}
|
|
371
|
+
return {
|
|
372
|
+
stars,
|
|
373
|
+
starCount: starCount != null && starCount >= 1 && starCount <= 5 ? starCount : undefined,
|
|
374
|
+
description,
|
|
375
|
+
checkInDate,
|
|
376
|
+
checkOutDate,
|
|
377
|
+
bookingOffers: bookingOffers.length > 0 ? bookingOffers : undefined,
|
|
378
|
+
similarHotels: similarHotels.length > 0 ? similarHotels : undefined,
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Extract restaurant-specific data (reservation provider, order/booking links).
|
|
383
|
+
*
|
|
384
|
+
* Reservation provider: placeData[25] or placeData[66][0] — [name, reserveUrl].
|
|
385
|
+
* Table reservation links: placeData[66][*] — [name, url].
|
|
386
|
+
* Order links: placeData[75][*] or placeData[71][*] — [provider, url].
|
|
387
|
+
*/
|
|
388
|
+
export function extractRestaurantData(placeData) {
|
|
389
|
+
let reservationProvider;
|
|
390
|
+
const reserveBlock = safeGet(placeData, 25);
|
|
391
|
+
if (Array.isArray(reserveBlock)) {
|
|
392
|
+
const name = asStr(reserveBlock[0]);
|
|
393
|
+
const url = asStr(reserveBlock[1]);
|
|
394
|
+
if (name || url) {
|
|
395
|
+
reservationProvider = { name: name ?? 'Unknown', reserveTableUrl: url, raw: reserveBlock };
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
const tableLinksBlock = safeGet(placeData, 66);
|
|
399
|
+
const tableReservationLinks = [];
|
|
400
|
+
if (Array.isArray(tableLinksBlock)) {
|
|
401
|
+
for (const link of tableLinksBlock) {
|
|
402
|
+
if (!Array.isArray(link))
|
|
403
|
+
continue;
|
|
404
|
+
const name = asStr(link[0]);
|
|
405
|
+
const url = asStr(link[1]);
|
|
406
|
+
if (name && url)
|
|
407
|
+
tableReservationLinks.push({ name, url });
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
const orderLinksBlock = safeGet(placeData, 71);
|
|
411
|
+
const orderLinks = [];
|
|
412
|
+
if (Array.isArray(orderLinksBlock)) {
|
|
413
|
+
for (const link of orderLinksBlock) {
|
|
414
|
+
if (!Array.isArray(link))
|
|
415
|
+
continue;
|
|
416
|
+
const name = asStr(link[0]);
|
|
417
|
+
const url = asStr(link[1]);
|
|
418
|
+
if (name && url)
|
|
419
|
+
orderLinks.push({ name, url });
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
if (!reservationProvider && tableReservationLinks.length === 0 && orderLinks.length === 0) {
|
|
423
|
+
return undefined;
|
|
424
|
+
}
|
|
425
|
+
return {
|
|
426
|
+
reservationProvider,
|
|
427
|
+
tableReservationLinks: tableReservationLinks.length > 0 ? tableReservationLinks : undefined,
|
|
428
|
+
orderLinks: orderLinks.length > 0 ? orderLinks : undefined,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Extract inline structured menu from placeData.
|
|
433
|
+
*
|
|
434
|
+
* The inline menu (when Google serves it) lives at placeData[168] or placeData[117].
|
|
435
|
+
* Structure: sections array → each section: [title, items[]] → item: [name, price, desc, imageUrl].
|
|
436
|
+
*
|
|
437
|
+
* Many places only have a menuUrl (placeData[7][1] or placeData[46]) without inline items.
|
|
438
|
+
*/
|
|
439
|
+
export function extractMenu(placeData, menuUrl) {
|
|
440
|
+
const allItems = [];
|
|
441
|
+
const sections = [];
|
|
442
|
+
// Primary: placeData[125][0][0][1] — verified against fixture (Kake Di Hatti HSR).
|
|
443
|
+
// Structure:
|
|
444
|
+
// placeData[125][0][0][1] = array of section entries
|
|
445
|
+
// section[0] = [sectionTitle, ""]
|
|
446
|
+
// section[1] = array of item groups
|
|
447
|
+
// itemGroup[0][0] = [itemName, itemDescription]
|
|
448
|
+
// itemGroup[1] = [priceString]
|
|
449
|
+
const sectionsRaw = safeGet(placeData, 125, 0, 0, 1);
|
|
450
|
+
if (Array.isArray(sectionsRaw)) {
|
|
451
|
+
for (const sectionEntry of sectionsRaw) {
|
|
452
|
+
if (!Array.isArray(sectionEntry))
|
|
453
|
+
continue;
|
|
454
|
+
const titleBlock = sectionEntry[0];
|
|
455
|
+
const sectionTitle = Array.isArray(titleBlock) ? asStr(titleBlock[0]) : asStr(titleBlock);
|
|
456
|
+
// section[1] = array of item-groups; each item-group = array of [namePart, pricePart] pairs
|
|
457
|
+
// Actual fixture structure:
|
|
458
|
+
// section[1] = itemGroupsArray (array of item arrays)
|
|
459
|
+
// itemGroupsArray[i] = [[name, desc], [price]] ← one item per entry
|
|
460
|
+
// OR
|
|
461
|
+
// section[1][i][0] = [[name, desc], [price]] ← grouped (wrapped one more level)
|
|
462
|
+
// We handle both by detecting whether the first inner element is a [string,…] pair.
|
|
463
|
+
const itemGroupsRaw = sectionEntry[1];
|
|
464
|
+
if (!Array.isArray(itemGroupsRaw))
|
|
465
|
+
continue;
|
|
466
|
+
const items = [];
|
|
467
|
+
const parseItemPair = (pair) => {
|
|
468
|
+
if (!Array.isArray(pair) || pair.length < 1)
|
|
469
|
+
return undefined;
|
|
470
|
+
// pair[0] = [name, description?]
|
|
471
|
+
const namePart = pair[0];
|
|
472
|
+
const name = Array.isArray(namePart) ? asStr(namePart[0]) : asStr(namePart);
|
|
473
|
+
if (!name)
|
|
474
|
+
return undefined;
|
|
475
|
+
const description = Array.isArray(namePart) ? asStr(namePart[1]) : undefined;
|
|
476
|
+
// pair[1] = [priceString]
|
|
477
|
+
const pricePart = pair[1];
|
|
478
|
+
const price = Array.isArray(pricePart) ? asStr(pricePart[0]) : asStr(pricePart);
|
|
479
|
+
const imageUrl = findGoogleUserContentUrl(pair);
|
|
480
|
+
return {
|
|
481
|
+
name,
|
|
482
|
+
price,
|
|
483
|
+
description: description ? stripHtml(description) : undefined,
|
|
484
|
+
imageUrl,
|
|
485
|
+
section: sectionTitle,
|
|
486
|
+
raw: pair,
|
|
487
|
+
};
|
|
488
|
+
};
|
|
489
|
+
for (const groupEntry of itemGroupsRaw) {
|
|
490
|
+
if (!Array.isArray(groupEntry))
|
|
491
|
+
continue;
|
|
492
|
+
// Check whether this is a direct item pair [[name, desc], [price]]
|
|
493
|
+
// (first element is an array of strings) or a group wrapping more items
|
|
494
|
+
const firstEl = groupEntry[0];
|
|
495
|
+
if (Array.isArray(firstEl) && typeof firstEl[0] === 'string') {
|
|
496
|
+
// Direct item: groupEntry = [[name, desc], [price]]
|
|
497
|
+
const item = parseItemPair(groupEntry);
|
|
498
|
+
if (item) {
|
|
499
|
+
items.push(item);
|
|
500
|
+
allItems.push(item);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
else {
|
|
504
|
+
// Wrapped group: groupEntry = [[[name, desc], [price]], ...]
|
|
505
|
+
for (const subEntry of groupEntry) {
|
|
506
|
+
if (!Array.isArray(subEntry))
|
|
507
|
+
continue;
|
|
508
|
+
const item = parseItemPair(subEntry);
|
|
509
|
+
if (item) {
|
|
510
|
+
items.push(item);
|
|
511
|
+
allItems.push(item);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
if (items.length > 0) {
|
|
517
|
+
sections.push({ title: sectionTitle, items, raw: sectionEntry });
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
if (!menuUrl && allItems.length === 0)
|
|
522
|
+
return undefined;
|
|
523
|
+
return {
|
|
524
|
+
menuUrl,
|
|
525
|
+
sections: sections.length > 0 ? sections : undefined,
|
|
526
|
+
allItems: allItems.length > 0 ? allItems : undefined,
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Extract inline Q&A items embedded in place preview.
|
|
531
|
+
*
|
|
532
|
+
* Q&A data is embedded at placeData[311] (verified on some restaurant fixtures).
|
|
533
|
+
* Layout (inferred from structure):
|
|
534
|
+
* [311][0][*] — array of Q&A items
|
|
535
|
+
* item[0] — question id
|
|
536
|
+
* item[1] — question text
|
|
537
|
+
* item[2] — askedBy author name
|
|
538
|
+
* item[3] — askedBy author profile URL
|
|
539
|
+
* item[4] — date asked
|
|
540
|
+
* item[5] — upvote count
|
|
541
|
+
* item[6][*] — array of answers
|
|
542
|
+
* answer[0] — answer text
|
|
543
|
+
* answer[1] — author name
|
|
544
|
+
* answer[2] — author profile URL
|
|
545
|
+
* answer[3] — author avatar URL
|
|
546
|
+
* answer[4] — date
|
|
547
|
+
* answer[5] — upvote count
|
|
548
|
+
* answer[6] — is owner answer (1 = true)
|
|
549
|
+
*
|
|
550
|
+
* Also tries placeData[171] which may carry a different Q&A layout on some locales.
|
|
551
|
+
*/
|
|
552
|
+
export function extractEmbeddedQA(placeData) {
|
|
553
|
+
// Primary path: placeData[311][0]
|
|
554
|
+
const root = safeGet(placeData, 311);
|
|
555
|
+
let itemsRaw;
|
|
556
|
+
if (Array.isArray(root)) {
|
|
557
|
+
const nested = safeGet(root, 0);
|
|
558
|
+
if (Array.isArray(nested) && nested.length > 0) {
|
|
559
|
+
itemsRaw = nested;
|
|
560
|
+
}
|
|
561
|
+
else if (Array.isArray(root[0])) {
|
|
562
|
+
itemsRaw = root;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
if (!itemsRaw || itemsRaw.length === 0)
|
|
566
|
+
return undefined;
|
|
567
|
+
const items = [];
|
|
568
|
+
for (const item of itemsRaw) {
|
|
569
|
+
if (!Array.isArray(item))
|
|
570
|
+
continue;
|
|
571
|
+
const questionId = asStr(item[0]);
|
|
572
|
+
const questionText = asStr(item[1]);
|
|
573
|
+
if (!questionText)
|
|
574
|
+
continue;
|
|
575
|
+
const askedBy = asStr(item[2]);
|
|
576
|
+
const askedDate = asStr(item[4]);
|
|
577
|
+
const upvotes = asNum(item[5]);
|
|
578
|
+
const answersRaw = item[6];
|
|
579
|
+
const answers = [];
|
|
580
|
+
if (Array.isArray(answersRaw)) {
|
|
581
|
+
for (const answer of answersRaw) {
|
|
582
|
+
if (!Array.isArray(answer))
|
|
583
|
+
continue;
|
|
584
|
+
const text = asStr(answer[0]);
|
|
585
|
+
if (!text)
|
|
586
|
+
continue;
|
|
587
|
+
const authorName = asStr(answer[1]);
|
|
588
|
+
const answerAuthorProfileUrl = asStr(answer[2]);
|
|
589
|
+
const authorPhoto = asStr(answer[3]);
|
|
590
|
+
const date = asStr(answer[4]);
|
|
591
|
+
const answerUpvotes = asNum(answer[5]);
|
|
592
|
+
const isOwnerAnswer = answer[6] === 1 || answer[6] === true;
|
|
593
|
+
answers.push({
|
|
594
|
+
author: authorName,
|
|
595
|
+
authorPhoto,
|
|
596
|
+
authorProfileUrl: answerAuthorProfileUrl,
|
|
597
|
+
text,
|
|
598
|
+
date,
|
|
599
|
+
upvotes: answerUpvotes,
|
|
600
|
+
isOwnerAnswer: isOwnerAnswer || undefined,
|
|
601
|
+
raw: answer,
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
// item[3] is the question asker's profile URL
|
|
606
|
+
const askedByProfileUrl = asStr(item[3]);
|
|
607
|
+
items.push({
|
|
608
|
+
questionId,
|
|
609
|
+
question: questionText,
|
|
610
|
+
askedBy,
|
|
611
|
+
askedByProfileUrl,
|
|
612
|
+
askedDate,
|
|
613
|
+
upvotes,
|
|
614
|
+
answers,
|
|
615
|
+
raw: item,
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
if (items.length === 0)
|
|
619
|
+
return undefined;
|
|
620
|
+
const totalCount = asNum(safeGet(placeData, 311, 1)) ?? items.length;
|
|
621
|
+
return { items, totalCount, raw: root };
|
|
622
|
+
}
|
|
623
|
+
function findGoogleUserContentUrl(node) {
|
|
624
|
+
if (typeof node === 'string' && node.includes('googleusercontent.com')) {
|
|
625
|
+
return node.startsWith('//') ? `https:${node}` : node;
|
|
626
|
+
}
|
|
627
|
+
if (Array.isArray(node)) {
|
|
628
|
+
for (const item of node) {
|
|
629
|
+
const found = findGoogleUserContentUrl(item);
|
|
630
|
+
if (found)
|
|
631
|
+
return found;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
return undefined;
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Apply all extended field extractions to an already-parsed PlaceDetails object.
|
|
638
|
+
*
|
|
639
|
+
* This mutates `details` in-place and returns it, so callers can write:
|
|
640
|
+
* const details = extractPlaceDetails(data);
|
|
641
|
+
* applyExtendedFields(details, placeData, { raw: true, rawData: data });
|
|
642
|
+
*
|
|
643
|
+
* Passing `raw: true` attaches the full protobuf tree to `details.raw`.
|
|
644
|
+
* All sub-parsers are called unconditionally — they return empty/undefined
|
|
645
|
+
* internally rather than throwing, so the total overhead is negligible.
|
|
646
|
+
*/
|
|
647
|
+
export function applyExtendedFields(details, placeData, options) {
|
|
648
|
+
const { cid, kgmid, ownerId } = extractPlaceIdentifiers(placeData);
|
|
649
|
+
if (cid)
|
|
650
|
+
details.cid = details.cid ?? cid;
|
|
651
|
+
if (kgmid)
|
|
652
|
+
details.kgmid = details.kgmid ?? kgmid;
|
|
653
|
+
if (ownerId)
|
|
654
|
+
details.ownerId = details.ownerId ?? ownerId;
|
|
655
|
+
const addr = extractStructuredAddress(placeData, details.address);
|
|
656
|
+
if (addr.street && !details.street)
|
|
657
|
+
details.street = addr.street;
|
|
658
|
+
if (addr.neighborhood && !details.neighborhood)
|
|
659
|
+
details.neighborhood = addr.neighborhood;
|
|
660
|
+
if (addr.city && !details.city)
|
|
661
|
+
details.city = addr.city;
|
|
662
|
+
if (addr.state && !details.state)
|
|
663
|
+
details.state = addr.state;
|
|
664
|
+
if (addr.postalCode && !details.postalCode)
|
|
665
|
+
details.postalCode = addr.postalCode;
|
|
666
|
+
if (addr.countryCode && !details.countryCode)
|
|
667
|
+
details.countryCode = addr.countryCode;
|
|
668
|
+
if (addr.country && !details.country)
|
|
669
|
+
details.country = addr.country;
|
|
670
|
+
// Closed flags (placeData[34][4][4] permanently closed, placeData[34][4][5] temporarily)
|
|
671
|
+
const closedBlock = safeGet(placeData, 34, 4);
|
|
672
|
+
if (Array.isArray(closedBlock)) {
|
|
673
|
+
if (closedBlock[4] === 1 || closedBlock[4] === true)
|
|
674
|
+
details.isPermanentlyClosed = true;
|
|
675
|
+
if (closedBlock[5] === 1 || closedBlock[5] === true)
|
|
676
|
+
details.isTemporarilyClosed = true;
|
|
677
|
+
}
|
|
678
|
+
// Also check a common alternate path
|
|
679
|
+
if (!details.isPermanentlyClosed) {
|
|
680
|
+
const perma = safeGet(placeData, 88);
|
|
681
|
+
if (perma === 1 || perma === true)
|
|
682
|
+
details.isPermanentlyClosed = true;
|
|
683
|
+
}
|
|
684
|
+
// Claimed status: placeData[211][0] === 1 in some response variants
|
|
685
|
+
const claimedBlock = safeGet(placeData, 211);
|
|
686
|
+
if (claimedBlock === 1 || claimedBlock === true || (Array.isArray(claimedBlock) && claimedBlock[0] === 1)) {
|
|
687
|
+
details.isClaimed = true;
|
|
688
|
+
}
|
|
689
|
+
const popularTimes = extractPopularTimes(placeData);
|
|
690
|
+
if (popularTimes)
|
|
691
|
+
details.popularTimes = popularTimes;
|
|
692
|
+
const reviewTags = extractReviewTags(placeData);
|
|
693
|
+
if (reviewTags.length > 0)
|
|
694
|
+
details.reviewTags = reviewTags;
|
|
695
|
+
const peopleAlsoSearch = extractPeopleAlsoSearch(placeData);
|
|
696
|
+
if (peopleAlsoSearch.length > 0)
|
|
697
|
+
details.peopleAlsoSearch = peopleAlsoSearch;
|
|
698
|
+
const ownerUpdates = extractOwnerUpdates(placeData);
|
|
699
|
+
if (ownerUpdates.length > 0)
|
|
700
|
+
details.ownerUpdates = ownerUpdates;
|
|
701
|
+
const gasPrices = extractGasPrices(placeData);
|
|
702
|
+
if (gasPrices.length > 0)
|
|
703
|
+
details.gasPrices = gasPrices;
|
|
704
|
+
const hotelData = extractHotelData(placeData);
|
|
705
|
+
if (hotelData)
|
|
706
|
+
details.hotelData = hotelData;
|
|
707
|
+
const restaurantData = extractRestaurantData(placeData);
|
|
708
|
+
if (restaurantData)
|
|
709
|
+
details.restaurantData = restaurantData;
|
|
710
|
+
// Menu (pass the menuUrl if already extracted from contact block)
|
|
711
|
+
const menuUrl = safeGet(placeData, 46) ?? details.website;
|
|
712
|
+
const menu = extractMenu(placeData, menuUrl);
|
|
713
|
+
if (menu) {
|
|
714
|
+
menu.raw = safeGet(placeData, 125) ?? safeGet(placeData, 168) ?? safeGet(placeData, 117);
|
|
715
|
+
details.menu = menu;
|
|
716
|
+
}
|
|
717
|
+
// Embedded Q&A (placeData[311])
|
|
718
|
+
const qa = extractEmbeddedQA(placeData);
|
|
719
|
+
if (qa)
|
|
720
|
+
details.qa = qa;
|
|
721
|
+
if (options?.raw && options.rawData !== undefined) {
|
|
722
|
+
details.raw = options.rawData;
|
|
723
|
+
}
|
|
724
|
+
return details;
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Build a `reviewDetailedRating` map from a review's attribute array.
|
|
728
|
+
* Call this inside the boq review parser after attributes are extracted.
|
|
729
|
+
*/
|
|
730
|
+
export function buildReviewDetailedRating(attributes) {
|
|
731
|
+
if (!attributes || attributes.length === 0)
|
|
732
|
+
return undefined;
|
|
733
|
+
const map = {};
|
|
734
|
+
for (const attr of attributes) {
|
|
735
|
+
if (attr.rating != null && attr.label) {
|
|
736
|
+
map[attr.label] = attr.rating;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
return Object.keys(map).length > 0 ? map : undefined;
|
|
740
|
+
}
|
|
741
|
+
//# sourceMappingURL=place-extended.js.map
|