@domandigital/gbp 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/CHANGELOG.md +104 -0
- package/README.md +44 -11
- package/package.json +6 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@domandigital/gbp`.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
|
6
|
+
this project uses [semantic versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
Releases before 0.3.1 were consumed as git dependencies pinned to a tag. This
|
|
9
|
+
file was written retroactively from that tag history, so entries below 0.3.1
|
|
10
|
+
describe what the diffs actually changed rather than what was recorded at the
|
|
11
|
+
time.
|
|
12
|
+
|
|
13
|
+
## [Unreleased]
|
|
14
|
+
|
|
15
|
+
## [0.3.1] - 2026-08-16
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- `./package.json` is now exposed in the `exports` map. Tooling that reads a
|
|
20
|
+
dependency's manifest previously hit `ERR_PACKAGE_PATH_NOT_EXPORTED`.
|
|
21
|
+
- `@types/node` is declared as a devDependency, and `tsconfig.json` sets
|
|
22
|
+
`"types": ["node"]`. This package uses `process.env`, `fetch`,
|
|
23
|
+
`URLSearchParams`, `RequestInit` and `Response`, all of which need those
|
|
24
|
+
types, and none of which had a declared source. `pnpm typecheck` passed only
|
|
25
|
+
because TypeScript walks up past the repo root and can find an `@types/node`
|
|
26
|
+
installed elsewhere on the machine. No consumer was affected, since published
|
|
27
|
+
`.d.ts` files carry their own references, but the check was not real.
|
|
28
|
+
- CI on every push and pull request: typecheck, test and build across Node 20,
|
|
29
|
+
22 and 24. Previously the only workflow was the tag-triggered release.
|
|
30
|
+
- README section covering `scripts/oauth-listener.mjs`, the one-time local flow
|
|
31
|
+
that mints a client's `GBP_REFRESH_TOKEN` and writes it straight to Doppler.
|
|
32
|
+
It shipped in 0.3.0 with no documentation at all.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- `engines.node` raised from `>=18` to `>=20`. Node 18 reached end of life in
|
|
37
|
+
April 2025, and the previous range was never exercised by anything.
|
|
38
|
+
- README rewritten for npm distribution. The install section still described the
|
|
39
|
+
package as unpublished and pointed at the `#v0.1.0` git tag.
|
|
40
|
+
|
|
41
|
+
## [0.3.0] - 2026-08-16
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- `scripts/oauth-listener.mjs`: a one-time local OAuth flow that prints a
|
|
46
|
+
consent URL, catches Google's redirect on a local listener, exchanges the
|
|
47
|
+
code, looks up the account and location IDs, and writes all three values to
|
|
48
|
+
Doppler. The token never passes through stdout, so it can't land in a
|
|
49
|
+
captured log.
|
|
50
|
+
|
|
51
|
+
This script is not part of the published package. It isn't in `files`, so it's
|
|
52
|
+
absent from the npm tarball: it shells out to the `doppler` binary, which has
|
|
53
|
+
no place in a public library's runtime contract. Clone the repo to use it.
|
|
54
|
+
|
|
55
|
+
### Fixed
|
|
56
|
+
|
|
57
|
+
- The pagination test asserted a fixed order against a result the library
|
|
58
|
+
deliberately shuffles. With two reviews a shuffle returns the input order
|
|
59
|
+
about half the time, so the test failed roughly 50% of runs and survived two
|
|
60
|
+
releases because nothing ran the suite automatically. It now compares the set
|
|
61
|
+
of ids.
|
|
62
|
+
|
|
63
|
+
### Changed
|
|
64
|
+
|
|
65
|
+
- Licensed Apache-2.0, with publish metadata and `publishConfig` for public
|
|
66
|
+
access and provenance. First version published to the npm registry.
|
|
67
|
+
|
|
68
|
+
## [0.2.0] - 2026-07-31
|
|
69
|
+
|
|
70
|
+
### Changed
|
|
71
|
+
|
|
72
|
+
- **`getBusinessReviews` now returns reviews in random order.** Results are
|
|
73
|
+
shuffled before being returned, replacing the API's own
|
|
74
|
+
`orderBy=updateTime desc` ordering. There is no way to opt out.
|
|
75
|
+
|
|
76
|
+
Two consequences worth knowing before you upgrade from 0.1.0: output is not
|
|
77
|
+
stable across builds, so a statically generated testimonial section reorders
|
|
78
|
+
on every rebuild; and because the shuffle runs after `limit` is applied, you
|
|
79
|
+
get the most recent N reviews in random order rather than a random N.
|
|
80
|
+
|
|
81
|
+
(The 0.2.0 tag message also credits min-star filtering. That's inaccurate:
|
|
82
|
+
`filterMinStars` shipped in 0.1.0.)
|
|
83
|
+
|
|
84
|
+
## [0.1.0] - 2026-07-30
|
|
85
|
+
|
|
86
|
+
### Added
|
|
87
|
+
|
|
88
|
+
- Initial release, extracted from MMM Beauty's `packages/google-apis`. Zero
|
|
89
|
+
runtime dependencies.
|
|
90
|
+
- `getGoogleOAuthAccessToken` and `hasGoogleOAuthCredentials`: user
|
|
91
|
+
refresh-token OAuth, with the access token cached in process and refreshed a
|
|
92
|
+
minute before expiry. Service accounts are rejected by the Business Profile
|
|
93
|
+
API entirely, so this is the only auth route.
|
|
94
|
+
- `getBusinessReviews` and `isBusinessProfileConfigured`: a paginated reviews
|
|
95
|
+
fetch (the API caps each page at 50) that decodes Google's star-rating enums,
|
|
96
|
+
includes the business's reply to each review, and supports `limit`,
|
|
97
|
+
`filterMinStars` and a Next.js `next` cache hint. Returns empty results rather
|
|
98
|
+
than throwing when unconfigured, so UI can render unconditionally.
|
|
99
|
+
|
|
100
|
+
[Unreleased]: https://github.com/Doman-Digital/dd-gbp/compare/v0.3.1...HEAD
|
|
101
|
+
[0.3.1]: https://github.com/Doman-Digital/dd-gbp/compare/v0.3.0...v0.3.1
|
|
102
|
+
[0.3.0]: https://github.com/Doman-Digital/dd-gbp/compare/v0.2.0...v0.3.0
|
|
103
|
+
[0.2.0]: https://github.com/Doman-Digital/dd-gbp/compare/v0.1.0...v0.2.0
|
|
104
|
+
[0.1.0]: https://github.com/Doman-Digital/dd-gbp/releases/tag/v0.1.0
|
package/README.md
CHANGED
|
@@ -53,19 +53,16 @@ with the reply attached, for free.
|
|
|
53
53
|
|
|
54
54
|
## Install
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
```json
|
|
59
|
-
{
|
|
60
|
-
"dependencies": {
|
|
61
|
-
"@domandigital/gbp": "github:Doman-Digital/dd-gbp#v0.1.0"
|
|
62
|
-
}
|
|
63
|
-
}
|
|
56
|
+
```bash
|
|
57
|
+
pnpm add @domandigital/gbp
|
|
64
58
|
```
|
|
65
59
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
60
|
+
Public on npm, Apache-2.0, published with provenance from a tagged release.
|
|
61
|
+
Zero runtime dependencies. ESM and CJS builds ship together, each with its own
|
|
62
|
+
types. Requires Node 20 or newer.
|
|
63
|
+
|
|
64
|
+
Upgrading a repo that still pins `github:Doman-Digital/dd-gbp#vX.Y.Z`? Swap it
|
|
65
|
+
for a semver range.
|
|
69
66
|
|
|
70
67
|
## Env
|
|
71
68
|
|
|
@@ -81,6 +78,42 @@ Which actual Google Cloud OAuth client + refresh token you point at (the
|
|
|
81
78
|
agency's shared credential, or a business's own dedicated one) is entirely a
|
|
82
79
|
deployment-env decision, not a code-level one -- each app configures its own.
|
|
83
80
|
|
|
81
|
+
## Minting a client's refresh token
|
|
82
|
+
|
|
83
|
+
`GBP_REFRESH_TOKEN` can only be obtained by a human completing Google's consent
|
|
84
|
+
flow as the business owner. `scripts/oauth-listener.mjs` in this repo automates
|
|
85
|
+
everything around that: it prints a consent URL, catches Google's redirect on a
|
|
86
|
+
local listener, exchanges the code, looks up the account and location IDs, and
|
|
87
|
+
writes all three values straight to Doppler.
|
|
88
|
+
|
|
89
|
+
The token and both IDs travel via argv into `doppler secrets set` and are never
|
|
90
|
+
printed to stdout or returned from the process, so a captured terminal log can't
|
|
91
|
+
leak them.
|
|
92
|
+
|
|
93
|
+
This script is repo-only. It isn't in the package's `files`, so it's absent from
|
|
94
|
+
the npm tarball, deliberately: it shells out to the `doppler` binary, which has
|
|
95
|
+
no business being a runtime expectation of a public library. Clone the repo to
|
|
96
|
+
use it.
|
|
97
|
+
|
|
98
|
+
Run it from inside the **client's** repo, so `doppler secrets set` targets that
|
|
99
|
+
client's own project and config via their local `.doppler.yaml` scoping:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
GBP_CLIENT_ID=$(doppler secrets get GBP_CLIENT_ID --plain) GBP_CLIENT_SECRET=$(doppler secrets get GBP_CLIENT_SECRET --plain) node ../dd-gbp/scripts/oauth-listener.mjs
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Two things that will bite you once each:
|
|
106
|
+
|
|
107
|
+
- `http://127.0.0.1:3333/oauth2callback` has to be registered as an authorised
|
|
108
|
+
redirect URI on the OAuth client in the GCP console. If it isn't, Google
|
|
109
|
+
returns `redirect_uri_mismatch`.
|
|
110
|
+
- If the account has already granted this app access, Google can decline to
|
|
111
|
+
issue a new refresh token even with `prompt=consent`. Revoke it at
|
|
112
|
+
https://myaccount.google.com/permissions and run the script again.
|
|
113
|
+
|
|
114
|
+
If the account has more than one location, the script uses the first and prints
|
|
115
|
+
every location it saw, so you can check it picked the right one.
|
|
116
|
+
|
|
84
117
|
## API
|
|
85
118
|
|
|
86
119
|
### `getBusinessReviews(options?): Promise<BusinessReviewsResult>`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@domandigital/gbp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Zero-dependency Google Business Profile client: OAuth refresh-token auth and a reviews (with owner replies) fetch, shared across Doman Digital / IDS client sites.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -16,9 +16,11 @@
|
|
|
16
16
|
"types": "./dist/index.d.cts",
|
|
17
17
|
"default": "./dist/index.cjs"
|
|
18
18
|
}
|
|
19
|
-
}
|
|
19
|
+
},
|
|
20
|
+
"./package.json": "./package.json"
|
|
20
21
|
},
|
|
21
22
|
"files": [
|
|
23
|
+
"CHANGELOG.md",
|
|
22
24
|
"LICENSE",
|
|
23
25
|
"README.md",
|
|
24
26
|
"dist"
|
|
@@ -30,12 +32,13 @@
|
|
|
30
32
|
"prepublishOnly": "pnpm run build"
|
|
31
33
|
},
|
|
32
34
|
"devDependencies": {
|
|
35
|
+
"@types/node": "^20",
|
|
33
36
|
"tsup": "^8.3.5",
|
|
34
37
|
"typescript": "^5.6.3",
|
|
35
38
|
"vitest": "^2.1.9"
|
|
36
39
|
},
|
|
37
40
|
"engines": {
|
|
38
|
-
"node": ">=
|
|
41
|
+
"node": ">=20"
|
|
39
42
|
},
|
|
40
43
|
"packageManager": "pnpm@9.15.9",
|
|
41
44
|
"repository": {
|