@logto/connector-dingtalk-web 0.1.1 → 0.2.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
@@ -1,177 +1,184 @@
1
- import { got, HTTPError } from 'got';
2
- import { ConnectorPlatform, ConnectorConfigFormItemType, parseJson, ConnectorError, ConnectorErrorCodes, ConnectorType, validateConfig } from '@logto/connector-kit';
3
- import { z } from 'zod';
1
+ // src/index.ts
2
+ import { got, HTTPError } from "got";
3
+ import {
4
+ ConnectorError,
5
+ ConnectorErrorCodes,
6
+ validateConfig,
7
+ ConnectorType,
8
+ parseJson
9
+ } from "@logto/connector-kit";
4
10
 
5
- // https://open.dingtalk.com/document/orgapp-server/use-dingtalk-account-to-log-on-to-third-party-websites-1
6
- const authorizationEndpoint = 'https://login.dingtalk.com/oauth2/auth';
7
- // https://open.dingtalk.com/document/isvapp/obtain-user-token
8
- const accessTokenEndpoint = 'https://api.dingtalk.com/v1.0/oauth2/userAccessToken';
9
- // https://open.dingtalk.com/document/isvapp/dingtalk-retrieve-user-information
10
- // To obtain the current authorized person's information, the unionId parameter can be set to "me".
11
- const userInfoEndpoint = 'https://api.dingtalk.com/v1.0/contact/users/me';
12
- const scope = 'openid';
13
- const defaultMetadata = {
14
- id: 'dingtalk-web',
15
- target: 'dingtalk',
16
- platform: ConnectorPlatform.Web,
17
- name: {
18
- en: 'DingTalk',
19
- 'zh-CN': '钉钉',
20
- 'tr-TR': 'DingTalk',
21
- ko: 'DingTalk',
11
+ // src/constant.ts
12
+ import { ConnectorConfigFormItemType, ConnectorPlatform } from "@logto/connector-kit";
13
+ var authorizationEndpoint = "https://login.dingtalk.com/oauth2/auth";
14
+ var accessTokenEndpoint = "https://api.dingtalk.com/v1.0/oauth2/userAccessToken";
15
+ var userInfoEndpoint = "https://api.dingtalk.com/v1.0/contact/users/me";
16
+ var scope = "openid";
17
+ var defaultMetadata = {
18
+ id: "dingtalk-web",
19
+ target: "dingtalk",
20
+ platform: ConnectorPlatform.Web,
21
+ name: {
22
+ en: "DingTalk",
23
+ "zh-CN": "\u9489\u9489",
24
+ "tr-TR": "DingTalk",
25
+ ko: "DingTalk"
26
+ },
27
+ logo: "./logo.svg",
28
+ logoDark: null,
29
+ description: {
30
+ en: "DingTalk is an enterprise-level intelligent mobile office platform launched by Alibaba Group.",
31
+ "zh-CN": "\u9489\u9489\u662F\u4E00\u4E2A\u7531\u963F\u91CC\u5DF4\u5DF4\u96C6\u56E2\u63A8\u51FA\u7684\u4F01\u4E1A\u7EA7\u667A\u80FD\u79FB\u52A8\u529E\u516C\u5E73\u53F0\u3002",
32
+ "tr-TR": "DingTalk, Alibaba Grubu taraf\u0131ndan piyasaya s\xFCr\xFClen kurumsal d\xFCzeyde ak\u0131ll\u0131 mobil ofis platformudur.",
33
+ ko: "\uB529\uD1A1\uC740 \uC54C\uB9AC\uBC14\uBC14 \uADF8\uB8F9\uC774 \uCD9C\uC2DC\uD55C \uAE30\uC5C5\uC6A9 \uC9C0\uB2A5\uD615 \uBAA8\uBC14\uC77C \uC624\uD53C\uC2A4 \uD50C\uB7AB\uD3FC\uC785\uB2C8\uB2E4."
34
+ },
35
+ readme: "./README.md",
36
+ formItems: [
37
+ {
38
+ key: "clientId",
39
+ label: "Client ID",
40
+ required: true,
41
+ type: ConnectorConfigFormItemType.Text,
42
+ placeholder: "<client-id>"
22
43
  },
23
- logo: './logo.svg',
24
- logoDark: null,
25
- description: {
26
- en: 'DingTalk is an enterprise-level intelligent mobile office platform launched by Alibaba Group.',
27
- 'zh-CN': '钉钉是一个由阿里巴巴集团推出的企业级智能移动办公平台。',
28
- 'tr-TR': 'DingTalk, Alibaba Grubu tarafından piyasaya sürülen kurumsal düzeyde akıllı mobil ofis platformudur.',
29
- ko: '딩톡은 알리바바 그룹이 출시한 기업용 지능형 모바일 오피스 플랫폼입니다.',
44
+ {
45
+ key: "clientSecret",
46
+ label: "Client Secret",
47
+ required: true,
48
+ type: ConnectorConfigFormItemType.Text,
49
+ placeholder: "<client-secret>"
30
50
  },
31
- readme: './README.md',
32
- formItems: [
33
- {
34
- key: 'clientId',
35
- label: 'Client ID',
36
- required: true,
37
- type: ConnectorConfigFormItemType.Text,
38
- placeholder: '<client-id>',
39
- },
40
- {
41
- key: 'clientSecret',
42
- label: 'Client Secret',
43
- required: true,
44
- type: ConnectorConfigFormItemType.Text,
45
- placeholder: '<client-secret>',
46
- },
47
- {
48
- key: 'scope',
49
- type: ConnectorConfigFormItemType.Text,
50
- label: 'Scope',
51
- required: false,
52
- placeholder: '<scope>',
53
- description: "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.",
54
- },
55
- ],
51
+ {
52
+ key: "scope",
53
+ type: ConnectorConfigFormItemType.Text,
54
+ label: "Scope",
55
+ required: false,
56
+ placeholder: "<scope>",
57
+ description: "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."
58
+ }
59
+ ]
56
60
  };
57
- const defaultTimeout = 5000;
61
+ var defaultTimeout = 5e3;
58
62
 
59
- const dingtalkConfigGuard = z.object({
60
- clientId: z.string(),
61
- clientSecret: z.string(),
62
- scope: z.string().optional(),
63
+ // src/types.ts
64
+ import { z } from "zod";
65
+ var dingtalkConfigGuard = z.object({
66
+ clientId: z.string(),
67
+ clientSecret: z.string(),
68
+ scope: z.string().optional()
63
69
  });
64
- const accessTokenResponseGuard = z.object({
65
- accessToken: z.string(),
66
- refreshToken: z.string().optional(),
67
- expireIn: z.number().optional(), // In seconds
68
- corpId: z.string().optional(),
70
+ var accessTokenResponseGuard = z.object({
71
+ accessToken: z.string(),
72
+ refreshToken: z.string().optional(),
73
+ expireIn: z.number().optional(),
74
+ // In seconds
75
+ corpId: z.string().optional()
69
76
  });
70
- // https://open.dingtalk.com/document/isvapp/dingtalk-retrieve-user-information
71
- const userInfoResponseGuard = z.object({
72
- nick: z.string().optional(),
73
- avatarUrl: z.string().optional(),
74
- mobile: z.string().optional(),
75
- openId: z.string().optional(), // DingTalk no longer recommends using OpenId for integration. Instead, use unionId.
76
- unionId: z.string(),
77
- email: z.string().optional(),
78
- stateCode: z.string().optional(),
77
+ var userInfoResponseGuard = z.object({
78
+ nick: z.string().optional(),
79
+ avatarUrl: z.string().optional(),
80
+ mobile: z.string().optional(),
81
+ openId: z.string().optional(),
82
+ // DingTalk no longer recommends using OpenId for integration. Instead, use unionId.
83
+ unionId: z.string(),
84
+ email: z.string().optional(),
85
+ stateCode: z.string().optional()
79
86
  });
80
- const authResponseGuard = z.object({ code: z.string() });
87
+ var authResponseGuard = z.object({ code: z.string() });
81
88
 
82
- /**
83
- * DingTalk OAuth2 Connector
84
- * https://open.dingtalk.com/document/orgapp/obtain-identity-credentials#title-4up-u8w-5ug
85
- */
86
- const getAuthorizationUri = (getConfig) => async ({ state, redirectUri }) => {
87
- const config = await getConfig(defaultMetadata.id);
88
- validateConfig(config, dingtalkConfigGuard);
89
- const { clientId, scope: scope$1 } = config;
90
- const queryParameters = new URLSearchParams({
91
- client_id: clientId,
92
- redirect_uri: encodeURI(redirectUri), // The variable `redirectUri` should match {clientId, clientSecret}
93
- response_type: 'code',
94
- scope: scope$1 ?? scope,
95
- state,
96
- prompt: 'consent',
97
- });
98
- return `${authorizationEndpoint}?${queryParameters.toString()}`;
89
+ // src/index.ts
90
+ var getAuthorizationUri = (getConfig) => async ({ state, redirectUri }) => {
91
+ const config = await getConfig(defaultMetadata.id);
92
+ validateConfig(config, dingtalkConfigGuard);
93
+ const { clientId, scope: scope2 } = config;
94
+ const queryParameters = new URLSearchParams({
95
+ client_id: clientId,
96
+ redirect_uri: encodeURI(redirectUri),
97
+ // The variable `redirectUri` should match {clientId, clientSecret}
98
+ response_type: "code",
99
+ scope: scope2 ?? scope,
100
+ state,
101
+ prompt: "consent"
102
+ });
103
+ return `${authorizationEndpoint}?${queryParameters.toString()}`;
104
+ };
105
+ var getAccessToken = async (code, config) => {
106
+ const { clientId, clientSecret } = config;
107
+ const httpResponse = await got.post(accessTokenEndpoint, {
108
+ json: {
109
+ clientId,
110
+ clientSecret,
111
+ code,
112
+ grantType: "authorization_code"
113
+ },
114
+ timeout: { request: defaultTimeout }
115
+ });
116
+ const result = accessTokenResponseGuard.safeParse(parseJson(httpResponse.body));
117
+ if (!result.success) {
118
+ throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
119
+ }
120
+ const { accessToken } = result.data;
121
+ return { accessToken };
99
122
  };
100
- const getAccessToken = async (code, config) => {
101
- const { clientId, clientSecret } = config;
102
- const httpResponse = await got.post(accessTokenEndpoint, {
103
- json: {
104
- clientId,
105
- clientSecret,
106
- code,
107
- grantType: 'authorization_code',
108
- },
109
- timeout: { request: defaultTimeout },
123
+ var getUserInfo = (getConfig) => async (data) => {
124
+ const { code } = await authorizationCallbackHandler(data);
125
+ const config = await getConfig(defaultMetadata.id);
126
+ validateConfig(config, dingtalkConfigGuard);
127
+ const { accessToken } = await getAccessToken(code, config);
128
+ try {
129
+ const httpResponse = await got.get(userInfoEndpoint, {
130
+ headers: {
131
+ "x-acs-dingtalk-access-token": accessToken
132
+ },
133
+ timeout: { request: defaultTimeout }
110
134
  });
111
- const result = accessTokenResponseGuard.safeParse(parseJson(httpResponse.body));
135
+ const rawData = parseJson(httpResponse.body);
136
+ const result = userInfoResponseGuard.safeParse(rawData);
112
137
  if (!result.success) {
113
- throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
138
+ throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
114
139
  }
115
- const { accessToken } = result.data;
116
- return { accessToken };
140
+ const { nick: name, avatarUrl: avatar, unionId: id, email, mobile, stateCode } = result.data;
141
+ return {
142
+ id,
143
+ avatar,
144
+ phone: stateCode && mobile ? `${stateCode}${mobile}` : void 0,
145
+ email,
146
+ name,
147
+ rawData
148
+ };
149
+ } catch (error) {
150
+ return getUserInfoErrorHandler(error);
151
+ }
117
152
  };
118
- const getUserInfo = (getConfig) => async (data) => {
119
- const { code } = await authorizationCallbackHandler(data);
120
- const config = await getConfig(defaultMetadata.id);
121
- validateConfig(config, dingtalkConfigGuard);
122
- const { accessToken } = await getAccessToken(code, config);
123
- try {
124
- const httpResponse = await got.get(userInfoEndpoint, {
125
- headers: {
126
- 'x-acs-dingtalk-access-token': accessToken,
127
- },
128
- timeout: { request: defaultTimeout },
129
- });
130
- const rawData = parseJson(httpResponse.body);
131
- const result = userInfoResponseGuard.safeParse(rawData);
132
- if (!result.success) {
133
- throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, result.error);
134
- }
135
- const { nick: name, avatarUrl: avatar, unionId: id, email, mobile, stateCode } = result.data;
136
- return {
137
- id,
138
- avatar,
139
- phone: stateCode && mobile ? `${stateCode}${mobile}` : undefined,
140
- email,
141
- name,
142
- rawData,
143
- };
144
- }
145
- catch (error) {
146
- return getUserInfoErrorHandler(error);
153
+ var getUserInfoErrorHandler = (error) => {
154
+ if (error instanceof HTTPError) {
155
+ const { statusCode, body: rawBody } = error.response;
156
+ if (statusCode === 400) {
157
+ throw new ConnectorError(ConnectorErrorCodes.SocialAccessTokenInvalid);
147
158
  }
159
+ throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(rawBody));
160
+ }
161
+ throw error;
148
162
  };
149
- const getUserInfoErrorHandler = (error) => {
150
- // https://open.dingtalk.com/document/personalapp/error-code-2#title-m5s-krt-vds
151
- if (error instanceof HTTPError) {
152
- const { statusCode, body: rawBody } = error.response;
153
- if (statusCode === 400) {
154
- throw new ConnectorError(ConnectorErrorCodes.SocialAccessTokenInvalid);
155
- }
156
- throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(rawBody));
157
- }
158
- throw error;
163
+ var authorizationCallbackHandler = async (parameterObject) => {
164
+ const result = authResponseGuard.safeParse(parameterObject);
165
+ if (!result.success) {
166
+ throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(parameterObject));
167
+ }
168
+ return result.data;
159
169
  };
160
- const authorizationCallbackHandler = async (parameterObject) => {
161
- const result = authResponseGuard.safeParse(parameterObject);
162
- if (!result.success) {
163
- throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(parameterObject));
164
- }
165
- return result.data;
170
+ var createDingtalkConnector = async ({ getConfig }) => {
171
+ return {
172
+ metadata: defaultMetadata,
173
+ type: ConnectorType.Social,
174
+ configGuard: dingtalkConfigGuard,
175
+ getAuthorizationUri: getAuthorizationUri(getConfig),
176
+ getUserInfo: getUserInfo(getConfig)
177
+ };
166
178
  };
167
- const createDingtalkConnector = async ({ getConfig }) => {
168
- return {
169
- metadata: defaultMetadata,
170
- type: ConnectorType.Social,
171
- configGuard: dingtalkConfigGuard,
172
- getAuthorizationUri: getAuthorizationUri(getConfig),
173
- getUserInfo: getUserInfo(getConfig),
174
- };
179
+ var index_default = createDingtalkConnector;
180
+ export {
181
+ index_default as default,
182
+ getAccessToken
175
183
  };
176
-
177
- export { createDingtalkConnector as default, getAccessToken };
184
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/constant.ts","../src/types.ts"],"sourcesContent":["/**\n * DingTalk OAuth2 Connector\n * https://open.dingtalk.com/document/orgapp/obtain-identity-credentials#title-4up-u8w-5ug\n */\n\nimport { got, HTTPError } from 'got';\n\nimport type {\n GetAuthorizationUri,\n GetUserInfo,\n GetConnectorConfig,\n CreateConnector,\n SocialConnector,\n} from '@logto/connector-kit';\nimport {\n ConnectorError,\n ConnectorErrorCodes,\n validateConfig,\n ConnectorType,\n parseJson,\n} from '@logto/connector-kit';\n\nimport {\n authorizationEndpoint,\n accessTokenEndpoint,\n userInfoEndpoint,\n scope as defaultScope,\n defaultMetadata,\n defaultTimeout,\n} from './constant.js';\nimport type { DingtalkConfig } from './types.js';\nimport {\n dingtalkConfigGuard,\n accessTokenResponseGuard,\n userInfoResponseGuard,\n authResponseGuard,\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, dingtalkConfigGuard);\n\n const { clientId, scope } = config;\n\n const queryParameters = new URLSearchParams({\n client_id: clientId,\n redirect_uri: encodeURI(redirectUri), // The variable `redirectUri` should match {clientId, clientSecret}\n response_type: 'code',\n scope: scope ?? defaultScope,\n state,\n prompt: 'consent',\n });\n\n return `${authorizationEndpoint}?${queryParameters.toString()}`;\n };\n\nexport const getAccessToken = async (\n code: string,\n config: DingtalkConfig\n): Promise<{ accessToken: string }> => {\n const { clientId, clientSecret } = config;\n\n const httpResponse = await got.post(accessTokenEndpoint, {\n json: {\n clientId,\n clientSecret,\n code,\n grantType: 'authorization_code',\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 { accessToken } = result.data;\n\n return { accessToken };\n};\n\nconst getUserInfo =\n (getConfig: GetConnectorConfig): GetUserInfo =>\n async (data) => {\n const { code } = await authorizationCallbackHandler(data);\n const config = await getConfig(defaultMetadata.id);\n validateConfig(config, dingtalkConfigGuard);\n const { accessToken } = await getAccessToken(code, config);\n\n try {\n const httpResponse = await got.get(userInfoEndpoint, {\n headers: {\n 'x-acs-dingtalk-access-token': 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 { nick: name, avatarUrl: avatar, unionId: id, email, mobile, stateCode } = result.data;\n return {\n id,\n avatar,\n phone: stateCode && mobile ? `${stateCode}${mobile}` : undefined,\n email,\n name,\n rawData,\n };\n } catch (error: unknown) {\n return getUserInfoErrorHandler(error);\n }\n };\n\nconst getUserInfoErrorHandler = (error: unknown) => {\n // https://open.dingtalk.com/document/personalapp/error-code-2#title-m5s-krt-vds\n if (error instanceof HTTPError) {\n const { statusCode, body: rawBody } = error.response;\n\n if (statusCode === 400) {\n throw new ConnectorError(ConnectorErrorCodes.SocialAccessTokenInvalid);\n }\n\n throw new ConnectorError(ConnectorErrorCodes.General, JSON.stringify(rawBody));\n }\n\n throw error;\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 createDingtalkConnector: CreateConnector<SocialConnector> = async ({ getConfig }) => {\n return {\n metadata: defaultMetadata,\n type: ConnectorType.Social,\n configGuard: dingtalkConfigGuard,\n getAuthorizationUri: getAuthorizationUri(getConfig),\n getUserInfo: getUserInfo(getConfig),\n };\n};\n\nexport default createDingtalkConnector;\n","import type { ConnectorMetadata } from '@logto/connector-kit';\nimport { ConnectorConfigFormItemType, ConnectorPlatform } from '@logto/connector-kit';\n\n// https://open.dingtalk.com/document/orgapp-server/use-dingtalk-account-to-log-on-to-third-party-websites-1\nexport const authorizationEndpoint = 'https://login.dingtalk.com/oauth2/auth';\n// https://open.dingtalk.com/document/isvapp/obtain-user-token\nexport const accessTokenEndpoint = 'https://api.dingtalk.com/v1.0/oauth2/userAccessToken';\n// https://open.dingtalk.com/document/isvapp/dingtalk-retrieve-user-information\n// To obtain the current authorized person's information, the unionId parameter can be set to \"me\".\nexport const userInfoEndpoint = 'https://api.dingtalk.com/v1.0/contact/users/me';\nexport const scope = 'openid';\n\nexport const defaultMetadata: ConnectorMetadata = {\n id: 'dingtalk-web',\n target: 'dingtalk',\n platform: ConnectorPlatform.Web,\n name: {\n en: 'DingTalk',\n 'zh-CN': '钉钉',\n 'tr-TR': 'DingTalk',\n ko: 'DingTalk',\n },\n logo: './logo.svg',\n logoDark: null,\n description: {\n en: 'DingTalk is an enterprise-level intelligent mobile office platform launched by Alibaba Group.',\n 'zh-CN': '钉钉是一个由阿里巴巴集团推出的企业级智能移动办公平台。',\n 'tr-TR':\n 'DingTalk, Alibaba Grubu tarafından piyasaya sürülen kurumsal düzeyde akıllı mobil ofis platformudur.',\n ko: '딩톡은 알리바바 그룹이 출시한 기업용 지능형 모바일 오피스 플랫폼입니다.',\n },\n readme: './README.md',\n formItems: [\n {\n key: 'clientId',\n label: 'Client ID',\n required: true,\n type: ConnectorConfigFormItemType.Text,\n placeholder: '<client-id>',\n },\n {\n key: 'clientSecret',\n label: 'Client Secret',\n required: true,\n type: ConnectorConfigFormItemType.Text,\n placeholder: '<client-secret>',\n },\n {\n key: 'scope',\n type: ConnectorConfigFormItemType.Text,\n label: 'Scope',\n required: false,\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 { z } from 'zod';\n\nexport const dingtalkConfigGuard = z.object({\n clientId: z.string(),\n clientSecret: z.string(),\n scope: z.string().optional(),\n});\n\nexport type DingtalkConfig = z.infer<typeof dingtalkConfigGuard>;\n\nexport const accessTokenResponseGuard = z.object({\n accessToken: z.string(),\n refreshToken: z.string().optional(),\n expireIn: z.number().optional(), // In seconds\n corpId: z.string().optional(),\n});\n\n// https://open.dingtalk.com/document/isvapp/dingtalk-retrieve-user-information\nexport const userInfoResponseGuard = z.object({\n nick: z.string().optional(),\n avatarUrl: z.string().optional(),\n mobile: z.string().optional(),\n openId: z.string().optional(), // DingTalk no longer recommends using OpenId for integration. Instead, use unionId.\n unionId: z.string(),\n email: z.string().optional(),\n stateCode: z.string().optional(),\n});\n\nexport type UserInfoResponse = z.infer<typeof userInfoResponseGuard>;\n\nexport type UserInfoResponseMessageParser = (userInfo: Partial<UserInfoResponse>) => void;\n\nexport const authResponseGuard = z.object({ code: z.string() });\n"],"mappings":"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","names":["scope"]}
package/package.json CHANGED
@@ -1,36 +1,31 @@
1
1
  {
2
2
  "name": "@logto/connector-dingtalk-web",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "Dingtalk web connector implementation.",
5
5
  "dependencies": {
6
- "@logto/connector-kit": "^4.0.0",
6
+ "@logto/connector-kit": "^4.1.1",
7
7
  "@silverhand/essentials": "^2.9.1",
8
8
  "dayjs": "^1.10.5",
9
9
  "got": "^14.0.0",
10
10
  "iconv-lite": "^0.6.3",
11
- "snakecase-keys": "^8.0.0",
12
- "zod": "^3.22.4"
11
+ "snakecase-keys": "^8.0.1",
12
+ "zod": "^3.23.8"
13
13
  },
14
14
  "devDependencies": {
15
- "@rollup/plugin-commonjs": "^26.0.0",
16
- "@rollup/plugin-json": "^6.1.0",
17
- "@rollup/plugin-node-resolve": "^15.2.3",
18
- "@rollup/plugin-typescript": "^11.1.6",
19
15
  "@shopify/jest-koa-mocks": "^5.0.0",
20
16
  "@silverhand/eslint-config": "6.0.1",
21
17
  "@silverhand/ts-config": "6.0.0",
22
18
  "@types/node": "^20.11.20",
23
19
  "@types/supertest": "^6.0.2",
24
- "@vitest/coverage-v8": "^1.4.0",
20
+ "@vitest/coverage-v8": "^2.1.9",
25
21
  "eslint": "^8.56.0",
26
22
  "lint-staged": "^15.0.2",
27
23
  "nock": "^13.3.1",
28
24
  "prettier": "^3.0.0",
29
- "rollup": "^4.12.0",
30
- "rollup-plugin-output-size": "^1.3.0",
31
25
  "supertest": "^7.0.0",
32
- "typescript": "^5.3.3",
33
- "vitest": "^1.4.0"
26
+ "tsup": "^8.3.0",
27
+ "typescript": "^5.5.3",
28
+ "vitest": "^2.1.9"
34
29
  },
35
30
  "main": "./lib/index.js",
36
31
  "module": "./lib/index.js",
@@ -64,9 +59,9 @@
64
59
  },
65
60
  "scripts": {
66
61
  "precommit": "lint-staged",
67
- "build:test": "rm -rf lib/ && tsc -p tsconfig.test.json --sourcemap",
68
- "build": "rm -rf lib/ && tsc -p tsconfig.build.json --noEmit && rollup -c",
69
- "dev": "tsc -p tsconfig.build.json --watch --preserveWatchOutput --incremental",
62
+ "check": "tsc --noEmit",
63
+ "build": "tsup",
64
+ "dev": "tsup --watch",
70
65
  "lint": "eslint --ext .ts src",
71
66
  "lint:report": "pnpm lint --format json --output-file report.json",
72
67
  "test": "vitest src",
package/lib/constant.d.ts DELETED
@@ -1,7 +0,0 @@
1
- import type { ConnectorMetadata } from '@logto/connector-kit';
2
- export declare const authorizationEndpoint = "https://login.dingtalk.com/oauth2/auth";
3
- export declare const accessTokenEndpoint = "https://api.dingtalk.com/v1.0/oauth2/userAccessToken";
4
- export declare const userInfoEndpoint = "https://api.dingtalk.com/v1.0/contact/users/me";
5
- export declare const scope = "openid";
6
- export declare const defaultMetadata: ConnectorMetadata;
7
- export declare const defaultTimeout = 5000;
package/lib/index.d.ts DELETED
@@ -1,11 +0,0 @@
1
- /**
2
- * DingTalk OAuth2 Connector
3
- * https://open.dingtalk.com/document/orgapp/obtain-identity-credentials#title-4up-u8w-5ug
4
- */
5
- import type { CreateConnector, SocialConnector } from '@logto/connector-kit';
6
- import type { DingtalkConfig } from './types.js';
7
- export declare const getAccessToken: (code: string, config: DingtalkConfig) => Promise<{
8
- accessToken: string;
9
- }>;
10
- declare const createDingtalkConnector: CreateConnector<SocialConnector>;
11
- export default createDingtalkConnector;
package/lib/mock.d.ts DELETED
@@ -1,5 +0,0 @@
1
- export declare const mockedConfig: {
2
- clientId: string;
3
- clientSecret: string;
4
- scode: string;
5
- };
package/lib/types.d.ts DELETED
@@ -1,65 +0,0 @@
1
- import { z } from 'zod';
2
- export declare const dingtalkConfigGuard: z.ZodObject<{
3
- clientId: z.ZodString;
4
- clientSecret: z.ZodString;
5
- scope: z.ZodOptional<z.ZodString>;
6
- }, "strip", z.ZodTypeAny, {
7
- clientId: string;
8
- clientSecret: string;
9
- scope?: string | undefined;
10
- }, {
11
- clientId: string;
12
- clientSecret: string;
13
- scope?: string | undefined;
14
- }>;
15
- export type DingtalkConfig = z.infer<typeof dingtalkConfigGuard>;
16
- export declare const accessTokenResponseGuard: z.ZodObject<{
17
- accessToken: z.ZodString;
18
- refreshToken: z.ZodOptional<z.ZodString>;
19
- expireIn: z.ZodOptional<z.ZodNumber>;
20
- corpId: z.ZodOptional<z.ZodString>;
21
- }, "strip", z.ZodTypeAny, {
22
- accessToken: string;
23
- refreshToken?: string | undefined;
24
- expireIn?: number | undefined;
25
- corpId?: string | undefined;
26
- }, {
27
- accessToken: string;
28
- refreshToken?: string | undefined;
29
- expireIn?: number | undefined;
30
- corpId?: string | undefined;
31
- }>;
32
- export declare const userInfoResponseGuard: z.ZodObject<{
33
- nick: z.ZodOptional<z.ZodString>;
34
- avatarUrl: z.ZodOptional<z.ZodString>;
35
- mobile: z.ZodOptional<z.ZodString>;
36
- openId: z.ZodOptional<z.ZodString>;
37
- unionId: z.ZodString;
38
- email: z.ZodOptional<z.ZodString>;
39
- stateCode: z.ZodOptional<z.ZodString>;
40
- }, "strip", z.ZodTypeAny, {
41
- unionId: string;
42
- nick?: string | undefined;
43
- avatarUrl?: string | undefined;
44
- mobile?: string | undefined;
45
- openId?: string | undefined;
46
- email?: string | undefined;
47
- stateCode?: string | undefined;
48
- }, {
49
- unionId: string;
50
- nick?: string | undefined;
51
- avatarUrl?: string | undefined;
52
- mobile?: string | undefined;
53
- openId?: string | undefined;
54
- email?: string | undefined;
55
- stateCode?: string | undefined;
56
- }>;
57
- export type UserInfoResponse = z.infer<typeof userInfoResponseGuard>;
58
- export type UserInfoResponseMessageParser = (userInfo: Partial<UserInfoResponse>) => void;
59
- export declare const authResponseGuard: z.ZodObject<{
60
- code: z.ZodString;
61
- }, "strip", z.ZodTypeAny, {
62
- code: string;
63
- }, {
64
- code: string;
65
- }>;