@ones-open/node-sdk 0.0.4-10001.152 → 0.0.4-10114.223
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/dist/index.cjs +67 -3
- package/dist/index.js +67 -3
- package/dist/types/packages/node/event/index.d.ts +2 -0
- package/dist/types/packages/node/event/index.d.ts.map +1 -0
- package/dist/types/packages/node/event/types.d.ts +22 -0
- package/dist/types/packages/node/event/types.d.ts.map +1 -0
- package/dist/types/packages/node/index.d.ts +3 -0
- package/dist/types/packages/node/index.d.ts.map +1 -1
- package/dist/types/packages/node/oauth/index.d.ts +4 -0
- package/dist/types/packages/node/oauth/index.d.ts.map +1 -0
- package/dist/types/packages/node/oauth/types.d.ts +28 -0
- package/dist/types/packages/node/oauth/types.d.ts.map +1 -0
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const
|
|
3
|
+
const node_crypto = require("node:crypto");
|
|
4
4
|
const Fetch = require("axios");
|
|
5
|
+
const lodashEs = require("lodash-es");
|
|
5
6
|
const _sortInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/sort");
|
|
6
7
|
const getONESHostedBaseUrl = () => {
|
|
7
8
|
return process.env.ONES_HOSTED_BASE_URL;
|
|
@@ -12,12 +13,74 @@ const getONESHostedAppID = () => {
|
|
|
12
13
|
const getONESHostedToken = () => {
|
|
13
14
|
return process.env.ONES_HOSTED_TOKEN;
|
|
14
15
|
};
|
|
15
|
-
const index$
|
|
16
|
+
const index$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
16
17
|
__proto__: null,
|
|
17
18
|
getONESHostedAppID,
|
|
18
19
|
getONESHostedBaseUrl,
|
|
19
20
|
getONESHostedToken
|
|
20
21
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
22
|
+
const ASSERTION_TTL_SECONDS = 24 * 60 * 60;
|
|
23
|
+
const ASSERTION_JTI_LENGTH = 16;
|
|
24
|
+
const TOKEN_GRANT_TYPE = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
|
|
25
|
+
const fetch$2 = Fetch.create();
|
|
26
|
+
const buildJWTAssertion = (installationInfo, userID) => {
|
|
27
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
28
|
+
const header = {
|
|
29
|
+
alg: "HS256",
|
|
30
|
+
typ: "JWT"
|
|
31
|
+
};
|
|
32
|
+
const payload = {
|
|
33
|
+
uid: userID,
|
|
34
|
+
rsh: "",
|
|
35
|
+
iss: installationInfo.installation_id,
|
|
36
|
+
sub: installationInfo.installation_id,
|
|
37
|
+
aud: "oauth",
|
|
38
|
+
exp: now + ASSERTION_TTL_SECONDS,
|
|
39
|
+
iat: now,
|
|
40
|
+
jti: node_crypto.randomUUID().replace(/-/g, "").slice(0, ASSERTION_JTI_LENGTH)
|
|
41
|
+
};
|
|
42
|
+
const encodedHeader = Buffer.from(JSON.stringify(header)).toString("base64url");
|
|
43
|
+
const encodedPayload = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
44
|
+
const signingInput = `${encodedHeader}.${encodedPayload}`;
|
|
45
|
+
const signKey = Buffer.from(installationInfo.shared_secret, "base64");
|
|
46
|
+
const signature = node_crypto.createHmac("sha256", signKey).update(signingInput).digest("base64url");
|
|
47
|
+
return `${signingInput}.${signature}`;
|
|
48
|
+
};
|
|
49
|
+
const getAccessTokenByInstallationInfo = async function(installationInfo) {
|
|
50
|
+
let userID = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "";
|
|
51
|
+
const assertion = buildJWTAssertion(installationInfo, userID);
|
|
52
|
+
const tokenURL = new URL("/oauth2/token", installationInfo.ones_base_url);
|
|
53
|
+
const formData = new URLSearchParams();
|
|
54
|
+
formData.set("grant_type", TOKEN_GRANT_TYPE);
|
|
55
|
+
formData.set("client_id", installationInfo.installation_id);
|
|
56
|
+
formData.set("assertion", assertion);
|
|
57
|
+
try {
|
|
58
|
+
const response = await fetch$2.post(tokenURL.toString(), formData.toString(), {
|
|
59
|
+
headers: {
|
|
60
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
const token = response.data;
|
|
64
|
+
if (!token.access_token) {
|
|
65
|
+
throw new Error("failed to get access token: empty access_token in response");
|
|
66
|
+
}
|
|
67
|
+
return token.access_token;
|
|
68
|
+
} catch (error) {
|
|
69
|
+
if (error instanceof Fetch.AxiosError) {
|
|
70
|
+
var _error$response, _error$response$statu, _error$response2, _error$response3;
|
|
71
|
+
const status = (_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.status;
|
|
72
|
+
const statusText = (_error$response$statu = (_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.statusText) !== null && _error$response$statu !== void 0 ? _error$response$statu : "";
|
|
73
|
+
const data = (_error$response3 = error.response) === null || _error$response3 === void 0 ? void 0 : _error$response3.data;
|
|
74
|
+
const responseText = typeof data === "string" ? data : JSON.stringify(data);
|
|
75
|
+
throw new Error(`failed to get access token: ${status !== null && status !== void 0 ? status : "unknown"} ${statusText}, response: ${responseText}`);
|
|
76
|
+
}
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const index$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
81
|
+
__proto__: null,
|
|
82
|
+
getAccessTokenByInstallationInfo
|
|
83
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
21
84
|
var EntityWhereConditionEnum = /* @__PURE__ */ ((EntityWhereConditionEnum2) => {
|
|
22
85
|
EntityWhereConditionEnum2["beginsWith"] = "beginsWith";
|
|
23
86
|
EntityWhereConditionEnum2["between"] = "between";
|
|
@@ -552,5 +615,6 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
552
615
|
object
|
|
553
616
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
554
617
|
exports.ErrorCode = ErrorCode;
|
|
555
|
-
exports.env = index$
|
|
618
|
+
exports.env = index$2;
|
|
619
|
+
exports.oauth = index$1;
|
|
556
620
|
exports.storage = index;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { randomUUID, createHmac } from "node:crypto";
|
|
2
2
|
import Fetch, { AxiosError } from "axios";
|
|
3
|
+
import { isNull, isUndefined, isSymbol, set } from "lodash-es";
|
|
3
4
|
import _sortInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/sort";
|
|
4
5
|
const getONESHostedBaseUrl = () => {
|
|
5
6
|
return process.env.ONES_HOSTED_BASE_URL;
|
|
@@ -10,12 +11,74 @@ const getONESHostedAppID = () => {
|
|
|
10
11
|
const getONESHostedToken = () => {
|
|
11
12
|
return process.env.ONES_HOSTED_TOKEN;
|
|
12
13
|
};
|
|
13
|
-
const index$
|
|
14
|
+
const index$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
14
15
|
__proto__: null,
|
|
15
16
|
getONESHostedAppID,
|
|
16
17
|
getONESHostedBaseUrl,
|
|
17
18
|
getONESHostedToken
|
|
18
19
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
20
|
+
const ASSERTION_TTL_SECONDS = 24 * 60 * 60;
|
|
21
|
+
const ASSERTION_JTI_LENGTH = 16;
|
|
22
|
+
const TOKEN_GRANT_TYPE = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer";
|
|
23
|
+
const fetch$2 = Fetch.create();
|
|
24
|
+
const buildJWTAssertion = (installationInfo, userID) => {
|
|
25
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
26
|
+
const header = {
|
|
27
|
+
alg: "HS256",
|
|
28
|
+
typ: "JWT"
|
|
29
|
+
};
|
|
30
|
+
const payload = {
|
|
31
|
+
uid: userID,
|
|
32
|
+
rsh: "",
|
|
33
|
+
iss: installationInfo.installation_id,
|
|
34
|
+
sub: installationInfo.installation_id,
|
|
35
|
+
aud: "oauth",
|
|
36
|
+
exp: now + ASSERTION_TTL_SECONDS,
|
|
37
|
+
iat: now,
|
|
38
|
+
jti: randomUUID().replace(/-/g, "").slice(0, ASSERTION_JTI_LENGTH)
|
|
39
|
+
};
|
|
40
|
+
const encodedHeader = Buffer.from(JSON.stringify(header)).toString("base64url");
|
|
41
|
+
const encodedPayload = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
42
|
+
const signingInput = `${encodedHeader}.${encodedPayload}`;
|
|
43
|
+
const signKey = Buffer.from(installationInfo.shared_secret, "base64");
|
|
44
|
+
const signature = createHmac("sha256", signKey).update(signingInput).digest("base64url");
|
|
45
|
+
return `${signingInput}.${signature}`;
|
|
46
|
+
};
|
|
47
|
+
const getAccessTokenByInstallationInfo = async function(installationInfo) {
|
|
48
|
+
let userID = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "";
|
|
49
|
+
const assertion = buildJWTAssertion(installationInfo, userID);
|
|
50
|
+
const tokenURL = new URL("/oauth2/token", installationInfo.ones_base_url);
|
|
51
|
+
const formData = new URLSearchParams();
|
|
52
|
+
formData.set("grant_type", TOKEN_GRANT_TYPE);
|
|
53
|
+
formData.set("client_id", installationInfo.installation_id);
|
|
54
|
+
formData.set("assertion", assertion);
|
|
55
|
+
try {
|
|
56
|
+
const response = await fetch$2.post(tokenURL.toString(), formData.toString(), {
|
|
57
|
+
headers: {
|
|
58
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
const token = response.data;
|
|
62
|
+
if (!token.access_token) {
|
|
63
|
+
throw new Error("failed to get access token: empty access_token in response");
|
|
64
|
+
}
|
|
65
|
+
return token.access_token;
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (error instanceof AxiosError) {
|
|
68
|
+
var _error$response, _error$response$statu, _error$response2, _error$response3;
|
|
69
|
+
const status = (_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.status;
|
|
70
|
+
const statusText = (_error$response$statu = (_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.statusText) !== null && _error$response$statu !== void 0 ? _error$response$statu : "";
|
|
71
|
+
const data = (_error$response3 = error.response) === null || _error$response3 === void 0 ? void 0 : _error$response3.data;
|
|
72
|
+
const responseText = typeof data === "string" ? data : JSON.stringify(data);
|
|
73
|
+
throw new Error(`failed to get access token: ${status !== null && status !== void 0 ? status : "unknown"} ${statusText}, response: ${responseText}`);
|
|
74
|
+
}
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const index$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
79
|
+
__proto__: null,
|
|
80
|
+
getAccessTokenByInstallationInfo
|
|
81
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
19
82
|
var EntityWhereConditionEnum = /* @__PURE__ */ ((EntityWhereConditionEnum2) => {
|
|
20
83
|
EntityWhereConditionEnum2["beginsWith"] = "beginsWith";
|
|
21
84
|
EntityWhereConditionEnum2["between"] = "between";
|
|
@@ -551,6 +614,7 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
551
614
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
552
615
|
export {
|
|
553
616
|
ErrorCode,
|
|
554
|
-
index$
|
|
617
|
+
index$2 as env,
|
|
618
|
+
index$1 as oauth,
|
|
555
619
|
index as storage
|
|
556
620
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/packages/node/event/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,SAAS,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description ONES 事件回调 HTTP 请求体
|
|
3
|
+
*/
|
|
4
|
+
export interface EventBody<EventData = unknown> {
|
|
5
|
+
/**
|
|
6
|
+
* @description 事件 ID(在 ONES 实例内唯一)
|
|
7
|
+
*/
|
|
8
|
+
eventID: string;
|
|
9
|
+
/**
|
|
10
|
+
* @description 事件类型(如 ones:project:issue:created)
|
|
11
|
+
*/
|
|
12
|
+
eventType: string;
|
|
13
|
+
/**
|
|
14
|
+
* @description 事件发生时间戳(毫秒)
|
|
15
|
+
*/
|
|
16
|
+
timestamp: number;
|
|
17
|
+
/**
|
|
18
|
+
* @description 事件数据载荷
|
|
19
|
+
*/
|
|
20
|
+
eventData: EventData;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/packages/node/event/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,SAAS,CAAC,SAAS,GAAG,OAAO;IAC5C;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,SAAS,EAAE,SAAS,CAAA;CACrB"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export * as env from '../../packages/strict/env';
|
|
2
|
+
export * as oauth from './oauth';
|
|
2
3
|
export * as storage from './storage';
|
|
4
|
+
export type * from './event';
|
|
3
5
|
export { ErrorCode } from '../../packages/strict/error';
|
|
4
6
|
export type { Entity, EntityBatchSetItem, EntityQuery, EntityListResultData, EntityError, ObjectError, ObjectStoreUploadResult, ObjectStoreDownloadResult, } from './storage';
|
|
7
|
+
export type { InstallationInfo, OAuthClient } from './oauth';
|
|
5
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/packages/node/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,uBAAuB,CAAA;AAC5C,OAAO,KAAK,OAAO,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/packages/node/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,uBAAuB,CAAA;AAC5C,OAAO,KAAK,KAAK,MAAM,SAAS,CAAA;AAChC,OAAO,KAAK,OAAO,MAAM,WAAW,CAAA;AACpC,mBAAmB,SAAS,CAAA;AAE5B,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAEnD,YAAY,EACV,MAAM,EACN,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EACpB,WAAW,EACX,WAAW,EACX,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,WAAW,CAAA;AAClB,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/packages/node/oauth/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAoB,WAAW,EAAE,MAAM,SAAS,CAAA;AAE5D,mBAAmB,SAAS,CAAA;AAiD5B,eAAO,MAAM,gCAAgC,EAAE,WAAW,CAAC,kCAAkC,CAsC1F,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description Installation callback data used for token exchange
|
|
3
|
+
*/
|
|
4
|
+
export interface InstallationInfo {
|
|
5
|
+
/**
|
|
6
|
+
* @description Installation ID of the app
|
|
7
|
+
*/
|
|
8
|
+
installation_id: string;
|
|
9
|
+
/**
|
|
10
|
+
* @description Base64 encoded installation shared secret
|
|
11
|
+
*/
|
|
12
|
+
shared_secret: string;
|
|
13
|
+
/**
|
|
14
|
+
* @description ONES base URL of the installation
|
|
15
|
+
*/
|
|
16
|
+
ones_base_url: string;
|
|
17
|
+
}
|
|
18
|
+
export interface OAuthClient {
|
|
19
|
+
/**
|
|
20
|
+
* @description Exchange installation info for an OAuth access token
|
|
21
|
+
* @param installationInfo Installation callback data
|
|
22
|
+
* @param userID User ID in the installation organization.
|
|
23
|
+
* Empty string means requesting token as the app itself.
|
|
24
|
+
* @returns Access token
|
|
25
|
+
*/
|
|
26
|
+
getAccessTokenByInstallationInfo(installationInfo: InstallationInfo, userID?: string): Promise<string>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/packages/node/oauth/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B;;;;;;OAMG;IACH,gCAAgC,CAC9B,gBAAgB,EAAE,gBAAgB,EAClC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAAA;CACnB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ones-open/node-sdk",
|
|
3
|
-
"version": "0.0.4-
|
|
3
|
+
"version": "0.0.4-10114.223+882c7713",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/lodash-es": "^4.17.12"
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "882c77136f62dec9551760afa8e6cacb066589ba"
|
|
54
54
|
}
|