@tks/wayfinder 0.3.0 → 0.3.1
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 +6 -0
- package/package.json +1 -1
- package/src/cli.ts +3 -2
- package/src/parse.ts +16 -0
- package/src/serpapi.ts +2 -1
- package/src/types.ts +2 -0
package/README.md
CHANGED
|
@@ -118,6 +118,12 @@ Search nearby coffee spots:
|
|
|
118
118
|
wayfinder places --near "Shinjuku, Tokyo" --type coffee --limit 5
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
+
Narrow results to walking-distance intent:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
wayfinder places --near "Domino Park, Brooklyn, NY" --range walk
|
|
125
|
+
```
|
|
126
|
+
|
|
121
127
|
Structured places output for scripting:
|
|
122
128
|
|
|
123
129
|
```bash
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -22,7 +22,7 @@ interface RunOptions {
|
|
|
22
22
|
promptImpl?: (prompt: string) => Promise<string>;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
const HELP_TEXT = `wayfinder v0.3.
|
|
25
|
+
const HELP_TEXT = `wayfinder v0.3.1 travel search
|
|
26
26
|
|
|
27
27
|
Usage:
|
|
28
28
|
wayfinder setup [--reset]
|
|
@@ -30,7 +30,7 @@ Usage:
|
|
|
30
30
|
wayfinder flights one-way --from SFO --to JFK --date 2026-03-21 [filters]
|
|
31
31
|
wayfinder flights booking --from SFO --to JFK --date 2026-03-21 --token <BOOKING_TOKEN> [--token <BOOKING_TOKEN>] [--json]
|
|
32
32
|
wayfinder hotels --where "New York, NY" --check-in 2026-03-21 --check-out 2026-03-23 [filters]
|
|
33
|
-
wayfinder places --near "Shinjuku, Tokyo" [--type restaurant|coffee] [--limit N] [--json]
|
|
33
|
+
wayfinder places --near "Shinjuku, Tokyo" [--type restaurant|coffee] [--range walk] [--limit N] [--json]
|
|
34
34
|
|
|
35
35
|
Setup:
|
|
36
36
|
Runs interactive key setup and stores your SerpApi key in local config.
|
|
@@ -72,6 +72,7 @@ Places required:
|
|
|
72
72
|
|
|
73
73
|
Places optional filters:
|
|
74
74
|
--type <restaurant|coffee> Place type (default restaurant)
|
|
75
|
+
--range <walk> Heuristic nearby scope; "walk" narrows to walking-distance intent
|
|
75
76
|
--limit <N> Maximum number of results (default 10)
|
|
76
77
|
|
|
77
78
|
Output:
|
package/src/parse.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
HotelQuery,
|
|
7
7
|
ParsedArgs,
|
|
8
8
|
PlaceQuery,
|
|
9
|
+
PlaceRange,
|
|
9
10
|
PlaceType,
|
|
10
11
|
} from "./types";
|
|
11
12
|
|
|
@@ -47,6 +48,7 @@ interface PlaceRawOptions {
|
|
|
47
48
|
near?: string;
|
|
48
49
|
type?: string;
|
|
49
50
|
limit?: string;
|
|
51
|
+
range?: string;
|
|
50
52
|
outputJson: boolean;
|
|
51
53
|
help: boolean;
|
|
52
54
|
}
|
|
@@ -339,6 +341,9 @@ function parsePlacesArgs(args: string[]): ParsedArgs {
|
|
|
339
341
|
case "--limit":
|
|
340
342
|
raw.limit = value;
|
|
341
343
|
break;
|
|
344
|
+
case "--range":
|
|
345
|
+
raw.range = value;
|
|
346
|
+
break;
|
|
342
347
|
default:
|
|
343
348
|
throw new CliError(`Unknown flag: ${token}`, ExitCode.InvalidInput);
|
|
344
349
|
}
|
|
@@ -497,11 +502,13 @@ function buildPlaceQuery(raw: PlaceRawOptions): PlaceQuery {
|
|
|
497
502
|
const near = normalizeLocation(raw.near);
|
|
498
503
|
const type = raw.type ? normalizePlaceType(raw.type) : "restaurant";
|
|
499
504
|
const limit = raw.limit ? normalizeLimit(raw.limit, "--limit") : 10;
|
|
505
|
+
const range = raw.range ? normalizePlaceRange(raw.range) : undefined;
|
|
500
506
|
|
|
501
507
|
return {
|
|
502
508
|
near,
|
|
503
509
|
type,
|
|
504
510
|
limit,
|
|
511
|
+
range,
|
|
505
512
|
};
|
|
506
513
|
}
|
|
507
514
|
|
|
@@ -658,6 +665,15 @@ function normalizePlaceType(value: string): PlaceType {
|
|
|
658
665
|
return normalized;
|
|
659
666
|
}
|
|
660
667
|
|
|
668
|
+
function normalizePlaceRange(value: string): PlaceRange {
|
|
669
|
+
const normalized = value.trim().toLowerCase();
|
|
670
|
+
if (normalized !== "walk") {
|
|
671
|
+
throw new CliError("--range must be: walk", ExitCode.InvalidInput);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
return normalized;
|
|
675
|
+
}
|
|
676
|
+
|
|
661
677
|
function normalizeTime(value: string, flagName: string): number {
|
|
662
678
|
const match = /^([01]\d|2[0-3]):([0-5]\d)$/.exec(value);
|
|
663
679
|
if (!match) {
|
package/src/serpapi.ts
CHANGED
|
@@ -387,10 +387,11 @@ function buildHotelRequestUrl(query: HotelQuery, apiKey: string): string {
|
|
|
387
387
|
function buildPlaceRequestUrl(query: PlaceQuery, apiKey: string): string {
|
|
388
388
|
const url = new URL("https://serpapi.com/search.json");
|
|
389
389
|
const searchTerm = query.type === "coffee" ? "coffee" : "restaurants";
|
|
390
|
+
const rangePrefix = query.range === "walk" ? "within walking distance " : "";
|
|
390
391
|
|
|
391
392
|
url.searchParams.set("engine", "google_maps");
|
|
392
393
|
url.searchParams.set("type", "search");
|
|
393
|
-
url.searchParams.set("q", `${searchTerm} near ${query.near}`);
|
|
394
|
+
url.searchParams.set("q", `${rangePrefix}${searchTerm} near ${query.near}`);
|
|
394
395
|
url.searchParams.set("api_key", apiKey);
|
|
395
396
|
return url.toString();
|
|
396
397
|
}
|
package/src/types.ts
CHANGED
|
@@ -31,11 +31,13 @@ export interface HotelQuery {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export type PlaceType = "restaurant" | "coffee";
|
|
34
|
+
export type PlaceRange = "walk";
|
|
34
35
|
|
|
35
36
|
export interface PlaceQuery {
|
|
36
37
|
near: string;
|
|
37
38
|
type: PlaceType;
|
|
38
39
|
limit: number;
|
|
40
|
+
range?: PlaceRange;
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
export interface ParsedArgsHelp {
|