@stigmer/sdk 0.0.36 → 0.0.39
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/__tests__/config.test.d.ts +2 -0
- package/__tests__/config.test.d.ts.map +1 -0
- package/__tests__/config.test.js +35 -0
- package/__tests__/config.test.js.map +1 -0
- package/__tests__/errors.test.d.ts +2 -0
- package/__tests__/errors.test.d.ts.map +1 -0
- package/__tests__/errors.test.js +125 -0
- package/__tests__/errors.test.js.map +1 -0
- package/__tests__/gen/errors.test.d.ts +2 -0
- package/__tests__/gen/errors.test.d.ts.map +1 -0
- package/__tests__/gen/errors.test.js +97 -0
- package/__tests__/gen/errors.test.js.map +1 -0
- package/__tests__/gen/proto-utils.test.d.ts +2 -0
- package/__tests__/gen/proto-utils.test.d.ts.map +1 -0
- package/__tests__/gen/proto-utils.test.js +45 -0
- package/__tests__/gen/proto-utils.test.js.map +1 -0
- package/__tests__/gen/session-client.test.d.ts +2 -0
- package/__tests__/gen/session-client.test.d.ts.map +1 -0
- package/__tests__/gen/session-client.test.js +148 -0
- package/__tests__/gen/session-client.test.js.map +1 -0
- package/gen/agent.d.ts +4 -0
- package/gen/agent.d.ts.map +1 -1
- package/gen/agent.js +69 -7
- package/gen/agent.js.map +1 -1
- package/gen/agentexecution.d.ts +4 -1
- package/gen/agentexecution.d.ts.map +1 -1
- package/gen/agentexecution.js +55 -6
- package/gen/agentexecution.js.map +1 -1
- package/gen/agentinstance.d.ts +4 -1
- package/gen/agentinstance.d.ts.map +1 -1
- package/gen/agentinstance.js +15 -3
- package/gen/agentinstance.js.map +1 -1
- package/gen/apikey.d.ts +2 -0
- package/gen/apikey.d.ts.map +1 -1
- package/gen/apikey.js +5 -2
- package/gen/apikey.js.map +1 -1
- package/gen/environment.d.ts +8 -0
- package/gen/environment.d.ts.map +1 -1
- package/gen/environment.js +43 -4
- package/gen/environment.js.map +1 -1
- package/gen/executioncontext.d.ts +2 -0
- package/gen/executioncontext.d.ts.map +1 -1
- package/gen/executioncontext.js +11 -4
- package/gen/executioncontext.js.map +1 -1
- package/gen/iampolicy.d.ts +2 -0
- package/gen/iampolicy.d.ts.map +1 -1
- package/gen/iampolicy.js +17 -5
- package/gen/iampolicy.js.map +1 -1
- package/gen/identityaccount.d.ts +2 -0
- package/gen/identityaccount.d.ts.map +1 -1
- package/gen/identityaccount.js +8 -3
- package/gen/identityaccount.js.map +1 -1
- package/gen/identityprovider.d.ts +2 -0
- package/gen/identityprovider.d.ts.map +1 -1
- package/gen/identityprovider.js +5 -2
- package/gen/identityprovider.js.map +1 -1
- package/gen/mcpserver.d.ts +2 -0
- package/gen/mcpserver.d.ts.map +1 -1
- package/gen/mcpserver.js +49 -10
- package/gen/mcpserver.js.map +1 -1
- package/gen/organization.d.ts +2 -0
- package/gen/organization.d.ts.map +1 -1
- package/gen/organization.js +8 -3
- package/gen/organization.js.map +1 -1
- package/gen/project.d.ts +2 -0
- package/gen/project.d.ts.map +1 -1
- package/gen/project.js +7 -3
- package/gen/project.js.map +1 -1
- package/gen/proto-utils.d.ts +6 -0
- package/gen/proto-utils.d.ts.map +1 -0
- package/gen/proto-utils.js +15 -0
- package/gen/proto-utils.js.map +1 -0
- package/gen/session.d.ts +18 -1
- package/gen/session.d.ts.map +1 -1
- package/gen/session.js +62 -3
- package/gen/session.js.map +1 -1
- package/gen/skill.d.ts +4 -1
- package/gen/skill.d.ts.map +1 -1
- package/gen/skill.js +13 -2
- package/gen/skill.js.map +1 -1
- package/gen/workflow.d.ts +2 -0
- package/gen/workflow.d.ts.map +1 -1
- package/gen/workflow.js +53 -6
- package/gen/workflow.js.map +1 -1
- package/gen/workflowexecution.d.ts +2 -0
- package/gen/workflowexecution.d.ts.map +1 -1
- package/gen/workflowexecution.js +11 -3
- package/gen/workflowexecution.js.map +1 -1
- package/gen/workflowinstance.d.ts +3 -1
- package/gen/workflowinstance.d.ts.map +1 -1
- package/gen/workflowinstance.js +7 -3
- package/gen/workflowinstance.js.map +1 -1
- package/github.d.ts +38 -0
- package/github.d.ts.map +1 -0
- package/github.js +51 -0
- package/github.js.map +1 -0
- package/index.d.ts +1 -0
- package/index.d.ts.map +1 -1
- package/index.js +2 -0
- package/index.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/config.test.ts +52 -0
- package/src/__tests__/errors.test.ts +188 -0
- package/src/__tests__/gen/errors.test.ts +138 -0
- package/src/__tests__/gen/proto-utils.test.ts +53 -0
- package/src/__tests__/gen/session-client.test.ts +202 -0
- package/src/gen/agent.ts +65 -8
- package/src/gen/agentexecution.ts +55 -7
- package/src/gen/agentinstance.ts +16 -4
- package/src/gen/apikey.ts +7 -2
- package/src/gen/environment.ts +39 -4
- package/src/gen/executioncontext.ts +14 -4
- package/src/gen/iampolicy.ts +19 -4
- package/src/gen/identityaccount.ts +10 -3
- package/src/gen/identityprovider.ts +7 -2
- package/src/gen/mcpserver.ts +53 -10
- package/src/gen/organization.ts +10 -4
- package/src/gen/project.ts +9 -3
- package/src/gen/proto-utils.ts +15 -0
- package/src/gen/session.ts +82 -4
- package/src/gen/skill.ts +14 -3
- package/src/gen/workflow.ts +54 -6
- package/src/gen/workflowexecution.ts +14 -3
- package/src/gen/workflowinstance.ts +10 -4
- package/src/github.ts +89 -0
- package/src/index.ts +9 -0
- package/src/stigmer.ts +3 -0
- package/stigmer.d.ts +2 -0
- package/stigmer.d.ts.map +1 -1
- package/stigmer.js +3 -0
- package/stigmer.js.map +1 -1
package/github.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { createClient } from "@connectrpc/connect";
|
|
2
|
+
import { create } from "@bufbuild/protobuf";
|
|
3
|
+
import { ExchangeOAuthCodeRequestSchema, GetOAuthAuthorizeUrlRequestSchema, GitHubService, } from "@stigmer/protos/ai/stigmer/platform/github/v1/service_pb";
|
|
4
|
+
import { wrapError } from "./gen/errors";
|
|
5
|
+
/**
|
|
6
|
+
* Client for GitHub OAuth integration.
|
|
7
|
+
*
|
|
8
|
+
* Provides methods to initiate the OAuth flow (get authorize URL) and
|
|
9
|
+
* exchange the authorization code for an access token. The access token
|
|
10
|
+
* is returned to the caller — the backend never persists it.
|
|
11
|
+
*/
|
|
12
|
+
export class GitHubClient {
|
|
13
|
+
github;
|
|
14
|
+
constructor(transport) {
|
|
15
|
+
this.github = createClient(GitHubService, transport);
|
|
16
|
+
}
|
|
17
|
+
/** Get the GitHub OAuth authorize URL to redirect the user to. */
|
|
18
|
+
async getOAuthAuthorizeUrl(params) {
|
|
19
|
+
try {
|
|
20
|
+
const resp = await this.github.getOAuthAuthorizeUrl(create(GetOAuthAuthorizeUrlRequestSchema, {
|
|
21
|
+
redirectUri: params.redirectUri,
|
|
22
|
+
}));
|
|
23
|
+
return {
|
|
24
|
+
authorizeUrl: resp.authorizeUrl,
|
|
25
|
+
state: resp.state,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
throw wrapError(e);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Exchange an OAuth authorization code for an access token. */
|
|
33
|
+
async exchangeOAuthCode(params) {
|
|
34
|
+
try {
|
|
35
|
+
const resp = await this.github.exchangeOAuthCode(create(ExchangeOAuthCodeRequestSchema, {
|
|
36
|
+
code: params.code,
|
|
37
|
+
state: params.state,
|
|
38
|
+
redirectUri: params.redirectUri,
|
|
39
|
+
}));
|
|
40
|
+
return {
|
|
41
|
+
accessToken: resp.accessToken,
|
|
42
|
+
tokenType: resp.tokenType,
|
|
43
|
+
scope: resp.scope,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
throw wrapError(e);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=github.js.map
|
package/github.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA+B,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EACL,8BAA8B,EAC9B,iCAAiC,EACjC,aAAa,GACd,MAAM,0DAA0D,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AA2BzC;;;;;;GAMG;AACH,MAAM,OAAO,YAAY;IACN,MAAM,CAA+B;IAEtD,YAAY,SAAoB;QAC9B,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IACvD,CAAC;IAED,kEAAkE;IAClE,KAAK,CAAC,oBAAoB,CACxB,MAAkC;QAElC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,oBAAoB,CACjD,MAAM,CAAC,iCAAiC,EAAE;gBACxC,WAAW,EAAE,MAAM,CAAC,WAAW;aAChC,CAAC,CACH,CAAC;YACF,OAAO;gBACL,YAAY,EAAE,IAAI,CAAC,YAAY;gBAC/B,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,gEAAgE;IAChE,KAAK,CAAC,iBAAiB,CACrB,MAA+B;QAE/B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAC9C,MAAM,CAAC,8BAA8B,EAAE;gBACrC,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,WAAW,EAAE,MAAM,CAAC,WAAW;aAChC,CAAC,CACH,CAAC;YACF,OAAO;gBACL,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;CACF"}
|
package/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { Stigmer } from "./stigmer";
|
|
|
2
2
|
export { type StigmerConfig, type TokenProvider } from "./config";
|
|
3
3
|
export { StigmerError, type ErrorCode, isNotFound, isUnauthenticated, isPermissionDenied, isRetryable, type ErrorCategory, isConnectError, classifyError, isRetryableError, getUserMessage, type RpcErrorMetadata, annotateRpcError, getRpcMetadata, } from "./errors";
|
|
4
4
|
export { SearchClient, type SearchParams, type SearchResponse, ApiResourceKind, } from "./search";
|
|
5
|
+
export { GitHubClient, type GetOAuthAuthorizeUrlParams, type OAuthAuthorizeUrlResponse, type ExchangeOAuthCodeParams, type OAuthTokenResponse, } from "./github";
|
|
5
6
|
export { type DeleteResourceInput, type ResourceRef, type Page, type ListParams, type ListResult, type EnvSpecInput, type EnvVarInput, } from "./gen/types";
|
|
6
7
|
export { AgentClient, type AgentInput, type McpServerUsageInput, type ToolApprovalOverrideInput, type SubAgentInput, type McpAccessInput, } from "./gen/agent";
|
|
7
8
|
export { AgentExecutionClient, type AgentExecutionInput, type ExecutionConfigInput, type ContextManagementConfigInput, type AttachmentInput, } from "./gen/agentexecution";
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAGlE,OAAO,EACL,YAAY,EACZ,KAAK,SAAS,EACd,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EACX,KAAK,aAAa,EAClB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,KAAK,gBAAgB,EACrB,gBAAgB,EAChB,cAAc,GACf,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,YAAY,EACZ,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,eAAe,GAChB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,IAAI,EACT,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,WAAW,GACjB,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,WAAW,EACX,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,aAAa,EAClB,KAAK,cAAc,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,4BAA4B,EACjC,KAAK,eAAe,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,mBAAmB,EACnB,KAAK,kBAAkB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,iBAAiB,EACjB,KAAK,gBAAgB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,sBAAsB,EACtB,KAAK,qBAAqB,GAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,mBAAmB,GACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,qBAAqB,EACrB,KAAK,oBAAoB,GAC1B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,sBAAsB,EACtB,KAAK,qBAAqB,GAC3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,GAC7B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,kBAAkB,EAClB,KAAK,iBAAiB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EACL,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,GAC1B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EACL,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,uBAAuB,EACvB,KAAK,sBAAsB,GAC5B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,sBAAsB,EACtB,KAAK,qBAAqB,GAC3B,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/index.js
CHANGED
|
@@ -5,6 +5,8 @@ export { Stigmer } from "./stigmer";
|
|
|
5
5
|
export { StigmerError, isNotFound, isUnauthenticated, isPermissionDenied, isRetryable, isConnectError, classifyError, isRetryableError, getUserMessage, annotateRpcError, getRpcMetadata, } from "./errors";
|
|
6
6
|
// Search client
|
|
7
7
|
export { SearchClient, ApiResourceKind, } from "./search";
|
|
8
|
+
// GitHub OAuth client
|
|
9
|
+
export { GitHubClient, } from "./github";
|
|
8
10
|
// Re-export all resource client classes and input types
|
|
9
11
|
export { AgentClient, } from "./gen/agent";
|
|
10
12
|
export { AgentExecutionClient, } from "./gen/agentexecution";
|
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,mBAAmB;AACnB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,iBAAiB;AACjB,OAAO,EACL,YAAY,EAEZ,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EAEX,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,cAAc,EAEd,gBAAgB,EAChB,cAAc,GACf,MAAM,UAAU,CAAC;AAElB,gBAAgB;AAChB,OAAO,EACL,YAAY,EAGZ,eAAe,GAChB,MAAM,UAAU,CAAC;AAalB,wDAAwD;AACxD,OAAO,EACL,WAAW,GAMZ,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,oBAAoB,GAKrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,mBAAmB,GAEpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAoB,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,iBAAiB,GAElB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,sBAAsB,GAEvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,eAAe,GAGhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,qBAAqB,GAEtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,sBAAsB,GAEvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,eAAe,GAKhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,kBAAkB,GAEnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAqB,MAAM,eAAe,CAAC;AACjE,OAAO,EACL,aAAa,GAMd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,WAAW,EAAmB,MAAM,aAAa,CAAC;AAC3D,OAAO,EACL,cAAc,GAMf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,uBAAuB,GAExB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,sBAAsB,GAEvB,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,mBAAmB;AACnB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,iBAAiB;AACjB,OAAO,EACL,YAAY,EAEZ,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EAEX,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,cAAc,EAEd,gBAAgB,EAChB,cAAc,GACf,MAAM,UAAU,CAAC;AAElB,gBAAgB;AAChB,OAAO,EACL,YAAY,EAGZ,eAAe,GAChB,MAAM,UAAU,CAAC;AAElB,sBAAsB;AACtB,OAAO,EACL,YAAY,GAKb,MAAM,UAAU,CAAC;AAalB,wDAAwD;AACxD,OAAO,EACL,WAAW,GAMZ,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,oBAAoB,GAKrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,mBAAmB,GAEpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAoB,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,iBAAiB,GAElB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,sBAAsB,GAEvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,eAAe,GAGhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,qBAAqB,GAEtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,sBAAsB,GAEvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,eAAe,GAKhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,kBAAkB,GAEnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAqB,MAAM,eAAe,CAAC;AACjE,OAAO,EACL,aAAa,GAMd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,WAAW,EAAmB,MAAM,aAAa,CAAC;AAC3D,OAAO,EACL,cAAc,GAMf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,uBAAuB,GAExB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,sBAAsB,GAEvB,MAAM,wBAAwB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stigmer/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.39",
|
|
4
4
|
"description": "Stigmer TypeScript SDK — typed API client for all Stigmer platform resources",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -35,6 +35,6 @@
|
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
37
|
"@bufbuild/protobuf": "^2.0.0",
|
|
38
|
-
"@stigmer/protos": "0.0.
|
|
38
|
+
"@stigmer/protos": "0.0.39"
|
|
39
39
|
}
|
|
40
40
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { validateConfig, type StigmerConfig } from "../config";
|
|
3
|
+
|
|
4
|
+
describe("validateConfig", () => {
|
|
5
|
+
const validApiKeyConfig: StigmerConfig = {
|
|
6
|
+
baseUrl: "https://api.stigmer.io",
|
|
7
|
+
apiKey: "sk_live_abc123",
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const validTokenProviderConfig: StigmerConfig = {
|
|
11
|
+
baseUrl: "https://api.stigmer.io",
|
|
12
|
+
getAccessToken: () => "token",
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
it("accepts a valid config with apiKey", () => {
|
|
16
|
+
expect(() => validateConfig(validApiKeyConfig)).not.toThrow();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("accepts a valid config with getAccessToken", () => {
|
|
20
|
+
expect(() => validateConfig(validTokenProviderConfig)).not.toThrow();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("rejects missing baseUrl", () => {
|
|
24
|
+
expect(() =>
|
|
25
|
+
validateConfig({ baseUrl: "", apiKey: "key" }),
|
|
26
|
+
).toThrow("stigmer: baseUrl is required");
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("rejects missing both apiKey and getAccessToken", () => {
|
|
30
|
+
expect(() =>
|
|
31
|
+
validateConfig({ baseUrl: "https://api.stigmer.io" }),
|
|
32
|
+
).toThrow("stigmer: either apiKey or getAccessToken must be provided");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("rejects empty apiKey without getAccessToken", () => {
|
|
36
|
+
expect(() =>
|
|
37
|
+
validateConfig({ baseUrl: "https://api.stigmer.io", apiKey: "" }),
|
|
38
|
+
).toThrow("stigmer: either apiKey or getAccessToken must be provided");
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("rejects providing both apiKey and getAccessToken", () => {
|
|
42
|
+
expect(() =>
|
|
43
|
+
validateConfig({
|
|
44
|
+
baseUrl: "https://api.stigmer.io",
|
|
45
|
+
apiKey: "sk_live_abc123",
|
|
46
|
+
getAccessToken: () => "token",
|
|
47
|
+
}),
|
|
48
|
+
).toThrow(
|
|
49
|
+
"stigmer: apiKey and getAccessToken are mutually exclusive — provide one, not both",
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { ConnectError, Code } from "@connectrpc/connect";
|
|
3
|
+
import { StigmerError, type ErrorCode } from "../gen/errors";
|
|
4
|
+
import {
|
|
5
|
+
classifyError,
|
|
6
|
+
isRetryableError,
|
|
7
|
+
getUserMessage,
|
|
8
|
+
annotateRpcError,
|
|
9
|
+
getRpcMetadata,
|
|
10
|
+
type ErrorCategory,
|
|
11
|
+
} from "../errors";
|
|
12
|
+
|
|
13
|
+
describe("classifyError", () => {
|
|
14
|
+
const stigmerMappings: Array<[string, ErrorCategory]> = [
|
|
15
|
+
["unauthenticated", "auth"],
|
|
16
|
+
["permission-denied", "permission"],
|
|
17
|
+
["not-found", "not-found"],
|
|
18
|
+
["invalid-argument", "validation"],
|
|
19
|
+
["already-exists", "validation"],
|
|
20
|
+
["failed-precondition", "validation"],
|
|
21
|
+
["resource-exhausted", "unavailable"],
|
|
22
|
+
["internal", "server"],
|
|
23
|
+
["unavailable", "unavailable"],
|
|
24
|
+
["cancelled", "cancelled"],
|
|
25
|
+
["unknown", "server"],
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
it.each(stigmerMappings)(
|
|
29
|
+
"maps StigmerError code '%s' to category '%s'",
|
|
30
|
+
(errorCode, expectedCategory) => {
|
|
31
|
+
const result = classifyError(
|
|
32
|
+
new StigmerError(errorCode as ErrorCode, "test", Code.Unknown),
|
|
33
|
+
);
|
|
34
|
+
expect(result).toBe(expectedCategory);
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const connectMappings: Array<[Code, ErrorCategory]> = [
|
|
39
|
+
[Code.Unauthenticated, "auth"],
|
|
40
|
+
[Code.PermissionDenied, "permission"],
|
|
41
|
+
[Code.NotFound, "not-found"],
|
|
42
|
+
[Code.InvalidArgument, "validation"],
|
|
43
|
+
[Code.FailedPrecondition, "validation"],
|
|
44
|
+
[Code.OutOfRange, "validation"],
|
|
45
|
+
[Code.AlreadyExists, "validation"],
|
|
46
|
+
[Code.Aborted, "validation"],
|
|
47
|
+
[Code.Internal, "server"],
|
|
48
|
+
[Code.Unknown, "server"],
|
|
49
|
+
[Code.DataLoss, "server"],
|
|
50
|
+
[Code.Unimplemented, "server"],
|
|
51
|
+
[Code.Unavailable, "unavailable"],
|
|
52
|
+
[Code.DeadlineExceeded, "unavailable"],
|
|
53
|
+
[Code.ResourceExhausted, "unavailable"],
|
|
54
|
+
[Code.Canceled, "cancelled"],
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
it.each(connectMappings)(
|
|
58
|
+
"maps ConnectError code %i to category '%s'",
|
|
59
|
+
(code, expectedCategory) => {
|
|
60
|
+
const result = classifyError(new ConnectError("test", code));
|
|
61
|
+
expect(result).toBe(expectedCategory);
|
|
62
|
+
},
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
it("returns 'unknown' for plain Error", () => {
|
|
66
|
+
expect(classifyError(new Error("random"))).toBe("unknown");
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("returns 'unknown' for string", () => {
|
|
70
|
+
expect(classifyError("just a string")).toBe("unknown");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("returns 'unknown' for null", () => {
|
|
74
|
+
expect(classifyError(null)).toBe("unknown");
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe("isRetryableError", () => {
|
|
79
|
+
it("returns true for 'server' category errors", () => {
|
|
80
|
+
expect(
|
|
81
|
+
isRetryableError(new StigmerError("internal", "boom", Code.Internal)),
|
|
82
|
+
).toBe(true);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("returns true for 'unavailable' category errors", () => {
|
|
86
|
+
expect(
|
|
87
|
+
isRetryableError(
|
|
88
|
+
new StigmerError("unavailable", "down", Code.Unavailable),
|
|
89
|
+
),
|
|
90
|
+
).toBe(true);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("returns false for 'auth' category errors", () => {
|
|
94
|
+
expect(
|
|
95
|
+
isRetryableError(
|
|
96
|
+
new StigmerError("unauthenticated", "bad token", Code.Unauthenticated),
|
|
97
|
+
),
|
|
98
|
+
).toBe(false);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("returns false for 'not-found' category errors", () => {
|
|
102
|
+
expect(
|
|
103
|
+
isRetryableError(
|
|
104
|
+
new StigmerError("not-found", "gone", Code.NotFound),
|
|
105
|
+
),
|
|
106
|
+
).toBe(false);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("returns false for plain Error", () => {
|
|
110
|
+
expect(isRetryableError(new Error("oops"))).toBe(false);
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe("getUserMessage", () => {
|
|
115
|
+
it("extracts message from StigmerError", () => {
|
|
116
|
+
const err = new StigmerError("not-found", "Agent not found", Code.NotFound);
|
|
117
|
+
expect(getUserMessage(err)).toBe("Agent not found");
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("extracts rawMessage from ConnectError", () => {
|
|
121
|
+
const err = new ConnectError("Agent not found", Code.NotFound);
|
|
122
|
+
expect(getUserMessage(err)).toBe("Agent not found");
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("extracts message from plain Error", () => {
|
|
126
|
+
expect(getUserMessage(new Error("something"))).toBe("something");
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it("extracts message from string", () => {
|
|
130
|
+
expect(getUserMessage("a string error")).toBe("a string error");
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("sanitizes 'no healthy upstream' to readable message", () => {
|
|
134
|
+
const err = new StigmerError(
|
|
135
|
+
"unavailable",
|
|
136
|
+
"no healthy upstream",
|
|
137
|
+
Code.Unavailable,
|
|
138
|
+
);
|
|
139
|
+
expect(getUserMessage(err)).toBe(
|
|
140
|
+
"The server is temporarily unavailable.",
|
|
141
|
+
);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it("sanitizes 'ECONNREFUSED'", () => {
|
|
145
|
+
expect(getUserMessage(new Error("connect ECONNREFUSED 127.0.0.1"))).toBe(
|
|
146
|
+
"Unable to connect to the server.",
|
|
147
|
+
);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("sanitizes 'fetch failed'", () => {
|
|
151
|
+
expect(getUserMessage(new Error("fetch failed"))).toBe(
|
|
152
|
+
"Unable to reach the server. Check your connection.",
|
|
153
|
+
);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("uses category fallback when message is empty", () => {
|
|
157
|
+
const err = new StigmerError("not-found", "", Code.NotFound);
|
|
158
|
+
expect(getUserMessage(err)).toBe("The requested resource was not found.");
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("uses custom fallback when provided and message is empty", () => {
|
|
162
|
+
const err = new StigmerError("not-found", "", Code.NotFound);
|
|
163
|
+
expect(getUserMessage(err, "Custom fallback")).toBe("Custom fallback");
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("uses 'unknown' category fallback for non-SDK errors without message", () => {
|
|
167
|
+
expect(getUserMessage(42)).toBe("An unexpected error occurred.");
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
describe("annotateRpcError / getRpcMetadata", () => {
|
|
172
|
+
it("roundtrips metadata on an error object", () => {
|
|
173
|
+
const err = new Error("test");
|
|
174
|
+
const metadata = { method: "Get", path: "/api/agent" };
|
|
175
|
+
annotateRpcError(err, metadata);
|
|
176
|
+
expect(getRpcMetadata(err)).toEqual(metadata);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it("returns undefined for unannotated errors", () => {
|
|
180
|
+
expect(getRpcMetadata(new Error("no metadata"))).toBeUndefined();
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it("returns undefined for non-object errors", () => {
|
|
184
|
+
expect(getRpcMetadata("string error")).toBeUndefined();
|
|
185
|
+
expect(getRpcMetadata(null)).toBeUndefined();
|
|
186
|
+
expect(getRpcMetadata(42)).toBeUndefined();
|
|
187
|
+
});
|
|
188
|
+
});
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { ConnectError, Code } from "@connectrpc/connect";
|
|
3
|
+
import {
|
|
4
|
+
StigmerError,
|
|
5
|
+
wrapError,
|
|
6
|
+
isNotFound,
|
|
7
|
+
isUnauthenticated,
|
|
8
|
+
isPermissionDenied,
|
|
9
|
+
isRetryable,
|
|
10
|
+
} from "../../gen/errors";
|
|
11
|
+
|
|
12
|
+
describe("StigmerError", () => {
|
|
13
|
+
it("has name 'StigmerError'", () => {
|
|
14
|
+
const err = new StigmerError("not-found", "resource missing", Code.NotFound);
|
|
15
|
+
expect(err.name).toBe("StigmerError");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("inherits from Error", () => {
|
|
19
|
+
const err = new StigmerError("internal", "boom", Code.Internal);
|
|
20
|
+
expect(err).toBeInstanceOf(Error);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("exposes code and connectCode", () => {
|
|
24
|
+
const err = new StigmerError("unauthenticated", "bad token", Code.Unauthenticated);
|
|
25
|
+
expect(err.code).toBe("unauthenticated");
|
|
26
|
+
expect(err.connectCode).toBe(Code.Unauthenticated);
|
|
27
|
+
expect(err.message).toBe("bad token");
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe("wrapError", () => {
|
|
32
|
+
const connectCodeMappings: Array<[Code, string]> = [
|
|
33
|
+
[Code.NotFound, "not-found"],
|
|
34
|
+
[Code.PermissionDenied, "permission-denied"],
|
|
35
|
+
[Code.Unauthenticated, "unauthenticated"],
|
|
36
|
+
[Code.InvalidArgument, "invalid-argument"],
|
|
37
|
+
[Code.AlreadyExists, "already-exists"],
|
|
38
|
+
[Code.ResourceExhausted, "resource-exhausted"],
|
|
39
|
+
[Code.FailedPrecondition, "failed-precondition"],
|
|
40
|
+
[Code.Internal, "internal"],
|
|
41
|
+
[Code.Unavailable, "unavailable"],
|
|
42
|
+
[Code.Canceled, "cancelled"],
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
it.each(connectCodeMappings)(
|
|
46
|
+
"maps ConnectError code %i to ErrorCode '%s'",
|
|
47
|
+
(connectCode, expectedErrorCode) => {
|
|
48
|
+
const connectErr = new ConnectError("test", connectCode);
|
|
49
|
+
const result = wrapError(connectErr);
|
|
50
|
+
expect(result).toBeInstanceOf(StigmerError);
|
|
51
|
+
expect(result.code).toBe(expectedErrorCode);
|
|
52
|
+
},
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
it("maps unmapped ConnectError codes to 'unknown'", () => {
|
|
56
|
+
const connectErr = new ConnectError("test", 0 as unknown as Code);
|
|
57
|
+
const result = wrapError(connectErr);
|
|
58
|
+
expect(result.code).toBe("unknown");
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("passes through StigmerError unchanged", () => {
|
|
62
|
+
const original = new StigmerError("not-found", "gone", Code.NotFound);
|
|
63
|
+
const result = wrapError(original);
|
|
64
|
+
expect(result).toBe(original);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("wraps plain Error as 'unknown'", () => {
|
|
68
|
+
const result = wrapError(new Error("something broke"));
|
|
69
|
+
expect(result).toBeInstanceOf(StigmerError);
|
|
70
|
+
expect(result.code).toBe("unknown");
|
|
71
|
+
expect(result.message).toBe("something broke");
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("wraps string as 'unknown'", () => {
|
|
75
|
+
const result = wrapError("raw string error");
|
|
76
|
+
expect(result).toBeInstanceOf(StigmerError);
|
|
77
|
+
expect(result.code).toBe("unknown");
|
|
78
|
+
expect(result.message).toBe("raw string error");
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe("predicates", () => {
|
|
83
|
+
it("isNotFound returns true for not-found StigmerError", () => {
|
|
84
|
+
expect(isNotFound(new StigmerError("not-found", "x", Code.NotFound))).toBe(true);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("isNotFound returns false for other codes", () => {
|
|
88
|
+
expect(isNotFound(new StigmerError("internal", "x", Code.Internal))).toBe(false);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("isNotFound returns false for non-StigmerError", () => {
|
|
92
|
+
expect(isNotFound(new Error("not found"))).toBe(false);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("isUnauthenticated returns true for unauthenticated StigmerError", () => {
|
|
96
|
+
expect(
|
|
97
|
+
isUnauthenticated(new StigmerError("unauthenticated", "x", Code.Unauthenticated)),
|
|
98
|
+
).toBe(true);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("isUnauthenticated returns false for other codes", () => {
|
|
102
|
+
expect(
|
|
103
|
+
isUnauthenticated(new StigmerError("not-found", "x", Code.NotFound)),
|
|
104
|
+
).toBe(false);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("isPermissionDenied returns true for permission-denied StigmerError", () => {
|
|
108
|
+
expect(
|
|
109
|
+
isPermissionDenied(
|
|
110
|
+
new StigmerError("permission-denied", "x", Code.PermissionDenied),
|
|
111
|
+
),
|
|
112
|
+
).toBe(true);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("isPermissionDenied returns false for other codes", () => {
|
|
116
|
+
expect(
|
|
117
|
+
isPermissionDenied(new StigmerError("internal", "x", Code.Internal)),
|
|
118
|
+
).toBe(false);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("isRetryable returns true for internal", () => {
|
|
122
|
+
expect(isRetryable(new StigmerError("internal", "x", Code.Internal))).toBe(true);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it("isRetryable returns true for unavailable", () => {
|
|
126
|
+
expect(isRetryable(new StigmerError("unavailable", "x", Code.Unavailable))).toBe(
|
|
127
|
+
true,
|
|
128
|
+
);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it("isRetryable returns false for not-found", () => {
|
|
132
|
+
expect(isRetryable(new StigmerError("not-found", "x", Code.NotFound))).toBe(false);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("isRetryable returns false for non-StigmerError", () => {
|
|
136
|
+
expect(isRetryable(new Error("server error"))).toBe(false);
|
|
137
|
+
});
|
|
138
|
+
});
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { stripUndefined } from "../../gen/proto-utils";
|
|
3
|
+
|
|
4
|
+
describe("stripUndefined", () => {
|
|
5
|
+
it("removes keys with undefined values", () => {
|
|
6
|
+
const result = stripUndefined({ a: 1, b: undefined, c: "hello" });
|
|
7
|
+
expect(result).toEqual({ a: 1, c: "hello" });
|
|
8
|
+
expect("b" in result).toBe(false);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("preserves null values (falsy but defined)", () => {
|
|
12
|
+
const result = stripUndefined({ a: null });
|
|
13
|
+
expect(result).toEqual({ a: null });
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("preserves 0 (falsy but defined)", () => {
|
|
17
|
+
const result = stripUndefined({ count: 0 });
|
|
18
|
+
expect(result).toEqual({ count: 0 });
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("preserves empty string (falsy but defined)", () => {
|
|
22
|
+
const result = stripUndefined({ name: "" });
|
|
23
|
+
expect(result).toEqual({ name: "" });
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("preserves false (falsy but defined)", () => {
|
|
27
|
+
const result = stripUndefined({ enabled: false });
|
|
28
|
+
expect(result).toEqual({ enabled: false });
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("returns empty object when all values are undefined", () => {
|
|
32
|
+
const result = stripUndefined({ a: undefined, b: undefined });
|
|
33
|
+
expect(result).toEqual({});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("returns all keys when nothing is undefined", () => {
|
|
37
|
+
const input = { x: 1, y: "two", z: true };
|
|
38
|
+
const result = stripUndefined(input);
|
|
39
|
+
expect(result).toEqual(input);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("preserves nested objects without deep-stripping", () => {
|
|
43
|
+
const nested = { inner: undefined };
|
|
44
|
+
const result = stripUndefined({ outer: nested });
|
|
45
|
+
expect(result).toEqual({ outer: nested });
|
|
46
|
+
expect((result as Record<string, unknown>).outer).toBe(nested);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("returns empty object for empty input", () => {
|
|
50
|
+
const result = stripUndefined({});
|
|
51
|
+
expect(result).toEqual({});
|
|
52
|
+
});
|
|
53
|
+
});
|