@logto/connector-discord 1.4.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -182,9 +182,9 @@ var createDiscordConnector = async ({ getConfig }) => {
182
182
  getUserInfo: getUserInfo(getConfig)
183
183
  };
184
184
  };
185
- var src_default = createDiscordConnector;
185
+ var index_default = createDiscordConnector;
186
186
  export {
187
- src_default as default,
187
+ index_default as default,
188
188
  getAccessToken
189
189
  };
190
190
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/constant.ts","../src/types.ts"],"sourcesContent":["/**\n * Discord OAuth2 Connector\n * https://discord.com/developers/docs/topics/oauth2\n */\n\nimport { assert, conditional } from '@silverhand/essentials';\nimport { got, HTTPError } from 'got';\n\nimport type {\n GetConnectorConfig,\n GetAuthorizationUri,\n GetUserInfo,\n CreateConnector,\n SocialConnector,\n} from '@logto/connector-kit';\nimport {\n socialUserInfoGuard,\n validateConfig,\n ConnectorError,\n ConnectorErrorCodes,\n ConnectorType,\n parseJson,\n} from '@logto/connector-kit';\n\nimport {\n defaultMetadata,\n scope as defaultScope,\n authorizationEndpoint,\n accessTokenEndpoint,\n defaultTimeout,\n userInfoEndpoint,\n} from './constant.js';\nimport type { DiscordConfig } from './types.js';\nimport {\n discordConfigGuard,\n authResponseGuard,\n accessTokenResponseGuard,\n userInfoResponseGuard,\n} from './types.js';\n\nconst getAuthorizationUri =\n (getConfig: GetConnectorConfig): GetAuthorizationUri =>\n async ({ state, redirectUri }) => {\n const config = await getConfig(defaultMetadata.id);\n validateConfig(config, discordConfigGuard);\n\n const queryParameters = new URLSearchParams({\n client_id: config.clientId,\n redirect_uri: redirectUri,\n response_type: 'code',\n scope: config.scope ?? defaultScope,\n state,\n });\n\n return `${authorizationEndpoint}?${queryParameters.toString()}`;\n };\n\nexport const getAccessToken = async (\n config: DiscordConfig,\n codeObject: { code: string; redirectUri: string }\n) => {\n const { code, redirectUri } = codeObject;\n\n const { clientId: client_id, clientSecret: client_secret } = config;\n\n const httpResponse = await got.post(accessTokenEndpoint, {\n form: {\n client_id,\n client_secret,\n grant_type: 'authorization_code',\n code,\n redirect_uri: redirectUri,\n },\n timeout: { request: defaultTimeout },\n });\n\n const result = accessTokenResponseGuard.safeParse(parseJson(httpResponse.body));\n\n if (!result.success) {\n throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);\n }\n\n const { access_token: accessToken } = result.data;\n\n assert(accessToken, new ConnectorError(ConnectorErrorCodes.SocialAuthCodeInvalid));\n\n return { accessToken };\n};\n\nconst getUserInfo =\n (getConfig: GetConnectorConfig): GetUserInfo =>\n async (data) => {\n const { code, redirectUri } = await authorizationCallbackHandler(data);\n const config = await getConfig(defaultMetadata.id);\n validateConfig(config, discordConfigGuard);\n const { accessToken } = await getAccessToken(config, { code, redirectUri });\n\n try {\n const httpResponse = await got.get(userInfoEndpoint, {\n headers: {\n authorization: `Bearer ${accessToken}`,\n },\n timeout: { request: defaultTimeout },\n });\n const rawData = parseJson(httpResponse.body);\n const result = userInfoResponseGuard.safeParse(rawData);\n\n if (!result.success) {\n throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);\n }\n\n const { id, username: name, avatar, email, verified } = result.data;\n\n const rawUserInfo = {\n id,\n name,\n avatar: conditional(avatar && `https://cdn.discordapp.com/avatars/${id}/${avatar}`),\n email: conditional(verified && email),\n };\n\n const userInfoResult = socialUserInfoGuard.safeParse(rawUserInfo);\n\n if (!userInfoResult.success) {\n throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, userInfoResult.error);\n }\n\n return { ...userInfoResult.data, rawData };\n } catch (error: unknown) {\n if (error instanceof HTTPError) {\n const { statusCode, body: rawBody } = error.response;\n\n if (statusCode === 401) {\n throw new ConnectorError(ConnectorErrorCodes.SocialAccessTokenInvalid);\n }\n\n throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(rawBody));\n }\n\n throw error;\n }\n };\n\nconst authorizationCallbackHandler = async (parameterObject: unknown) => {\n const result = authResponseGuard.safeParse(parameterObject);\n\n if (!result.success) {\n throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(parameterObject));\n }\n\n return result.data;\n};\n\nconst createDiscordConnector: CreateConnector<SocialConnector> = async ({ getConfig }) => {\n return {\n metadata: defaultMetadata,\n type: ConnectorType.Social,\n configGuard: discordConfigGuard,\n getAuthorizationUri: getAuthorizationUri(getConfig),\n getUserInfo: getUserInfo(getConfig),\n };\n};\n\nexport default createDiscordConnector;\n","import type { ConnectorMetadata } from '@logto/connector-kit';\nimport { ConnectorConfigFormItemType, ConnectorPlatform } from '@logto/connector-kit';\n\n/**\n * Base authorization URL.\n * https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-urls\n */\nexport const authorizationEndpoint = 'https://discord.com/oauth2/authorize';\n\n/**\n * Discord exposes different versions of the API, You should specify which version to use by including it in your requests.\n * https://discord.com/developers/docs/reference#api-reference\n */\nexport const accessTokenEndpoint = 'https://discord.com/api/v10/oauth2/token';\nexport const userInfoEndpoint = 'https://discord.com/api/v10/users/@me';\n\n/**\n * OAuth2 Scopes\n * https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes\n */\nexport const scope = 'identify email';\n\nexport const defaultMetadata: ConnectorMetadata = {\n id: 'discord-universal',\n target: 'discord',\n platform: ConnectorPlatform.Universal,\n name: {\n en: 'Discord',\n },\n logo: './logo.svg',\n logoDark: null,\n description: {\n en: 'Discord is the easiest way to talk over voice, video, and text.',\n 'pt-PT': 'Discord é a forma mais fácil de comunicar por voz, vídeo e texto.',\n 'zh-CN': 'Discord 是一款专为社群设计的免费网络实时通话软件与数字发行平台。',\n 'tr-TR': 'Discord, sesli, görüntülü ve metin üzerinden konuşmanın en kolay yoludur.',\n ko: 'Discord는 음성, 비디오 및 텍스트로 대화하는 가장 쉬운 방법입니다.',\n },\n readme: './README.md',\n formItems: [\n {\n key: 'clientId',\n type: ConnectorConfigFormItemType.Text,\n required: true,\n label: 'Client ID',\n placeholder: '<client-id>',\n },\n {\n key: 'clientSecret',\n type: ConnectorConfigFormItemType.Text,\n required: true,\n label: 'Client Secret',\n placeholder: '<client-secret>',\n },\n {\n key: 'scope',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n label: 'Scope',\n placeholder: '<scope>',\n description:\n \"The `scope` determines permissions granted by the user's authorization. If you are not sure what to enter, do not worry, just leave it blank.\",\n },\n ],\n};\n\nexport const defaultTimeout = 5000;\n","import type { Nullable, Optional } from '@silverhand/essentials';\nimport { z } from 'zod';\n\nconst nullishToUndefined = <T = unknown>(input: Nullable<T>): Optional<T> => {\n if (!input) {\n return;\n }\n\n return input;\n};\n\nexport const discordConfigGuard = z.object({\n clientId: z.string(),\n clientSecret: z.string(),\n scope: z.string().optional(),\n});\n\nexport type DiscordConfig = z.infer<typeof discordConfigGuard>;\n\nexport const accessTokenResponseGuard = z.object({\n access_token: z.string(),\n token_type: z.string(),\n expires_in: z.number(),\n scope: z.string(),\n});\n\nexport type AccessTokenResponse = z.infer<typeof accessTokenResponseGuard>;\n\nexport const userInfoResponseGuard = z.object({\n id: z.string(),\n username: z.string().nullish().transform(nullishToUndefined),\n avatar: z.string().nullish().transform(nullishToUndefined),\n email: z.string().nullish().transform(nullishToUndefined),\n verified: z.boolean().nullish().transform(nullishToUndefined),\n});\n\nexport type UserInfoResponse = z.infer<typeof userInfoResponseGuard>;\n\nexport const authorizationCallbackErrorGuard = z.object({\n error: z.string(),\n error_description: z.string(),\n});\n\nexport const authResponseGuard = z.object({ code: z.string(), redirectUri: z.string() });\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/constant.ts","../src/types.ts"],"sourcesContent":["/**\n * Discord OAuth2 Connector\n * https://discord.com/developers/docs/topics/oauth2\n */\n\nimport { assert, conditional } from '@silverhand/essentials';\nimport { got, HTTPError } from 'got';\n\nimport type {\n GetConnectorConfig,\n GetAuthorizationUri,\n GetUserInfo,\n CreateConnector,\n SocialConnector,\n} from '@logto/connector-kit';\nimport {\n socialUserInfoGuard,\n validateConfig,\n ConnectorError,\n ConnectorErrorCodes,\n ConnectorType,\n parseJson,\n} from '@logto/connector-kit';\n\nimport {\n defaultMetadata,\n scope as defaultScope,\n authorizationEndpoint,\n accessTokenEndpoint,\n defaultTimeout,\n userInfoEndpoint,\n} from './constant.js';\nimport type { DiscordConfig } from './types.js';\nimport {\n discordConfigGuard,\n authResponseGuard,\n accessTokenResponseGuard,\n userInfoResponseGuard,\n} from './types.js';\n\nconst getAuthorizationUri =\n (getConfig: GetConnectorConfig): GetAuthorizationUri =>\n async ({ state, redirectUri }) => {\n const config = await getConfig(defaultMetadata.id);\n validateConfig(config, discordConfigGuard);\n\n const queryParameters = new URLSearchParams({\n client_id: config.clientId,\n redirect_uri: redirectUri,\n response_type: 'code',\n scope: config.scope ?? defaultScope,\n state,\n });\n\n return `${authorizationEndpoint}?${queryParameters.toString()}`;\n };\n\nexport const getAccessToken = async (\n config: DiscordConfig,\n codeObject: { code: string; redirectUri: string }\n) => {\n const { code, redirectUri } = codeObject;\n\n const { clientId: client_id, clientSecret: client_secret } = config;\n\n const httpResponse = await got.post(accessTokenEndpoint, {\n form: {\n client_id,\n client_secret,\n grant_type: 'authorization_code',\n code,\n redirect_uri: redirectUri,\n },\n timeout: { request: defaultTimeout },\n });\n\n const result = accessTokenResponseGuard.safeParse(parseJson(httpResponse.body));\n\n if (!result.success) {\n throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);\n }\n\n const { access_token: accessToken } = result.data;\n\n assert(accessToken, new ConnectorError(ConnectorErrorCodes.SocialAuthCodeInvalid));\n\n return { accessToken };\n};\n\nconst getUserInfo =\n (getConfig: GetConnectorConfig): GetUserInfo =>\n async (data) => {\n const { code, redirectUri } = await authorizationCallbackHandler(data);\n const config = await getConfig(defaultMetadata.id);\n validateConfig(config, discordConfigGuard);\n const { accessToken } = await getAccessToken(config, { code, redirectUri });\n\n try {\n const httpResponse = await got.get(userInfoEndpoint, {\n headers: {\n authorization: `Bearer ${accessToken}`,\n },\n timeout: { request: defaultTimeout },\n });\n const rawData = parseJson(httpResponse.body);\n const result = userInfoResponseGuard.safeParse(rawData);\n\n if (!result.success) {\n throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);\n }\n\n const { id, username: name, avatar, email, verified } = result.data;\n\n const rawUserInfo = {\n id,\n name,\n avatar: conditional(avatar && `https://cdn.discordapp.com/avatars/${id}/${avatar}`),\n email: conditional(verified && email),\n };\n\n const userInfoResult = socialUserInfoGuard.safeParse(rawUserInfo);\n\n if (!userInfoResult.success) {\n throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, userInfoResult.error);\n }\n\n return { ...userInfoResult.data, rawData };\n } catch (error: unknown) {\n if (error instanceof HTTPError) {\n const { statusCode, body: rawBody } = error.response;\n\n if (statusCode === 401) {\n throw new ConnectorError(ConnectorErrorCodes.SocialAccessTokenInvalid);\n }\n\n throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(rawBody));\n }\n\n throw error;\n }\n };\n\nconst authorizationCallbackHandler = async (parameterObject: unknown) => {\n const result = authResponseGuard.safeParse(parameterObject);\n\n if (!result.success) {\n throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(parameterObject));\n }\n\n return result.data;\n};\n\nconst createDiscordConnector: CreateConnector<SocialConnector> = async ({ getConfig }) => {\n return {\n metadata: defaultMetadata,\n type: ConnectorType.Social,\n configGuard: discordConfigGuard,\n getAuthorizationUri: getAuthorizationUri(getConfig),\n getUserInfo: getUserInfo(getConfig),\n };\n};\n\nexport default createDiscordConnector;\n","import type { ConnectorMetadata } from '@logto/connector-kit';\nimport { ConnectorConfigFormItemType, ConnectorPlatform } from '@logto/connector-kit';\n\n/**\n * Base authorization URL.\n * https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-urls\n */\nexport const authorizationEndpoint = 'https://discord.com/oauth2/authorize';\n\n/**\n * Discord exposes different versions of the API, You should specify which version to use by including it in your requests.\n * https://discord.com/developers/docs/reference#api-reference\n */\nexport const accessTokenEndpoint = 'https://discord.com/api/v10/oauth2/token';\nexport const userInfoEndpoint = 'https://discord.com/api/v10/users/@me';\n\n/**\n * OAuth2 Scopes\n * https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes\n */\nexport const scope = 'identify email';\n\nexport const defaultMetadata: ConnectorMetadata = {\n id: 'discord-universal',\n target: 'discord',\n platform: ConnectorPlatform.Universal,\n name: {\n en: 'Discord',\n },\n logo: './logo.svg',\n logoDark: null,\n description: {\n en: 'Discord is the easiest way to talk over voice, video, and text.',\n 'pt-PT': 'Discord é a forma mais fácil de comunicar por voz, vídeo e texto.',\n 'zh-CN': 'Discord 是一款专为社群设计的免费网络实时通话软件与数字发行平台。',\n 'tr-TR': 'Discord, sesli, görüntülü ve metin üzerinden konuşmanın en kolay yoludur.',\n ko: 'Discord는 음성, 비디오 및 텍스트로 대화하는 가장 쉬운 방법입니다.',\n },\n readme: './README.md',\n formItems: [\n {\n key: 'clientId',\n type: ConnectorConfigFormItemType.Text,\n required: true,\n label: 'Client ID',\n placeholder: '<client-id>',\n },\n {\n key: 'clientSecret',\n type: ConnectorConfigFormItemType.Text,\n required: true,\n label: 'Client Secret',\n placeholder: '<client-secret>',\n },\n {\n key: 'scope',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n label: 'Scope',\n placeholder: '<scope>',\n description:\n \"The `scope` determines permissions granted by the user's authorization. If you are not sure what to enter, do not worry, just leave it blank.\",\n },\n ],\n};\n\nexport const defaultTimeout = 5000;\n","import type { Nullable, Optional } from '@silverhand/essentials';\nimport { z } from 'zod';\n\nconst nullishToUndefined = <T = unknown>(input: Nullable<T>): Optional<T> => {\n if (!input) {\n return;\n }\n\n return input;\n};\n\nexport const discordConfigGuard = z.object({\n clientId: z.string(),\n clientSecret: z.string(),\n scope: z.string().optional(),\n});\n\nexport type DiscordConfig = z.infer<typeof discordConfigGuard>;\n\nexport const accessTokenResponseGuard = z.object({\n access_token: z.string(),\n token_type: z.string(),\n expires_in: z.number(),\n scope: z.string(),\n});\n\nexport type AccessTokenResponse = z.infer<typeof accessTokenResponseGuard>;\n\nexport const userInfoResponseGuard = z.object({\n id: z.string(),\n username: z.string().nullish().transform(nullishToUndefined),\n avatar: z.string().nullish().transform(nullishToUndefined),\n email: z.string().nullish().transform(nullishToUndefined),\n verified: z.boolean().nullish().transform(nullishToUndefined),\n});\n\nexport type UserInfoResponse = z.infer<typeof userInfoResponseGuard>;\n\nexport const authorizationCallbackErrorGuard = z.object({\n error: z.string(),\n error_description: z.string(),\n});\n\nexport const authResponseGuard = z.object({ code: z.string(), redirectUri: z.string() });\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@logto/connector-discord",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "Discord connector implementation.",
5
5
  "author": "ZR3SYSTEMS. <https://github.com/FlurryNight>",
6
6
  "dependencies": {
7
- "@logto/connector-kit": "^4.0.0",
7
+ "@logto/connector-kit": "^4.1.1",
8
8
  "@silverhand/essentials": "^2.9.1",
9
9
  "got": "^14.0.0",
10
10
  "snakecase-keys": "^8.0.1",
@@ -45,15 +45,15 @@
45
45
  "@silverhand/ts-config": "6.0.0",
46
46
  "@types/node": "^20.11.20",
47
47
  "@types/supertest": "^6.0.2",
48
- "@vitest/coverage-v8": "^2.0.0",
48
+ "@vitest/coverage-v8": "^2.1.9",
49
49
  "eslint": "^8.56.0",
50
50
  "lint-staged": "^15.0.2",
51
51
  "nock": "^13.3.1",
52
52
  "prettier": "^3.0.0",
53
53
  "supertest": "^7.0.0",
54
- "tsup": "^8.1.0",
54
+ "tsup": "^8.3.0",
55
55
  "typescript": "^5.5.3",
56
- "vitest": "^2.0.0"
56
+ "vitest": "^2.1.9"
57
57
  },
58
58
  "scripts": {
59
59
  "precommit": "lint-staged",