@metamask-previews/profile-controller 1.2.1-preview-6ebaf4e52 → 2.0.0-preview-b6e8e7385
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 +22 -1
- package/dist/ProfileService-method-action-types.d.ts +37 -1
- package/dist/ProfileService-method-action-types.d.ts.map +1 -1
- package/dist/ProfileService-method-action-types.js.map +1 -1
- package/dist/ProfileService.d.ts +44 -0
- package/dist/ProfileService.d.ts.map +1 -1
- package/dist/ProfileService.js +105 -2
- package/dist/ProfileService.js.map +1 -1
- package/dist/index.d.ts +2 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/ProfileServiceMock.d.ts +0 -25
- package/dist/ProfileServiceMock.d.ts.map +0 -1
- package/dist/ProfileServiceMock.js +0 -65
- package/dist/ProfileServiceMock.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.0.0]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Add `checkDisplayNameValidity` to `ProfileService` for checking display name validity via `GET profiles/display-name/validity` ([#11339](https://github.com/MetaMask/core/pull/11339))
|
|
15
|
+
- Add `checkBioValidity` to `ProfileService` for checking bio validity via `GET profiles/bio/validity` ([#11339](https://github.com/MetaMask/core/pull/11339))
|
|
16
|
+
- Add `checkEarlyAccess` to `ProfileService` for checking early access status via `GET early-access` ([#11339](https://github.com/MetaMask/core/pull/11339))
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Preserve the Profile API's error message in the `HttpError` ([#11330](https://github.com/MetaMask/core/pull/11330))
|
|
21
|
+
- Clients can now surface the server-provided reason.
|
|
22
|
+
- When a non-2xx response body contains a `{ code, message }` payload, the error message is now `<operation error>: <status>: <API message>`.
|
|
23
|
+
- Falls back to `<operation error>: <status>` when the body is absent, unreadable, or has no `message`
|
|
24
|
+
|
|
25
|
+
### Removed
|
|
26
|
+
|
|
27
|
+
- **BREAKING:** Remove `ProfileServiceMock`, `buildMockProfileService`, `MockProfileServiceHandlers`, `MOCK_PROFILE_API_RESPONSE`, `MOCK_X_CONNECT_RESPONSE`, and `MOCK_X_AUTH_URL_RESPONSE` exports ([#11340](https://github.com/MetaMask/core/pull/11340))
|
|
28
|
+
- These were test utilities that were used to mock the profile service before the Profile API was live.
|
|
29
|
+
|
|
10
30
|
## [1.2.1]
|
|
11
31
|
|
|
12
32
|
### Added
|
|
@@ -72,7 +92,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
72
92
|
- Add `ProfileController` for managing user profile state, exposing `getMetaMaskProfile`, `getXprofile`, `createProfile`, `replaceProfile`, `updateProfile`, `deleteProfile`, `checkUsernameAvailability`, `getXAuthUrl`, `connectX`, and `getXAccount` via the messenger ([#10558](https://github.com/MetaMask/core/pull/10558))
|
|
73
93
|
- Add `ProfileService` for communicating with the MetaMask Profile API, exposing `getProfile`, `createProfile`, `replaceProfile`, `updateProfile`, `deleteProfile`, `checkUsernameAvailability`, `getXAuthUrl`, `connectX`, and `getXAccount` via the messenger, with superstruct validation on all inputs and responses ([#10558](https://github.com/MetaMask/core/pull/10558))
|
|
74
94
|
|
|
75
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/profile-controller@
|
|
95
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/profile-controller@2.0.0...HEAD
|
|
96
|
+
[2.0.0]: https://github.com/MetaMask/core/compare/@metamask/profile-controller@1.2.1...@metamask/profile-controller@2.0.0
|
|
76
97
|
[1.2.1]: https://github.com/MetaMask/core/compare/@metamask/profile-controller@1.2.0...@metamask/profile-controller@1.2.1
|
|
77
98
|
[1.2.0]: https://github.com/MetaMask/core/compare/@metamask/profile-controller@1.1.1...@metamask/profile-controller@1.2.0
|
|
78
99
|
[1.1.1]: https://github.com/MetaMask/core/compare/@metamask/profile-controller@1.1.0...@metamask/profile-controller@1.1.1
|
|
@@ -76,6 +76,42 @@ export type ProfileServiceCheckUsernameAvailabilityAction = {
|
|
|
76
76
|
type: `ProfileService:checkUsernameAvailability`;
|
|
77
77
|
handler: ProfileService['checkUsernameAvailability'];
|
|
78
78
|
};
|
|
79
|
+
/**
|
|
80
|
+
* Checks whether a display name is valid.
|
|
81
|
+
*
|
|
82
|
+
* @param displayName - The display name to validate.
|
|
83
|
+
* @returns An object with a `valid` boolean.
|
|
84
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
85
|
+
* @throws {StructError} If the response does not match the expected shape.
|
|
86
|
+
*/
|
|
87
|
+
export type ProfileServiceCheckDisplayNameValidityAction = {
|
|
88
|
+
type: `ProfileService:checkDisplayNameValidity`;
|
|
89
|
+
handler: ProfileService['checkDisplayNameValidity'];
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Checks whether a bio is valid.
|
|
93
|
+
*
|
|
94
|
+
* @param bio - The bio to validate.
|
|
95
|
+
* @returns An object with a `valid` boolean.
|
|
96
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
97
|
+
* @throws {StructError} If the response does not match the expected shape.
|
|
98
|
+
*/
|
|
99
|
+
export type ProfileServiceCheckBioValidityAction = {
|
|
100
|
+
type: `ProfileService:checkBioValidity`;
|
|
101
|
+
handler: ProfileService['checkBioValidity'];
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Checks whether the authenticated profile has early access.
|
|
105
|
+
* The profile is resolved server-side from the verified bearer token.
|
|
106
|
+
*
|
|
107
|
+
* @returns An object with a `hasAccess` boolean.
|
|
108
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
109
|
+
* @throws {StructError} If the response does not match the expected shape.
|
|
110
|
+
*/
|
|
111
|
+
export type ProfileServiceCheckEarlyAccessAction = {
|
|
112
|
+
type: `ProfileService:checkEarlyAccess`;
|
|
113
|
+
handler: ProfileService['checkEarlyAccess'];
|
|
114
|
+
};
|
|
79
115
|
/**
|
|
80
116
|
* Fetches the X OAuth PKCE authorization URL and its associated state parameter.
|
|
81
117
|
* The profile is resolved server-side from the verified bearer token.
|
|
@@ -134,5 +170,5 @@ export type ProfileServiceDisconnectXAction = {
|
|
|
134
170
|
/**
|
|
135
171
|
* Union of all ProfileService action types.
|
|
136
172
|
*/
|
|
137
|
-
export type ProfileServiceMethodActions = ProfileServiceGetProfileAction | ProfileServiceCreateProfileAction | ProfileServiceReplaceProfileAction | ProfileServiceUpdateProfileAction | ProfileServiceDeleteProfileAction | ProfileServiceCheckUsernameAvailabilityAction | ProfileServiceGetXAuthUrlAction | ProfileServiceConnectXAction | ProfileServiceGetXAccountAction | ProfileServiceDisconnectXAction;
|
|
173
|
+
export type ProfileServiceMethodActions = ProfileServiceGetProfileAction | ProfileServiceCreateProfileAction | ProfileServiceReplaceProfileAction | ProfileServiceUpdateProfileAction | ProfileServiceDeleteProfileAction | ProfileServiceCheckUsernameAvailabilityAction | ProfileServiceCheckDisplayNameValidityAction | ProfileServiceCheckBioValidityAction | ProfileServiceCheckEarlyAccessAction | ProfileServiceGetXAuthUrlAction | ProfileServiceConnectXAction | ProfileServiceGetXAccountAction | ProfileServiceDisconnectXAction;
|
|
138
174
|
//# sourceMappingURL=ProfileService-method-action-types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProfileService-method-action-types.d.ts","sourceRoot":"","sources":["../src/ProfileService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,MAAM,8BAA8B,GAAG;IAC3C,IAAI,EAAE,2BAA2B,CAAC;IAClC,OAAO,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;CACvC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,IAAI,EAAE,8BAA8B,CAAC;IACrC,OAAO,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;CAC1C,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,IAAI,EAAE,+BAA+B,CAAC;IACtC,OAAO,EAAE,cAAc,CAAC,gBAAgB,CAAC,CAAC;CAC3C,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,IAAI,EAAE,8BAA8B,CAAC;IACrC,OAAO,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;CAC1C,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,IAAI,EAAE,8BAA8B,CAAC;IACrC,OAAO,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;CAC1C,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,6CAA6C,GAAG;IAC1D,IAAI,EAAE,0CAA0C,CAAC;IACjD,OAAO,EAAE,cAAc,CAAC,2BAA2B,CAAC,CAAC;CACtD,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,IAAI,EAAE,4BAA4B,CAAC;IACnC,OAAO,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;CACxC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,IAAI,EAAE,yBAAyB,CAAC;IAChC,OAAO,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;CACrC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,IAAI,EAAE,4BAA4B,CAAC;IACnC,OAAO,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;CACxC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,IAAI,EAAE,4BAA4B,CAAC;IACnC,OAAO,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;CACxC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,2BAA2B,GACnC,8BAA8B,GAC9B,iCAAiC,GACjC,kCAAkC,GAClC,iCAAiC,GACjC,iCAAiC,GACjC,6CAA6C,GAC7C,+BAA+B,GAC/B,4BAA4B,GAC5B,+BAA+B,GAC/B,+BAA+B,CAAC"}
|
|
1
|
+
{"version":3,"file":"ProfileService-method-action-types.d.ts","sourceRoot":"","sources":["../src/ProfileService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,MAAM,8BAA8B,GAAG;IAC3C,IAAI,EAAE,2BAA2B,CAAC;IAClC,OAAO,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;CACvC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,IAAI,EAAE,8BAA8B,CAAC;IACrC,OAAO,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;CAC1C,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,kCAAkC,GAAG;IAC/C,IAAI,EAAE,+BAA+B,CAAC;IACtC,OAAO,EAAE,cAAc,CAAC,gBAAgB,CAAC,CAAC;CAC3C,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,IAAI,EAAE,8BAA8B,CAAC;IACrC,OAAO,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;CAC1C,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,IAAI,EAAE,8BAA8B,CAAC;IACrC,OAAO,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;CAC1C,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,6CAA6C,GAAG;IAC1D,IAAI,EAAE,0CAA0C,CAAC;IACjD,OAAO,EAAE,cAAc,CAAC,2BAA2B,CAAC,CAAC;CACtD,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,4CAA4C,GAAG;IACzD,IAAI,EAAE,yCAAyC,CAAC;IAChD,OAAO,EAAE,cAAc,CAAC,0BAA0B,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,oCAAoC,GAAG;IACjD,IAAI,EAAE,iCAAiC,CAAC;IACxC,OAAO,EAAE,cAAc,CAAC,kBAAkB,CAAC,CAAC;CAC7C,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,oCAAoC,GAAG;IACjD,IAAI,EAAE,iCAAiC,CAAC;IACxC,OAAO,EAAE,cAAc,CAAC,kBAAkB,CAAC,CAAC;CAC7C,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,IAAI,EAAE,4BAA4B,CAAC;IACnC,OAAO,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;CACxC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,IAAI,EAAE,yBAAyB,CAAC;IAChC,OAAO,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;CACrC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,IAAI,EAAE,4BAA4B,CAAC;IACnC,OAAO,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;CACxC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,IAAI,EAAE,4BAA4B,CAAC;IACnC,OAAO,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;CACxC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,2BAA2B,GACnC,8BAA8B,GAC9B,iCAAiC,GACjC,kCAAkC,GAClC,iCAAiC,GACjC,iCAAiC,GACjC,6CAA6C,GAC7C,4CAA4C,GAC5C,oCAAoC,GACpC,oCAAoC,GACpC,+BAA+B,GAC/B,4BAA4B,GAC5B,+BAA+B,GAC/B,+BAA+B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProfileService-method-action-types.js","sourceRoot":"","sources":["../src/ProfileService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { ProfileService } from './ProfileService.js';\n\n/**\n * Fetches a profile by its identifier.\n *\n * @param profileId - The profile identifier to fetch.\n * @returns The profile data from the API.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceGetProfileAction = {\n type: `ProfileService:getProfile`;\n handler: ProfileService['getProfile'];\n};\n\n/**\n * Creates a new MetaMask profile.\n *\n * @param params - The profile creation parameters.\n * @returns The created profile data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response do not match the expected shape.\n */\nexport type ProfileServiceCreateProfileAction = {\n type: `ProfileService:createProfile`;\n handler: ProfileService['createProfile'];\n};\n\n/**\n * Fully replaces an existing profile (PUT).\n *\n * @param profileId - The identifier of the profile to replace.\n * @param params - The replacement profile data.\n * @returns The updated profile data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response do not match the expected shape.\n */\nexport type ProfileServiceReplaceProfileAction = {\n type: `ProfileService:replaceProfile`;\n handler: ProfileService['replaceProfile'];\n};\n\n/**\n * Partially updates an existing profile (PATCH).\n *\n * @param profileId - The identifier of the profile to update.\n * @param params - The fields to update.\n * @returns The updated profile data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response do not match the expected shape.\n */\nexport type ProfileServiceUpdateProfileAction = {\n type: `ProfileService:updateProfile`;\n handler: ProfileService['updateProfile'];\n};\n\n/**\n * Deletes a profile by its identifier.\n *\n * @param profileId - The identifier of the profile to delete.\n * @returns The result of the mutation.\n * @throws {HttpError} If the API returns a non-2xx response.\n */\nexport type ProfileServiceDeleteProfileAction = {\n type: `ProfileService:deleteProfile`;\n handler: ProfileService['deleteProfile'];\n};\n\n/**\n * Checks whether a username is available.\n *\n * @param username - The username to check.\n * @returns Availability details including validity and normalized form.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceCheckUsernameAvailabilityAction = {\n type: `ProfileService:checkUsernameAvailability`;\n handler: ProfileService['checkUsernameAvailability'];\n};\n\n/**\n * Fetches the X OAuth PKCE authorization URL and its associated state parameter.\n * The profile is resolved server-side from the verified bearer token.\n *\n * @returns An object containing the authorization URL and the state token.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceGetXAuthUrlAction = {\n type: `ProfileService:getXAuthUrl`;\n handler: ProfileService['getXAuthUrl'];\n};\n\n/**\n * Completes the X OAuth PKCE flow and links the X account to the profile.\n * The profile is resolved server-side from the verified bearer token.\n *\n * @param params - The OAuth callback code and state from the X redirect.\n * @returns The linked X account data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceConnectXAction = {\n type: `ProfileService:connectX`;\n handler: ProfileService['connectX'];\n};\n\n/**\n * Fetches the X account currently linked to the authenticated profile.\n * The profile is resolved server-side from the verified bearer token.\n *\n * @returns The linked X account data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceGetXAccountAction = {\n type: `ProfileService:getXAccount`;\n handler: ProfileService['getXAccount'];\n};\n\n/**\n * Disconnects the X account linked to the authenticated profile.\n * Identity is resolved server-side from the verified bearer token, so the\n * request targets the shared account endpoint rather than a profile-scoped\n * path.\n * A `404` response is treated as success (no X account is linked), making\n * the operation idempotent.\n *\n * @param profileId - The ID of the profile whose cached data should be\n * invalidated after the disconnection. The API resolves the linked X account\n * from the bearer token, not from this value.\n * @returns The result of the mutation.\n * @throws {HttpError} If the API returns a non-2xx response other than `404`.\n */\nexport type ProfileServiceDisconnectXAction = {\n type: `ProfileService:disconnectX`;\n handler: ProfileService['disconnectX'];\n};\n\n/**\n * Union of all ProfileService action types.\n */\nexport type ProfileServiceMethodActions =\n | ProfileServiceGetProfileAction\n | ProfileServiceCreateProfileAction\n | ProfileServiceReplaceProfileAction\n | ProfileServiceUpdateProfileAction\n | ProfileServiceDeleteProfileAction\n | ProfileServiceCheckUsernameAvailabilityAction\n | ProfileServiceGetXAuthUrlAction\n | ProfileServiceConnectXAction\n | ProfileServiceGetXAccountAction\n | ProfileServiceDisconnectXAction;\n"]}
|
|
1
|
+
{"version":3,"file":"ProfileService-method-action-types.js","sourceRoot":"","sources":["../src/ProfileService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { ProfileService } from './ProfileService.js';\n\n/**\n * Fetches a profile by its identifier.\n *\n * @param profileId - The profile identifier to fetch.\n * @returns The profile data from the API.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceGetProfileAction = {\n type: `ProfileService:getProfile`;\n handler: ProfileService['getProfile'];\n};\n\n/**\n * Creates a new MetaMask profile.\n *\n * @param params - The profile creation parameters.\n * @returns The created profile data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response do not match the expected shape.\n */\nexport type ProfileServiceCreateProfileAction = {\n type: `ProfileService:createProfile`;\n handler: ProfileService['createProfile'];\n};\n\n/**\n * Fully replaces an existing profile (PUT).\n *\n * @param profileId - The identifier of the profile to replace.\n * @param params - The replacement profile data.\n * @returns The updated profile data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response do not match the expected shape.\n */\nexport type ProfileServiceReplaceProfileAction = {\n type: `ProfileService:replaceProfile`;\n handler: ProfileService['replaceProfile'];\n};\n\n/**\n * Partially updates an existing profile (PATCH).\n *\n * @param profileId - The identifier of the profile to update.\n * @param params - The fields to update.\n * @returns The updated profile data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response do not match the expected shape.\n */\nexport type ProfileServiceUpdateProfileAction = {\n type: `ProfileService:updateProfile`;\n handler: ProfileService['updateProfile'];\n};\n\n/**\n * Deletes a profile by its identifier.\n *\n * @param profileId - The identifier of the profile to delete.\n * @returns The result of the mutation.\n * @throws {HttpError} If the API returns a non-2xx response.\n */\nexport type ProfileServiceDeleteProfileAction = {\n type: `ProfileService:deleteProfile`;\n handler: ProfileService['deleteProfile'];\n};\n\n/**\n * Checks whether a username is available.\n *\n * @param username - The username to check.\n * @returns Availability details including validity and normalized form.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceCheckUsernameAvailabilityAction = {\n type: `ProfileService:checkUsernameAvailability`;\n handler: ProfileService['checkUsernameAvailability'];\n};\n\n/**\n * Checks whether a display name is valid.\n *\n * @param displayName - The display name to validate.\n * @returns An object with a `valid` boolean.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceCheckDisplayNameValidityAction = {\n type: `ProfileService:checkDisplayNameValidity`;\n handler: ProfileService['checkDisplayNameValidity'];\n};\n\n/**\n * Checks whether a bio is valid.\n *\n * @param bio - The bio to validate.\n * @returns An object with a `valid` boolean.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceCheckBioValidityAction = {\n type: `ProfileService:checkBioValidity`;\n handler: ProfileService['checkBioValidity'];\n};\n\n/**\n * Checks whether the authenticated profile has early access.\n * The profile is resolved server-side from the verified bearer token.\n *\n * @returns An object with a `hasAccess` boolean.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceCheckEarlyAccessAction = {\n type: `ProfileService:checkEarlyAccess`;\n handler: ProfileService['checkEarlyAccess'];\n};\n\n/**\n * Fetches the X OAuth PKCE authorization URL and its associated state parameter.\n * The profile is resolved server-side from the verified bearer token.\n *\n * @returns An object containing the authorization URL and the state token.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceGetXAuthUrlAction = {\n type: `ProfileService:getXAuthUrl`;\n handler: ProfileService['getXAuthUrl'];\n};\n\n/**\n * Completes the X OAuth PKCE flow and links the X account to the profile.\n * The profile is resolved server-side from the verified bearer token.\n *\n * @param params - The OAuth callback code and state from the X redirect.\n * @returns The linked X account data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceConnectXAction = {\n type: `ProfileService:connectX`;\n handler: ProfileService['connectX'];\n};\n\n/**\n * Fetches the X account currently linked to the authenticated profile.\n * The profile is resolved server-side from the verified bearer token.\n *\n * @returns The linked X account data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\nexport type ProfileServiceGetXAccountAction = {\n type: `ProfileService:getXAccount`;\n handler: ProfileService['getXAccount'];\n};\n\n/**\n * Disconnects the X account linked to the authenticated profile.\n * Identity is resolved server-side from the verified bearer token, so the\n * request targets the shared account endpoint rather than a profile-scoped\n * path.\n * A `404` response is treated as success (no X account is linked), making\n * the operation idempotent.\n *\n * @param profileId - The ID of the profile whose cached data should be\n * invalidated after the disconnection. The API resolves the linked X account\n * from the bearer token, not from this value.\n * @returns The result of the mutation.\n * @throws {HttpError} If the API returns a non-2xx response other than `404`.\n */\nexport type ProfileServiceDisconnectXAction = {\n type: `ProfileService:disconnectX`;\n handler: ProfileService['disconnectX'];\n};\n\n/**\n * Union of all ProfileService action types.\n */\nexport type ProfileServiceMethodActions =\n | ProfileServiceGetProfileAction\n | ProfileServiceCreateProfileAction\n | ProfileServiceReplaceProfileAction\n | ProfileServiceUpdateProfileAction\n | ProfileServiceDeleteProfileAction\n | ProfileServiceCheckUsernameAvailabilityAction\n | ProfileServiceCheckDisplayNameValidityAction\n | ProfileServiceCheckBioValidityAction\n | ProfileServiceCheckEarlyAccessAction\n | ProfileServiceGetXAuthUrlAction\n | ProfileServiceConnectXAction\n | ProfileServiceGetXAccountAction\n | ProfileServiceDisconnectXAction;\n"]}
|
package/dist/ProfileService.d.ts
CHANGED
|
@@ -13,6 +13,9 @@ export declare const ProfileServiceErrorMessage: {
|
|
|
13
13
|
readonly UPDATE_PROFILE_FAILED: 'ProfileService: failed to update profile';
|
|
14
14
|
readonly DELETE_PROFILE_FAILED: 'ProfileService: failed to delete profile';
|
|
15
15
|
readonly CHECK_USERNAME_AVAILABILITY_FAILED: 'ProfileService: failed to check username availability';
|
|
16
|
+
readonly CHECK_DISPLAY_NAME_VALIDITY_FAILED: 'ProfileService: failed to check display name validity';
|
|
17
|
+
readonly CHECK_BIO_VALIDITY_FAILED: 'ProfileService: failed to check bio validity';
|
|
18
|
+
readonly CHECK_EARLY_ACCESS_FAILED: 'ProfileService: failed to check early access status';
|
|
16
19
|
readonly GET_X_AUTH_URL_FAILED: 'ProfileService: failed to get X authentication URL';
|
|
17
20
|
readonly CONNECT_X_FAILED: 'ProfileService: failed to connect X account';
|
|
18
21
|
readonly GET_X_ACCOUNT_FAILED: 'ProfileService: failed to get X account';
|
|
@@ -44,6 +47,16 @@ declare const ProfileApiResponseStruct: import("@metamask/superstruct").Struct<{
|
|
|
44
47
|
created_at: import("@metamask/superstruct").Struct<string, null>;
|
|
45
48
|
updated_at: import("@metamask/superstruct").Struct<string, null>;
|
|
46
49
|
}>;
|
|
50
|
+
declare const FieldValidityResponseStruct: import("@metamask/superstruct").Struct<{
|
|
51
|
+
valid: boolean;
|
|
52
|
+
}, {
|
|
53
|
+
valid: import("@metamask/superstruct").Struct<boolean, null>;
|
|
54
|
+
}>;
|
|
55
|
+
declare const EarlyAccessResponseStruct: import("@metamask/superstruct").Struct<{
|
|
56
|
+
hasAccess: boolean;
|
|
57
|
+
}, {
|
|
58
|
+
hasAccess: import("@metamask/superstruct").Struct<boolean, null>;
|
|
59
|
+
}>;
|
|
47
60
|
declare const UsernameAvailabilityResponseStruct: import("@metamask/superstruct").Struct<{
|
|
48
61
|
username: string;
|
|
49
62
|
available: boolean;
|
|
@@ -184,6 +197,10 @@ export type ProfileApiResponse = Infer<typeof ProfileApiResponseStruct>;
|
|
|
184
197
|
export type CreateProfileResponse = Infer<typeof CreateProfileResponseStruct>;
|
|
185
198
|
/** The response shape for a username availability check. */
|
|
186
199
|
export type UsernameAvailabilityResponse = Infer<typeof UsernameAvailabilityResponseStruct>;
|
|
200
|
+
/** The response shape for display name and bio validity checks. */
|
|
201
|
+
export type FieldValidityResponse = Infer<typeof FieldValidityResponseStruct>;
|
|
202
|
+
/** The response shape for the early access check. */
|
|
203
|
+
export type EarlyAccessResponse = Infer<typeof EarlyAccessResponseStruct>;
|
|
187
204
|
/** The response shape returned when connecting or fetching an X account. */
|
|
188
205
|
export type ConnectXResponse = Infer<typeof ConnectXResponseStruct>;
|
|
189
206
|
/** The response shape returned when requesting the X OAuth authentication URL. */
|
|
@@ -281,6 +298,33 @@ export declare class ProfileService extends BaseDataService<typeof serviceName,
|
|
|
281
298
|
* @throws {StructError} If the response does not match the expected shape.
|
|
282
299
|
*/
|
|
283
300
|
checkUsernameAvailability(username: string): Promise<UsernameAvailabilityResponse>;
|
|
301
|
+
/**
|
|
302
|
+
* Checks whether a display name is valid.
|
|
303
|
+
*
|
|
304
|
+
* @param displayName - The display name to validate.
|
|
305
|
+
* @returns An object with a `valid` boolean.
|
|
306
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
307
|
+
* @throws {StructError} If the response does not match the expected shape.
|
|
308
|
+
*/
|
|
309
|
+
checkDisplayNameValidity(displayName: string): Promise<FieldValidityResponse>;
|
|
310
|
+
/**
|
|
311
|
+
* Checks whether a bio is valid.
|
|
312
|
+
*
|
|
313
|
+
* @param bio - The bio to validate.
|
|
314
|
+
* @returns An object with a `valid` boolean.
|
|
315
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
316
|
+
* @throws {StructError} If the response does not match the expected shape.
|
|
317
|
+
*/
|
|
318
|
+
checkBioValidity(bio: string): Promise<FieldValidityResponse>;
|
|
319
|
+
/**
|
|
320
|
+
* Checks whether the authenticated profile has early access.
|
|
321
|
+
* The profile is resolved server-side from the verified bearer token.
|
|
322
|
+
*
|
|
323
|
+
* @returns An object with a `hasAccess` boolean.
|
|
324
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
325
|
+
* @throws {StructError} If the response does not match the expected shape.
|
|
326
|
+
*/
|
|
327
|
+
checkEarlyAccess(): Promise<EarlyAccessResponse>;
|
|
284
328
|
/**
|
|
285
329
|
* Fetches the X OAuth PKCE authorization URL and its associated state parameter.
|
|
286
330
|
* The profile is resolved server-side from the verified bearer token.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProfileService.d.ts","sourceRoot":"","sources":["../src/ProfileService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC5B,oCAAoC,EACpC,kCAAkC,EACnC,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"ProfileService.d.ts","sourceRoot":"","sources":["../src/ProfileService.ts"],"names":[],"mappings":"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"}
|
package/dist/ProfileService.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseDataService } from '@metamask/base-data-service';
|
|
2
2
|
import { HttpError } from '@metamask/controller-utils';
|
|
3
|
-
import { array, boolean, enums, intersection, nullable, optional, sensitive, string, type as structType, } from '@metamask/superstruct';
|
|
3
|
+
import { array, boolean, enums, intersection, nullable, optional, sensitive, string, type as structType, validate, } from '@metamask/superstruct';
|
|
4
4
|
import { CaipAccountIdStruct } from '@metamask/utils';
|
|
5
5
|
export const serviceName = 'ProfileService';
|
|
6
6
|
// ---------------------------------------------------------------------------
|
|
@@ -14,6 +14,9 @@ export const ProfileServiceErrorMessage = {
|
|
|
14
14
|
UPDATE_PROFILE_FAILED: 'ProfileService: failed to update profile',
|
|
15
15
|
DELETE_PROFILE_FAILED: 'ProfileService: failed to delete profile',
|
|
16
16
|
CHECK_USERNAME_AVAILABILITY_FAILED: 'ProfileService: failed to check username availability',
|
|
17
|
+
CHECK_DISPLAY_NAME_VALIDITY_FAILED: 'ProfileService: failed to check display name validity',
|
|
18
|
+
CHECK_BIO_VALIDITY_FAILED: 'ProfileService: failed to check bio validity',
|
|
19
|
+
CHECK_EARLY_ACCESS_FAILED: 'ProfileService: failed to check early access status',
|
|
17
20
|
GET_X_AUTH_URL_FAILED: 'ProfileService: failed to get X authentication URL',
|
|
18
21
|
CONNECT_X_FAILED: 'ProfileService: failed to connect X account',
|
|
19
22
|
GET_X_ACCOUNT_FAILED: 'ProfileService: failed to get X account',
|
|
@@ -23,6 +26,15 @@ export const ProfileServiceErrorMessage = {
|
|
|
23
26
|
// Superstruct schemas
|
|
24
27
|
// ---------------------------------------------------------------------------
|
|
25
28
|
const TradingPrivacyStruct = enums(['public', 'private']);
|
|
29
|
+
/**
|
|
30
|
+
* The body the Profile API returns for a non-2xx response. The `message` is
|
|
31
|
+
* surfaced to clients so they can react to the specific failure; `code` is
|
|
32
|
+
* optional because not every error includes one.
|
|
33
|
+
*/
|
|
34
|
+
const ApiErrorResponseStruct = structType({
|
|
35
|
+
code: optional(string()),
|
|
36
|
+
message: string(),
|
|
37
|
+
});
|
|
26
38
|
const ProfileApiResponseStruct = structType({
|
|
27
39
|
profile_id: string(),
|
|
28
40
|
username: string(),
|
|
@@ -35,6 +47,12 @@ const ProfileApiResponseStruct = structType({
|
|
|
35
47
|
created_at: string(),
|
|
36
48
|
updated_at: string(),
|
|
37
49
|
});
|
|
50
|
+
const FieldValidityResponseStruct = structType({
|
|
51
|
+
valid: boolean(),
|
|
52
|
+
});
|
|
53
|
+
const EarlyAccessResponseStruct = structType({
|
|
54
|
+
hasAccess: boolean(),
|
|
55
|
+
});
|
|
38
56
|
const UsernameAvailabilityErrorStruct = structType({
|
|
39
57
|
code: string(),
|
|
40
58
|
message: string(),
|
|
@@ -102,6 +120,9 @@ const MESSENGER_EXPOSED_METHODS = [
|
|
|
102
120
|
'updateProfile',
|
|
103
121
|
'deleteProfile',
|
|
104
122
|
'checkUsernameAvailability',
|
|
123
|
+
'checkDisplayNameValidity',
|
|
124
|
+
'checkBioValidity',
|
|
125
|
+
'checkEarlyAccess',
|
|
105
126
|
'getXAuthUrl',
|
|
106
127
|
'connectX',
|
|
107
128
|
'getXAccount',
|
|
@@ -138,6 +159,29 @@ export class ProfileService extends BaseDataService {
|
|
|
138
159
|
const token = await this.messenger.call('AuthenticationController:getBearerToken');
|
|
139
160
|
return { Authorization: `Bearer ${token}` };
|
|
140
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Reads the error message from an unsuccessful API response body.
|
|
164
|
+
*
|
|
165
|
+
* The Profile API returns errors as `{ code, message }`. If the body is
|
|
166
|
+
* missing, is not JSON, or does not contain a message, this returns
|
|
167
|
+
* `undefined` so the caller can fall back to a generic message.
|
|
168
|
+
*
|
|
169
|
+
* @param response - The unsuccessful response.
|
|
170
|
+
* @returns The API-provided error message, or `undefined` if unavailable.
|
|
171
|
+
*/
|
|
172
|
+
async #readErrorMessage(response) {
|
|
173
|
+
try {
|
|
174
|
+
const body = await response.json();
|
|
175
|
+
const [error, result] = validate(body, ApiErrorResponseStruct);
|
|
176
|
+
if (!error) {
|
|
177
|
+
return result.message;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
// The body is absent or not valid JSON; fall back to a generic message.
|
|
182
|
+
}
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
141
185
|
async #fetch(endpoint, { method = 'GET', error, json, searchParams, }) {
|
|
142
186
|
const authHeaders = await this.#getAuthHeaders();
|
|
143
187
|
const url = new URL(`${this.#v1Url}/${endpoint}`);
|
|
@@ -155,7 +199,10 @@ export class ProfileService extends BaseDataService {
|
|
|
155
199
|
...(json === undefined ? {} : { body: JSON.stringify(json) }),
|
|
156
200
|
});
|
|
157
201
|
if (!response.ok) {
|
|
158
|
-
|
|
202
|
+
const apiMessage = await this.#readErrorMessage(response);
|
|
203
|
+
throw new HttpError(response.status, apiMessage
|
|
204
|
+
? `${error}: ${response.status}: ${apiMessage}`
|
|
205
|
+
: `${error}: ${response.status}`);
|
|
159
206
|
}
|
|
160
207
|
if (method === 'DELETE') {
|
|
161
208
|
return null;
|
|
@@ -273,6 +320,62 @@ export class ProfileService extends BaseDataService {
|
|
|
273
320
|
}),
|
|
274
321
|
});
|
|
275
322
|
}
|
|
323
|
+
/**
|
|
324
|
+
* Checks whether a display name is valid.
|
|
325
|
+
*
|
|
326
|
+
* @param displayName - The display name to validate.
|
|
327
|
+
* @returns An object with a `valid` boolean.
|
|
328
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
329
|
+
* @throws {StructError} If the response does not match the expected shape.
|
|
330
|
+
*/
|
|
331
|
+
async checkDisplayNameValidity(displayName) {
|
|
332
|
+
return this.fetchQuery({
|
|
333
|
+
queryKey: [`${this.name}:checkDisplayNameValidity`, displayName],
|
|
334
|
+
staleTime: 0,
|
|
335
|
+
responseStruct: FieldValidityResponseStruct,
|
|
336
|
+
queryFn: async () => this.#fetch('profiles/display-name/validity', {
|
|
337
|
+
error: ProfileServiceErrorMessage.CHECK_DISPLAY_NAME_VALIDITY_FAILED,
|
|
338
|
+
searchParams: { display_name: displayName },
|
|
339
|
+
}),
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Checks whether a bio is valid.
|
|
344
|
+
*
|
|
345
|
+
* @param bio - The bio to validate.
|
|
346
|
+
* @returns An object with a `valid` boolean.
|
|
347
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
348
|
+
* @throws {StructError} If the response does not match the expected shape.
|
|
349
|
+
*/
|
|
350
|
+
async checkBioValidity(bio) {
|
|
351
|
+
return this.fetchQuery({
|
|
352
|
+
queryKey: [`${this.name}:checkBioValidity`, bio],
|
|
353
|
+
staleTime: 0,
|
|
354
|
+
responseStruct: FieldValidityResponseStruct,
|
|
355
|
+
queryFn: async () => this.#fetch('profiles/bio/validity', {
|
|
356
|
+
error: ProfileServiceErrorMessage.CHECK_BIO_VALIDITY_FAILED,
|
|
357
|
+
searchParams: { bio },
|
|
358
|
+
}),
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Checks whether the authenticated profile has early access.
|
|
363
|
+
* The profile is resolved server-side from the verified bearer token.
|
|
364
|
+
*
|
|
365
|
+
* @returns An object with a `hasAccess` boolean.
|
|
366
|
+
* @throws {HttpError} If the API returns a non-2xx response.
|
|
367
|
+
* @throws {StructError} If the response does not match the expected shape.
|
|
368
|
+
*/
|
|
369
|
+
async checkEarlyAccess() {
|
|
370
|
+
return this.fetchQuery({
|
|
371
|
+
queryKey: [`${this.name}:checkEarlyAccess`],
|
|
372
|
+
staleTime: 0,
|
|
373
|
+
responseStruct: EarlyAccessResponseStruct,
|
|
374
|
+
queryFn: async () => this.#fetch('early-access', {
|
|
375
|
+
error: ProfileServiceErrorMessage.CHECK_EARLY_ACCESS_FAILED,
|
|
376
|
+
}),
|
|
377
|
+
});
|
|
378
|
+
}
|
|
276
379
|
/**
|
|
277
380
|
* Fetches the X OAuth PKCE authorization URL and its associated state parameter.
|
|
278
381
|
* The profile is resolved server-side from the verified bearer token.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProfileService.js","sourceRoot":"","sources":["../src/ProfileService.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseDataService } from '@metamask/base-data-service';\nimport type {\n CreateServicePolicyOptions,\n DataServiceCacheUpdatedEvent,\n DataServiceGranularCacheUpdatedEvent,\n DataServiceInvalidateQueriesAction,\n} from '@metamask/base-data-service';\nimport { HttpError } from '@metamask/controller-utils';\nimport type { Messenger } from '@metamask/messenger';\nimport type { AuthenticationController } from '@metamask/profile-sync-controller';\nimport {\n array,\n boolean,\n enums,\n intersection,\n nullable,\n optional,\n sensitive,\n string,\n type as structType,\n} from '@metamask/superstruct';\nimport type { Infer } from '@metamask/superstruct';\nimport type { Json } from '@metamask/utils';\nimport { CaipAccountIdStruct } from '@metamask/utils';\n\nimport type { ProfileServiceMethodActions } from './ProfileService-method-action-types.js';\n\nexport const serviceName = 'ProfileService';\n\n// ---------------------------------------------------------------------------\n// Error messages\n// ---------------------------------------------------------------------------\n\n/** Human-readable error messages for each ProfileService operation. */\nexport const ProfileServiceErrorMessage = {\n GET_PROFILE_FAILED: 'ProfileService: failed to fetch profile',\n CREATE_PROFILE_FAILED: 'ProfileService: failed to create profile',\n REPLACE_PROFILE_FAILED: 'ProfileService: failed to replace profile',\n UPDATE_PROFILE_FAILED: 'ProfileService: failed to update profile',\n DELETE_PROFILE_FAILED: 'ProfileService: failed to delete profile',\n CHECK_USERNAME_AVAILABILITY_FAILED:\n 'ProfileService: failed to check username availability',\n GET_X_AUTH_URL_FAILED: 'ProfileService: failed to get X authentication URL',\n CONNECT_X_FAILED: 'ProfileService: failed to connect X account',\n GET_X_ACCOUNT_FAILED: 'ProfileService: failed to get X account',\n DISCONNECT_X_FAILED: 'ProfileService: failed to disconnect X account',\n} as const;\n\n// ---------------------------------------------------------------------------\n// Superstruct schemas\n// ---------------------------------------------------------------------------\n\nconst TradingPrivacyStruct = enums(['public', 'private'] as const);\n\nconst ProfileApiResponseStruct = structType({\n profile_id: string(),\n username: string(),\n display_name: string(),\n bio: nullable(string()),\n linked_addresses: array(CaipAccountIdStruct),\n avatar_url: string(),\n trading_privacy: TradingPrivacyStruct,\n connected_to_x: boolean(),\n created_at: string(),\n updated_at: string(),\n});\n\nconst UsernameAvailabilityErrorStruct = structType({\n code: string(),\n message: string(),\n});\n\nconst UsernameAvailabilityResponseStruct = structType({\n username: string(),\n available: boolean(),\n valid: boolean(),\n normalized: string(),\n errors: array(UsernameAvailabilityErrorStruct),\n});\n\nconst XAuthUrlResponseStruct = structType({\n url: sensitive(string()),\n state: sensitive(string()),\n});\n\nconst ConnectXResponseStruct = structType({\n x_user_id: string(),\n x_profile_url: string(),\n username: string(),\n display_name: string(),\n avatar_url: string(),\n created_at: string(),\n updated_at: string(),\n});\n\nconst CreateProfileResponseStruct = intersection([\n ProfileApiResponseStruct,\n structType({ x_profile: optional(ConnectXResponseStruct) }),\n]);\n\nconst ConnectXParamsStruct = structType({\n code: sensitive(string()),\n state: sensitive(string()),\n});\n\nconst CreateProfileParamsStruct = structType({\n profile_id: string(),\n username: string(),\n display_name: string(),\n bio: optional(nullable(string())),\n linked_addresses: array(CaipAccountIdStruct),\n avatar_url: optional(string()),\n trading_privacy: TradingPrivacyStruct,\n});\n\nconst ReplaceProfileParamsStruct = structType({\n username: string(),\n display_name: string(),\n bio: optional(nullable(string())),\n linked_addresses: array(CaipAccountIdStruct),\n avatar_url: optional(string()),\n trading_privacy: TradingPrivacyStruct,\n});\n\nconst UpdateProfileParamsStruct = structType({\n username: optional(string()),\n display_name: optional(string()),\n bio: optional(nullable(string())),\n linked_addresses: optional(array(CaipAccountIdStruct)),\n avatar_url: optional(string()),\n trading_privacy: optional(TradingPrivacyStruct),\n});\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'getProfile',\n 'createProfile',\n 'replaceProfile',\n 'updateProfile',\n 'deleteProfile',\n 'checkUsernameAvailability',\n 'getXAuthUrl',\n 'connectX',\n 'getXAccount',\n 'disconnectX',\n] as const;\n\n/** The shape of a profile returned by the MetaMask Profile API. */\nexport type ProfileApiResponse = Infer<typeof ProfileApiResponseStruct>;\n\n/** The response shape for createProfile — includes an optional linked X profile if the user had already connected X. */\nexport type CreateProfileResponse = Infer<typeof CreateProfileResponseStruct>;\n\n/** The response shape for a username availability check. */\nexport type UsernameAvailabilityResponse = Infer<\n typeof UsernameAvailabilityResponseStruct\n>;\n\n/** The response shape returned when connecting or fetching an X account. */\nexport type ConnectXResponse = Infer<typeof ConnectXResponseStruct>;\n\n/** The response shape returned when requesting the X OAuth authentication URL. */\nexport type XAuthUrlResponse = Infer<typeof XAuthUrlResponseStruct>;\n\n/** Alias for {@link ConnectXResponse} returned when fetching the linked X account. */\nexport type XAccountResponse = ConnectXResponse;\n\n/** Parameters for creating a new MetaMask profile. */\nexport type CreateProfileParams = Infer<typeof CreateProfileParamsStruct>;\n\n/** Parameters for fully replacing an existing MetaMask profile (PUT). */\nexport type ReplaceProfileParams = Infer<typeof ReplaceProfileParamsStruct>;\n\n/** Parameters for partially updating an existing MetaMask profile (PATCH). */\nexport type UpdateProfileParams = Infer<typeof UpdateProfileParamsStruct>;\n\n/** Parameters for completing the X OAuth PKCE flow. */\nexport type ConnectXParams = Infer<typeof ConnectXParamsStruct>;\n\n// ---------------------------------------------------------------------------\n// Messenger types\n// ---------------------------------------------------------------------------\n\n/** Union of all actions exposed by ProfileService, including cache invalidation. */\nexport type ProfileServiceActions =\n | ProfileServiceMethodActions\n | DataServiceInvalidateQueriesAction<typeof serviceName>;\n\n/** Event emitted when the ProfileService query cache is updated. */\nexport type ProfileServiceCacheUpdatedEvent = DataServiceCacheUpdatedEvent<\n typeof serviceName\n>;\n\n/** Event emitted with per-query granularity when the ProfileService cache is updated. */\nexport type ProfileServiceGranularCacheUpdatedEvent =\n DataServiceGranularCacheUpdatedEvent<typeof serviceName>;\n\n/** Union of all events emitted by ProfileService. */\nexport type ProfileServiceEvents =\n | ProfileServiceCacheUpdatedEvent\n | ProfileServiceGranularCacheUpdatedEvent;\n\ntype AllowedActions =\n AuthenticationController.AuthenticationControllerGetBearerTokenAction;\n\ntype AllowedEvents = never;\n\n/** Messenger type for ProfileService, scoped to its actions and events. */\nexport type ProfileServiceMessenger = Messenger<\n typeof serviceName,\n ProfileServiceActions | AllowedActions,\n ProfileServiceEvents | AllowedEvents\n>;\n\n// ---------------------------------------------------------------------------\n// Service\n// ---------------------------------------------------------------------------\n\n/** Communicates with the MetaMask Profile API and exposes all operations via the messenger. */\nexport class ProfileService extends BaseDataService<\n typeof serviceName,\n ProfileServiceMessenger\n> {\n readonly #baseUrl: string;\n\n get #v1Url(): string {\n return `${this.#baseUrl}/v1`;\n }\n\n /**\n * Creates a new ProfileService instance.\n *\n * @param options - Constructor options.\n * @param options.messenger - The messenger scoped to ProfileService.\n * @param options.baseUrl - Base URL for the MetaMask Profile API.\n * @param options.policyOptions - Optional service policy configuration.\n */\n constructor({\n messenger,\n baseUrl,\n policyOptions,\n }: {\n messenger: ProfileServiceMessenger;\n baseUrl: string;\n policyOptions?: CreateServicePolicyOptions;\n }) {\n super({ name: serviceName, messenger, policyOptions });\n this.#baseUrl = baseUrl;\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Gets the authentication headers for the request.\n *\n * @returns The authentication headers.\n */\n async #getAuthHeaders(): Promise<Record<string, string>> {\n const token = await this.messenger.call(\n 'AuthenticationController:getBearerToken',\n );\n return { Authorization: `Bearer ${token}` };\n }\n\n /**\n * Executes an authenticated HTTP request and returns the parsed JSON response.\n *\n * @param endpoint - The path relative to the v1 base URL.\n * @param options - Request options.\n * @param options.method - The HTTP method. Defaults to 'GET'.\n * @param options.error - The error message to use if the response is not OK.\n * @param options.json - Optional JSON body. If provided, sets Content-Type and serializes as body.\n * @returns The parsed JSON response.\n * @throws {HttpError} If the response is not a 2xx status code.\n */\n async #fetch(\n endpoint: string,\n options: { method: 'DELETE'; error: string },\n ): Promise<null>;\n\n async #fetch<ResponseType extends Json>(\n endpoint: string,\n options: {\n method?: string;\n error: string;\n json?: unknown;\n searchParams?: Record<string, string>;\n },\n ): Promise<ResponseType>;\n\n async #fetch<ResponseType extends Json>(\n endpoint: string,\n {\n method = 'GET',\n error,\n json,\n searchParams,\n }: {\n method?: string;\n error: string;\n json?: unknown;\n searchParams?: Record<string, string>;\n },\n ): Promise<ResponseType | null> {\n const authHeaders = await this.#getAuthHeaders();\n const url = new URL(`${this.#v1Url}/${endpoint}`);\n if (searchParams) {\n for (const [key, value] of Object.entries(searchParams)) {\n url.searchParams.append(key, value);\n }\n }\n const response = await fetch(url.toString(), {\n ...(method === 'GET' ? {} : { method }),\n headers: {\n ...authHeaders,\n ...(json === undefined ? {} : { 'Content-Type': 'application/json' }),\n },\n ...(json === undefined ? {} : { body: JSON.stringify(json) }),\n });\n if (!response.ok) {\n throw new HttpError(response.status, `${error}: ${response.status}`);\n }\n if (method === 'DELETE') {\n return null;\n }\n return (await response.json()) as ResponseType;\n }\n\n /**\n * Fetches a profile by its identifier.\n *\n * @param profileId - The profile identifier to fetch.\n * @returns The profile data from the API.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\n async getProfile(profileId: string): Promise<ProfileApiResponse> {\n return this.fetchQuery({\n queryKey: [`${this.name}:getProfile`, profileId],\n responseStruct: ProfileApiResponseStruct,\n queryFn: async () =>\n this.#fetch<ProfileApiResponse>(\n `profiles/${encodeURIComponent(profileId)}`,\n {\n error: ProfileServiceErrorMessage.GET_PROFILE_FAILED,\n },\n ),\n });\n }\n\n /**\n * Creates a new MetaMask profile.\n *\n * @param params - The profile creation parameters.\n * @returns The created profile data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response do not match the expected shape.\n */\n async createProfile(\n params: CreateProfileParams,\n ): Promise<CreateProfileResponse> {\n return this.executeMutation({\n mutationKey: [`${this.name}:createProfile`],\n responseStruct: CreateProfileResponseStruct,\n mutationFn: async () =>\n this.#fetch<CreateProfileResponse>('profiles', {\n method: 'POST',\n error: ProfileServiceErrorMessage.CREATE_PROFILE_FAILED,\n json: params,\n }),\n });\n }\n\n /**\n * Fully replaces an existing profile (PUT).\n *\n * @param profileId - The identifier of the profile to replace.\n * @param params - The replacement profile data.\n * @returns The updated profile data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response do not match the expected shape.\n */\n async replaceProfile(\n profileId: string,\n params: ReplaceProfileParams,\n ): Promise<ProfileApiResponse> {\n return this.executeMutation({\n mutationKey: [`${this.name}:replaceProfile`, profileId],\n responseStruct: ProfileApiResponseStruct,\n mutationFn: async () =>\n this.#fetch<ProfileApiResponse>(\n `profiles/${encodeURIComponent(profileId)}`,\n {\n method: 'PUT',\n error: ProfileServiceErrorMessage.REPLACE_PROFILE_FAILED,\n json: params,\n },\n ),\n });\n }\n\n /**\n * Partially updates an existing profile (PATCH).\n *\n * @param profileId - The identifier of the profile to update.\n * @param params - The fields to update.\n * @returns The updated profile data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response do not match the expected shape.\n */\n async updateProfile(\n profileId: string,\n params: UpdateProfileParams,\n ): Promise<ProfileApiResponse> {\n return this.executeMutation({\n mutationKey: [`${this.name}:updateProfile`, profileId],\n responseStruct: ProfileApiResponseStruct,\n mutationFn: async () =>\n this.#fetch<ProfileApiResponse>(\n `profiles/${encodeURIComponent(profileId)}`,\n {\n method: 'PATCH',\n error: ProfileServiceErrorMessage.UPDATE_PROFILE_FAILED,\n json: params,\n },\n ),\n });\n }\n\n /**\n * Deletes a profile by its identifier.\n *\n * @param profileId - The identifier of the profile to delete.\n * @returns The result of the mutation.\n * @throws {HttpError} If the API returns a non-2xx response.\n */\n async deleteProfile(profileId: string): Promise<void> {\n return this.executeMutation({\n mutationKey: [`${this.name}:deleteProfile`, profileId],\n mutationFn: async () =>\n this.#fetch(`profiles/${encodeURIComponent(profileId)}`, {\n method: 'DELETE',\n error: ProfileServiceErrorMessage.DELETE_PROFILE_FAILED,\n }),\n });\n }\n\n /**\n * Checks whether a username is available.\n *\n * @param username - The username to check.\n * @returns Availability details including validity and normalized form.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\n async checkUsernameAvailability(\n username: string,\n ): Promise<UsernameAvailabilityResponse> {\n return this.fetchQuery({\n queryKey: [`${this.name}:checkUsernameAvailability`, username],\n staleTime: 0,\n responseStruct: UsernameAvailabilityResponseStruct,\n queryFn: async () =>\n this.#fetch<UsernameAvailabilityResponse>(\n 'profiles/username/availability',\n {\n error:\n ProfileServiceErrorMessage.CHECK_USERNAME_AVAILABILITY_FAILED,\n searchParams: { username },\n },\n ),\n });\n }\n\n /**\n * Fetches the X OAuth PKCE authorization URL and its associated state parameter.\n * The profile is resolved server-side from the verified bearer token.\n *\n * @returns An object containing the authorization URL and the state token.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\n async getXAuthUrl(): Promise<XAuthUrlResponse> {\n return this.executeMutation({\n mutationKey: [`${this.name}:getXAuthUrl`],\n responseStruct: XAuthUrlResponseStruct,\n mutationFn: async () =>\n this.#fetch<XAuthUrlResponse>('profiles/x/authentication-url', {\n error: ProfileServiceErrorMessage.GET_X_AUTH_URL_FAILED,\n }),\n });\n }\n\n /**\n * Completes the X OAuth PKCE flow and links the X account to the profile.\n * The profile is resolved server-side from the verified bearer token.\n *\n * @param params - The OAuth callback code and state from the X redirect.\n * @returns The linked X account data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\n async connectX(params: ConnectXParams): Promise<ConnectXResponse> {\n const response = await this.executeMutation({\n mutationKey: [`${this.name}:connectX`],\n responseStruct: ConnectXResponseStruct,\n mutationFn: async () =>\n this.#fetch<ConnectXResponse>('profiles/x/connect', {\n method: 'POST',\n error: ProfileServiceErrorMessage.CONNECT_X_FAILED,\n json: params,\n }),\n });\n // The response does not identify the profile, so drop every cached\n // profile: `connected_to_x` is now out of date.\n await this.invalidateQueries({ queryKey: [`${this.name}:getProfile`] });\n return response;\n }\n\n /**\n * Fetches the X account currently linked to the authenticated profile.\n * The profile is resolved server-side from the verified bearer token.\n *\n * @returns The linked X account data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\n async getXAccount(): Promise<XAccountResponse> {\n return this.fetchQuery({\n queryKey: [`${this.name}:getXAccount`],\n staleTime: 0,\n responseStruct: ConnectXResponseStruct,\n queryFn: async () =>\n this.#fetch<ConnectXResponse>('profiles/x/account', {\n error: ProfileServiceErrorMessage.GET_X_ACCOUNT_FAILED,\n }),\n });\n }\n\n /**\n * Disconnects the X account linked to the authenticated profile.\n * Identity is resolved server-side from the verified bearer token, so the\n * request targets the shared account endpoint rather than a profile-scoped\n * path.\n * A `404` response is treated as success (no X account is linked), making\n * the operation idempotent.\n *\n * @param profileId - The ID of the profile whose cached data should be\n * invalidated after the disconnection. The API resolves the linked X account\n * from the bearer token, not from this value.\n * @returns The result of the mutation.\n * @throws {HttpError} If the API returns a non-2xx response other than `404`.\n */\n async disconnectX(profileId: string): Promise<void> {\n await this.executeMutation({\n mutationKey: [`${this.name}:disconnectX`, profileId],\n mutationFn: async () => {\n try {\n return await this.#fetch('profiles/x/account', {\n method: 'DELETE',\n error: ProfileServiceErrorMessage.DISCONNECT_X_FAILED,\n });\n } catch (error) {\n if (error instanceof HttpError && error.httpStatus === 404) {\n return null;\n }\n throw error;\n }\n },\n });\n // The cached profile no longer reflects `connected_to_x`.\n await this.invalidateQueries({\n queryKey: [`${this.name}:getProfile`, profileId],\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ProfileService.js","sourceRoot":"","sources":["../src/ProfileService.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseDataService } from '@metamask/base-data-service';\nimport type {\n CreateServicePolicyOptions,\n DataServiceCacheUpdatedEvent,\n DataServiceGranularCacheUpdatedEvent,\n DataServiceInvalidateQueriesAction,\n} from '@metamask/base-data-service';\nimport { HttpError } from '@metamask/controller-utils';\nimport type { Messenger } from '@metamask/messenger';\nimport type { AuthenticationController } from '@metamask/profile-sync-controller';\nimport {\n array,\n boolean,\n enums,\n intersection,\n nullable,\n optional,\n sensitive,\n string,\n type as structType,\n validate,\n} from '@metamask/superstruct';\nimport type { Infer } from '@metamask/superstruct';\nimport type { Json } from '@metamask/utils';\nimport { CaipAccountIdStruct } from '@metamask/utils';\n\nimport type { ProfileServiceMethodActions } from './ProfileService-method-action-types.js';\n\nexport const serviceName = 'ProfileService';\n\n// ---------------------------------------------------------------------------\n// Error messages\n// ---------------------------------------------------------------------------\n\n/** Human-readable error messages for each ProfileService operation. */\nexport const ProfileServiceErrorMessage = {\n GET_PROFILE_FAILED: 'ProfileService: failed to fetch profile',\n CREATE_PROFILE_FAILED: 'ProfileService: failed to create profile',\n REPLACE_PROFILE_FAILED: 'ProfileService: failed to replace profile',\n UPDATE_PROFILE_FAILED: 'ProfileService: failed to update profile',\n DELETE_PROFILE_FAILED: 'ProfileService: failed to delete profile',\n CHECK_USERNAME_AVAILABILITY_FAILED:\n 'ProfileService: failed to check username availability',\n CHECK_DISPLAY_NAME_VALIDITY_FAILED:\n 'ProfileService: failed to check display name validity',\n CHECK_BIO_VALIDITY_FAILED: 'ProfileService: failed to check bio validity',\n CHECK_EARLY_ACCESS_FAILED:\n 'ProfileService: failed to check early access status',\n GET_X_AUTH_URL_FAILED: 'ProfileService: failed to get X authentication URL',\n CONNECT_X_FAILED: 'ProfileService: failed to connect X account',\n GET_X_ACCOUNT_FAILED: 'ProfileService: failed to get X account',\n DISCONNECT_X_FAILED: 'ProfileService: failed to disconnect X account',\n} as const;\n\n// ---------------------------------------------------------------------------\n// Superstruct schemas\n// ---------------------------------------------------------------------------\n\nconst TradingPrivacyStruct = enums(['public', 'private'] as const);\n\n/**\n * The body the Profile API returns for a non-2xx response. The `message` is\n * surfaced to clients so they can react to the specific failure; `code` is\n * optional because not every error includes one.\n */\nconst ApiErrorResponseStruct = structType({\n code: optional(string()),\n message: string(),\n});\n\nconst ProfileApiResponseStruct = structType({\n profile_id: string(),\n username: string(),\n display_name: string(),\n bio: nullable(string()),\n linked_addresses: array(CaipAccountIdStruct),\n avatar_url: string(),\n trading_privacy: TradingPrivacyStruct,\n connected_to_x: boolean(),\n created_at: string(),\n updated_at: string(),\n});\n\nconst FieldValidityResponseStruct = structType({\n valid: boolean(),\n});\n\nconst EarlyAccessResponseStruct = structType({\n hasAccess: boolean(),\n});\n\nconst UsernameAvailabilityErrorStruct = structType({\n code: string(),\n message: string(),\n});\n\nconst UsernameAvailabilityResponseStruct = structType({\n username: string(),\n available: boolean(),\n valid: boolean(),\n normalized: string(),\n errors: array(UsernameAvailabilityErrorStruct),\n});\n\nconst XAuthUrlResponseStruct = structType({\n url: sensitive(string()),\n state: sensitive(string()),\n});\n\nconst ConnectXResponseStruct = structType({\n x_user_id: string(),\n x_profile_url: string(),\n username: string(),\n display_name: string(),\n avatar_url: string(),\n created_at: string(),\n updated_at: string(),\n});\n\nconst CreateProfileResponseStruct = intersection([\n ProfileApiResponseStruct,\n structType({ x_profile: optional(ConnectXResponseStruct) }),\n]);\n\nconst ConnectXParamsStruct = structType({\n code: sensitive(string()),\n state: sensitive(string()),\n});\n\nconst CreateProfileParamsStruct = structType({\n profile_id: string(),\n username: string(),\n display_name: string(),\n bio: optional(nullable(string())),\n linked_addresses: array(CaipAccountIdStruct),\n avatar_url: optional(string()),\n trading_privacy: TradingPrivacyStruct,\n});\n\nconst ReplaceProfileParamsStruct = structType({\n username: string(),\n display_name: string(),\n bio: optional(nullable(string())),\n linked_addresses: array(CaipAccountIdStruct),\n avatar_url: optional(string()),\n trading_privacy: TradingPrivacyStruct,\n});\n\nconst UpdateProfileParamsStruct = structType({\n username: optional(string()),\n display_name: optional(string()),\n bio: optional(nullable(string())),\n linked_addresses: optional(array(CaipAccountIdStruct)),\n avatar_url: optional(string()),\n trading_privacy: optional(TradingPrivacyStruct),\n});\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'getProfile',\n 'createProfile',\n 'replaceProfile',\n 'updateProfile',\n 'deleteProfile',\n 'checkUsernameAvailability',\n 'checkDisplayNameValidity',\n 'checkBioValidity',\n 'checkEarlyAccess',\n 'getXAuthUrl',\n 'connectX',\n 'getXAccount',\n 'disconnectX',\n] as const;\n\n/** The shape of a profile returned by the MetaMask Profile API. */\nexport type ProfileApiResponse = Infer<typeof ProfileApiResponseStruct>;\n\n/** The response shape for createProfile — includes an optional linked X profile if the user had already connected X. */\nexport type CreateProfileResponse = Infer<typeof CreateProfileResponseStruct>;\n\n/** The response shape for a username availability check. */\nexport type UsernameAvailabilityResponse = Infer<\n typeof UsernameAvailabilityResponseStruct\n>;\n\n/** The response shape for display name and bio validity checks. */\nexport type FieldValidityResponse = Infer<typeof FieldValidityResponseStruct>;\n\n/** The response shape for the early access check. */\nexport type EarlyAccessResponse = Infer<typeof EarlyAccessResponseStruct>;\n\n/** The response shape returned when connecting or fetching an X account. */\nexport type ConnectXResponse = Infer<typeof ConnectXResponseStruct>;\n\n/** The response shape returned when requesting the X OAuth authentication URL. */\nexport type XAuthUrlResponse = Infer<typeof XAuthUrlResponseStruct>;\n\n/** Alias for {@link ConnectXResponse} returned when fetching the linked X account. */\nexport type XAccountResponse = ConnectXResponse;\n\n/** Parameters for creating a new MetaMask profile. */\nexport type CreateProfileParams = Infer<typeof CreateProfileParamsStruct>;\n\n/** Parameters for fully replacing an existing MetaMask profile (PUT). */\nexport type ReplaceProfileParams = Infer<typeof ReplaceProfileParamsStruct>;\n\n/** Parameters for partially updating an existing MetaMask profile (PATCH). */\nexport type UpdateProfileParams = Infer<typeof UpdateProfileParamsStruct>;\n\n/** Parameters for completing the X OAuth PKCE flow. */\nexport type ConnectXParams = Infer<typeof ConnectXParamsStruct>;\n\n// ---------------------------------------------------------------------------\n// Messenger types\n// ---------------------------------------------------------------------------\n\n/** Union of all actions exposed by ProfileService, including cache invalidation. */\nexport type ProfileServiceActions =\n | ProfileServiceMethodActions\n | DataServiceInvalidateQueriesAction<typeof serviceName>;\n\n/** Event emitted when the ProfileService query cache is updated. */\nexport type ProfileServiceCacheUpdatedEvent = DataServiceCacheUpdatedEvent<\n typeof serviceName\n>;\n\n/** Event emitted with per-query granularity when the ProfileService cache is updated. */\nexport type ProfileServiceGranularCacheUpdatedEvent =\n DataServiceGranularCacheUpdatedEvent<typeof serviceName>;\n\n/** Union of all events emitted by ProfileService. */\nexport type ProfileServiceEvents =\n | ProfileServiceCacheUpdatedEvent\n | ProfileServiceGranularCacheUpdatedEvent;\n\ntype AllowedActions =\n AuthenticationController.AuthenticationControllerGetBearerTokenAction;\n\ntype AllowedEvents = never;\n\n/** Messenger type for ProfileService, scoped to its actions and events. */\nexport type ProfileServiceMessenger = Messenger<\n typeof serviceName,\n ProfileServiceActions | AllowedActions,\n ProfileServiceEvents | AllowedEvents\n>;\n\n// ---------------------------------------------------------------------------\n// Service\n// ---------------------------------------------------------------------------\n\n/** Communicates with the MetaMask Profile API and exposes all operations via the messenger. */\nexport class ProfileService extends BaseDataService<\n typeof serviceName,\n ProfileServiceMessenger\n> {\n readonly #baseUrl: string;\n\n get #v1Url(): string {\n return `${this.#baseUrl}/v1`;\n }\n\n /**\n * Creates a new ProfileService instance.\n *\n * @param options - Constructor options.\n * @param options.messenger - The messenger scoped to ProfileService.\n * @param options.baseUrl - Base URL for the MetaMask Profile API.\n * @param options.policyOptions - Optional service policy configuration.\n */\n constructor({\n messenger,\n baseUrl,\n policyOptions,\n }: {\n messenger: ProfileServiceMessenger;\n baseUrl: string;\n policyOptions?: CreateServicePolicyOptions;\n }) {\n super({ name: serviceName, messenger, policyOptions });\n this.#baseUrl = baseUrl;\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Gets the authentication headers for the request.\n *\n * @returns The authentication headers.\n */\n async #getAuthHeaders(): Promise<Record<string, string>> {\n const token = await this.messenger.call(\n 'AuthenticationController:getBearerToken',\n );\n return { Authorization: `Bearer ${token}` };\n }\n\n /**\n * Reads the error message from an unsuccessful API response body.\n *\n * The Profile API returns errors as `{ code, message }`. If the body is\n * missing, is not JSON, or does not contain a message, this returns\n * `undefined` so the caller can fall back to a generic message.\n *\n * @param response - The unsuccessful response.\n * @returns The API-provided error message, or `undefined` if unavailable.\n */\n async #readErrorMessage(response: Response): Promise<string | undefined> {\n try {\n const body: unknown = await response.json();\n const [error, result] = validate(body, ApiErrorResponseStruct);\n if (!error) {\n return result.message;\n }\n } catch {\n // The body is absent or not valid JSON; fall back to a generic message.\n }\n return undefined;\n }\n\n /**\n * Executes an authenticated HTTP request and returns the parsed JSON response.\n *\n * @param endpoint - The path relative to the v1 base URL.\n * @param options - Request options.\n * @param options.method - The HTTP method. Defaults to 'GET'.\n * @param options.error - The error message to use if the response is not OK.\n * @param options.json - Optional JSON body. If provided, sets Content-Type and serializes as body.\n * @returns The parsed JSON response.\n * @throws {HttpError} If the response is not a 2xx status code. The error\n * message includes the API-provided message when the response body contains one.\n */\n async #fetch(\n endpoint: string,\n options: { method: 'DELETE'; error: string },\n ): Promise<null>;\n\n async #fetch<ResponseType extends Json>(\n endpoint: string,\n options: {\n method?: string;\n error: string;\n json?: unknown;\n searchParams?: Record<string, string>;\n },\n ): Promise<ResponseType>;\n\n async #fetch<ResponseType extends Json>(\n endpoint: string,\n {\n method = 'GET',\n error,\n json,\n searchParams,\n }: {\n method?: string;\n error: string;\n json?: unknown;\n searchParams?: Record<string, string>;\n },\n ): Promise<ResponseType | null> {\n const authHeaders = await this.#getAuthHeaders();\n const url = new URL(`${this.#v1Url}/${endpoint}`);\n if (searchParams) {\n for (const [key, value] of Object.entries(searchParams)) {\n url.searchParams.append(key, value);\n }\n }\n const response = await fetch(url.toString(), {\n ...(method === 'GET' ? {} : { method }),\n headers: {\n ...authHeaders,\n ...(json === undefined ? {} : { 'Content-Type': 'application/json' }),\n },\n ...(json === undefined ? {} : { body: JSON.stringify(json) }),\n });\n if (!response.ok) {\n const apiMessage = await this.#readErrorMessage(response);\n throw new HttpError(\n response.status,\n apiMessage\n ? `${error}: ${response.status}: ${apiMessage}`\n : `${error}: ${response.status}`,\n );\n }\n if (method === 'DELETE') {\n return null;\n }\n return (await response.json()) as ResponseType;\n }\n\n /**\n * Fetches a profile by its identifier.\n *\n * @param profileId - The profile identifier to fetch.\n * @returns The profile data from the API.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\n async getProfile(profileId: string): Promise<ProfileApiResponse> {\n return this.fetchQuery({\n queryKey: [`${this.name}:getProfile`, profileId],\n responseStruct: ProfileApiResponseStruct,\n queryFn: async () =>\n this.#fetch<ProfileApiResponse>(\n `profiles/${encodeURIComponent(profileId)}`,\n {\n error: ProfileServiceErrorMessage.GET_PROFILE_FAILED,\n },\n ),\n });\n }\n\n /**\n * Creates a new MetaMask profile.\n *\n * @param params - The profile creation parameters.\n * @returns The created profile data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response do not match the expected shape.\n */\n async createProfile(\n params: CreateProfileParams,\n ): Promise<CreateProfileResponse> {\n return this.executeMutation({\n mutationKey: [`${this.name}:createProfile`],\n responseStruct: CreateProfileResponseStruct,\n mutationFn: async () =>\n this.#fetch<CreateProfileResponse>('profiles', {\n method: 'POST',\n error: ProfileServiceErrorMessage.CREATE_PROFILE_FAILED,\n json: params,\n }),\n });\n }\n\n /**\n * Fully replaces an existing profile (PUT).\n *\n * @param profileId - The identifier of the profile to replace.\n * @param params - The replacement profile data.\n * @returns The updated profile data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response do not match the expected shape.\n */\n async replaceProfile(\n profileId: string,\n params: ReplaceProfileParams,\n ): Promise<ProfileApiResponse> {\n return this.executeMutation({\n mutationKey: [`${this.name}:replaceProfile`, profileId],\n responseStruct: ProfileApiResponseStruct,\n mutationFn: async () =>\n this.#fetch<ProfileApiResponse>(\n `profiles/${encodeURIComponent(profileId)}`,\n {\n method: 'PUT',\n error: ProfileServiceErrorMessage.REPLACE_PROFILE_FAILED,\n json: params,\n },\n ),\n });\n }\n\n /**\n * Partially updates an existing profile (PATCH).\n *\n * @param profileId - The identifier of the profile to update.\n * @param params - The fields to update.\n * @returns The updated profile data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response do not match the expected shape.\n */\n async updateProfile(\n profileId: string,\n params: UpdateProfileParams,\n ): Promise<ProfileApiResponse> {\n return this.executeMutation({\n mutationKey: [`${this.name}:updateProfile`, profileId],\n responseStruct: ProfileApiResponseStruct,\n mutationFn: async () =>\n this.#fetch<ProfileApiResponse>(\n `profiles/${encodeURIComponent(profileId)}`,\n {\n method: 'PATCH',\n error: ProfileServiceErrorMessage.UPDATE_PROFILE_FAILED,\n json: params,\n },\n ),\n });\n }\n\n /**\n * Deletes a profile by its identifier.\n *\n * @param profileId - The identifier of the profile to delete.\n * @returns The result of the mutation.\n * @throws {HttpError} If the API returns a non-2xx response.\n */\n async deleteProfile(profileId: string): Promise<void> {\n return this.executeMutation({\n mutationKey: [`${this.name}:deleteProfile`, profileId],\n mutationFn: async () =>\n this.#fetch(`profiles/${encodeURIComponent(profileId)}`, {\n method: 'DELETE',\n error: ProfileServiceErrorMessage.DELETE_PROFILE_FAILED,\n }),\n });\n }\n\n /**\n * Checks whether a username is available.\n *\n * @param username - The username to check.\n * @returns Availability details including validity and normalized form.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\n async checkUsernameAvailability(\n username: string,\n ): Promise<UsernameAvailabilityResponse> {\n return this.fetchQuery({\n queryKey: [`${this.name}:checkUsernameAvailability`, username],\n staleTime: 0,\n responseStruct: UsernameAvailabilityResponseStruct,\n queryFn: async () =>\n this.#fetch<UsernameAvailabilityResponse>(\n 'profiles/username/availability',\n {\n error:\n ProfileServiceErrorMessage.CHECK_USERNAME_AVAILABILITY_FAILED,\n searchParams: { username },\n },\n ),\n });\n }\n\n /**\n * Checks whether a display name is valid.\n *\n * @param displayName - The display name to validate.\n * @returns An object with a `valid` boolean.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\n async checkDisplayNameValidity(\n displayName: string,\n ): Promise<FieldValidityResponse> {\n return this.fetchQuery({\n queryKey: [`${this.name}:checkDisplayNameValidity`, displayName],\n staleTime: 0,\n responseStruct: FieldValidityResponseStruct,\n queryFn: async () =>\n this.#fetch<FieldValidityResponse>('profiles/display-name/validity', {\n error: ProfileServiceErrorMessage.CHECK_DISPLAY_NAME_VALIDITY_FAILED,\n searchParams: { display_name: displayName },\n }),\n });\n }\n\n /**\n * Checks whether a bio is valid.\n *\n * @param bio - The bio to validate.\n * @returns An object with a `valid` boolean.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\n async checkBioValidity(bio: string): Promise<FieldValidityResponse> {\n return this.fetchQuery({\n queryKey: [`${this.name}:checkBioValidity`, bio],\n staleTime: 0,\n responseStruct: FieldValidityResponseStruct,\n queryFn: async () =>\n this.#fetch<FieldValidityResponse>('profiles/bio/validity', {\n error: ProfileServiceErrorMessage.CHECK_BIO_VALIDITY_FAILED,\n searchParams: { bio },\n }),\n });\n }\n\n /**\n * Checks whether the authenticated profile has early access.\n * The profile is resolved server-side from the verified bearer token.\n *\n * @returns An object with a `hasAccess` boolean.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\n async checkEarlyAccess(): Promise<EarlyAccessResponse> {\n return this.fetchQuery({\n queryKey: [`${this.name}:checkEarlyAccess`],\n staleTime: 0,\n responseStruct: EarlyAccessResponseStruct,\n queryFn: async () =>\n this.#fetch<EarlyAccessResponse>('early-access', {\n error: ProfileServiceErrorMessage.CHECK_EARLY_ACCESS_FAILED,\n }),\n });\n }\n\n /**\n * Fetches the X OAuth PKCE authorization URL and its associated state parameter.\n * The profile is resolved server-side from the verified bearer token.\n *\n * @returns An object containing the authorization URL and the state token.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\n async getXAuthUrl(): Promise<XAuthUrlResponse> {\n return this.executeMutation({\n mutationKey: [`${this.name}:getXAuthUrl`],\n responseStruct: XAuthUrlResponseStruct,\n mutationFn: async () =>\n this.#fetch<XAuthUrlResponse>('profiles/x/authentication-url', {\n error: ProfileServiceErrorMessage.GET_X_AUTH_URL_FAILED,\n }),\n });\n }\n\n /**\n * Completes the X OAuth PKCE flow and links the X account to the profile.\n * The profile is resolved server-side from the verified bearer token.\n *\n * @param params - The OAuth callback code and state from the X redirect.\n * @returns The linked X account data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\n async connectX(params: ConnectXParams): Promise<ConnectXResponse> {\n const response = await this.executeMutation({\n mutationKey: [`${this.name}:connectX`],\n responseStruct: ConnectXResponseStruct,\n mutationFn: async () =>\n this.#fetch<ConnectXResponse>('profiles/x/connect', {\n method: 'POST',\n error: ProfileServiceErrorMessage.CONNECT_X_FAILED,\n json: params,\n }),\n });\n // The response does not identify the profile, so drop every cached\n // profile: `connected_to_x` is now out of date.\n await this.invalidateQueries({ queryKey: [`${this.name}:getProfile`] });\n return response;\n }\n\n /**\n * Fetches the X account currently linked to the authenticated profile.\n * The profile is resolved server-side from the verified bearer token.\n *\n * @returns The linked X account data.\n * @throws {HttpError} If the API returns a non-2xx response.\n * @throws {StructError} If the response does not match the expected shape.\n */\n async getXAccount(): Promise<XAccountResponse> {\n return this.fetchQuery({\n queryKey: [`${this.name}:getXAccount`],\n staleTime: 0,\n responseStruct: ConnectXResponseStruct,\n queryFn: async () =>\n this.#fetch<ConnectXResponse>('profiles/x/account', {\n error: ProfileServiceErrorMessage.GET_X_ACCOUNT_FAILED,\n }),\n });\n }\n\n /**\n * Disconnects the X account linked to the authenticated profile.\n * Identity is resolved server-side from the verified bearer token, so the\n * request targets the shared account endpoint rather than a profile-scoped\n * path.\n * A `404` response is treated as success (no X account is linked), making\n * the operation idempotent.\n *\n * @param profileId - The ID of the profile whose cached data should be\n * invalidated after the disconnection. The API resolves the linked X account\n * from the bearer token, not from this value.\n * @returns The result of the mutation.\n * @throws {HttpError} If the API returns a non-2xx response other than `404`.\n */\n async disconnectX(profileId: string): Promise<void> {\n await this.executeMutation({\n mutationKey: [`${this.name}:disconnectX`, profileId],\n mutationFn: async () => {\n try {\n return await this.#fetch('profiles/x/account', {\n method: 'DELETE',\n error: ProfileServiceErrorMessage.DISCONNECT_X_FAILED,\n });\n } catch (error) {\n if (error instanceof HttpError && error.httpStatus === 404) {\n return null;\n }\n throw error;\n }\n },\n });\n // The cached profile no longer reflects `connected_to_x`.\n await this.invalidateQueries({\n queryKey: [`${this.name}:getProfile`, profileId],\n });\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
export type { Profile, XProfile, ConnectXSession, ProfileControllerState, ProfileControllerGetStateAction, ProfileControllerActions, ProfileControllerChangeEvent, ProfileControllerEvents, ProfileControllerMessenger, } from './ProfileController.js';
|
|
2
2
|
export { ProfileController, getDefaultProfileControllerState, } from './ProfileController.js';
|
|
3
3
|
export type { ProfileControllerCheckUsernameAvailabilityAction, ProfileControllerConnectXAction, ProfileControllerCreateProfileAction, ProfileControllerDeleteProfileAction, ProfileControllerDisconnectXAction, ProfileControllerGetProfileAction, ProfileControllerFetchAndUpdateXAccountAction, ProfileControllerFetchAndUpdateProfileAction, ProfileControllerGetXProfileAction, ProfileControllerReplaceProfileAction, ProfileControllerGetXAuthorizationUrlAction, ProfileControllerUpdateProfileAction, ProfileControllerClearStateAction, } from './ProfileController-method-action-types.js';
|
|
4
|
-
export type { ProfileApiResponse, CreateProfileResponse, CreateProfileParams, ReplaceProfileParams, UpdateProfileParams, ConnectXParams, UsernameAvailabilityResponse, XAuthUrlResponse, ConnectXResponse, XAccountResponse, ProfileServiceActions, ProfileServiceEvents, ProfileServiceMessenger, } from './ProfileService.js';
|
|
4
|
+
export type { ProfileApiResponse, CreateProfileResponse, CreateProfileParams, ReplaceProfileParams, UpdateProfileParams, ConnectXParams, UsernameAvailabilityResponse, FieldValidityResponse, EarlyAccessResponse, XAuthUrlResponse, ConnectXResponse, XAccountResponse, ProfileServiceActions, ProfileServiceEvents, ProfileServiceMessenger, } from './ProfileService.js';
|
|
5
5
|
export { ProfileService, ProfileServiceErrorMessage, } from './ProfileService.js';
|
|
6
|
-
export type {
|
|
7
|
-
export { buildMockProfileService, MOCK_PROFILE_API_RESPONSE, MOCK_X_CONNECT_RESPONSE, MOCK_X_AUTH_URL_RESPONSE, } from './ProfileServiceMock.js';
|
|
8
|
-
export type { ProfileServiceCheckUsernameAvailabilityAction, ProfileServiceConnectXAction, ProfileServiceCreateProfileAction, ProfileServiceDeleteProfileAction, ProfileServiceDisconnectXAction, ProfileServiceGetProfileAction, ProfileServiceGetXAccountAction, ProfileServiceGetXAuthUrlAction, ProfileServiceReplaceProfileAction, ProfileServiceUpdateProfileAction, } from './ProfileService-method-action-types.js';
|
|
6
|
+
export type { ProfileServiceCheckUsernameAvailabilityAction, ProfileServiceCheckDisplayNameValidityAction, ProfileServiceCheckBioValidityAction, ProfileServiceCheckEarlyAccessAction, ProfileServiceConnectXAction, ProfileServiceCreateProfileAction, ProfileServiceDeleteProfileAction, ProfileServiceDisconnectXAction, ProfileServiceGetProfileAction, ProfileServiceGetXAccountAction, ProfileServiceGetXAuthUrlAction, ProfileServiceReplaceProfileAction, ProfileServiceUpdateProfileAction, } from './ProfileService-method-action-types.js';
|
|
9
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,OAAO,EACP,QAAQ,EACR,eAAe,EACf,sBAAsB,EACtB,+BAA+B,EAC/B,wBAAwB,EACxB,4BAA4B,EAC5B,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,iBAAiB,EACjB,gCAAgC,GACjC,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,gDAAgD,EAChD,+BAA+B,EAC/B,oCAAoC,EACpC,oCAAoC,EACpC,kCAAkC,EAClC,iCAAiC,EACjC,6CAA6C,EAC7C,4CAA4C,EAC5C,kCAAkC,EAClC,qCAAqC,EACrC,2CAA2C,EAC3C,oCAAoC,EACpC,iCAAiC,GAClC,MAAM,4CAA4C,CAAC;AACpD,YAAY,EACV,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,4BAA4B,EAC5B,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,cAAc,EACd,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,OAAO,EACP,QAAQ,EACR,eAAe,EACf,sBAAsB,EACtB,+BAA+B,EAC/B,wBAAwB,EACxB,4BAA4B,EAC5B,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,iBAAiB,EACjB,gCAAgC,GACjC,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,gDAAgD,EAChD,+BAA+B,EAC/B,oCAAoC,EACpC,oCAAoC,EACpC,kCAAkC,EAClC,iCAAiC,EACjC,6CAA6C,EAC7C,4CAA4C,EAC5C,kCAAkC,EAClC,qCAAqC,EACrC,2CAA2C,EAC3C,oCAAoC,EACpC,iCAAiC,GAClC,MAAM,4CAA4C,CAAC;AACpD,YAAY,EACV,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,4BAA4B,EAC5B,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,cAAc,EACd,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,6CAA6C,EAC7C,4CAA4C,EAC5C,oCAAoC,EACpC,oCAAoC,EACpC,4BAA4B,EAC5B,iCAAiC,EACjC,iCAAiC,EACjC,+BAA+B,EAC/B,8BAA8B,EAC9B,+BAA+B,EAC/B,+BAA+B,EAC/B,kCAAkC,EAClC,iCAAiC,GAClC,MAAM,yCAAyC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export { ProfileController, getDefaultProfileControllerState, } from './ProfileController.js';
|
|
2
2
|
export { ProfileService, ProfileServiceErrorMessage, } from './ProfileService.js';
|
|
3
|
-
export { buildMockProfileService, MOCK_PROFILE_API_RESPONSE, MOCK_X_CONNECT_RESPONSE, MOCK_X_AUTH_URL_RESPONSE, } from './ProfileServiceMock.js';
|
|
4
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,iBAAiB,EACjB,gCAAgC,GACjC,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,iBAAiB,EACjB,gCAAgC,GACjC,MAAM,wBAAwB,CAAC;AAiChC,OAAO,EACL,cAAc,EACd,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC","sourcesContent":["export type {\n Profile,\n XProfile,\n ConnectXSession,\n ProfileControllerState,\n ProfileControllerGetStateAction,\n ProfileControllerActions,\n ProfileControllerChangeEvent,\n ProfileControllerEvents,\n ProfileControllerMessenger,\n} from './ProfileController.js';\nexport {\n ProfileController,\n getDefaultProfileControllerState,\n} from './ProfileController.js';\nexport type {\n ProfileControllerCheckUsernameAvailabilityAction,\n ProfileControllerConnectXAction,\n ProfileControllerCreateProfileAction,\n ProfileControllerDeleteProfileAction,\n ProfileControllerDisconnectXAction,\n ProfileControllerGetProfileAction,\n ProfileControllerFetchAndUpdateXAccountAction,\n ProfileControllerFetchAndUpdateProfileAction,\n ProfileControllerGetXProfileAction,\n ProfileControllerReplaceProfileAction,\n ProfileControllerGetXAuthorizationUrlAction,\n ProfileControllerUpdateProfileAction,\n ProfileControllerClearStateAction,\n} from './ProfileController-method-action-types.js';\nexport type {\n ProfileApiResponse,\n CreateProfileResponse,\n CreateProfileParams,\n ReplaceProfileParams,\n UpdateProfileParams,\n ConnectXParams,\n UsernameAvailabilityResponse,\n FieldValidityResponse,\n EarlyAccessResponse,\n XAuthUrlResponse,\n ConnectXResponse,\n XAccountResponse,\n ProfileServiceActions,\n ProfileServiceEvents,\n ProfileServiceMessenger,\n} from './ProfileService.js';\nexport {\n ProfileService,\n ProfileServiceErrorMessage,\n} from './ProfileService.js';\nexport type {\n ProfileServiceCheckUsernameAvailabilityAction,\n ProfileServiceCheckDisplayNameValidityAction,\n ProfileServiceCheckBioValidityAction,\n ProfileServiceCheckEarlyAccessAction,\n ProfileServiceConnectXAction,\n ProfileServiceCreateProfileAction,\n ProfileServiceDeleteProfileAction,\n ProfileServiceDisconnectXAction,\n ProfileServiceGetProfileAction,\n ProfileServiceGetXAccountAction,\n ProfileServiceGetXAuthUrlAction,\n ProfileServiceReplaceProfileAction,\n ProfileServiceUpdateProfileAction,\n} from './ProfileService-method-action-types.js';\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask-previews/profile-controller",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-preview-b6e8e7385",
|
|
4
4
|
"description": "Controller for managing user profile data including username, bio, avatar, and linked accounts via the MetaMask Profile API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ethereum",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"registry": "https://registry.npmjs.org/"
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
35
|
+
"allow-scripts": "yarn workspace @metamask/core-monorepo run allow-scripts",
|
|
35
36
|
"build": "tsc --project tsconfig.build.json",
|
|
36
37
|
"build:all": "tsc --build tsconfig.build.json --verbose",
|
|
37
38
|
"build:clean": "yarn build:only-clean && yarn build",
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { ConnectXParams, CreateProfileParams, CreateProfileResponse, ProfileApiResponse, ProfileServiceMessenger, ReplaceProfileParams, UpdateProfileParams, UsernameAvailabilityResponse, XAccountResponse, XAuthUrlResponse, ConnectXResponse } from './ProfileService.js';
|
|
2
|
-
export declare const MOCK_PROFILE_API_RESPONSE: ProfileApiResponse;
|
|
3
|
-
export declare const MOCK_X_CONNECT_RESPONSE: ConnectXResponse;
|
|
4
|
-
export declare const MOCK_X_AUTH_URL_RESPONSE: XAuthUrlResponse;
|
|
5
|
-
export type MockProfileServiceHandlers = {
|
|
6
|
-
getProfile?: (profileId: string) => Promise<ProfileApiResponse>;
|
|
7
|
-
createProfile?: (params: CreateProfileParams) => Promise<CreateProfileResponse>;
|
|
8
|
-
replaceProfile?: (profileId: string, params: ReplaceProfileParams) => Promise<ProfileApiResponse>;
|
|
9
|
-
updateProfile?: (profileId: string, params: UpdateProfileParams) => Promise<ProfileApiResponse>;
|
|
10
|
-
deleteProfile?: (profileId: string) => Promise<void>;
|
|
11
|
-
checkUsernameAvailability?: (username: string) => Promise<UsernameAvailabilityResponse>;
|
|
12
|
-
getXAuthUrl?: () => Promise<XAuthUrlResponse>;
|
|
13
|
-
connectX?: (params: ConnectXParams) => Promise<ConnectXResponse>;
|
|
14
|
-
getXAccount?: () => Promise<XAccountResponse>;
|
|
15
|
-
disconnectX?: (profileId: string) => Promise<void>;
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* Registers stub action handlers for all ProfileService methods on the provided messenger.
|
|
19
|
-
* Use this in place of instantiating a real ProfileService when the profile API is unavailable.
|
|
20
|
-
*
|
|
21
|
-
* @param messenger - The ProfileServiceMessenger to register handlers on.
|
|
22
|
-
* @param handlers - Optional per-method overrides. Unspecified methods return fixture data.
|
|
23
|
-
*/
|
|
24
|
-
export declare function buildMockProfileService(messenger: ProfileServiceMessenger, handlers?: MockProfileServiceHandlers): void;
|
|
25
|
-
//# sourceMappingURL=ProfileServiceMock.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProfileServiceMock.d.ts","sourceRoot":"","sources":["../src/ProfileServiceMock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,EACnB,4BAA4B,EAC5B,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AAE7B,eAAO,MAAM,yBAAyB,EAAE,kBAiBvC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,gBAQrC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,gBAGtC,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAChE,aAAa,CAAC,EAAE,CACd,MAAM,EAAE,mBAAmB,KACxB,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACpC,cAAc,CAAC,EAAE,CACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,oBAAoB,KACzB,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,aAAa,CAAC,EAAE,CACd,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,mBAAmB,KACxB,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,yBAAyB,CAAC,EAAE,CAC1B,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,4BAA4B,CAAC,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC9C,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACjE,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC9C,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,uBAAuB,EAClC,QAAQ,GAAE,0BAA+B,GACxC,IAAI,CAoEN"}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
export const MOCK_PROFILE_API_RESPONSE = {
|
|
2
|
-
profile_id: 'mock-profile-id',
|
|
3
|
-
username: 'mockuser',
|
|
4
|
-
display_name: 'Mock User',
|
|
5
|
-
bio: null,
|
|
6
|
-
linked_addresses: [
|
|
7
|
-
'eip155:1:0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb',
|
|
8
|
-
'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:EEivRh9T4GTLEJprEaKQyjSQzW13JRb5D7jSpvPQ8296',
|
|
9
|
-
'bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6',
|
|
10
|
-
'tron:728126428:TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH',
|
|
11
|
-
'stellar:pubnet:GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H',
|
|
12
|
-
],
|
|
13
|
-
avatar_url: 'https://pbs.twimg.com/profile_images/mock.jpg',
|
|
14
|
-
trading_privacy: 'public',
|
|
15
|
-
connected_to_x: true,
|
|
16
|
-
created_at: '2024-01-01T00:00:00.000Z',
|
|
17
|
-
updated_at: '2024-01-01T00:00:00.000Z',
|
|
18
|
-
};
|
|
19
|
-
export const MOCK_X_CONNECT_RESPONSE = {
|
|
20
|
-
x_user_id: 'mock-x-user-id',
|
|
21
|
-
x_profile_url: 'https://x.com/mockuser',
|
|
22
|
-
username: 'mockuser',
|
|
23
|
-
display_name: 'Mock User',
|
|
24
|
-
avatar_url: 'https://pbs.twimg.com/profile_images/mock.jpg',
|
|
25
|
-
created_at: '2024-01-01T00:00:00.000Z',
|
|
26
|
-
updated_at: '2024-01-01T00:00:00.000Z',
|
|
27
|
-
};
|
|
28
|
-
export const MOCK_X_AUTH_URL_RESPONSE = {
|
|
29
|
-
url: 'https://x.com/i/oauth2/authorize?mock=true',
|
|
30
|
-
state: 'mock-oauth-state',
|
|
31
|
-
};
|
|
32
|
-
/**
|
|
33
|
-
* Registers stub action handlers for all ProfileService methods on the provided messenger.
|
|
34
|
-
* Use this in place of instantiating a real ProfileService when the profile API is unavailable.
|
|
35
|
-
*
|
|
36
|
-
* @param messenger - The ProfileServiceMessenger to register handlers on.
|
|
37
|
-
* @param handlers - Optional per-method overrides. Unspecified methods return fixture data.
|
|
38
|
-
*/
|
|
39
|
-
export function buildMockProfileService(messenger, handlers = {}) {
|
|
40
|
-
messenger.registerActionHandler('ProfileService:getProfile', handlers.getProfile ??
|
|
41
|
-
(async (_profileId) => MOCK_PROFILE_API_RESPONSE));
|
|
42
|
-
messenger.registerActionHandler('ProfileService:createProfile', handlers.createProfile ??
|
|
43
|
-
(async (_params) => MOCK_PROFILE_API_RESPONSE));
|
|
44
|
-
messenger.registerActionHandler('ProfileService:replaceProfile', handlers.replaceProfile ??
|
|
45
|
-
(async (_profileId, _params) => MOCK_PROFILE_API_RESPONSE));
|
|
46
|
-
messenger.registerActionHandler('ProfileService:updateProfile', handlers.updateProfile ??
|
|
47
|
-
(async (_profileId, _params) => MOCK_PROFILE_API_RESPONSE));
|
|
48
|
-
messenger.registerActionHandler('ProfileService:deleteProfile', handlers.deleteProfile ?? (async (_profileId) => undefined));
|
|
49
|
-
messenger.registerActionHandler('ProfileService:checkUsernameAvailability', handlers.checkUsernameAvailability ??
|
|
50
|
-
(async (username) => ({
|
|
51
|
-
username,
|
|
52
|
-
available: true,
|
|
53
|
-
valid: true,
|
|
54
|
-
normalized: username,
|
|
55
|
-
errors: [],
|
|
56
|
-
})));
|
|
57
|
-
messenger.registerActionHandler('ProfileService:getXAuthUrl', handlers.getXAuthUrl ??
|
|
58
|
-
(async () => MOCK_X_AUTH_URL_RESPONSE));
|
|
59
|
-
messenger.registerActionHandler('ProfileService:connectX', handlers.connectX ??
|
|
60
|
-
(async (_params) => MOCK_X_CONNECT_RESPONSE));
|
|
61
|
-
messenger.registerActionHandler('ProfileService:getXAccount', handlers.getXAccount ??
|
|
62
|
-
(async () => MOCK_X_CONNECT_RESPONSE));
|
|
63
|
-
messenger.registerActionHandler('ProfileService:disconnectX', handlers.disconnectX ?? (async (_profileId) => undefined));
|
|
64
|
-
}
|
|
65
|
-
//# sourceMappingURL=ProfileServiceMock.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ProfileServiceMock.js","sourceRoot":"","sources":["../src/ProfileServiceMock.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ConnectXParams,\n CreateProfileParams,\n CreateProfileResponse,\n ProfileApiResponse,\n ProfileServiceMessenger,\n ReplaceProfileParams,\n UpdateProfileParams,\n UsernameAvailabilityResponse,\n XAccountResponse,\n XAuthUrlResponse,\n ConnectXResponse,\n} from './ProfileService.js';\n\nexport const MOCK_PROFILE_API_RESPONSE: ProfileApiResponse = {\n profile_id: 'mock-profile-id',\n username: 'mockuser',\n display_name: 'Mock User',\n bio: null,\n linked_addresses: [\n 'eip155:1:0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb',\n 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:EEivRh9T4GTLEJprEaKQyjSQzW13JRb5D7jSpvPQ8296',\n 'bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6',\n 'tron:728126428:TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH',\n 'stellar:pubnet:GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H',\n ],\n avatar_url: 'https://pbs.twimg.com/profile_images/mock.jpg',\n trading_privacy: 'public',\n connected_to_x: true,\n created_at: '2024-01-01T00:00:00.000Z',\n updated_at: '2024-01-01T00:00:00.000Z',\n};\n\nexport const MOCK_X_CONNECT_RESPONSE: ConnectXResponse = {\n x_user_id: 'mock-x-user-id',\n x_profile_url: 'https://x.com/mockuser',\n username: 'mockuser',\n display_name: 'Mock User',\n avatar_url: 'https://pbs.twimg.com/profile_images/mock.jpg',\n created_at: '2024-01-01T00:00:00.000Z',\n updated_at: '2024-01-01T00:00:00.000Z',\n};\n\nexport const MOCK_X_AUTH_URL_RESPONSE: XAuthUrlResponse = {\n url: 'https://x.com/i/oauth2/authorize?mock=true',\n state: 'mock-oauth-state',\n};\n\nexport type MockProfileServiceHandlers = {\n getProfile?: (profileId: string) => Promise<ProfileApiResponse>;\n createProfile?: (\n params: CreateProfileParams,\n ) => Promise<CreateProfileResponse>;\n replaceProfile?: (\n profileId: string,\n params: ReplaceProfileParams,\n ) => Promise<ProfileApiResponse>;\n updateProfile?: (\n profileId: string,\n params: UpdateProfileParams,\n ) => Promise<ProfileApiResponse>;\n deleteProfile?: (profileId: string) => Promise<void>;\n checkUsernameAvailability?: (\n username: string,\n ) => Promise<UsernameAvailabilityResponse>;\n getXAuthUrl?: () => Promise<XAuthUrlResponse>;\n connectX?: (params: ConnectXParams) => Promise<ConnectXResponse>;\n getXAccount?: () => Promise<XAccountResponse>;\n disconnectX?: (profileId: string) => Promise<void>;\n};\n\n/**\n * Registers stub action handlers for all ProfileService methods on the provided messenger.\n * Use this in place of instantiating a real ProfileService when the profile API is unavailable.\n *\n * @param messenger - The ProfileServiceMessenger to register handlers on.\n * @param handlers - Optional per-method overrides. Unspecified methods return fixture data.\n */\nexport function buildMockProfileService(\n messenger: ProfileServiceMessenger,\n handlers: MockProfileServiceHandlers = {},\n): void {\n messenger.registerActionHandler(\n 'ProfileService:getProfile',\n handlers.getProfile ??\n (async (_profileId): Promise<ProfileApiResponse> =>\n MOCK_PROFILE_API_RESPONSE),\n );\n\n messenger.registerActionHandler(\n 'ProfileService:createProfile',\n handlers.createProfile ??\n (async (_params): Promise<CreateProfileResponse> =>\n MOCK_PROFILE_API_RESPONSE),\n );\n\n messenger.registerActionHandler(\n 'ProfileService:replaceProfile',\n handlers.replaceProfile ??\n (async (_profileId, _params): Promise<ProfileApiResponse> =>\n MOCK_PROFILE_API_RESPONSE),\n );\n\n messenger.registerActionHandler(\n 'ProfileService:updateProfile',\n handlers.updateProfile ??\n (async (_profileId, _params): Promise<ProfileApiResponse> =>\n MOCK_PROFILE_API_RESPONSE),\n );\n\n messenger.registerActionHandler(\n 'ProfileService:deleteProfile',\n handlers.deleteProfile ?? (async (_profileId): Promise<void> => undefined),\n );\n\n messenger.registerActionHandler(\n 'ProfileService:checkUsernameAvailability',\n handlers.checkUsernameAvailability ??\n (async (username): Promise<UsernameAvailabilityResponse> => ({\n username,\n available: true,\n valid: true,\n normalized: username,\n errors: [],\n })),\n );\n\n messenger.registerActionHandler(\n 'ProfileService:getXAuthUrl',\n handlers.getXAuthUrl ??\n (async (): Promise<XAuthUrlResponse> => MOCK_X_AUTH_URL_RESPONSE),\n );\n\n messenger.registerActionHandler(\n 'ProfileService:connectX',\n handlers.connectX ??\n (async (_params): Promise<ConnectXResponse> => MOCK_X_CONNECT_RESPONSE),\n );\n\n messenger.registerActionHandler(\n 'ProfileService:getXAccount',\n handlers.getXAccount ??\n (async (): Promise<XAccountResponse> => MOCK_X_CONNECT_RESPONSE),\n );\n\n messenger.registerActionHandler(\n 'ProfileService:disconnectX',\n handlers.disconnectX ?? (async (_profileId): Promise<void> => undefined),\n );\n}\n"]}
|