@mitralab.io/sdk-core 0.2.0-beta.0 → 0.2.0-beta.2

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.js CHANGED
@@ -783,24 +783,25 @@ function expectIntegrationTemplate(value, context, errors = defaultSdkCoreErrorF
783
783
  expectIntegrationLoginConfig(template.loginConfig, `${context} loginConfig`, errors);
784
784
  }
785
785
  expectIntegrationRequestConfig(template.requestConfig, `${context} requestConfig`, errors);
786
- expectObjectArray(template.fieldsSchema, `${context} fieldsSchema`, errors).forEach(
787
- (field, position) => {
788
- const fieldContext = `${context} field ${position}`;
789
- if (typeof field.key !== "string") invalidField(fieldContext, "key", errors);
790
- if (typeof field.label !== "string") invalidField(fieldContext, "label", errors);
791
- if (!isOneOf(field.type, ["url", "text", "secret"])) {
792
- invalidField(fieldContext, "type", errors);
793
- }
794
- if (typeof field.required !== "boolean") invalidField(fieldContext, "required", errors);
795
- if (!isNullableString(field.placeholder)) invalidField(fieldContext, "placeholder", errors);
796
- if (!isNullableString(field.default)) invalidField(fieldContext, "default", errors);
797
- }
798
- );
786
+ expectIntegrationFieldsSchema(template.fieldsSchema, `${context} fieldsSchema`, errors);
799
787
  if (!isNullableString(template.documentationUrl)) {
800
788
  invalidField(context, "documentationUrl", errors);
801
789
  }
802
790
  return template;
803
791
  }
792
+ function expectIntegrationFieldsSchema(value, context, errors) {
793
+ expectObjectArray(value, context, errors).forEach((field, position) => {
794
+ const fieldContext = `${context} field ${position}`;
795
+ if (typeof field.key !== "string") invalidField(fieldContext, "key", errors);
796
+ if (typeof field.label !== "string") invalidField(fieldContext, "label", errors);
797
+ if (!isOneOf(field.type, ["url", "text", "secret"])) {
798
+ invalidField(fieldContext, "type", errors);
799
+ }
800
+ if (typeof field.required !== "boolean") invalidField(fieldContext, "required", errors);
801
+ if (!isNullableString(field.placeholder)) invalidField(fieldContext, "placeholder", errors);
802
+ if (!isNullableString(field.default)) invalidField(fieldContext, "default", errors);
803
+ });
804
+ }
804
805
  function expectIntegrationLoginConfig(value, context, errors) {
805
806
  const config = expectObject(value, context, errors);
806
807
  if (!isNullableString(config.url)) invalidField(context, "url", errors);
@@ -847,13 +848,33 @@ function expectIntegrationRequestConfig(value, context, errors) {
847
848
  });
848
849
  }
849
850
  }
851
+ function expectInlineDefinition(config, context, errors) {
852
+ if (hasOwn(config, "fieldsSchemaInline") && config.fieldsSchemaInline !== null) {
853
+ expectIntegrationFieldsSchema(
854
+ config.fieldsSchemaInline,
855
+ `${context} fieldsSchemaInline`,
856
+ errors
857
+ );
858
+ }
859
+ if (hasOwn(config, "requestConfigInline") && config.requestConfigInline !== null) {
860
+ expectIntegrationRequestConfig(
861
+ config.requestConfigInline,
862
+ `${context} requestConfigInline`,
863
+ errors
864
+ );
865
+ }
866
+ if (hasOwn(config, "loginConfigInline") && config.loginConfigInline !== null) {
867
+ expectIntegrationLoginConfig(config.loginConfigInline, `${context} loginConfigInline`, errors);
868
+ }
869
+ }
850
870
  function expectTemplateConfigSummary(value, context, errors = defaultSdkCoreErrorFactory) {
851
871
  const config = expectObject(value, context, errors);
852
872
  if (typeof config.id !== "string") invalidField(context, "id", errors);
853
873
  if (!isNullableString(config.appId)) invalidField(context, "appId", errors);
854
874
  if (!isNullableInteger(config.legacyId)) invalidField(context, "legacyId", errors);
855
- if (typeof config.templateId !== "string") invalidField(context, "templateId", errors);
875
+ if (!isNullableString(config.templateId)) invalidField(context, "templateId", errors);
856
876
  if (typeof config.alias !== "string") invalidField(context, "alias", errors);
877
+ expectInlineDefinition(config, context, errors);
857
878
  if (config.status !== null && !isOneOf(config.status, ["unchecked", "connected", "error"])) {
858
879
  invalidField(context, "status", errors);
859
880
  }
@@ -3608,10 +3629,79 @@ var CoreAgentTaskSession = class {
3608
3629
  }
3609
3630
  }
3610
3631
  };
3632
+
3633
+ // src/apiKeySession.ts
3634
+ var API_KEY_EXCHANGE_PATH = "/api/v1/auth/exchange";
3635
+ function appAccessTokenPath(appId) {
3636
+ return `/api/v1/auth/apps/${encodeURIComponent(appId)}/access-token`;
3637
+ }
3638
+ function decodeTokenPayload(token) {
3639
+ const segment = token.split(".")[1];
3640
+ if (!segment || typeof globalThis.atob !== "function") return null;
3641
+ try {
3642
+ const base64 = segment.replaceAll("-", "+").replaceAll("_", "/");
3643
+ const padded = base64 + "=".repeat((4 - base64.length % 4) % 4);
3644
+ const decoded = JSON.parse(globalThis.atob(padded));
3645
+ if (!decoded || typeof decoded !== "object" || Array.isArray(decoded)) return null;
3646
+ return decoded;
3647
+ } catch {
3648
+ return null;
3649
+ }
3650
+ }
3651
+ function readTokenAppId(token) {
3652
+ const appId = decodeTokenPayload(token)?.app_id;
3653
+ return typeof appId === "string" && appId ? appId : null;
3654
+ }
3655
+ function readTokenExpiry(token) {
3656
+ const exp = decodeTokenPayload(token)?.exp;
3657
+ return typeof exp === "number" && Number.isFinite(exp) ? exp * 1e3 : null;
3658
+ }
3659
+ function tokenAuthorizesApp(token, appId) {
3660
+ const payload = decodeTokenPayload(token);
3661
+ if (!payload) return true;
3662
+ return payload.app_id === appId;
3663
+ }
3664
+ function isWorkspaceSession(token) {
3665
+ const payload = decodeTokenPayload(token);
3666
+ return payload !== null && payload.app_id === void 0;
3667
+ }
3668
+ function readAccessToken(payload, operation, errors) {
3669
+ const token = payload && typeof payload === "object" ? payload.accessToken : void 0;
3670
+ if (typeof token !== "string" || !token.trim()) {
3671
+ throw errors.invalidResponse(`The ${operation} response did not include an access token`);
3672
+ }
3673
+ return token;
3674
+ }
3675
+ async function resolveApiKeyToken(call, appId, apiKey, errors = defaultSdkCoreErrorFactory) {
3676
+ if (!apiKey.trim()) {
3677
+ throw errors.configuration("An api key is required to authenticate with an api key");
3678
+ }
3679
+ if (!appId.trim()) {
3680
+ throw errors.configuration("An app id is required to authenticate with an api key");
3681
+ }
3682
+ const exchanged = readAccessToken(
3683
+ await call(API_KEY_EXCHANGE_PATH, { body: { apiKey } }),
3684
+ "api key exchange",
3685
+ errors
3686
+ );
3687
+ if (tokenAuthorizesApp(exchanged, appId)) return exchanged;
3688
+ if (!isWorkspaceSession(exchanged)) {
3689
+ throw errors.configuration(
3690
+ `This api key belongs to app ${readTokenAppId(exchanged) ?? "unknown"}, not to ${appId}. Create the key for this app, or use a workspace key.`
3691
+ );
3692
+ }
3693
+ return readAccessToken(
3694
+ await call(appAccessTokenPath(appId), { bearer: exchanged }),
3695
+ "app token",
3696
+ errors
3697
+ );
3698
+ }
3611
3699
  export {
3700
+ API_KEY_EXCHANGE_PATH,
3612
3701
  AgentTaskTurnError,
3613
3702
  SdkCoreConfigurationError,
3614
3703
  SdkCoreResponseError,
3704
+ appAccessTokenPath,
3615
3705
  createAgentConnectionsModule,
3616
3706
  createAgentCredentialsModule,
3617
3707
  createAgentTaskSessionManager,
@@ -3647,6 +3737,11 @@ export {
3647
3737
  expectObjectArray,
3648
3738
  expectPage,
3649
3739
  expectStringArray,
3740
+ isWorkspaceSession,
3741
+ readTokenAppId,
3742
+ readTokenExpiry,
3743
+ resolveApiKeyToken,
3650
3744
  toAgentTimelineItem,
3745
+ tokenAuthorizesApp,
3651
3746
  withAgentTaskSessions
3652
3747
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mitralab.io/sdk-core",
3
- "version": "0.2.0-beta.0",
3
+ "version": "0.2.0-beta.2",
4
4
  "description": "Environment-neutral contracts and modules shared by Mitra JavaScript SDKs",
5
5
  "type": "module",
6
6
  "sideEffects": false,