@slates/provider 1.0.0-rc.2 → 1.0.0-rc.21
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 +2885 -2
- package/dist/index.d.cts +1019 -0
- package/dist/index.d.ts +1019 -9
- package/dist/index.module.js +2775 -2
- package/package.json +9 -6
- package/src/action/action.ts +92 -4
- package/src/action/attachment.ts +87 -0
- package/src/action/builder.test.ts +136 -0
- package/src/action/builder.ts +113 -15
- package/src/action/directUpload.test.ts +70 -0
- package/src/action/directUpload.ts +105 -0
- package/src/action/getFileUrlTool.ts +41 -0
- package/src/action/index.ts +4 -2
- package/src/action/publicTool.ts +36 -0
- package/src/action/scopes.test.ts +76 -0
- package/src/action/scopes.ts +103 -0
- package/src/action/tool.ts +22 -6
- package/src/action/trigger.ts +19 -11
- package/src/adapter/adapter.ts +38 -0
- package/src/adapter/index.test.ts +322 -0
- package/src/adapter/index.ts +2 -0
- package/src/adapter/spec.ts +154 -0
- package/src/auth/auth.ts +3 -3
- package/src/auth/index.ts +2 -0
- package/src/auth/oauth.test.ts +83 -0
- package/src/auth/oauth.ts +150 -0
- package/src/auth/redact.test.ts +103 -0
- package/src/auth/redact.ts +111 -0
- package/src/auth/types.ts +72 -13
- package/src/axios/http.test.ts +83 -0
- package/src/axios/index.ts +116 -10
- package/src/axios/trace.test.ts +377 -0
- package/src/axios/trace.ts +803 -0
- package/src/config/config.ts +14 -3
- package/src/context/context.ts +264 -17
- package/src/context/hook.test.ts +46 -0
- package/src/context/hook.ts +15 -6
- package/src/context/index.ts +1 -0
- package/src/context/pQueue.ts +4 -0
- package/src/crypto/hmac.test.ts +40 -0
- package/src/crypto/hmac.ts +32 -0
- package/src/crypto/index.ts +1 -0
- package/src/docs.ts +22 -0
- package/src/error/api.test.ts +114 -0
- package/src/error/api.ts +236 -0
- package/src/error/axios.ts +220 -0
- package/src/error/base.test.ts +178 -0
- package/src/error/base.ts +108 -2
- package/src/error/declaration.ts +7 -2
- package/src/error/defaults.ts +50 -0
- package/src/error/index.ts +4 -0
- package/src/error/service.ts +170 -0
- package/src/error/types.ts +75 -0
- package/src/error/utils.ts +157 -0
- package/src/file/index.test.ts +36 -0
- package/src/file/index.ts +27 -0
- package/src/index.ts +8 -0
- package/src/logger/logger.test.ts +57 -0
- package/src/logger/logger.ts +72 -11
- package/src/module/resolveDefaultExport.test.ts +32 -0
- package/src/module/resolveDefaultExport.ts +14 -0
- package/src/object/index.test.ts +38 -0
- package/src/object/index.ts +12 -0
- package/src/specification/slate.ts +40 -4
- package/src/specification/specification.ts +10 -6
- package/src/webhook/graph.test.ts +37 -0
- package/src/webhook/graph.ts +22 -0
- package/src/webhook/index.ts +2 -0
- package/src/webhook/meta.test.ts +52 -0
- package/src/webhook/meta.ts +43 -0
- package/dist/action/action.d.ts +0 -98
- package/dist/action/action.d.ts.map +0 -1
- package/dist/action/builder.d.ts +0 -27
- package/dist/action/builder.d.ts.map +0 -1
- package/dist/action/index.d.ts +0 -5
- package/dist/action/index.d.ts.map +0 -1
- package/dist/action/tool.d.ts +0 -14
- package/dist/action/tool.d.ts.map +0 -1
- package/dist/action/trigger.d.ts +0 -32
- package/dist/action/trigger.d.ts.map +0 -1
- package/dist/auth/auth.d.ts +0 -30
- package/dist/auth/auth.d.ts.map +0 -1
- package/dist/auth/index.d.ts +0 -3
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/types.d.ts +0 -148
- package/dist/auth/types.d.ts.map +0 -1
- package/dist/axios/index.d.ts +0 -4
- package/dist/axios/index.d.ts.map +0 -1
- package/dist/config/config.d.ts +0 -26
- package/dist/config/config.d.ts.map +0 -1
- package/dist/config/index.d.ts +0 -2
- package/dist/config/index.d.ts.map +0 -1
- package/dist/context/context.d.ts +0 -20
- package/dist/context/context.d.ts.map +0 -1
- package/dist/context/hook.d.ts +0 -4
- package/dist/context/hook.d.ts.map +0 -1
- package/dist/context/index.d.ts +0 -2
- package/dist/context/index.d.ts.map +0 -1
- package/dist/error/base.d.ts +0 -5
- package/dist/error/base.d.ts.map +0 -1
- package/dist/error/declaration.d.ts +0 -6
- package/dist/error/declaration.d.ts.map +0 -1
- package/dist/error/index.d.ts +0 -3
- package/dist/error/index.d.ts.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.modern.js +0 -2
- package/dist/index.modern.js.map +0 -1
- package/dist/index.module.js.map +0 -1
- package/dist/index.umd.js +0 -2
- package/dist/index.umd.js.map +0 -1
- package/dist/logger/index.d.ts +0 -2
- package/dist/logger/index.d.ts.map +0 -1
- package/dist/logger/logger.d.ts +0 -20
- package/dist/logger/logger.d.ts.map +0 -1
- package/dist/specification/index.d.ts +0 -3
- package/dist/specification/index.d.ts.map +0 -1
- package/dist/specification/slate.d.ts +0 -15
- package/dist/specification/slate.d.ts.map +0 -1
- package/dist/specification/specification.d.ts +0 -30
- package/dist/specification/specification.d.ts.map +0 -1
- package/dist/specification/zero.d.ts +0 -13
- package/dist/specification/zero.d.ts.map +0 -1
- package/dist/tokens.d.ts +0 -34
- package/dist/tokens.d.ts.map +0 -1
package/dist/index.module.js
CHANGED
|
@@ -1,2 +1,2775 @@
|
|
|
1
|
-
import t from"axios";import{AsyncLocalStorage as e}from"async_hooks";import{encode as n}from"@toon-format/toon";import r from"zod";function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=Array(e);n<e;n++)r[n]=t[n];return r}function o(t,e){if(!{}.hasOwnProperty.call(t,e))throw new TypeError("attempted to use private field on non-instance");return t}var u=0;function a(t){return"__private_"+u+++"_"+t}function c(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,d(r.key),r)}}function s(t,e,n){return e&&c(t.prototype,e),n&&c(t,n),Object.defineProperty(t,"prototype",{writable:!1}),t}function h(){return h=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)({}).hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t},h.apply(null,arguments)}function f(t){return f=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},f(t)}function l(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,g(t,e)}function p(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(p=function(){return!!t})()}function g(t,e){return g=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},g(t,e)}function d(t){var e=function(t){if("object"!=typeof t||!t)return t;var e=t[Symbol.toPrimitive];if(void 0!==e){var n=e.call(t,"string");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)}(t);return"symbol"==typeof e?e:e+""}function y(t){var e="function"==typeof Map?new Map:void 0;return y=function(t){if(null===t||!function(t){try{return-1!==Function.toString.call(t).indexOf("[native code]")}catch(e){return"function"==typeof t}}(t))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==e){if(e.has(t))return e.get(t);e.set(t,n)}function n(){return function(t,e,n){if(p())return Reflect.construct.apply(null,arguments);var r=[null];r.push.apply(r,e);var i=new(t.bind.apply(t,r));return n&&g(i,n.prototype),i}(t,arguments,f(this).constructor)}return n.prototype=Object.create(t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),g(n,t)},y(t)}var v=/*#__PURE__*/function(){return s(function(t,e,n,r,i){this.type=void 0,this._spec=void 0,this._inputSchema=void 0,this._outputSchema=void 0,this._params=void 0,this.type=t,this._spec=e,this._inputSchema=n,this._outputSchema=r,this._params=i},[{key:"configSchema",get:function(){return this._spec.configSchema}},{key:"inputSchema",get:function(){return this._inputSchema}},{key:"outputSchema",get:function(){return this._outputSchema}},{key:"parameters",get:function(){return this._params}},{key:"key",get:function(){return this._params.key}},{key:"name",get:function(){return this._params.name}},{key:"description",get:function(){return this._params.description}},{key:"tags",get:function(){return this._params.tags}},{key:"instructions",get:function(){return this._params.instructions}},{key:"constraints",get:function(){return this._params.constraints}},{key:"metadata",get:function(){return this._params.metadata}}])}(),b=/*#__PURE__*/function(t){function e(e){var n;return(n=t.call(this,e)||this).name="SlateError",n}return l(e,t),e.is=function(t){return t instanceof e},e}(/*#__PURE__*/y(Error)),m=/*#__PURE__*/function(t){function e(e){var n;return(n=t.call(this,"[Declaration Error]: "+e)||this).name="SlateError.DeclarationError",n}return l(e,t),e.is=function(t){return t instanceof e},e}(b),w=/*#__PURE__*/a("configSchema"),k=/*#__PURE__*/a("authSchema"),O=/*#__PURE__*/a("inputSchema"),_=/*#__PURE__*/a("outputSchema"),S=/*#__PURE__*/a("toolParams"),j=/*#__PURE__*/a("triggerParams"),P=/*#__PURE__*/function(){function t(t,e,n,r){this.type=void 0,this.spec=void 0,this.params=void 0,this.factory=void 0,Object.defineProperty(this,w,{writable:!0,value:void 0}),Object.defineProperty(this,k,{writable:!0,value:void 0}),Object.defineProperty(this,O,{writable:!0,value:null}),Object.defineProperty(this,_,{writable:!0,value:null}),Object.defineProperty(this,S,{writable:!0,value:null}),Object.defineProperty(this,j,{writable:!0,value:null}),this.type=t,this.spec=e,this.params=n,this.factory=r,o(this,w)[w]=e.configSchema,o(this,k)[k]=e.authSchema}var e=t.prototype;return e.input=function(t){return o(this,O)[O]=t,this},e.output=function(t){return o(this,_)[_]=t,this},e.handleInvocation=function(t){if("tool"!==this.type)throw new m("handleInvocation can only be set for tool actions");return o(this,S)[S]={type:"tool",handleInvocation:t},this},e.webhook=function(t){if("trigger"!==this.type)throw new m("handleEvent can only be set for trigger actions");return o(this,j)[j]={type:"trigger",source:"webhook",handleEvent:t.handleEvent,handleRequest:t.handleRequest,autoRegisterWebhook:t.autoRegisterWebhook,autoUnregisterWebhook:t.autoUnregisterWebhook},this},e.polling=function(t){if("trigger"!==this.type)throw new m("handleEvent can only be set for trigger actions");return o(this,j)[j]={type:"trigger",source:"polling",polling:t.options,pollEvents:t.pollEvents,handleEvent:t.handleEvent},this},e.build=function(){if(!o(this,O)[O])throw new m("Input schema is not defined");if(!o(this,_)[_])throw new m("Output schema is not defined");if("tool"===this.type&&!o(this,S)[S])throw new m("Tool invocation handler is not defined");if("trigger"===this.type&&!o(this,j)[j])throw new m("Trigger event handlers are not defined");return this.factory(h({},this.params,{configSchema:o(this,w)[w],authSchema:o(this,k)[k],inputSchema:o(this,O)[O],outputSchema:o(this,_)[_]},o(this,S)[S],o(this,j)[j]))},t}(),E=/*#__PURE__*/a("handleInvocation"),A=/*#__PURE__*/function(t){function e(e,n,r,i){var u;return u=t.call(this,"tool",e,n,r,i)||this,Object.defineProperty(u,E,{writable:!0,value:void 0}),o(u,E)[E]=i.handleInvocation,u}return l(e,t),e.create=function(t,n){return new P("tool",t,n,function(n){if("tool"!=n.type)throw new Error("Invalid action type for tool");return new e(t,n.inputSchema,n.outputSchema,n)})},s(e,[{key:"handleInvocation",get:function(){return o(this,E)[E]}}])}(v),R=function(t,e){return A.create(t,e)},I=600,W=/*#__PURE__*/a("source"),C=/*#__PURE__*/a("polling"),T=/*#__PURE__*/a("handleEvent"),q=/*#__PURE__*/a("handleRequest"),x=/*#__PURE__*/a("pollEvents"),z=/*#__PURE__*/a("autoRegisterWebhook"),U=/*#__PURE__*/a("autoUnregisterWebhook"),D=/*#__PURE__*/function(t){function e(e,n,r,i){var u;return u=t.call(this,"trigger",e,n,r,i)||this,Object.defineProperty(u,W,{writable:!0,value:void 0}),Object.defineProperty(u,C,{writable:!0,value:void 0}),Object.defineProperty(u,T,{writable:!0,value:void 0}),Object.defineProperty(u,q,{writable:!0,value:void 0}),Object.defineProperty(u,x,{writable:!0,value:void 0}),Object.defineProperty(u,z,{writable:!0,value:void 0}),Object.defineProperty(u,U,{writable:!0,value:void 0}),o(u,W)[W]=i.source,o(u,C)[C]=i.polling||{intervalInSeconds:600},o(u,T)[T]=i.handleEvent,o(u,q)[q]=i.handleRequest,o(u,x)[x]=i.pollEvents,o(u,z)[z]=i.autoRegisterWebhook,o(u,U)[U]=i.autoUnregisterWebhook,u}return l(e,t),e.create=function(t,n){return new P("trigger",t,n,function(n){if("trigger"!=n.type)throw new Error("Invalid action type for trigger");return new e(t,n.inputSchema,n.outputSchema,n)})},s(e,[{key:"polling",get:function(){return o(this,C)[C]}},{key:"source",get:function(){return o(this,W)[W]}},{key:"handleEvent",get:function(){return o(this,T)[T]}},{key:"handleRequest",get:function(){return o(this,q)[q]}},{key:"pollEvents",get:function(){return o(this,x)[x]}},{key:"autoRegisterWebhook",get:function(){return o(this,z)[z]}},{key:"autoUnregisterWebhook",get:function(){return o(this,U)[U]}}])}(v),F=function(t,e){return D.create(t,e)},M=/*#__PURE__*/a("outputSchema"),N=/*#__PURE__*/a("authStack"),B=/*#__PURE__*/function(){function t(){Object.defineProperty(this,M,{writable:!0,value:null}),Object.defineProperty(this,N,{writable:!0,value:[]})}t.create=function(){return new t};var e=t.prototype;return e.output=function(t){return o(this,M)[M]=t,this},e.addAuth=function(t){if(o(this,N)[N].map(function(t){return t.key}).includes(t.key))throw new Error('Auth with key "'+t.key+'" already exists in the auth stack');return o(this,N)[N].push(t),this},e.addOauth=function(t){return this.addAuth(t),this},e.addTokenAuth=function(t){return this.addAuth(t),this},e.addServiceAccountAuth=function(t){return this.addAuth(t),this},e.addCustomAuth=function(t){return this.addAuth(t),this},e.addNone=function(){return this.addAuth({type:"auth.none",name:"No Authentication",key:"none"}),this},s(t,[{key:"authStack",get:function(){return o(this,N)[N].filter(function(t){return"auth.none"!=t.type})}},{key:"outputSchema",get:function(){if(!o(this,M)[M])throw new Error("Output schema is not defined for this auth");return o(this,M)[M]}}])}(),$=function(){return B.create()},G=new e,H=function(e){var n=t.create(h({},e,{headers:h({},null==e?void 0:e.headers)}));return n.interceptors.request.use(function(t){var e=function(){var t=G.getStore();if(!t)throw new Error("No Slate context is available");return t}();return t.headers.set("User-Agent","slates.dev@1.0.0/"+e.specification.key),t},function(t){return Promise.reject(t)}),n},J=H(),K=/*#__PURE__*/a("configSchema"),L=/*#__PURE__*/a("configChanged"),Q=/*#__PURE__*/a("getDefaultConfig"),V=/*#__PURE__*/function(){function t(t){Object.defineProperty(this,K,{writable:!0,value:void 0}),Object.defineProperty(this,L,{writable:!0,value:null}),Object.defineProperty(this,Q,{writable:!0,value:null}),o(this,K)[K]=t}t.create=function(e){return new t(e)};var e=t.prototype;return e.config=function(t){return o(this,K)[K]=t,this},e.onConfigChanged=function(t){return o(this,L)[L]=t,this},e.getDefaultConfig=function(t){return o(this,Q)[Q]=t,this},s(t,[{key:"configSchema",get:function(){return o(this,K)[K]}},{key:"handlers",get:function(){return{configChanged:o(this,L)[L],getDefaultConfig:o(this,Q)[Q]}}}])}(),X=function(t){return V.create(t)},Y=/*#__PURE__*/a("config"),Z=/*#__PURE__*/a("input"),tt=/*#__PURE__*/a("auth"),et=/*#__PURE__*/function(){function t(t,e,n,r,i){this.spec=void 0,this.logger=void 0,Object.defineProperty(this,Y,{writable:!0,value:void 0}),Object.defineProperty(this,Z,{writable:!0,value:void 0}),Object.defineProperty(this,tt,{writable:!0,value:void 0}),this.spec=r,this.logger=i,o(this,Y)[Y]=t,o(this,Z)[Z]=e,o(this,tt)[tt]=n}var e=t.prototype;return e.info=function(t){this.logger.info(t)},e.warn=function(t){this.logger.warn(t)},e.error=function(t){this.logger.error(t)},e.progress=function(t){this.logger.progress(t)},s(t,[{key:"specification",get:function(){return this.spec}},{key:"config",get:function(){return Object.freeze(o(this,Y)[Y])}},{key:"input",get:function(){return Object.freeze(o(this,Z)[Z])}},{key:"event",get:function(){return Object.freeze(o(this,Z)[Z])}},{key:"state",get:function(){return Object.freeze(o(this,Z)[Z].state)}},{key:"request",get:function(){return Object.freeze(o(this,Z)[Z].request)}},{key:"auth",get:function(){return Object.freeze(o(this,tt)[tt])}}])}(),nt=function(t){return"object"==typeof t?null===t?"null":t instanceof Error?"[ERROR]: "+t.name+": "+t.message+"\n"+t.stack:n(t):String(t)},rt=/*#__PURE__*/a("logs"),it=/*#__PURE__*/a("listeners"),ot=/*#__PURE__*/a("timer"),ut=/*#__PURE__*/function(){function t(t){var e;void 0===t&&(t=[]),Object.defineProperty(this,rt,{writable:!0,value:[]}),Object.defineProperty(this,it,{writable:!0,value:[]}),Object.defineProperty(this,ot,{writable:!0,value:null}),(e=o(this,it)[it]).push.apply(e,t)}var e=t.prototype;return e.flush=function(){if(o(this,ot)[ot]&&clearTimeout(o(this,ot)[ot]),0!==o(this,rt)[rt].length)for(var t,e=function(t){var e="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(e)return(e=e.call(t)).next.bind(e);if(Array.isArray(t)||(e=function(t,e){if(t){if("string"==typeof t)return i(t,e);var n={}.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?i(t,e):void 0}}(t))){e&&(t=e);var n=0;return function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}(o(this,it)[it]);!(t=e()).done;)(0,t.value)(o(this,rt)[rt])},e.scheduleFlush=function(){var t=this;o(this,ot)[ot]||(o(this,ot)[ot]=setTimeout(function(){t.flush(),o(t,ot)[ot]=null},10))},e.log=function(t,e){o(this,rt)[rt].push({type:t,timestamp:new Date,message:nt(e)}),this.scheduleFlush()},e.info=function(){this.log("info",[].slice.call(arguments).flat())},e.warn=function(){this.log("warn",[].slice.call(arguments).flat())},e.error=function(){this.log("error",[].slice.call(arguments).flat())},e.progress=function(){this.log("progress",[].slice.call(arguments).flat())},t}(),at=/*#__PURE__*/function(){function t(t,e){this._spec=void 0,this._actions=void 0,this._spec=t,this._actions=e}return t.create=function(e){return new t(e.spec,[].concat(e.triggers,e.tools))},s(t,[{key:"spec",get:function(){return this._spec}},{key:"actions",get:function(){return this._actions}}])}(),ct=/*#__PURE__*/function(){function t(t,e,n){this._config=void 0,this._auth=void 0,this._params=void 0,this._config=t,this._auth=e,this._params=n}return t.create=function(e){return new t(e.config,e.auth,e)},s(t,[{key:"configSchema",get:function(){return this._config.configSchema}},{key:"authSchema",get:function(){return"outputSchema"in this._auth?this._auth.outputSchema:r.object({})}},{key:"config",get:function(){return this._config}},{key:"auth",get:function(){return this._auth}},{key:"parameters",get:function(){return this._params}},{key:"key",get:function(){return this._params.key}},{key:"name",get:function(){return this._params.name}},{key:"description",get:function(){return this._params.description}}])}(),st=function(t){return ct.create(t)};export{at as Slate,v as SlateAction,B as SlateAuth,V as SlateConfig,et as SlateContext,m as SlateDeclarationError,I as SlateDefaultPollingIntervalSeconds,b as SlateError,ut as SlateLogger,ct as SlateSpecification,A as SlateTool,D as SlateTrigger,$ as auth,J as axios,X as config,H as createAxios,st as spec,R as tool,F as trigger};
|
|
2
|
-
|
|
1
|
+
// src/action/action.ts
|
|
2
|
+
var SlateAction = class {
|
|
3
|
+
constructor(type, _spec, _inputSchema, _outputSchema, _params) {
|
|
4
|
+
this.type = type;
|
|
5
|
+
this._spec = _spec;
|
|
6
|
+
this._inputSchema = _inputSchema;
|
|
7
|
+
this._outputSchema = _outputSchema;
|
|
8
|
+
this._params = _params;
|
|
9
|
+
}
|
|
10
|
+
type;
|
|
11
|
+
_spec;
|
|
12
|
+
_inputSchema;
|
|
13
|
+
_outputSchema;
|
|
14
|
+
_params;
|
|
15
|
+
get configSchema() {
|
|
16
|
+
return this._spec.configSchema;
|
|
17
|
+
}
|
|
18
|
+
get inputSchema() {
|
|
19
|
+
return this._inputSchema;
|
|
20
|
+
}
|
|
21
|
+
get outputSchema() {
|
|
22
|
+
return this._outputSchema;
|
|
23
|
+
}
|
|
24
|
+
get parameters() {
|
|
25
|
+
return this._params;
|
|
26
|
+
}
|
|
27
|
+
get key() {
|
|
28
|
+
return this._params.key;
|
|
29
|
+
}
|
|
30
|
+
get name() {
|
|
31
|
+
return this._params.name;
|
|
32
|
+
}
|
|
33
|
+
get description() {
|
|
34
|
+
return this._params.description;
|
|
35
|
+
}
|
|
36
|
+
get tags() {
|
|
37
|
+
return this._params.tags;
|
|
38
|
+
}
|
|
39
|
+
get instructions() {
|
|
40
|
+
return this._params.instructions;
|
|
41
|
+
}
|
|
42
|
+
get constraints() {
|
|
43
|
+
return this._params.constraints;
|
|
44
|
+
}
|
|
45
|
+
get metadata() {
|
|
46
|
+
return this._params.metadata;
|
|
47
|
+
}
|
|
48
|
+
get scopes() {
|
|
49
|
+
return this._params.scopes;
|
|
50
|
+
}
|
|
51
|
+
get authMethods() {
|
|
52
|
+
return this._params.authMethods;
|
|
53
|
+
}
|
|
54
|
+
get docs() {
|
|
55
|
+
return this._params.docs;
|
|
56
|
+
}
|
|
57
|
+
get adapter() {
|
|
58
|
+
return this._params.adapter ?? null;
|
|
59
|
+
}
|
|
60
|
+
get isPublic() {
|
|
61
|
+
return this._params.isPublic === true;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// src/error/api.ts
|
|
66
|
+
import { badRequestError, ServiceError } from "@lowerdeck/error";
|
|
67
|
+
var DEFAULT_DETAIL_KEYS = ["message", "detail", "error", "error_description", "code"];
|
|
68
|
+
var DEFAULT_NESTED_KEYS = ["errors"];
|
|
69
|
+
var isApiErrorRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
70
|
+
var pushDetail = (details, value, options = {}) => {
|
|
71
|
+
if (typeof value !== "string" && (options.includeNumbers === false || typeof value !== "number")) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
let detail = String(value).trim();
|
|
75
|
+
if (detail && !details.includes(detail)) {
|
|
76
|
+
details.push(detail);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
var collectApiErrorDetails = (value, details, options = {}) => {
|
|
80
|
+
if (Array.isArray(value)) {
|
|
81
|
+
for (let item of value) {
|
|
82
|
+
collectApiErrorDetails(item, details, options);
|
|
83
|
+
}
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (!isApiErrorRecord(value)) {
|
|
87
|
+
pushDetail(details, value, options);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
for (let key of options.detailKeys ?? DEFAULT_DETAIL_KEYS) {
|
|
91
|
+
pushDetail(details, value[key], options);
|
|
92
|
+
}
|
|
93
|
+
for (let key of options.nestedKeys ?? DEFAULT_NESTED_KEYS) {
|
|
94
|
+
collectApiErrorDetails(value[key], details, options);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
var getSlateErrorResponse = (error) => {
|
|
98
|
+
if (error.name !== "SlateError" || !isApiErrorRecord(error.data)) {
|
|
99
|
+
return void 0;
|
|
100
|
+
}
|
|
101
|
+
let data = error.data;
|
|
102
|
+
let upstream = isApiErrorRecord(data.upstream) ? data.upstream : void 0;
|
|
103
|
+
let status = upstream?.status ?? data.status;
|
|
104
|
+
return typeof status === "number" || typeof status === "string" ? { status } : void 0;
|
|
105
|
+
};
|
|
106
|
+
var getApiErrorResponse = (error) => {
|
|
107
|
+
if (!isApiErrorRecord(error)) {
|
|
108
|
+
return void 0;
|
|
109
|
+
}
|
|
110
|
+
if (!isApiErrorRecord(error.response)) {
|
|
111
|
+
return getSlateErrorResponse(error);
|
|
112
|
+
}
|
|
113
|
+
let response = error.response;
|
|
114
|
+
return {
|
|
115
|
+
status: typeof response.status === "number" || typeof response.status === "string" ? response.status : void 0,
|
|
116
|
+
statusText: typeof response.statusText === "string" ? response.statusText : void 0,
|
|
117
|
+
data: response.data
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
var getApiErrorStatus = (error) => getApiErrorResponse(error)?.status;
|
|
121
|
+
var statusLabelForApiError = (status, statusText) => status !== void 0 ? `HTTP ${status}${statusText ? ` ${statusText}` : ""}: ` : "";
|
|
122
|
+
var extractApiErrorMessage = (error, options = {}) => {
|
|
123
|
+
let details = [];
|
|
124
|
+
let response = options.response ?? getApiErrorResponse(error);
|
|
125
|
+
collectApiErrorDetails(response?.data, details, options);
|
|
126
|
+
if (details.length > 0) {
|
|
127
|
+
return details.join(options.separator ?? " - ");
|
|
128
|
+
}
|
|
129
|
+
if (error instanceof Error && error.message) {
|
|
130
|
+
return error.message;
|
|
131
|
+
}
|
|
132
|
+
return options.fallbackMessage ?? "Unknown error";
|
|
133
|
+
};
|
|
134
|
+
var createApiServiceError = (message, options = {}) => {
|
|
135
|
+
let error = new ServiceError(badRequestError({ message }));
|
|
136
|
+
if (options.reason !== void 0) {
|
|
137
|
+
error.data.reason = options.reason;
|
|
138
|
+
}
|
|
139
|
+
if ("upstreamStatus" in options) {
|
|
140
|
+
error.data.upstreamStatus = options.upstreamStatus;
|
|
141
|
+
}
|
|
142
|
+
if ("upstreamCode" in options) {
|
|
143
|
+
error.data.upstreamCode = options.upstreamCode;
|
|
144
|
+
}
|
|
145
|
+
if (options.parent instanceof Error) {
|
|
146
|
+
error.setParent(options.parent);
|
|
147
|
+
}
|
|
148
|
+
return error;
|
|
149
|
+
};
|
|
150
|
+
var helpers = {
|
|
151
|
+
collectDetails: collectApiErrorDetails,
|
|
152
|
+
extractMessage: extractApiErrorMessage,
|
|
153
|
+
getResponse: getApiErrorResponse,
|
|
154
|
+
getStatus: getApiErrorStatus,
|
|
155
|
+
isRecord: isApiErrorRecord,
|
|
156
|
+
statusLabelFor: statusLabelForApiError
|
|
157
|
+
};
|
|
158
|
+
var buildApiServiceError = (error, options) => {
|
|
159
|
+
if (error instanceof ServiceError) {
|
|
160
|
+
return error;
|
|
161
|
+
}
|
|
162
|
+
let operation = options.operation ?? "request";
|
|
163
|
+
let response = options.extractResponse?.(error, helpers) ?? getApiErrorResponse(error);
|
|
164
|
+
let status = options.extractStatus?.(error, response, helpers) ?? response?.status;
|
|
165
|
+
let message = options.extractMessage?.(error, helpers) ?? extractApiErrorMessage(error, { ...options, response });
|
|
166
|
+
let statusLabel = statusLabelForApiError(status, response?.statusText);
|
|
167
|
+
let fullMessage = options.formatMessage?.({
|
|
168
|
+
providerLabel: options.providerLabel,
|
|
169
|
+
operation,
|
|
170
|
+
statusLabel,
|
|
171
|
+
message,
|
|
172
|
+
response,
|
|
173
|
+
status
|
|
174
|
+
}) ?? `${options.providerLabel} API ${operation} failed: ${statusLabel}${message}`;
|
|
175
|
+
return createApiServiceError(fullMessage, {
|
|
176
|
+
reason: options.reason,
|
|
177
|
+
upstreamStatus: status,
|
|
178
|
+
upstreamCode: options.extractUpstreamCode?.(error, response, helpers),
|
|
179
|
+
parent: options.parent ?? error
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// src/error/axios.ts
|
|
184
|
+
import { isAxiosError } from "axios";
|
|
185
|
+
|
|
186
|
+
// src/context/hook.ts
|
|
187
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
188
|
+
var slateContextStorageKey = /* @__PURE__ */ Symbol.for("slates.provider.context.asyncLocalStorage");
|
|
189
|
+
var globalWithSlateContext = globalThis;
|
|
190
|
+
var asyncLocalStorage = globalWithSlateContext[slateContextStorageKey] ?? new AsyncLocalStorage();
|
|
191
|
+
globalWithSlateContext[slateContextStorageKey] = asyncLocalStorage;
|
|
192
|
+
var runWithContext = (context, fn) => {
|
|
193
|
+
return asyncLocalStorage.run(context, fn);
|
|
194
|
+
};
|
|
195
|
+
var getCurrentContext = () => {
|
|
196
|
+
let context = asyncLocalStorage.getStore();
|
|
197
|
+
if (!context) {
|
|
198
|
+
throw new Error("No Slate context is available");
|
|
199
|
+
}
|
|
200
|
+
return context;
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
// src/error/defaults.ts
|
|
204
|
+
var DEFAULT_CODE = "internal.unexpected";
|
|
205
|
+
var DEFAULT_MESSAGES = {
|
|
206
|
+
"declaration.invalid_definition": "The slate definition is invalid.",
|
|
207
|
+
"context.missing": "No Slate context is available.",
|
|
208
|
+
"input.invalid": "The provided input is invalid.",
|
|
209
|
+
"request.bad": "The request is invalid.",
|
|
210
|
+
"request.invalid_version": "The requested version is invalid.",
|
|
211
|
+
"request.precondition_failed": "The request precondition failed.",
|
|
212
|
+
"request.not_acceptable": "The request is not acceptable.",
|
|
213
|
+
"request.rate_limited": "Too many requests were made in a short period of time.",
|
|
214
|
+
"config.invalid": "The provided configuration is invalid.",
|
|
215
|
+
"auth.required": "Authentication is required.",
|
|
216
|
+
"auth.invalid": "Authentication failed.",
|
|
217
|
+
"auth.expired": "Authentication has expired.",
|
|
218
|
+
"permission.denied": "Permission was denied.",
|
|
219
|
+
"resource.not_found": "The requested resource was not found.",
|
|
220
|
+
"resource.conflict": "The requested resource is in conflict.",
|
|
221
|
+
"resource.gone": "The requested resource is no longer available.",
|
|
222
|
+
"payment.required": "Payment is required to continue.",
|
|
223
|
+
"operation.not_implemented": "The requested operation is not implemented.",
|
|
224
|
+
"upstream.invalid_request": "The upstream service rejected the request.",
|
|
225
|
+
"upstream.rate_limited": "The upstream service rate limited the request.",
|
|
226
|
+
"upstream.timeout": "The upstream service timed out.",
|
|
227
|
+
"upstream.network_error": "A network error occurred while contacting the upstream service.",
|
|
228
|
+
"upstream.unavailable": "The upstream service is unavailable.",
|
|
229
|
+
"upstream.invalid_response": "The upstream service returned an invalid response.",
|
|
230
|
+
"upstream.error": "The upstream service returned an error.",
|
|
231
|
+
"transport.invoke_failed": "The provider transport failed.",
|
|
232
|
+
"internal.timeout": "The operation timed out.",
|
|
233
|
+
"internal.unexpected": "An unexpected internal error occurred."
|
|
234
|
+
};
|
|
235
|
+
var SERVICE_ERROR_CODE_MAP = {
|
|
236
|
+
invalid_data: "input.invalid",
|
|
237
|
+
bad_request: "request.bad",
|
|
238
|
+
not_found: "resource.not_found",
|
|
239
|
+
unauthorized: "auth.required",
|
|
240
|
+
forbidden: "permission.denied",
|
|
241
|
+
invalid_version: "request.invalid_version",
|
|
242
|
+
conflict: "resource.conflict",
|
|
243
|
+
gone: "resource.gone",
|
|
244
|
+
payment_required: "payment.required",
|
|
245
|
+
precondition_failed: "request.precondition_failed",
|
|
246
|
+
not_acceptable: "request.not_acceptable",
|
|
247
|
+
not_implemented: "operation.not_implemented",
|
|
248
|
+
too_many_requests: "request.rate_limited",
|
|
249
|
+
timeout: "internal.timeout",
|
|
250
|
+
internal_server_error: "internal.unexpected"
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
// src/error/utils.ts
|
|
254
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
255
|
+
var normalizeKind = (code, kind) => {
|
|
256
|
+
if (kind) return kind;
|
|
257
|
+
if (code.startsWith("declaration.")) return "declaration";
|
|
258
|
+
if (code.startsWith("input.")) return "validation";
|
|
259
|
+
if (code.startsWith("request.")) return "request";
|
|
260
|
+
if (code.startsWith("config.")) return "config";
|
|
261
|
+
if (code.startsWith("auth.") || code.startsWith("permission.")) return "auth";
|
|
262
|
+
if (code.startsWith("resource.")) return "resource";
|
|
263
|
+
if (code.startsWith("payment.")) return "payment";
|
|
264
|
+
if (code.startsWith("transport.")) return "transport";
|
|
265
|
+
if (code.startsWith("upstream.")) return "upstream";
|
|
266
|
+
return "internal";
|
|
267
|
+
};
|
|
268
|
+
var normalizeStatus = (code, status) => {
|
|
269
|
+
if (status) return status;
|
|
270
|
+
if (code === "input.invalid" || code === "request.bad" || code === "config.invalid")
|
|
271
|
+
return 400;
|
|
272
|
+
if (code === "request.invalid_version") return 400;
|
|
273
|
+
if (code === "auth.required" || code === "auth.invalid" || code === "auth.expired")
|
|
274
|
+
return 401;
|
|
275
|
+
if (code === "payment.required") return 402;
|
|
276
|
+
if (code === "permission.denied") return 403;
|
|
277
|
+
if (code === "resource.not_found") return 404;
|
|
278
|
+
if (code === "resource.conflict") return 409;
|
|
279
|
+
if (code === "resource.gone") return 410;
|
|
280
|
+
if (code === "request.not_acceptable") return 406;
|
|
281
|
+
if (code === "request.precondition_failed") return 412;
|
|
282
|
+
if (code === "request.rate_limited" || code === "upstream.rate_limited") return 429;
|
|
283
|
+
if (code === "operation.not_implemented") return 501;
|
|
284
|
+
if (code === "upstream.invalid_request") return 400;
|
|
285
|
+
if (code === "upstream.timeout" || code === "internal.timeout") return 504;
|
|
286
|
+
if (code === "upstream.unavailable") return 503;
|
|
287
|
+
if (code === "upstream.error") return 502;
|
|
288
|
+
return void 0;
|
|
289
|
+
};
|
|
290
|
+
var normalizeRetryable = (code, retryable) => {
|
|
291
|
+
if (typeof retryable === "boolean") return retryable;
|
|
292
|
+
return code === "request.rate_limited" || code === "upstream.rate_limited" || code === "upstream.timeout" || code === "upstream.network_error" || code === "upstream.unavailable" || code === "upstream.error" || code === "transport.invoke_failed" || code === "internal.timeout";
|
|
293
|
+
};
|
|
294
|
+
var getDefaultMessage = (code, message) => {
|
|
295
|
+
if (message?.trim()) return message;
|
|
296
|
+
return DEFAULT_MESSAGES[code] ?? DEFAULT_MESSAGES[DEFAULT_CODE];
|
|
297
|
+
};
|
|
298
|
+
var cleanRecord = (value) => {
|
|
299
|
+
if (!value) return void 0;
|
|
300
|
+
let entries = Object.entries(value).filter(([, entry]) => entry !== void 0);
|
|
301
|
+
if (entries.length === 0) return void 0;
|
|
302
|
+
return Object.fromEntries(entries);
|
|
303
|
+
};
|
|
304
|
+
var mergeRecords = (left, right) => {
|
|
305
|
+
if (!left && !right) return void 0;
|
|
306
|
+
return cleanRecord({
|
|
307
|
+
...left ?? {},
|
|
308
|
+
...right ?? {}
|
|
309
|
+
});
|
|
310
|
+
};
|
|
311
|
+
var mergeSlateErrorData = (base, override) => {
|
|
312
|
+
if (!override) return base;
|
|
313
|
+
return {
|
|
314
|
+
...base,
|
|
315
|
+
...override,
|
|
316
|
+
provider: cleanRecord({
|
|
317
|
+
...base.provider ?? {},
|
|
318
|
+
...override.provider ?? {}
|
|
319
|
+
}),
|
|
320
|
+
upstream: cleanRecord({
|
|
321
|
+
...base.upstream ?? {},
|
|
322
|
+
...override.upstream ?? {}
|
|
323
|
+
}),
|
|
324
|
+
baggage: mergeRecords(base.baggage, override.baggage),
|
|
325
|
+
issues: override.issues ?? base.issues,
|
|
326
|
+
requestTraces: override.requestTraces ?? base.requestTraces
|
|
327
|
+
};
|
|
328
|
+
};
|
|
329
|
+
var sanitizeForBaggage = (value, depth = 0) => {
|
|
330
|
+
if (value == null) return value;
|
|
331
|
+
if (depth >= 4) return "[truncated]";
|
|
332
|
+
if (typeof value === "string") {
|
|
333
|
+
return value.length > 2e3 ? `${value.slice(0, 2e3)}...[truncated]` : value;
|
|
334
|
+
}
|
|
335
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
336
|
+
return value;
|
|
337
|
+
}
|
|
338
|
+
if (Array.isArray(value)) {
|
|
339
|
+
return value.slice(0, 20).map((item) => sanitizeForBaggage(item, depth + 1));
|
|
340
|
+
}
|
|
341
|
+
if (isRecord(value)) {
|
|
342
|
+
return Object.fromEntries(
|
|
343
|
+
Object.entries(value).slice(0, 30).map(([key, entry]) => [key, sanitizeForBaggage(entry, depth + 1)])
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
return String(value);
|
|
347
|
+
};
|
|
348
|
+
var normalizeSlateErrorInput = (input) => {
|
|
349
|
+
let code = input.code || DEFAULT_CODE;
|
|
350
|
+
return {
|
|
351
|
+
code,
|
|
352
|
+
message: getDefaultMessage(code, input.message),
|
|
353
|
+
kind: normalizeKind(code, input.kind),
|
|
354
|
+
retryable: normalizeRetryable(code, input.retryable),
|
|
355
|
+
status: normalizeStatus(code, input.status ?? input.upstream?.status),
|
|
356
|
+
issues: input.issues,
|
|
357
|
+
provider: cleanRecord(input.provider),
|
|
358
|
+
upstream: cleanRecord({
|
|
359
|
+
...input.upstream,
|
|
360
|
+
status: input.upstream?.status ?? input.status
|
|
361
|
+
}),
|
|
362
|
+
baggage: cleanRecord(input.baggage),
|
|
363
|
+
requestTraces: input.requestTraces
|
|
364
|
+
};
|
|
365
|
+
};
|
|
366
|
+
var isSlateErrorResponse = (error) => {
|
|
367
|
+
if (!isRecord(error)) return false;
|
|
368
|
+
return typeof error.code === "string" && typeof error.message === "string";
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
// src/error/axios.ts
|
|
372
|
+
var getResponseField = (value, key) => {
|
|
373
|
+
if (!isRecord(value)) return void 0;
|
|
374
|
+
return value[key];
|
|
375
|
+
};
|
|
376
|
+
var getNestedMessage = (value) => {
|
|
377
|
+
if (typeof value === "string") return value;
|
|
378
|
+
if (!isRecord(value)) return void 0;
|
|
379
|
+
let message = getResponseField(value, "message");
|
|
380
|
+
if (typeof message === "string" && message.trim()) return message;
|
|
381
|
+
let description = getResponseField(value, "description");
|
|
382
|
+
if (typeof description === "string" && description.trim()) return description;
|
|
383
|
+
let error = getResponseField(value, "error");
|
|
384
|
+
if (typeof error === "string" && error.trim()) return error;
|
|
385
|
+
if (isRecord(error)) {
|
|
386
|
+
let nested = getNestedMessage(error);
|
|
387
|
+
if (nested) return nested;
|
|
388
|
+
}
|
|
389
|
+
let errorDescription = getResponseField(value, "error_description");
|
|
390
|
+
if (typeof errorDescription === "string" && errorDescription.trim()) {
|
|
391
|
+
return errorDescription;
|
|
392
|
+
}
|
|
393
|
+
return void 0;
|
|
394
|
+
};
|
|
395
|
+
var getNestedCode = (value) => {
|
|
396
|
+
if (!isRecord(value)) return void 0;
|
|
397
|
+
let directCode = getResponseField(value, "code");
|
|
398
|
+
if (typeof directCode === "string" && directCode.trim()) return directCode;
|
|
399
|
+
let errorCode = getResponseField(value, "error_code");
|
|
400
|
+
if (typeof errorCode === "string" && errorCode.trim()) return errorCode;
|
|
401
|
+
let type = getResponseField(value, "type");
|
|
402
|
+
if (typeof type === "string" && type.trim()) return type;
|
|
403
|
+
let error = getResponseField(value, "error");
|
|
404
|
+
if (typeof error === "string" && error.trim()) return error;
|
|
405
|
+
if (isRecord(error)) return getNestedCode(error);
|
|
406
|
+
return void 0;
|
|
407
|
+
};
|
|
408
|
+
var getNestedType = (value) => {
|
|
409
|
+
if (!isRecord(value)) return void 0;
|
|
410
|
+
let type = getResponseField(value, "type");
|
|
411
|
+
if (typeof type === "string" && type.trim()) return type;
|
|
412
|
+
let error = getResponseField(value, "error");
|
|
413
|
+
if (isRecord(error)) {
|
|
414
|
+
let nestedType = getNestedType(error);
|
|
415
|
+
if (nestedType) return nestedType;
|
|
416
|
+
}
|
|
417
|
+
return void 0;
|
|
418
|
+
};
|
|
419
|
+
var getHeaderValue = (headers, key) => {
|
|
420
|
+
if (!headers) return void 0;
|
|
421
|
+
if (typeof headers.get === "function") {
|
|
422
|
+
let value = headers.get(key);
|
|
423
|
+
if (typeof value === "string" && value.trim()) return value;
|
|
424
|
+
}
|
|
425
|
+
if (isRecord(headers)) {
|
|
426
|
+
for (let [headerKey, headerValue] of Object.entries(headers)) {
|
|
427
|
+
if (headerKey.toLowerCase() !== key.toLowerCase()) continue;
|
|
428
|
+
if (typeof headerValue === "string" && headerValue.trim()) return headerValue;
|
|
429
|
+
if (Array.isArray(headerValue)) {
|
|
430
|
+
let first = headerValue.find((item) => typeof item === "string" && item.trim());
|
|
431
|
+
if (typeof first === "string") return first;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
return void 0;
|
|
436
|
+
};
|
|
437
|
+
var buildRequestUrl = (error) => {
|
|
438
|
+
let baseURL = error.config?.baseURL;
|
|
439
|
+
let url = error.config?.url;
|
|
440
|
+
if (!url) return void 0;
|
|
441
|
+
if (!baseURL) return url;
|
|
442
|
+
try {
|
|
443
|
+
return new URL(url, baseURL).toString();
|
|
444
|
+
} catch {
|
|
445
|
+
return url;
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
var getProviderDefaults = () => {
|
|
449
|
+
try {
|
|
450
|
+
let ctx = getCurrentContext();
|
|
451
|
+
return {
|
|
452
|
+
provider: {
|
|
453
|
+
key: ctx.specification.key
|
|
454
|
+
},
|
|
455
|
+
...ctx.getHttpTraces().length > 0 ? { requestTraces: ctx.getHttpTraces() } : {}
|
|
456
|
+
};
|
|
457
|
+
} catch {
|
|
458
|
+
return {};
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
var inferAxiosCode = (error, data) => {
|
|
462
|
+
let status = error.response?.status;
|
|
463
|
+
let axiosCode = error.code?.toUpperCase();
|
|
464
|
+
let remoteCode = getNestedCode(data)?.toLowerCase();
|
|
465
|
+
if (axiosCode === "ECONNABORTED" || axiosCode === "ETIMEDOUT" || status === 408 || remoteCode?.includes("timeout")) {
|
|
466
|
+
return "upstream.timeout";
|
|
467
|
+
}
|
|
468
|
+
if (!error.response) {
|
|
469
|
+
return "upstream.network_error";
|
|
470
|
+
}
|
|
471
|
+
if (status === 401) return "auth.invalid";
|
|
472
|
+
if (status === 403) {
|
|
473
|
+
return remoteCode?.includes("rate") ? "upstream.rate_limited" : "permission.denied";
|
|
474
|
+
}
|
|
475
|
+
if (status === 404) return "resource.not_found";
|
|
476
|
+
if (status === 409) return "resource.conflict";
|
|
477
|
+
if (status === 422 || status === 400) return "upstream.invalid_request";
|
|
478
|
+
if (status === 429) return "upstream.rate_limited";
|
|
479
|
+
if (status === 502 || status === 503 || status === 504) return "upstream.unavailable";
|
|
480
|
+
if (status && status >= 500) return "upstream.error";
|
|
481
|
+
return "upstream.error";
|
|
482
|
+
};
|
|
483
|
+
var inferAxiosMessage = (error, data, code) => {
|
|
484
|
+
return getNestedMessage(data) ?? error.response?.statusText ?? error.message ?? getDefaultMessage(code);
|
|
485
|
+
};
|
|
486
|
+
var inferAxiosRetryable = (error, code) => {
|
|
487
|
+
let headerValue = getHeaderValue(error.response?.headers, "retry-after");
|
|
488
|
+
if (headerValue) return true;
|
|
489
|
+
return normalizeRetryable(code, void 0);
|
|
490
|
+
};
|
|
491
|
+
var isAxiosErrorLike = (error) => isAxiosError(error);
|
|
492
|
+
var inferSlateErrorFromAxios = (error, options = {}) => {
|
|
493
|
+
let responseData = error.response ? options.extractResponseData?.(error.response) ?? error.response.data : void 0;
|
|
494
|
+
let code = inferAxiosCode(error, responseData);
|
|
495
|
+
return normalizeSlateErrorInput({
|
|
496
|
+
...getProviderDefaults(),
|
|
497
|
+
...options.defaults,
|
|
498
|
+
code: options.defaults?.code ?? code,
|
|
499
|
+
message: options.defaults?.message ?? inferAxiosMessage(error, responseData, code),
|
|
500
|
+
kind: options.defaults?.kind ?? normalizeKind(options.defaults?.code ?? code),
|
|
501
|
+
retryable: options.defaults?.retryable ?? inferAxiosRetryable(error, options.defaults?.code ?? code),
|
|
502
|
+
status: options.defaults?.status ?? error.response?.status,
|
|
503
|
+
provider: {
|
|
504
|
+
...getProviderDefaults().provider,
|
|
505
|
+
...options.defaults?.provider ?? {}
|
|
506
|
+
},
|
|
507
|
+
upstream: {
|
|
508
|
+
...options.defaults?.upstream ?? {},
|
|
509
|
+
status: error.response?.status ?? options.defaults?.upstream?.status,
|
|
510
|
+
code: getNestedCode(responseData) ?? options.defaults?.upstream?.code,
|
|
511
|
+
type: getNestedType(responseData) ?? options.defaults?.upstream?.type,
|
|
512
|
+
requestId: getHeaderValue(error.response?.headers, "x-request-id") ?? getHeaderValue(error.response?.headers, "request-id") ?? getHeaderValue(error.response?.headers, "x-correlation-id") ?? options.defaults?.upstream?.requestId,
|
|
513
|
+
method: error.config?.method?.toUpperCase() ?? options.defaults?.upstream?.method,
|
|
514
|
+
url: buildRequestUrl(error) ?? options.defaults?.upstream?.url
|
|
515
|
+
},
|
|
516
|
+
baggage: mergeRecords(options.defaults?.baggage, {
|
|
517
|
+
axiosCode: error.code,
|
|
518
|
+
response: sanitizeForBaggage(responseData)
|
|
519
|
+
})
|
|
520
|
+
});
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
// src/error/service.ts
|
|
524
|
+
import { isServiceError } from "@lowerdeck/error";
|
|
525
|
+
var SERVICE_ERROR_DATA_RESERVED_KEYS = /* @__PURE__ */ new Set([
|
|
526
|
+
"status",
|
|
527
|
+
"code",
|
|
528
|
+
"message",
|
|
529
|
+
"hint",
|
|
530
|
+
"description",
|
|
531
|
+
"reason",
|
|
532
|
+
"errors",
|
|
533
|
+
"object",
|
|
534
|
+
"ok"
|
|
535
|
+
]);
|
|
536
|
+
var isStructuredValue = (value) => (typeof value === "object" || typeof value === "function") && value !== null;
|
|
537
|
+
var mapServiceErrorCodeByStatus = (status) => {
|
|
538
|
+
if (status === 400) return "request.bad";
|
|
539
|
+
if (status === 401) return "auth.required";
|
|
540
|
+
if (status === 402) return "payment.required";
|
|
541
|
+
if (status === 403) return "permission.denied";
|
|
542
|
+
if (status === 404) return "resource.not_found";
|
|
543
|
+
if (status === 406) return "request.not_acceptable";
|
|
544
|
+
if (status === 409) return "resource.conflict";
|
|
545
|
+
if (status === 410) return "resource.gone";
|
|
546
|
+
if (status === 412) return "request.precondition_failed";
|
|
547
|
+
if (status === 429) return "request.rate_limited";
|
|
548
|
+
if (status === 501) return "operation.not_implemented";
|
|
549
|
+
if (status === 504) return "internal.timeout";
|
|
550
|
+
if (status && status >= 500) return "internal.unexpected";
|
|
551
|
+
return DEFAULT_CODE;
|
|
552
|
+
};
|
|
553
|
+
var normalizeServiceErrorIssues = (errors) => {
|
|
554
|
+
if (!Array.isArray(errors)) return void 0;
|
|
555
|
+
let issues = errors.map((error) => {
|
|
556
|
+
if (!isRecord(error)) {
|
|
557
|
+
return {
|
|
558
|
+
message: String(error)
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
let path = Array.isArray(error.path) ? error.path.map((entry) => String(entry)) : void 0;
|
|
562
|
+
return {
|
|
563
|
+
...error,
|
|
564
|
+
path,
|
|
565
|
+
code: typeof error.code === "string" ? error.code : void 0,
|
|
566
|
+
message: typeof error.message === "string" ? error.message : typeof error.hint === "string" ? error.hint : "Validation issue"
|
|
567
|
+
};
|
|
568
|
+
});
|
|
569
|
+
return issues.length > 0 ? issues : void 0;
|
|
570
|
+
};
|
|
571
|
+
var getServiceErrorBaggage = (data) => {
|
|
572
|
+
let extraEntries = Object.entries(data).filter(
|
|
573
|
+
([key]) => !SERVICE_ERROR_DATA_RESERVED_KEYS.has(key)
|
|
574
|
+
);
|
|
575
|
+
return cleanRecord({
|
|
576
|
+
serviceError: {
|
|
577
|
+
code: data.code,
|
|
578
|
+
status: data.status,
|
|
579
|
+
hint: data.hint,
|
|
580
|
+
description: data.description,
|
|
581
|
+
reason: data.reason
|
|
582
|
+
},
|
|
583
|
+
...extraEntries.length > 0 ? {
|
|
584
|
+
serviceErrorData: sanitizeForBaggage(Object.fromEntries(extraEntries))
|
|
585
|
+
} : {}
|
|
586
|
+
});
|
|
587
|
+
};
|
|
588
|
+
var mapServiceErrorCode = (code, status) => SERVICE_ERROR_CODE_MAP[code] ?? mapServiceErrorCodeByStatus(status);
|
|
589
|
+
var isServiceErrorData = (value) => isRecord(value) && typeof value.status === "number" && typeof value.code === "string" && typeof value.message === "string" && !("config" in value) && !("request" in value) && !("response" in value) && !("isAxiosError" in value);
|
|
590
|
+
var getServiceErrorData = (error) => {
|
|
591
|
+
if (isServiceError(error)) {
|
|
592
|
+
return isServiceErrorData(error.data) ? error.data : null;
|
|
593
|
+
}
|
|
594
|
+
if (isServiceErrorData(error)) {
|
|
595
|
+
return error;
|
|
596
|
+
}
|
|
597
|
+
if (isStructuredValue(error) && "data" in error && isServiceErrorData(error.data)) {
|
|
598
|
+
return error.data;
|
|
599
|
+
}
|
|
600
|
+
if (isStructuredValue(error) && "toResponse" in error && typeof error.toResponse === "function") {
|
|
601
|
+
let response = error.toResponse();
|
|
602
|
+
return isServiceErrorData(response) ? response : null;
|
|
603
|
+
}
|
|
604
|
+
return null;
|
|
605
|
+
};
|
|
606
|
+
var mapServiceErrorToSlateErrorInput = (error, defaults = {}) => {
|
|
607
|
+
let data = getServiceErrorData(error);
|
|
608
|
+
if (!data) {
|
|
609
|
+
return {
|
|
610
|
+
code: defaults.code ?? DEFAULT_CODE,
|
|
611
|
+
message: defaults.message ?? "An unexpected internal error occurred.",
|
|
612
|
+
kind: defaults.kind,
|
|
613
|
+
retryable: defaults.retryable,
|
|
614
|
+
status: defaults.status,
|
|
615
|
+
provider: defaults.provider,
|
|
616
|
+
upstream: defaults.upstream,
|
|
617
|
+
baggage: defaults.baggage
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
let code = defaults.code ?? mapServiceErrorCode(data.code, data.status);
|
|
621
|
+
return {
|
|
622
|
+
code,
|
|
623
|
+
message: defaults.message ?? data.message,
|
|
624
|
+
kind: defaults.kind ?? normalizeKind(code),
|
|
625
|
+
retryable: defaults.retryable ?? normalizeRetryable(code),
|
|
626
|
+
status: defaults.status ?? data.status,
|
|
627
|
+
issues: defaults.issues ?? normalizeServiceErrorIssues(data.errors),
|
|
628
|
+
provider: defaults.provider,
|
|
629
|
+
upstream: defaults.upstream,
|
|
630
|
+
baggage: cleanRecord({
|
|
631
|
+
...defaults.baggage ?? {},
|
|
632
|
+
...getServiceErrorBaggage(data)
|
|
633
|
+
})
|
|
634
|
+
};
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
// src/error/base.ts
|
|
638
|
+
var SlateError = class _SlateError extends Error {
|
|
639
|
+
cause;
|
|
640
|
+
data;
|
|
641
|
+
constructor(input) {
|
|
642
|
+
let normalized = normalizeSlateErrorInput(input);
|
|
643
|
+
super(normalized.message);
|
|
644
|
+
this.name = "SlateError";
|
|
645
|
+
this.data = normalized;
|
|
646
|
+
this.cause = input.cause;
|
|
647
|
+
}
|
|
648
|
+
get code() {
|
|
649
|
+
return this.data.code;
|
|
650
|
+
}
|
|
651
|
+
get kind() {
|
|
652
|
+
return this.data.kind;
|
|
653
|
+
}
|
|
654
|
+
get status() {
|
|
655
|
+
return this.data.status;
|
|
656
|
+
}
|
|
657
|
+
get retryable() {
|
|
658
|
+
return this.data.retryable;
|
|
659
|
+
}
|
|
660
|
+
toResponse() {
|
|
661
|
+
return {
|
|
662
|
+
...this.data
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
toJSON() {
|
|
666
|
+
return this.toResponse();
|
|
667
|
+
}
|
|
668
|
+
static is(error) {
|
|
669
|
+
return error instanceof _SlateError;
|
|
670
|
+
}
|
|
671
|
+
static fromUnknown(error, defaults = {}) {
|
|
672
|
+
if (_SlateError.is(error)) return error;
|
|
673
|
+
if (isSlateErrorResponse(error)) return new _SlateError({ ...defaults, ...error });
|
|
674
|
+
if (getServiceErrorData(error)) return _SlateError.fromServiceError(error, defaults);
|
|
675
|
+
if (isAxiosErrorLike(error)) return _SlateError.fromAxios(error, { defaults });
|
|
676
|
+
if (error instanceof Error) {
|
|
677
|
+
return new _SlateError({
|
|
678
|
+
code: defaults.code ?? DEFAULT_CODE,
|
|
679
|
+
message: error.message,
|
|
680
|
+
kind: defaults.kind,
|
|
681
|
+
retryable: defaults.retryable,
|
|
682
|
+
status: defaults.status,
|
|
683
|
+
issues: defaults.issues,
|
|
684
|
+
provider: defaults.provider,
|
|
685
|
+
upstream: defaults.upstream,
|
|
686
|
+
baggage: mergeRecords(defaults.baggage, {
|
|
687
|
+
originalName: error.name
|
|
688
|
+
}),
|
|
689
|
+
cause: error
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
return new _SlateError({
|
|
693
|
+
code: defaults.code ?? DEFAULT_CODE,
|
|
694
|
+
message: getDefaultMessage(defaults.code ?? DEFAULT_CODE, defaults.message),
|
|
695
|
+
kind: defaults.kind,
|
|
696
|
+
retryable: defaults.retryable,
|
|
697
|
+
status: defaults.status,
|
|
698
|
+
issues: defaults.issues,
|
|
699
|
+
provider: defaults.provider,
|
|
700
|
+
upstream: defaults.upstream,
|
|
701
|
+
baggage: mergeRecords(defaults.baggage, {
|
|
702
|
+
originalValue: sanitizeForBaggage(error)
|
|
703
|
+
})
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
static fromServiceError(error, defaults = {}) {
|
|
707
|
+
return new _SlateError(mapServiceErrorToSlateErrorInput(error, defaults));
|
|
708
|
+
}
|
|
709
|
+
static fromAxios(error, options = {}) {
|
|
710
|
+
if (_SlateError.is(error)) return error;
|
|
711
|
+
if (getServiceErrorData(error))
|
|
712
|
+
return _SlateError.fromServiceError(error, options.defaults);
|
|
713
|
+
if (!isAxiosErrorLike(error)) return _SlateError.fromUnknown(error, options.defaults);
|
|
714
|
+
let inferred = inferSlateErrorFromAxios(error, options);
|
|
715
|
+
let mapped = options.mapAxiosError?.(error, inferred);
|
|
716
|
+
if (_SlateError.is(mapped)) return mapped;
|
|
717
|
+
return new _SlateError(mergeSlateErrorData(inferred, mapped ?? void 0));
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
var createSlateError = (input) => new SlateError(input);
|
|
721
|
+
|
|
722
|
+
// src/error/declaration.ts
|
|
723
|
+
var SlateDeclarationError = class _SlateDeclarationError extends SlateError {
|
|
724
|
+
constructor(message, input = {}) {
|
|
725
|
+
super({
|
|
726
|
+
code: "declaration.invalid_definition",
|
|
727
|
+
kind: "declaration",
|
|
728
|
+
message,
|
|
729
|
+
...input
|
|
730
|
+
});
|
|
731
|
+
this.name = "SlateError.DeclarationError";
|
|
732
|
+
}
|
|
733
|
+
static is(error) {
|
|
734
|
+
return error instanceof _SlateDeclarationError;
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
|
|
738
|
+
// src/action/scopes.ts
|
|
739
|
+
var scopeClause = (...scopes) => {
|
|
740
|
+
assertScopeValues(scopes);
|
|
741
|
+
return {
|
|
742
|
+
OR: [...scopes]
|
|
743
|
+
};
|
|
744
|
+
};
|
|
745
|
+
var anyOf = (...scopes) => ({
|
|
746
|
+
AND: [scopeClause(...scopes)]
|
|
747
|
+
});
|
|
748
|
+
var allOf = (...inputs) => {
|
|
749
|
+
let AND = inputs.flatMap((input) => normalizeScopes(input).AND);
|
|
750
|
+
return validateScopes({ AND });
|
|
751
|
+
};
|
|
752
|
+
var mergeScopes = (...inputs) => {
|
|
753
|
+
let AND = inputs.flatMap((input) => input ? input.AND : []);
|
|
754
|
+
if (AND.length === 0) {
|
|
755
|
+
return void 0;
|
|
756
|
+
}
|
|
757
|
+
return validateScopes({ AND });
|
|
758
|
+
};
|
|
759
|
+
var validateScopes = (scopes) => {
|
|
760
|
+
if (!Array.isArray(scopes.AND) || scopes.AND.length === 0) {
|
|
761
|
+
throw new SlateDeclarationError("Action scopes must include at least one AND clause");
|
|
762
|
+
}
|
|
763
|
+
return {
|
|
764
|
+
AND: scopes.AND.map((clause) => normalizeClause(clause))
|
|
765
|
+
};
|
|
766
|
+
};
|
|
767
|
+
var normalizeScopes = (input) => {
|
|
768
|
+
if (isScopes(input)) {
|
|
769
|
+
return validateScopes(input);
|
|
770
|
+
}
|
|
771
|
+
return {
|
|
772
|
+
AND: [normalizeClause(input)]
|
|
773
|
+
};
|
|
774
|
+
};
|
|
775
|
+
var normalizeClause = (input) => {
|
|
776
|
+
if (typeof input === "string") {
|
|
777
|
+
return scopeClause(input);
|
|
778
|
+
}
|
|
779
|
+
if (Array.isArray(input)) {
|
|
780
|
+
return scopeClause(...input);
|
|
781
|
+
}
|
|
782
|
+
if (!isClause(input)) {
|
|
783
|
+
throw new SlateDeclarationError("Action scope clauses must be strings or OR clauses");
|
|
784
|
+
}
|
|
785
|
+
assertScopeValues(input.OR);
|
|
786
|
+
return {
|
|
787
|
+
OR: [...input.OR]
|
|
788
|
+
};
|
|
789
|
+
};
|
|
790
|
+
var assertScopeValues = (scopes) => {
|
|
791
|
+
if (scopes.length === 0) {
|
|
792
|
+
throw new SlateDeclarationError(
|
|
793
|
+
"Each action scope clause must include at least one OR scope"
|
|
794
|
+
);
|
|
795
|
+
}
|
|
796
|
+
for (let scope of scopes) {
|
|
797
|
+
if (typeof scope !== "string" || scope.trim().length === 0) {
|
|
798
|
+
throw new SlateDeclarationError("Action scopes must be non-empty strings");
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
};
|
|
802
|
+
var isClause = (value) => typeof value === "object" && value !== null && "OR" in value && Array.isArray(value.OR);
|
|
803
|
+
var isScopes = (value) => typeof value === "object" && value !== null && "AND" in value && Array.isArray(value.AND);
|
|
804
|
+
|
|
805
|
+
// src/action/builder.ts
|
|
806
|
+
var SlateActionBuilder = class {
|
|
807
|
+
constructor(type, spec2, params, factory, isPublicTool = false) {
|
|
808
|
+
this.type = type;
|
|
809
|
+
this.spec = spec2;
|
|
810
|
+
this.params = params;
|
|
811
|
+
this.factory = factory;
|
|
812
|
+
this.isPublicTool = isPublicTool;
|
|
813
|
+
this.#configSchema = spec2.configSchema;
|
|
814
|
+
this.#authSchema = spec2.authSchema;
|
|
815
|
+
}
|
|
816
|
+
type;
|
|
817
|
+
spec;
|
|
818
|
+
params;
|
|
819
|
+
factory;
|
|
820
|
+
isPublicTool;
|
|
821
|
+
#configSchema;
|
|
822
|
+
#authSchema;
|
|
823
|
+
#inputSchema = null;
|
|
824
|
+
#outputSchema = null;
|
|
825
|
+
#scopes;
|
|
826
|
+
#authMethods;
|
|
827
|
+
#toolParams = null;
|
|
828
|
+
#triggerParams = null;
|
|
829
|
+
#interfaceLocked = false;
|
|
830
|
+
input(schema) {
|
|
831
|
+
if (this.#interfaceLocked) {
|
|
832
|
+
throw new SlateDeclarationError("Adapter contract input schema cannot be changed");
|
|
833
|
+
}
|
|
834
|
+
this.#inputSchema = schema;
|
|
835
|
+
return this;
|
|
836
|
+
}
|
|
837
|
+
output(schema) {
|
|
838
|
+
if (this.#interfaceLocked) {
|
|
839
|
+
throw new SlateDeclarationError("Adapter contract output schema cannot be changed");
|
|
840
|
+
}
|
|
841
|
+
this.#outputSchema = schema;
|
|
842
|
+
return this;
|
|
843
|
+
}
|
|
844
|
+
lockInterface() {
|
|
845
|
+
this.#interfaceLocked = true;
|
|
846
|
+
return this;
|
|
847
|
+
}
|
|
848
|
+
scopes(scopes) {
|
|
849
|
+
validateScopes(scopes);
|
|
850
|
+
this.#scopes = scopes;
|
|
851
|
+
return this;
|
|
852
|
+
}
|
|
853
|
+
authMethods(authMethods) {
|
|
854
|
+
if (this.isPublicTool) {
|
|
855
|
+
throw new SlateDeclarationError("Public tools cannot require authentication methods");
|
|
856
|
+
}
|
|
857
|
+
this.#authMethods = this.validateAuthMethods(authMethods);
|
|
858
|
+
return this;
|
|
859
|
+
}
|
|
860
|
+
validateAuthMethods(authMethods) {
|
|
861
|
+
if (!authMethods) return void 0;
|
|
862
|
+
let normalized = [...new Set(authMethods.map((authMethod) => authMethod.trim()))];
|
|
863
|
+
if (normalized.some((authMethod) => !authMethod)) {
|
|
864
|
+
throw new SlateDeclarationError("Auth method IDs must be non-empty strings");
|
|
865
|
+
}
|
|
866
|
+
return normalized;
|
|
867
|
+
}
|
|
868
|
+
handleInvocation(handler) {
|
|
869
|
+
if (this.type !== "tool") {
|
|
870
|
+
throw new SlateDeclarationError("handleInvocation can only be set for tool actions");
|
|
871
|
+
}
|
|
872
|
+
this.#toolParams = {
|
|
873
|
+
type: "tool",
|
|
874
|
+
handleInvocation: handler
|
|
875
|
+
};
|
|
876
|
+
return this;
|
|
877
|
+
}
|
|
878
|
+
webhook(props) {
|
|
879
|
+
if (this.type !== "trigger") {
|
|
880
|
+
throw new SlateDeclarationError("handleEvent can only be set for trigger actions");
|
|
881
|
+
}
|
|
882
|
+
this.#triggerParams = {
|
|
883
|
+
type: "trigger",
|
|
884
|
+
source: "webhook",
|
|
885
|
+
handleEvent: props.handleEvent,
|
|
886
|
+
handleRequest: props.handleRequest,
|
|
887
|
+
autoRegisterWebhook: props.autoRegisterWebhook,
|
|
888
|
+
autoUnregisterWebhook: props.autoUnregisterWebhook,
|
|
889
|
+
http: props.http
|
|
890
|
+
};
|
|
891
|
+
return this;
|
|
892
|
+
}
|
|
893
|
+
polling(props) {
|
|
894
|
+
if (this.type !== "trigger") {
|
|
895
|
+
throw new SlateDeclarationError("handleEvent can only be set for trigger actions");
|
|
896
|
+
}
|
|
897
|
+
this.#triggerParams = {
|
|
898
|
+
type: "trigger",
|
|
899
|
+
source: "polling",
|
|
900
|
+
polling: props.options,
|
|
901
|
+
pollEvents: props.pollEvents,
|
|
902
|
+
handleEvent: props.handleEvent
|
|
903
|
+
};
|
|
904
|
+
return this;
|
|
905
|
+
}
|
|
906
|
+
build() {
|
|
907
|
+
let scopes = this.#scopes ?? this.params.scopes;
|
|
908
|
+
if (scopes) {
|
|
909
|
+
validateScopes(scopes);
|
|
910
|
+
}
|
|
911
|
+
let authMethods = this.validateAuthMethods(this.#authMethods ?? this.params.authMethods);
|
|
912
|
+
if (this.isPublicTool && authMethods) {
|
|
913
|
+
throw new SlateDeclarationError("Public tools cannot require authentication methods");
|
|
914
|
+
}
|
|
915
|
+
if (!this.#inputSchema) {
|
|
916
|
+
throw new SlateDeclarationError("Input schema is not defined");
|
|
917
|
+
}
|
|
918
|
+
if (!this.#outputSchema) {
|
|
919
|
+
throw new SlateDeclarationError("Output schema is not defined");
|
|
920
|
+
}
|
|
921
|
+
if (this.type === "tool" && !this.#toolParams) {
|
|
922
|
+
throw new SlateDeclarationError("Tool invocation handler is not defined");
|
|
923
|
+
}
|
|
924
|
+
if (this.type === "trigger" && !this.#triggerParams) {
|
|
925
|
+
throw new SlateDeclarationError("Trigger event handlers are not defined");
|
|
926
|
+
}
|
|
927
|
+
return this.factory({
|
|
928
|
+
...this.params,
|
|
929
|
+
scopes,
|
|
930
|
+
authMethods,
|
|
931
|
+
isPublic: this.isPublicTool === true,
|
|
932
|
+
configSchema: this.#configSchema,
|
|
933
|
+
authSchema: this.#authSchema,
|
|
934
|
+
inputSchema: this.#inputSchema,
|
|
935
|
+
outputSchema: this.#outputSchema,
|
|
936
|
+
...this.#toolParams,
|
|
937
|
+
...this.#triggerParams
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
};
|
|
941
|
+
|
|
942
|
+
// src/action/getFileUrlTool.ts
|
|
943
|
+
import { z } from "zod";
|
|
944
|
+
|
|
945
|
+
// src/action/tool.ts
|
|
946
|
+
var SlateTool = class _SlateTool extends SlateAction {
|
|
947
|
+
#handleInvocation;
|
|
948
|
+
constructor(spec2, inputSchema, outputSchema, params) {
|
|
949
|
+
super("tool", spec2, inputSchema, outputSchema, params);
|
|
950
|
+
this.#handleInvocation = params.handleInvocation;
|
|
951
|
+
}
|
|
952
|
+
static create(spec2, params) {
|
|
953
|
+
return new SlateActionBuilder("tool", spec2, params, (params2) => {
|
|
954
|
+
return _SlateTool.fromCreateParameters(spec2, params2);
|
|
955
|
+
});
|
|
956
|
+
}
|
|
957
|
+
static fromCreateParameters(spec2, params) {
|
|
958
|
+
if (params.type !== "tool") throw new Error("Invalid action type for tool");
|
|
959
|
+
return new _SlateTool(spec2, params.inputSchema, params.outputSchema, params);
|
|
960
|
+
}
|
|
961
|
+
get handleInvocation() {
|
|
962
|
+
return this.#handleInvocation;
|
|
963
|
+
}
|
|
964
|
+
};
|
|
965
|
+
var tool = (spec2, params) => SlateTool.create(spec2, params);
|
|
966
|
+
|
|
967
|
+
// src/action/getFileUrlTool.ts
|
|
968
|
+
var GET_FILE_URL_TOOL_ID = "metorial$getFileUrl";
|
|
969
|
+
var getFileUrlToolInputSchema = z.object({
|
|
970
|
+
url: z.string(),
|
|
971
|
+
reference: z.any().nullable()
|
|
972
|
+
});
|
|
973
|
+
var getFileUrlToolOutputSchema = z.object({
|
|
974
|
+
url: z.string(),
|
|
975
|
+
expiresAt: z.string(),
|
|
976
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
977
|
+
query: z.record(z.string(), z.string()).optional()
|
|
978
|
+
});
|
|
979
|
+
var getFileUrlTool = (spec2, handleGetFileUrl) => tool(spec2, {
|
|
980
|
+
key: GET_FILE_URL_TOOL_ID,
|
|
981
|
+
name: "Get File URL",
|
|
982
|
+
description: "Reserved: refreshes an expiring attachment download URL. Hub-internal only."
|
|
983
|
+
}).input(getFileUrlToolInputSchema).output(getFileUrlToolOutputSchema).handleInvocation(async (ctx) => ({
|
|
984
|
+
output: await handleGetFileUrl(ctx),
|
|
985
|
+
message: "ok"
|
|
986
|
+
})).build();
|
|
987
|
+
|
|
988
|
+
// src/action/publicTool.ts
|
|
989
|
+
var SlatePublicTool = class {
|
|
990
|
+
constructor() {
|
|
991
|
+
}
|
|
992
|
+
static create(spec2, params) {
|
|
993
|
+
return new SlateActionBuilder(
|
|
994
|
+
"tool",
|
|
995
|
+
spec2,
|
|
996
|
+
params,
|
|
997
|
+
(params2) => {
|
|
998
|
+
return SlateTool.fromCreateParameters(spec2, {
|
|
999
|
+
...params2,
|
|
1000
|
+
isPublic: true
|
|
1001
|
+
});
|
|
1002
|
+
},
|
|
1003
|
+
true
|
|
1004
|
+
);
|
|
1005
|
+
}
|
|
1006
|
+
};
|
|
1007
|
+
var publicTool = (spec2, params) => SlatePublicTool.create(spec2, params);
|
|
1008
|
+
|
|
1009
|
+
// src/action/trigger.ts
|
|
1010
|
+
var SlateDefaultPollingIntervalSeconds = 60 * 10;
|
|
1011
|
+
var SlateTrigger = class _SlateTrigger extends SlateAction {
|
|
1012
|
+
#source;
|
|
1013
|
+
#polling;
|
|
1014
|
+
#handleEvent;
|
|
1015
|
+
#handleRequest;
|
|
1016
|
+
#http;
|
|
1017
|
+
#pollEvents;
|
|
1018
|
+
#autoRegisterWebhook;
|
|
1019
|
+
#autoUnregisterWebhook;
|
|
1020
|
+
constructor(spec2, inputSchema, outputSchema, params) {
|
|
1021
|
+
super("trigger", spec2, inputSchema, outputSchema, params);
|
|
1022
|
+
this.#source = params.source;
|
|
1023
|
+
this.#polling = params.polling || {
|
|
1024
|
+
intervalInSeconds: SlateDefaultPollingIntervalSeconds
|
|
1025
|
+
};
|
|
1026
|
+
this.#handleEvent = params.handleEvent;
|
|
1027
|
+
this.#handleRequest = params.handleRequest;
|
|
1028
|
+
this.#http = params.http;
|
|
1029
|
+
this.#pollEvents = params.pollEvents;
|
|
1030
|
+
this.#autoRegisterWebhook = params.autoRegisterWebhook;
|
|
1031
|
+
this.#autoUnregisterWebhook = params.autoUnregisterWebhook;
|
|
1032
|
+
}
|
|
1033
|
+
static create(spec2, params) {
|
|
1034
|
+
return new SlateActionBuilder("trigger", spec2, params, (params2) => {
|
|
1035
|
+
if (params2.type !== "trigger") throw new Error("Invalid action type for trigger");
|
|
1036
|
+
return new _SlateTrigger(spec2, params2.inputSchema, params2.outputSchema, params2);
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
get polling() {
|
|
1040
|
+
return this.#polling;
|
|
1041
|
+
}
|
|
1042
|
+
get source() {
|
|
1043
|
+
return this.#source;
|
|
1044
|
+
}
|
|
1045
|
+
get handleEvent() {
|
|
1046
|
+
return this.#handleEvent;
|
|
1047
|
+
}
|
|
1048
|
+
get handleRequest() {
|
|
1049
|
+
return this.#handleRequest;
|
|
1050
|
+
}
|
|
1051
|
+
get http() {
|
|
1052
|
+
return this.#http;
|
|
1053
|
+
}
|
|
1054
|
+
get pollEvents() {
|
|
1055
|
+
return this.#pollEvents;
|
|
1056
|
+
}
|
|
1057
|
+
get autoRegisterWebhook() {
|
|
1058
|
+
return this.#autoRegisterWebhook;
|
|
1059
|
+
}
|
|
1060
|
+
get autoUnregisterWebhook() {
|
|
1061
|
+
return this.#autoUnregisterWebhook;
|
|
1062
|
+
}
|
|
1063
|
+
};
|
|
1064
|
+
var trigger = (spec2, params) => SlateTrigger.create(spec2, params);
|
|
1065
|
+
|
|
1066
|
+
// src/action/attachment.ts
|
|
1067
|
+
var createUrlAttachment = (url, opts = {}) => {
|
|
1068
|
+
if (opts.refreshReference !== void 0 && !opts.refreshAt) {
|
|
1069
|
+
throw new Error("createUrlAttachment: refreshAt is required when refreshReference is set");
|
|
1070
|
+
}
|
|
1071
|
+
return {
|
|
1072
|
+
mimeType: opts.mimeType,
|
|
1073
|
+
attachmentHash: opts.attachmentHash,
|
|
1074
|
+
content: {
|
|
1075
|
+
type: "url",
|
|
1076
|
+
url,
|
|
1077
|
+
...opts.headers ? { headers: opts.headers } : {},
|
|
1078
|
+
...opts.query ? { query: opts.query } : {},
|
|
1079
|
+
...opts.refreshReference !== void 0 ? { refreshReference: opts.refreshReference } : {},
|
|
1080
|
+
...opts.refreshAt ? { refreshAt: opts.refreshAt } : {}
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
};
|
|
1084
|
+
var createBase64Attachment = (content, mimeType, attachmentHash) => ({
|
|
1085
|
+
mimeType,
|
|
1086
|
+
attachmentHash,
|
|
1087
|
+
content: {
|
|
1088
|
+
type: "content",
|
|
1089
|
+
encoding: "base64",
|
|
1090
|
+
content
|
|
1091
|
+
}
|
|
1092
|
+
});
|
|
1093
|
+
var createTextAttachment = (content, mimeType, attachmentHash) => ({
|
|
1094
|
+
mimeType,
|
|
1095
|
+
attachmentHash,
|
|
1096
|
+
content: {
|
|
1097
|
+
type: "content",
|
|
1098
|
+
encoding: "utf-8",
|
|
1099
|
+
content
|
|
1100
|
+
}
|
|
1101
|
+
});
|
|
1102
|
+
|
|
1103
|
+
// src/action/directUpload.ts
|
|
1104
|
+
var bufferAttachmentBody = async (body, maxSizeBytes) => {
|
|
1105
|
+
if (body instanceof Uint8Array) {
|
|
1106
|
+
if (body.byteLength > maxSizeBytes) {
|
|
1107
|
+
throw new Error(`Attachment exceeds the maximum size of ${maxSizeBytes} bytes`);
|
|
1108
|
+
}
|
|
1109
|
+
return body;
|
|
1110
|
+
}
|
|
1111
|
+
let reader = body.getReader();
|
|
1112
|
+
let chunks = [];
|
|
1113
|
+
let sizeBytes = 0;
|
|
1114
|
+
while (true) {
|
|
1115
|
+
let { done, value } = await reader.read();
|
|
1116
|
+
if (done) break;
|
|
1117
|
+
if (!value) continue;
|
|
1118
|
+
sizeBytes += value.byteLength;
|
|
1119
|
+
if (sizeBytes > maxSizeBytes) {
|
|
1120
|
+
await reader.cancel();
|
|
1121
|
+
throw new Error(`Attachment exceeds the maximum size of ${maxSizeBytes} bytes`);
|
|
1122
|
+
}
|
|
1123
|
+
chunks.push(value);
|
|
1124
|
+
}
|
|
1125
|
+
let buffered = new Uint8Array(sizeBytes);
|
|
1126
|
+
let offset = 0;
|
|
1127
|
+
for (let chunk of chunks) {
|
|
1128
|
+
buffered.set(chunk, offset);
|
|
1129
|
+
offset += chunk.byteLength;
|
|
1130
|
+
}
|
|
1131
|
+
return buffered;
|
|
1132
|
+
};
|
|
1133
|
+
var uploadAttachmentDirect = async (d) => {
|
|
1134
|
+
let baseUrl = d.live.baseUrl.replace(/\/$/, "");
|
|
1135
|
+
let body = await bufferAttachmentBody(d.body, d.live.maxAttachmentSizeBytes);
|
|
1136
|
+
let registerRes = await fetch(`${baseUrl}/slates-hub/live-invocation/attachments`, {
|
|
1137
|
+
method: "POST",
|
|
1138
|
+
headers: {
|
|
1139
|
+
"content-type": "application/json",
|
|
1140
|
+
authorization: `Bearer ${d.live.token}`
|
|
1141
|
+
},
|
|
1142
|
+
body: JSON.stringify({
|
|
1143
|
+
attachments: [
|
|
1144
|
+
{
|
|
1145
|
+
mimeType: d.mimeType,
|
|
1146
|
+
filename: d.filename,
|
|
1147
|
+
sizeBytes: body.byteLength || void 0
|
|
1148
|
+
}
|
|
1149
|
+
]
|
|
1150
|
+
})
|
|
1151
|
+
});
|
|
1152
|
+
if (!registerRes.ok) {
|
|
1153
|
+
throw new Error(
|
|
1154
|
+
`Failed to register attachment for direct upload (status ${registerRes.status})`
|
|
1155
|
+
);
|
|
1156
|
+
}
|
|
1157
|
+
let { attachments } = await registerRes.json();
|
|
1158
|
+
let registration = attachments[0];
|
|
1159
|
+
if (!registration) {
|
|
1160
|
+
throw new Error("Live invocation API returned no attachment registrations");
|
|
1161
|
+
}
|
|
1162
|
+
let putRes = await fetch(registration.uploadUrl, {
|
|
1163
|
+
method: "PUT",
|
|
1164
|
+
headers: {
|
|
1165
|
+
...d.mimeType ? { "content-type": d.mimeType } : {},
|
|
1166
|
+
"content-length": String(body.byteLength)
|
|
1167
|
+
},
|
|
1168
|
+
body
|
|
1169
|
+
});
|
|
1170
|
+
if (!putRes.ok) {
|
|
1171
|
+
throw new Error(`Failed to upload attachment content (status ${putRes.status})`);
|
|
1172
|
+
}
|
|
1173
|
+
return {
|
|
1174
|
+
mimeType: d.mimeType,
|
|
1175
|
+
content: { type: "upload_reference", referenceId: registration.referenceId }
|
|
1176
|
+
};
|
|
1177
|
+
};
|
|
1178
|
+
|
|
1179
|
+
// src/adapter/adapter.ts
|
|
1180
|
+
var SlateAdapter = class {
|
|
1181
|
+
constructor(_spec, _tools, _triggers) {
|
|
1182
|
+
this._spec = _spec;
|
|
1183
|
+
this._tools = _tools;
|
|
1184
|
+
this._triggers = _triggers;
|
|
1185
|
+
}
|
|
1186
|
+
_spec;
|
|
1187
|
+
_tools;
|
|
1188
|
+
_triggers;
|
|
1189
|
+
get spec() {
|
|
1190
|
+
return this._spec;
|
|
1191
|
+
}
|
|
1192
|
+
get id() {
|
|
1193
|
+
return this._spec.id;
|
|
1194
|
+
}
|
|
1195
|
+
get name() {
|
|
1196
|
+
return this._spec.name;
|
|
1197
|
+
}
|
|
1198
|
+
get capabilities() {
|
|
1199
|
+
return this._spec.capabilities;
|
|
1200
|
+
}
|
|
1201
|
+
get tools() {
|
|
1202
|
+
return this._tools;
|
|
1203
|
+
}
|
|
1204
|
+
get triggers() {
|
|
1205
|
+
return this._triggers;
|
|
1206
|
+
}
|
|
1207
|
+
get actions() {
|
|
1208
|
+
return [...this._triggers, ...this._tools];
|
|
1209
|
+
}
|
|
1210
|
+
};
|
|
1211
|
+
|
|
1212
|
+
// src/adapter/spec.ts
|
|
1213
|
+
var SlateAdapterSpec = class _SlateAdapterSpec {
|
|
1214
|
+
constructor(_params) {
|
|
1215
|
+
this._params = _params;
|
|
1216
|
+
}
|
|
1217
|
+
_params;
|
|
1218
|
+
static create(params) {
|
|
1219
|
+
let id = params.id?.trim();
|
|
1220
|
+
let name = params.name?.trim();
|
|
1221
|
+
if (!id) {
|
|
1222
|
+
throw new SlateDeclarationError("Adapter id must be a non-empty string");
|
|
1223
|
+
}
|
|
1224
|
+
if (!name) {
|
|
1225
|
+
throw new SlateDeclarationError("Adapter name must be a non-empty string");
|
|
1226
|
+
}
|
|
1227
|
+
return new _SlateAdapterSpec({
|
|
1228
|
+
id,
|
|
1229
|
+
name,
|
|
1230
|
+
capabilities: validateCapabilities(params.capabilities ?? [])
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1233
|
+
get id() {
|
|
1234
|
+
return this._params.id;
|
|
1235
|
+
}
|
|
1236
|
+
get name() {
|
|
1237
|
+
return this._params.name;
|
|
1238
|
+
}
|
|
1239
|
+
get capabilities() {
|
|
1240
|
+
return this._params.capabilities;
|
|
1241
|
+
}
|
|
1242
|
+
get parameters() {
|
|
1243
|
+
return this._params;
|
|
1244
|
+
}
|
|
1245
|
+
tool(spec2, params) {
|
|
1246
|
+
return SlateTool.create(spec2, this.linkAction(params));
|
|
1247
|
+
}
|
|
1248
|
+
publicTool(spec2, params) {
|
|
1249
|
+
return SlatePublicTool.create(spec2, this.linkAction(params));
|
|
1250
|
+
}
|
|
1251
|
+
trigger(spec2, params) {
|
|
1252
|
+
return SlateTrigger.create(spec2, this.linkAction(params));
|
|
1253
|
+
}
|
|
1254
|
+
register(params) {
|
|
1255
|
+
let actions = [...params.tools, ...params.triggers];
|
|
1256
|
+
let seenKeys = /* @__PURE__ */ new Set();
|
|
1257
|
+
for (let action of actions) {
|
|
1258
|
+
if (action.adapter && action.adapter !== this.id) {
|
|
1259
|
+
throw new SlateDeclarationError(
|
|
1260
|
+
`Action "${action.key}" is linked to adapter "${action.adapter}", not "${this.id}"`
|
|
1261
|
+
);
|
|
1262
|
+
}
|
|
1263
|
+
if (!action.adapter) {
|
|
1264
|
+
throw new SlateDeclarationError(
|
|
1265
|
+
`Action "${action.key}" must be created with this adapter's tool(), publicTool(), or trigger() helpers`
|
|
1266
|
+
);
|
|
1267
|
+
}
|
|
1268
|
+
if (seenKeys.has(action.key)) {
|
|
1269
|
+
throw new SlateDeclarationError(
|
|
1270
|
+
`Adapter "${this.id}" already has an action with key "${action.key}"`
|
|
1271
|
+
);
|
|
1272
|
+
}
|
|
1273
|
+
seenKeys.add(action.key);
|
|
1274
|
+
}
|
|
1275
|
+
return new SlateAdapter(this, params.tools, params.triggers);
|
|
1276
|
+
}
|
|
1277
|
+
linkAction(params) {
|
|
1278
|
+
if (params.adapter != null && params.adapter !== this.id) {
|
|
1279
|
+
throw new SlateDeclarationError(
|
|
1280
|
+
`Action "${params.key}" cannot be linked to adapter "${this.id}" because it is already linked to "${params.adapter}"`
|
|
1281
|
+
);
|
|
1282
|
+
}
|
|
1283
|
+
return {
|
|
1284
|
+
...params,
|
|
1285
|
+
adapter: this.id
|
|
1286
|
+
};
|
|
1287
|
+
}
|
|
1288
|
+
};
|
|
1289
|
+
var adapterSpec = (params) => SlateAdapterSpec.create(params);
|
|
1290
|
+
var validateCapabilities = (capabilities) => {
|
|
1291
|
+
let seenIds = /* @__PURE__ */ new Set();
|
|
1292
|
+
return capabilities.map((capability) => {
|
|
1293
|
+
let id = capability.id?.trim();
|
|
1294
|
+
if (!id) {
|
|
1295
|
+
throw new SlateDeclarationError("Adapter capability ids must be non-empty strings");
|
|
1296
|
+
}
|
|
1297
|
+
if (seenIds.has(id)) {
|
|
1298
|
+
throw new SlateDeclarationError(`Adapter capability "${id}" is defined more than once`);
|
|
1299
|
+
}
|
|
1300
|
+
seenIds.add(id);
|
|
1301
|
+
return {
|
|
1302
|
+
id,
|
|
1303
|
+
value: capability.value
|
|
1304
|
+
};
|
|
1305
|
+
});
|
|
1306
|
+
};
|
|
1307
|
+
|
|
1308
|
+
// src/auth/auth.ts
|
|
1309
|
+
var SlateAuth = class _SlateAuth {
|
|
1310
|
+
#outputSchema = null;
|
|
1311
|
+
#authStack = [];
|
|
1312
|
+
constructor() {
|
|
1313
|
+
}
|
|
1314
|
+
static create() {
|
|
1315
|
+
return new _SlateAuth();
|
|
1316
|
+
}
|
|
1317
|
+
output(schema) {
|
|
1318
|
+
this.#outputSchema = schema;
|
|
1319
|
+
return this;
|
|
1320
|
+
}
|
|
1321
|
+
addAuth(auth2) {
|
|
1322
|
+
let existingKeys = this.#authStack.map((a) => a.key);
|
|
1323
|
+
if (existingKeys.includes(auth2.key)) {
|
|
1324
|
+
throw new Error(`Auth with key "${auth2.key}" already exists in the auth stack`);
|
|
1325
|
+
}
|
|
1326
|
+
this.#authStack.push(auth2);
|
|
1327
|
+
return this;
|
|
1328
|
+
}
|
|
1329
|
+
addOauth(auth2) {
|
|
1330
|
+
this.addAuth(auth2);
|
|
1331
|
+
return this;
|
|
1332
|
+
}
|
|
1333
|
+
addTokenAuth(auth2) {
|
|
1334
|
+
this.addAuth(auth2);
|
|
1335
|
+
return this;
|
|
1336
|
+
}
|
|
1337
|
+
addServiceAccountAuth(auth2) {
|
|
1338
|
+
this.addAuth(auth2);
|
|
1339
|
+
return this;
|
|
1340
|
+
}
|
|
1341
|
+
addCustomAuth(auth2) {
|
|
1342
|
+
this.addAuth(auth2);
|
|
1343
|
+
return this;
|
|
1344
|
+
}
|
|
1345
|
+
addNone() {
|
|
1346
|
+
this.addAuth({
|
|
1347
|
+
type: "auth.none",
|
|
1348
|
+
name: "No Authentication",
|
|
1349
|
+
key: "none"
|
|
1350
|
+
});
|
|
1351
|
+
return this;
|
|
1352
|
+
}
|
|
1353
|
+
get authStack() {
|
|
1354
|
+
return this.#authStack.filter((a) => a.type !== "auth.none");
|
|
1355
|
+
}
|
|
1356
|
+
get outputSchema() {
|
|
1357
|
+
if (!this.#outputSchema) {
|
|
1358
|
+
throw new Error("Output schema is not defined for this auth");
|
|
1359
|
+
}
|
|
1360
|
+
return this.#outputSchema;
|
|
1361
|
+
}
|
|
1362
|
+
};
|
|
1363
|
+
var auth = () => SlateAuth.create();
|
|
1364
|
+
|
|
1365
|
+
// src/auth/oauth.ts
|
|
1366
|
+
var isOAuthTokenResponse = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1367
|
+
var formatOAuthTokenResponseMessage = (fieldLabel, providerLabel = "OAuth provider", operation = "token response") => `${providerLabel} OAuth ${operation} did not return ${fieldLabel}.`;
|
|
1368
|
+
var getOAuthExpiresAtFromExpiresIn = (expiresIn, options = {}) => {
|
|
1369
|
+
let {
|
|
1370
|
+
nowMs = Date.now(),
|
|
1371
|
+
providerLabel,
|
|
1372
|
+
operation,
|
|
1373
|
+
required = false,
|
|
1374
|
+
expiresInType = "numberLike",
|
|
1375
|
+
message
|
|
1376
|
+
} = options;
|
|
1377
|
+
if (expiresIn === void 0 || expiresIn === null || expiresIn === "") {
|
|
1378
|
+
if (required) {
|
|
1379
|
+
throw createApiServiceError(
|
|
1380
|
+
message ?? formatOAuthTokenResponseMessage(
|
|
1381
|
+
"a valid expires_in value",
|
|
1382
|
+
providerLabel,
|
|
1383
|
+
operation
|
|
1384
|
+
),
|
|
1385
|
+
{ reason: "oauth_token_response" }
|
|
1386
|
+
);
|
|
1387
|
+
}
|
|
1388
|
+
return void 0;
|
|
1389
|
+
}
|
|
1390
|
+
let seconds = typeof expiresIn === "number" ? expiresIn : expiresInType === "numberLike" && typeof expiresIn === "string" ? Number(expiresIn) : Number.NaN;
|
|
1391
|
+
if (!Number.isFinite(seconds)) {
|
|
1392
|
+
throw createApiServiceError(
|
|
1393
|
+
message ?? formatOAuthTokenResponseMessage("a valid expires_in value", providerLabel, operation),
|
|
1394
|
+
{ reason: "oauth_token_response" }
|
|
1395
|
+
);
|
|
1396
|
+
}
|
|
1397
|
+
return new Date(nowMs + seconds * 1e3).toISOString();
|
|
1398
|
+
};
|
|
1399
|
+
var getRefreshToken = (refreshToken, previousRefreshToken, fallbackMode) => {
|
|
1400
|
+
if (typeof refreshToken === "string") {
|
|
1401
|
+
if (fallbackMode === "falsy" && !refreshToken) {
|
|
1402
|
+
return previousRefreshToken;
|
|
1403
|
+
}
|
|
1404
|
+
return refreshToken;
|
|
1405
|
+
}
|
|
1406
|
+
if (fallbackMode === "falsy" && !refreshToken) {
|
|
1407
|
+
return previousRefreshToken;
|
|
1408
|
+
}
|
|
1409
|
+
return refreshToken === void 0 || refreshToken === null ? previousRefreshToken : void 0;
|
|
1410
|
+
};
|
|
1411
|
+
var normalizeOAuthTokenResponse = (data, options = {}) => {
|
|
1412
|
+
let {
|
|
1413
|
+
providerLabel,
|
|
1414
|
+
operation,
|
|
1415
|
+
previousRefreshToken,
|
|
1416
|
+
refreshTokenFallbackMode = "nullish",
|
|
1417
|
+
accessTokenMessage,
|
|
1418
|
+
expiresInMessage,
|
|
1419
|
+
...expiresAtOptions
|
|
1420
|
+
} = options;
|
|
1421
|
+
if (!isOAuthTokenResponse(data)) {
|
|
1422
|
+
throw createApiServiceError(
|
|
1423
|
+
accessTokenMessage ?? formatOAuthTokenResponseMessage("a token response object", providerLabel, operation),
|
|
1424
|
+
{ reason: "oauth_token_response" }
|
|
1425
|
+
);
|
|
1426
|
+
}
|
|
1427
|
+
if (typeof data.access_token !== "string" || !data.access_token) {
|
|
1428
|
+
throw createApiServiceError(
|
|
1429
|
+
accessTokenMessage ?? formatOAuthTokenResponseMessage("an access token", providerLabel, operation),
|
|
1430
|
+
{ reason: "oauth_token_response" }
|
|
1431
|
+
);
|
|
1432
|
+
}
|
|
1433
|
+
return {
|
|
1434
|
+
token: data.access_token,
|
|
1435
|
+
refreshToken: getRefreshToken(
|
|
1436
|
+
data.refresh_token,
|
|
1437
|
+
previousRefreshToken,
|
|
1438
|
+
refreshTokenFallbackMode
|
|
1439
|
+
),
|
|
1440
|
+
expiresAt: getOAuthExpiresAtFromExpiresIn(data.expires_in, {
|
|
1441
|
+
...expiresAtOptions,
|
|
1442
|
+
providerLabel,
|
|
1443
|
+
operation,
|
|
1444
|
+
message: expiresInMessage
|
|
1445
|
+
})
|
|
1446
|
+
};
|
|
1447
|
+
};
|
|
1448
|
+
|
|
1449
|
+
// src/auth/redact.ts
|
|
1450
|
+
var AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX = "$$MT$secret$authConfig$";
|
|
1451
|
+
var AuthConfigSecretRedactor = class {
|
|
1452
|
+
secretToPlaceholder = /* @__PURE__ */ new Map();
|
|
1453
|
+
constructor(authConfig) {
|
|
1454
|
+
if (authConfig) this.buildSecretMap(authConfig);
|
|
1455
|
+
}
|
|
1456
|
+
redact(value) {
|
|
1457
|
+
return this.transform(value, (stringValue) => {
|
|
1458
|
+
return this.secretToPlaceholder.get(stringValue) ?? stringValue;
|
|
1459
|
+
});
|
|
1460
|
+
}
|
|
1461
|
+
buildSecretMap(value, path = []) {
|
|
1462
|
+
if (typeof value === "string") {
|
|
1463
|
+
if (value.length === 0) return;
|
|
1464
|
+
this.secretToPlaceholder.set(
|
|
1465
|
+
value,
|
|
1466
|
+
`${AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX}${path.join(".")}`
|
|
1467
|
+
);
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
1470
|
+
if (Array.isArray(value)) {
|
|
1471
|
+
value.forEach((item, index) => {
|
|
1472
|
+
this.buildSecretMap(item, [...path, String(index)]);
|
|
1473
|
+
});
|
|
1474
|
+
return;
|
|
1475
|
+
}
|
|
1476
|
+
if (this.isPlainObject(value)) {
|
|
1477
|
+
Object.entries(value).forEach(([key, nestedValue]) => {
|
|
1478
|
+
this.buildSecretMap(nestedValue, [...path, key]);
|
|
1479
|
+
});
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
transform(value, transformString) {
|
|
1483
|
+
if (typeof value === "string") {
|
|
1484
|
+
return transformString(value);
|
|
1485
|
+
}
|
|
1486
|
+
if (Array.isArray(value)) {
|
|
1487
|
+
return value.map((item) => this.transform(item, transformString));
|
|
1488
|
+
}
|
|
1489
|
+
if (this.isPlainObject(value)) {
|
|
1490
|
+
let result = {};
|
|
1491
|
+
Object.entries(value).forEach(([key, nestedValue]) => {
|
|
1492
|
+
result[key] = this.transform(nestedValue, transformString);
|
|
1493
|
+
});
|
|
1494
|
+
return result;
|
|
1495
|
+
}
|
|
1496
|
+
return value;
|
|
1497
|
+
}
|
|
1498
|
+
isPlainObject(value) {
|
|
1499
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1500
|
+
}
|
|
1501
|
+
};
|
|
1502
|
+
var redactUrlAttachmentSecrets = (attachments, authConfig) => {
|
|
1503
|
+
if (!authConfig || !attachments) return attachments;
|
|
1504
|
+
let redactor = new AuthConfigSecretRedactor(authConfig);
|
|
1505
|
+
return attachments.map((attachment) => {
|
|
1506
|
+
if (attachment.content.type !== "url") return attachment;
|
|
1507
|
+
if (!attachment.content.headers && !attachment.content.query) return attachment;
|
|
1508
|
+
return {
|
|
1509
|
+
...attachment,
|
|
1510
|
+
content: {
|
|
1511
|
+
...attachment.content,
|
|
1512
|
+
headers: attachment.content.headers ? redactor.redact(attachment.content.headers) : void 0,
|
|
1513
|
+
query: attachment.content.query ? redactor.redact(attachment.content.query) : void 0
|
|
1514
|
+
}
|
|
1515
|
+
};
|
|
1516
|
+
});
|
|
1517
|
+
};
|
|
1518
|
+
|
|
1519
|
+
// src/axios/index.ts
|
|
1520
|
+
import baseAxios, { getAdapter, isAxiosError as isAxiosError2 } from "axios";
|
|
1521
|
+
|
|
1522
|
+
// src/axios/trace.ts
|
|
1523
|
+
var traceDraftsByConfig = /* @__PURE__ */ new WeakMap();
|
|
1524
|
+
var traceDraftsByHeaders = /* @__PURE__ */ new WeakMap();
|
|
1525
|
+
var TRACE_TEXT_LIMIT = 10 * 1024;
|
|
1526
|
+
var REDACTED_VALUE = "[redacted]";
|
|
1527
|
+
var STRUCTURED_DEPTH_LIMIT = 6;
|
|
1528
|
+
var STRUCTURED_ENTRY_LIMIT = 50;
|
|
1529
|
+
var CORE_SECRET_KEY_ATOMS = [
|
|
1530
|
+
// HTTP authentication
|
|
1531
|
+
"authorization",
|
|
1532
|
+
"proxy[-_.]?authorization",
|
|
1533
|
+
"www[-_.]?authenticate",
|
|
1534
|
+
"bearer",
|
|
1535
|
+
// Generic tokens
|
|
1536
|
+
"token",
|
|
1537
|
+
"tokens",
|
|
1538
|
+
"access[-_.]?token",
|
|
1539
|
+
"refresh[-_.]?token",
|
|
1540
|
+
"id[-_.]?token",
|
|
1541
|
+
"auth[-_.]?token",
|
|
1542
|
+
"bearer[-_.]?token",
|
|
1543
|
+
"session[-_.]?token",
|
|
1544
|
+
"api[-_.]?token",
|
|
1545
|
+
"app[-_.]?token",
|
|
1546
|
+
"user[-_.]?token",
|
|
1547
|
+
"oauth[-_.]?token",
|
|
1548
|
+
"personal[-_.]?access[-_.]?token",
|
|
1549
|
+
"x[-_.]?auth[-_.]?token",
|
|
1550
|
+
"x[-_.]?access[-_.]?token",
|
|
1551
|
+
"x[-_.]?refresh[-_.]?token",
|
|
1552
|
+
// API keys
|
|
1553
|
+
"apikey",
|
|
1554
|
+
"api[-_.]?key",
|
|
1555
|
+
"app[-_.]?key",
|
|
1556
|
+
"x[-_.]?api[-_.]?key",
|
|
1557
|
+
"x[-_.]?app[-_.]?key",
|
|
1558
|
+
// OAuth client credentials
|
|
1559
|
+
"client[-_.]?secret",
|
|
1560
|
+
"client[-_.]?key",
|
|
1561
|
+
"consumer[-_.]?secret",
|
|
1562
|
+
"consumer[-_.]?key",
|
|
1563
|
+
// Cryptographic keys
|
|
1564
|
+
"private[-_.]?key",
|
|
1565
|
+
"privatekey",
|
|
1566
|
+
"secret[-_.]?key",
|
|
1567
|
+
"secretkey",
|
|
1568
|
+
"secret[-_.]?access[-_.]?key",
|
|
1569
|
+
"encryption[-_.]?key",
|
|
1570
|
+
"decryption[-_.]?key",
|
|
1571
|
+
"signing[-_.]?key",
|
|
1572
|
+
"signing[-_.]?secret",
|
|
1573
|
+
"master[-_.]?key",
|
|
1574
|
+
"master[-_.]?secret",
|
|
1575
|
+
"master[-_.]?password",
|
|
1576
|
+
"shared[-_.]?secret",
|
|
1577
|
+
"webhook[-_.]?secret",
|
|
1578
|
+
"webhook[-_.]?signing[-_.]?secret",
|
|
1579
|
+
// OAuth codes & PKCE
|
|
1580
|
+
"auth[-_.]?code",
|
|
1581
|
+
"authcode",
|
|
1582
|
+
"authorization[-_.]?code",
|
|
1583
|
+
"code[-_.]?verifier",
|
|
1584
|
+
"code[-_.]?challenge",
|
|
1585
|
+
// Passwords & passcodes
|
|
1586
|
+
"password",
|
|
1587
|
+
"passwd",
|
|
1588
|
+
"pwd",
|
|
1589
|
+
"passphrase",
|
|
1590
|
+
"pass[-_.]?phrase",
|
|
1591
|
+
"pin",
|
|
1592
|
+
"passcode",
|
|
1593
|
+
// Generic secret markers
|
|
1594
|
+
"secret",
|
|
1595
|
+
"secrets",
|
|
1596
|
+
"credential",
|
|
1597
|
+
"credentials",
|
|
1598
|
+
"creds",
|
|
1599
|
+
"auth",
|
|
1600
|
+
"x[-_.]?auth",
|
|
1601
|
+
"x[-_.]?auth[-_.]?key",
|
|
1602
|
+
// CSRF / XSRF
|
|
1603
|
+
"csrf",
|
|
1604
|
+
"xsrf",
|
|
1605
|
+
"csrf[-_.]?token",
|
|
1606
|
+
"xsrf[-_.]?token",
|
|
1607
|
+
"x[-_.]?csrf[-_.]?token",
|
|
1608
|
+
"x[-_.]?xsrf[-_.]?token",
|
|
1609
|
+
// JWT
|
|
1610
|
+
"jwt",
|
|
1611
|
+
// Sessions & cookies
|
|
1612
|
+
"session[-_.]?id",
|
|
1613
|
+
"sessionid",
|
|
1614
|
+
"sid",
|
|
1615
|
+
"cookie",
|
|
1616
|
+
"cookies",
|
|
1617
|
+
"set[-_.]?cookie",
|
|
1618
|
+
// Signatures / MAC
|
|
1619
|
+
"signature",
|
|
1620
|
+
"x[-_.]?hub[-_.]?signature",
|
|
1621
|
+
"x[-_.]?signature",
|
|
1622
|
+
"sig",
|
|
1623
|
+
"hmac",
|
|
1624
|
+
"mac",
|
|
1625
|
+
// Crypto artifacts
|
|
1626
|
+
"salt",
|
|
1627
|
+
"nonce",
|
|
1628
|
+
// Multi-factor / verification
|
|
1629
|
+
"otp",
|
|
1630
|
+
"totp",
|
|
1631
|
+
"mfa",
|
|
1632
|
+
"mfa[-_.]?code",
|
|
1633
|
+
"2fa",
|
|
1634
|
+
"two[-_.]?factor",
|
|
1635
|
+
"twofactor",
|
|
1636
|
+
"verification[-_.]?code",
|
|
1637
|
+
"verify[-_.]?code",
|
|
1638
|
+
"confirm(?:ation)?[-_.]?code",
|
|
1639
|
+
"sms[-_.]?code",
|
|
1640
|
+
"email[-_.]?code",
|
|
1641
|
+
// Recovery & seed phrases
|
|
1642
|
+
"seed[-_.]?phrase",
|
|
1643
|
+
"mnemonic",
|
|
1644
|
+
"recovery[-_.]?key",
|
|
1645
|
+
"recovery[-_.]?code",
|
|
1646
|
+
"recovery[-_.]?phrase",
|
|
1647
|
+
// PII / financial
|
|
1648
|
+
"card[-_.]?number",
|
|
1649
|
+
"card[-_.]?code",
|
|
1650
|
+
"cvv",
|
|
1651
|
+
"cvc",
|
|
1652
|
+
"ccv",
|
|
1653
|
+
"cc[-_.]?num(?:ber)?",
|
|
1654
|
+
"pan",
|
|
1655
|
+
"ssn",
|
|
1656
|
+
"social[-_.]?security",
|
|
1657
|
+
"license[-_.]?key"
|
|
1658
|
+
];
|
|
1659
|
+
var URL_FORM_SECRET_KEY_ATOMS = [...CORE_SECRET_KEY_ATOMS, "code"];
|
|
1660
|
+
var buildKeyBoundaryPattern = (atoms, flags) => new RegExp(`(?:^|[^A-Za-z0-9])(?:${atoms.join("|")})(?=[^A-Za-z0-9]|$)`, flags);
|
|
1661
|
+
var SECRET_KEY_PATTERN = buildKeyBoundaryPattern(CORE_SECRET_KEY_ATOMS, "i");
|
|
1662
|
+
var URL_FORM_SECRET_KEY_PATTERN = buildKeyBoundaryPattern(URL_FORM_SECRET_KEY_ATOMS, "i");
|
|
1663
|
+
var NON_SECRET_KEY_EXACT = /* @__PURE__ */ new Set([
|
|
1664
|
+
"token_type",
|
|
1665
|
+
"token-type",
|
|
1666
|
+
"tokentype",
|
|
1667
|
+
"token_kind",
|
|
1668
|
+
"token-kind",
|
|
1669
|
+
"tokenkind",
|
|
1670
|
+
"token_ttl",
|
|
1671
|
+
"token-ttl",
|
|
1672
|
+
"token_expires_in",
|
|
1673
|
+
"token-expires-in",
|
|
1674
|
+
"token_expiry",
|
|
1675
|
+
"signature_method",
|
|
1676
|
+
"signature-method",
|
|
1677
|
+
"signature_type",
|
|
1678
|
+
"signature-type",
|
|
1679
|
+
"signature_version",
|
|
1680
|
+
"signature-version",
|
|
1681
|
+
"auth_type",
|
|
1682
|
+
"auth-type",
|
|
1683
|
+
"auth_method",
|
|
1684
|
+
"auth-method",
|
|
1685
|
+
"authentication_type",
|
|
1686
|
+
"authentication-type",
|
|
1687
|
+
"authentication_method",
|
|
1688
|
+
"authentication-method",
|
|
1689
|
+
"grant_type",
|
|
1690
|
+
"grant-type",
|
|
1691
|
+
"password_strength",
|
|
1692
|
+
"password-strength",
|
|
1693
|
+
"password_policy",
|
|
1694
|
+
"password-policy",
|
|
1695
|
+
"key_type",
|
|
1696
|
+
"key-type",
|
|
1697
|
+
"key_name",
|
|
1698
|
+
"key-name",
|
|
1699
|
+
"key_id",
|
|
1700
|
+
"key-id",
|
|
1701
|
+
"kid"
|
|
1702
|
+
]);
|
|
1703
|
+
var isSecretKeyName = (name) => {
|
|
1704
|
+
let normalized = name.toLowerCase();
|
|
1705
|
+
if (NON_SECRET_KEY_EXACT.has(normalized)) return false;
|
|
1706
|
+
return SECRET_KEY_PATTERN.test(normalized);
|
|
1707
|
+
};
|
|
1708
|
+
var isUrlFormSecretKeyName = (name) => {
|
|
1709
|
+
let normalized = name.toLowerCase();
|
|
1710
|
+
if (NON_SECRET_KEY_EXACT.has(normalized)) return false;
|
|
1711
|
+
return URL_FORM_SECRET_KEY_PATTERN.test(normalized);
|
|
1712
|
+
};
|
|
1713
|
+
var KNOWN_SECRET_VALUE_PATTERNS = [
|
|
1714
|
+
// JSON Web Tokens (header.payload.signature)
|
|
1715
|
+
/\beyJ[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{4,}\b/g,
|
|
1716
|
+
// AWS access key IDs
|
|
1717
|
+
/\b(?:AKIA|ASIA|AGPA|AIDA|ANPA|ANVA|AROA|APKA|ASCA)[A-Z0-9]{16}\b/g,
|
|
1718
|
+
// GitHub tokens (PAT / OAuth / server-to-server / user-to-server / refresh)
|
|
1719
|
+
/\bgh[pousr]_[A-Za-z0-9]{30,}\b/g,
|
|
1720
|
+
// Slack tokens
|
|
1721
|
+
/\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g,
|
|
1722
|
+
// Stripe secret / public / restricted keys
|
|
1723
|
+
/\b(?:sk|rk|pk)_(?:test|live)_[A-Za-z0-9]{16,}\b/g,
|
|
1724
|
+
// OpenAI API keys
|
|
1725
|
+
/\bsk-(?:proj-)?[A-Za-z0-9_-]{20,}\b/g,
|
|
1726
|
+
// Anthropic API keys
|
|
1727
|
+
/\bsk-ant-[A-Za-z0-9_-]{20,}\b/g,
|
|
1728
|
+
// Google API keys
|
|
1729
|
+
/\bAIza[A-Za-z0-9_-]{35}\b/g,
|
|
1730
|
+
// SendGrid API keys
|
|
1731
|
+
/\bSG\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}\b/g,
|
|
1732
|
+
// Twilio API keys
|
|
1733
|
+
/\bSK[0-9a-fA-F]{32}\b/g,
|
|
1734
|
+
// PEM-encoded private keys (multi-line)
|
|
1735
|
+
/-----BEGIN[A-Z ]*PRIVATE KEY-----[\s\S]*?-----END[A-Z ]*PRIVATE KEY-----/g,
|
|
1736
|
+
// SSH private keys (OpenSSH format)
|
|
1737
|
+
/-----BEGIN OPENSSH PRIVATE KEY-----[\s\S]*?-----END OPENSSH PRIVATE KEY-----/g
|
|
1738
|
+
];
|
|
1739
|
+
var HTTP_AUTH_SCHEME_PATTERN = /\b(bearer|basic|digest|token|negotiate|apikey)\s+([A-Za-z0-9_\-.~+/=]{4,})/gi;
|
|
1740
|
+
var GENERIC_KEY_VALUE_PATTERN = /(?<![A-Za-z0-9])([A-Za-z0-9][A-Za-z0-9_\-.]*)(\s*=\s*)([^&#\s;]+)/g;
|
|
1741
|
+
var GENERIC_JSON_KEY_VALUE_PATTERN = /"([^"\\]*(?:\\.[^"\\]*)*)"(\s*:\s*)"([^"\\]*(?:\\.[^"\\]*)*)"/g;
|
|
1742
|
+
var SAFE_HEADER_NAMES = /* @__PURE__ */ new Set([
|
|
1743
|
+
"accept",
|
|
1744
|
+
"accept-encoding",
|
|
1745
|
+
"accept-language",
|
|
1746
|
+
"cache-control",
|
|
1747
|
+
"connection",
|
|
1748
|
+
"content-encoding",
|
|
1749
|
+
"content-language",
|
|
1750
|
+
"content-length",
|
|
1751
|
+
"content-type",
|
|
1752
|
+
"date",
|
|
1753
|
+
"etag",
|
|
1754
|
+
"expires",
|
|
1755
|
+
"if-modified-since",
|
|
1756
|
+
"if-none-match",
|
|
1757
|
+
"keep-alive",
|
|
1758
|
+
"last-modified",
|
|
1759
|
+
"location",
|
|
1760
|
+
"origin",
|
|
1761
|
+
"pragma",
|
|
1762
|
+
"referer",
|
|
1763
|
+
"referrer-policy",
|
|
1764
|
+
"request-id",
|
|
1765
|
+
"retry-after",
|
|
1766
|
+
"server",
|
|
1767
|
+
"transfer-encoding",
|
|
1768
|
+
"user-agent",
|
|
1769
|
+
"vary",
|
|
1770
|
+
"via",
|
|
1771
|
+
"x-correlation-id",
|
|
1772
|
+
"x-powered-by",
|
|
1773
|
+
"x-request-id",
|
|
1774
|
+
"x-slates-provider",
|
|
1775
|
+
"x-trace-id"
|
|
1776
|
+
]);
|
|
1777
|
+
var SAFE_HEADER_PREFIXES = ["ratelimit-", "x-ratelimit-"];
|
|
1778
|
+
var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1779
|
+
var isObjectLike = (value) => typeof value === "object" && value !== null;
|
|
1780
|
+
var normalizeContentType = (value) => value?.split(";")[0]?.trim().toLowerCase() || void 0;
|
|
1781
|
+
var isTextContentType = (contentType) => !contentType || /(^text\/)|json|xml|html|javascript|graphql|x-www-form-urlencoded|svg/.test(contentType);
|
|
1782
|
+
var isSafeHeaderName = (name) => {
|
|
1783
|
+
let normalized = name.toLowerCase();
|
|
1784
|
+
if (isSecretKeyName(normalized)) return false;
|
|
1785
|
+
if (SAFE_HEADER_NAMES.has(normalized)) return true;
|
|
1786
|
+
return SAFE_HEADER_PREFIXES.some((prefix) => normalized.startsWith(prefix));
|
|
1787
|
+
};
|
|
1788
|
+
var truncateText = (text) => {
|
|
1789
|
+
if (text.length <= TRACE_TEXT_LIMIT) {
|
|
1790
|
+
return { text, truncated: false };
|
|
1791
|
+
}
|
|
1792
|
+
return {
|
|
1793
|
+
text: `${text.slice(0, TRACE_TEXT_LIMIT)}...[truncated]`,
|
|
1794
|
+
truncated: true
|
|
1795
|
+
};
|
|
1796
|
+
};
|
|
1797
|
+
var sanitizeFreeText = (text, redactor) => {
|
|
1798
|
+
if (!text) return text;
|
|
1799
|
+
let result = redactor ? redactor.redact(text) : text;
|
|
1800
|
+
result = result.replace(
|
|
1801
|
+
HTTP_AUTH_SCHEME_PATTERN,
|
|
1802
|
+
(_match, scheme) => `${scheme} ${REDACTED_VALUE}`
|
|
1803
|
+
);
|
|
1804
|
+
for (let pattern of KNOWN_SECRET_VALUE_PATTERNS) {
|
|
1805
|
+
result = result.replace(pattern, REDACTED_VALUE);
|
|
1806
|
+
}
|
|
1807
|
+
result = result.replace(
|
|
1808
|
+
GENERIC_KEY_VALUE_PATTERN,
|
|
1809
|
+
(match, key, equals, _value) => isUrlFormSecretKeyName(key) ? `${key}${equals}${REDACTED_VALUE}` : match
|
|
1810
|
+
);
|
|
1811
|
+
result = result.replace(
|
|
1812
|
+
GENERIC_JSON_KEY_VALUE_PATTERN,
|
|
1813
|
+
(match, key, colon, _value) => isSecretKeyName(key) ? `"${key}"${colon}"${REDACTED_VALUE}"` : match
|
|
1814
|
+
);
|
|
1815
|
+
return result;
|
|
1816
|
+
};
|
|
1817
|
+
var sanitizeScalar = (value, redactor) => truncateText(sanitizeFreeText(value, redactor));
|
|
1818
|
+
var redactStructuredValue = (value, depth = 0, redactor) => {
|
|
1819
|
+
if (value == null) return value;
|
|
1820
|
+
if (depth >= STRUCTURED_DEPTH_LIMIT) return "[truncated]";
|
|
1821
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
1822
|
+
return typeof value === "string" ? sanitizeFreeText(value, redactor) : value;
|
|
1823
|
+
}
|
|
1824
|
+
if (Array.isArray(value)) {
|
|
1825
|
+
return value.slice(0, STRUCTURED_ENTRY_LIMIT).map((entry) => redactStructuredValue(entry, depth + 1, redactor));
|
|
1826
|
+
}
|
|
1827
|
+
if (isRecord2(value)) {
|
|
1828
|
+
return Object.fromEntries(
|
|
1829
|
+
Object.entries(value).slice(0, STRUCTURED_ENTRY_LIMIT).map(([key, entry]) => [
|
|
1830
|
+
key,
|
|
1831
|
+
isSecretKeyName(key) ? REDACTED_VALUE : redactStructuredValue(entry, depth + 1, redactor)
|
|
1832
|
+
])
|
|
1833
|
+
);
|
|
1834
|
+
}
|
|
1835
|
+
return String(value);
|
|
1836
|
+
};
|
|
1837
|
+
var maybeParseJson = (text, contentType) => {
|
|
1838
|
+
let trimmed = text.trim();
|
|
1839
|
+
if (!trimmed) return null;
|
|
1840
|
+
if (!contentType?.includes("json") && !/^[[{]/.test(trimmed)) {
|
|
1841
|
+
return null;
|
|
1842
|
+
}
|
|
1843
|
+
try {
|
|
1844
|
+
return JSON.parse(trimmed);
|
|
1845
|
+
} catch {
|
|
1846
|
+
return null;
|
|
1847
|
+
}
|
|
1848
|
+
};
|
|
1849
|
+
var sanitizeTextBody = (text, contentType, redactor) => {
|
|
1850
|
+
if (!text) return void 0;
|
|
1851
|
+
let normalizedContentType = normalizeContentType(contentType);
|
|
1852
|
+
let parsedJson = maybeParseJson(text, normalizedContentType);
|
|
1853
|
+
let normalizedText = parsedJson !== null ? JSON.stringify(redactStructuredValue(parsedJson, 0, redactor)) : sanitizeFreeText(text, redactor);
|
|
1854
|
+
let { text: truncatedText, truncated } = truncateText(normalizedText);
|
|
1855
|
+
return {
|
|
1856
|
+
...normalizedContentType ? { contentType: normalizedContentType } : {},
|
|
1857
|
+
text: truncatedText,
|
|
1858
|
+
...truncated ? { truncated: true } : {}
|
|
1859
|
+
};
|
|
1860
|
+
};
|
|
1861
|
+
var isBinaryLike = (value) => {
|
|
1862
|
+
if (typeof Buffer !== "undefined" && Buffer.isBuffer(value)) return true;
|
|
1863
|
+
if (value instanceof ArrayBuffer) return true;
|
|
1864
|
+
if (ArrayBuffer.isView(value)) return true;
|
|
1865
|
+
if (typeof Blob !== "undefined" && value instanceof Blob) return true;
|
|
1866
|
+
if (typeof FormData !== "undefined" && value instanceof FormData) return true;
|
|
1867
|
+
return false;
|
|
1868
|
+
};
|
|
1869
|
+
var serializeTextBody = (value, contentType, redactor) => {
|
|
1870
|
+
let normalizedContentType = normalizeContentType(contentType);
|
|
1871
|
+
if (value == null || isBinaryLike(value) || !isTextContentType(normalizedContentType)) {
|
|
1872
|
+
return void 0;
|
|
1873
|
+
}
|
|
1874
|
+
if (typeof value === "string") {
|
|
1875
|
+
return sanitizeTextBody(value, normalizedContentType, redactor);
|
|
1876
|
+
}
|
|
1877
|
+
if (value instanceof URLSearchParams) {
|
|
1878
|
+
return sanitizeTextBody(value.toString(), normalizedContentType, redactor);
|
|
1879
|
+
}
|
|
1880
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
1881
|
+
return sanitizeTextBody(String(value), normalizedContentType, redactor);
|
|
1882
|
+
}
|
|
1883
|
+
if (Array.isArray(value) || isRecord2(value)) {
|
|
1884
|
+
return sanitizeTextBody(
|
|
1885
|
+
JSON.stringify(redactStructuredValue(value, 0, redactor)),
|
|
1886
|
+
"application/json",
|
|
1887
|
+
redactor
|
|
1888
|
+
);
|
|
1889
|
+
}
|
|
1890
|
+
return void 0;
|
|
1891
|
+
};
|
|
1892
|
+
var buildUrl = (baseURL, url) => {
|
|
1893
|
+
if (!url) return "";
|
|
1894
|
+
if (!baseURL) return url;
|
|
1895
|
+
try {
|
|
1896
|
+
return new URL(url, baseURL).toString();
|
|
1897
|
+
} catch {
|
|
1898
|
+
return url;
|
|
1899
|
+
}
|
|
1900
|
+
};
|
|
1901
|
+
var REDACTED_ENCODED = encodeURIComponent(REDACTED_VALUE);
|
|
1902
|
+
var decodeRedactedMarker = (value) => REDACTED_ENCODED === REDACTED_VALUE ? value : value.split(REDACTED_ENCODED).join(REDACTED_VALUE);
|
|
1903
|
+
var redactHashFragment = (hash, redactor) => {
|
|
1904
|
+
if (!hash?.includes("=")) return hash;
|
|
1905
|
+
let withoutHash = hash.startsWith("#") ? hash.slice(1) : hash;
|
|
1906
|
+
let redacted = withoutHash.replace(
|
|
1907
|
+
/(?<![A-Za-z0-9])([A-Za-z0-9][A-Za-z0-9_\-.]*)=([^&]*)/g,
|
|
1908
|
+
(match, key, rawValue) => {
|
|
1909
|
+
if (isUrlFormSecretKeyName(key)) return `${key}=${REDACTED_VALUE}`;
|
|
1910
|
+
let literalRedacted = redactor ? redactor.redact(rawValue) : rawValue;
|
|
1911
|
+
return literalRedacted !== rawValue ? `${key}=${literalRedacted}` : match;
|
|
1912
|
+
}
|
|
1913
|
+
);
|
|
1914
|
+
return redacted ? `#${redacted}` : "";
|
|
1915
|
+
};
|
|
1916
|
+
var sanitizeUrl = (value, redactor) => {
|
|
1917
|
+
if (!value) return value;
|
|
1918
|
+
try {
|
|
1919
|
+
let url = new URL(value);
|
|
1920
|
+
if (url.username || url.password) {
|
|
1921
|
+
url.username = "";
|
|
1922
|
+
url.password = "";
|
|
1923
|
+
}
|
|
1924
|
+
for (let key of Array.from(url.searchParams.keys())) {
|
|
1925
|
+
if (isUrlFormSecretKeyName(key)) {
|
|
1926
|
+
url.searchParams.set(key, REDACTED_VALUE);
|
|
1927
|
+
continue;
|
|
1928
|
+
}
|
|
1929
|
+
let rawValue = url.searchParams.get(key) ?? "";
|
|
1930
|
+
let literalRedacted = redactor ? redactor.redact(rawValue) : rawValue;
|
|
1931
|
+
if (literalRedacted !== rawValue) url.searchParams.set(key, literalRedacted);
|
|
1932
|
+
}
|
|
1933
|
+
url.hash = redactHashFragment(url.hash, redactor);
|
|
1934
|
+
return decodeRedactedMarker(url.toString());
|
|
1935
|
+
} catch {
|
|
1936
|
+
let text = redactor ? redactor.redact(value) : value;
|
|
1937
|
+
return text.replace(
|
|
1938
|
+
/([?&]([^=&#]+)=)([^&#]+)/g,
|
|
1939
|
+
(_match, prefix, key, rawValue) => isUrlFormSecretKeyName(key) ? `${prefix}${REDACTED_VALUE}` : `${prefix}${rawValue}`
|
|
1940
|
+
);
|
|
1941
|
+
}
|
|
1942
|
+
};
|
|
1943
|
+
var flattenHeaderValue = (value) => {
|
|
1944
|
+
if (typeof value === "string") return value;
|
|
1945
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
1946
|
+
if (Array.isArray(value)) {
|
|
1947
|
+
let normalized = value.map((entry) => flattenHeaderValue(entry)).filter((entry) => typeof entry === "string" && entry.length > 0);
|
|
1948
|
+
return normalized.length > 0 ? normalized.join(", ") : void 0;
|
|
1949
|
+
}
|
|
1950
|
+
return void 0;
|
|
1951
|
+
};
|
|
1952
|
+
var headerEntries = (headers) => {
|
|
1953
|
+
if (!headers) return [];
|
|
1954
|
+
if (typeof headers.toJSON === "function") {
|
|
1955
|
+
let json = headers.toJSON();
|
|
1956
|
+
if (isRecord2(json)) {
|
|
1957
|
+
return Object.entries(json).map(([key, value]) => {
|
|
1958
|
+
let flattened = flattenHeaderValue(value);
|
|
1959
|
+
return flattened ? [key, flattened] : null;
|
|
1960
|
+
}).filter((entry) => entry !== null);
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
if (typeof headers.entries === "function") {
|
|
1964
|
+
return Array.from(
|
|
1965
|
+
headers.entries()
|
|
1966
|
+
).map(([key, value]) => [key, value]);
|
|
1967
|
+
}
|
|
1968
|
+
if (isRecord2(headers)) {
|
|
1969
|
+
return Object.entries(headers).map(([key, value]) => {
|
|
1970
|
+
let flattened = flattenHeaderValue(value);
|
|
1971
|
+
return flattened ? [key, flattened] : null;
|
|
1972
|
+
}).filter((entry) => entry !== null);
|
|
1973
|
+
}
|
|
1974
|
+
return [];
|
|
1975
|
+
};
|
|
1976
|
+
var sanitizeHeaders = (headers, redactor) => {
|
|
1977
|
+
let entries = headerEntries(headers).map(
|
|
1978
|
+
([key, value]) => [key.toLowerCase(), sanitizeScalar(value, redactor).text]
|
|
1979
|
+
).filter(([key]) => isSafeHeaderName(key));
|
|
1980
|
+
if (entries.length === 0) return void 0;
|
|
1981
|
+
return Object.fromEntries(entries);
|
|
1982
|
+
};
|
|
1983
|
+
var getContentType = (headers) => headerEntries(headers).find(([key]) => key.toLowerCase() === "content-type")?.[1];
|
|
1984
|
+
var takeTraceDraft = (config2) => {
|
|
1985
|
+
if (!config2) return void 0;
|
|
1986
|
+
let draft = config2.__slatesHttpTraceDraft ?? (isObjectLike(config2) ? traceDraftsByConfig.get(config2) : void 0) ?? (isObjectLike(config2.headers) ? traceDraftsByHeaders.get(config2.headers) : void 0);
|
|
1987
|
+
if (!draft) return void 0;
|
|
1988
|
+
return draft;
|
|
1989
|
+
};
|
|
1990
|
+
var clearTraceDraft = (config2, draft) => {
|
|
1991
|
+
if (!config2) return;
|
|
1992
|
+
if (config2.__slatesHttpTraceDraft === draft) {
|
|
1993
|
+
config2.__slatesHttpTraceDraft = void 0;
|
|
1994
|
+
}
|
|
1995
|
+
if (isObjectLike(config2)) {
|
|
1996
|
+
traceDraftsByConfig.delete(config2);
|
|
1997
|
+
}
|
|
1998
|
+
if (isObjectLike(config2.headers)) {
|
|
1999
|
+
traceDraftsByHeaders.delete(config2.headers);
|
|
2000
|
+
}
|
|
2001
|
+
};
|
|
2002
|
+
var attachHttpTraceDraft = (config2, context) => {
|
|
2003
|
+
let traceAwareConfig = config2;
|
|
2004
|
+
let contentType = getContentType(config2.headers);
|
|
2005
|
+
let redactor = new AuthConfigSecretRedactor(context._getAuthConfigForRedaction());
|
|
2006
|
+
traceAwareConfig.__slatesHttpTraceDraft = {
|
|
2007
|
+
context,
|
|
2008
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2009
|
+
startedAtMs: Date.now(),
|
|
2010
|
+
request: {
|
|
2011
|
+
method: (config2.method ?? "GET").toUpperCase(),
|
|
2012
|
+
url: sanitizeUrl(buildUrl(config2.baseURL, config2.url), redactor),
|
|
2013
|
+
...sanitizeHeaders(config2.headers, redactor) ? { headers: sanitizeHeaders(config2.headers, redactor) } : {},
|
|
2014
|
+
...serializeTextBody(config2.data, contentType, redactor) ? { body: serializeTextBody(config2.data, contentType, redactor) } : {}
|
|
2015
|
+
}
|
|
2016
|
+
};
|
|
2017
|
+
if (isObjectLike(traceAwareConfig)) {
|
|
2018
|
+
traceDraftsByConfig.set(traceAwareConfig, traceAwareConfig.__slatesHttpTraceDraft);
|
|
2019
|
+
}
|
|
2020
|
+
if (isObjectLike(traceAwareConfig.headers)) {
|
|
2021
|
+
traceDraftsByHeaders.set(
|
|
2022
|
+
traceAwareConfig.headers,
|
|
2023
|
+
traceAwareConfig.__slatesHttpTraceDraft
|
|
2024
|
+
);
|
|
2025
|
+
}
|
|
2026
|
+
return config2;
|
|
2027
|
+
};
|
|
2028
|
+
var recordHttpTraceFromResponse = (response) => {
|
|
2029
|
+
let config2 = response.config;
|
|
2030
|
+
let draft = takeTraceDraft(config2);
|
|
2031
|
+
if (!draft) return response;
|
|
2032
|
+
clearTraceDraft(config2, draft);
|
|
2033
|
+
let redactor = new AuthConfigSecretRedactor(draft.context._getAuthConfigForRedaction());
|
|
2034
|
+
let contentType = getContentType(response.headers);
|
|
2035
|
+
draft.context.recordHttpTrace({
|
|
2036
|
+
startedAt: draft.startedAt,
|
|
2037
|
+
durationMs: Math.max(Date.now() - draft.startedAtMs, 0),
|
|
2038
|
+
request: draft.request,
|
|
2039
|
+
response: {
|
|
2040
|
+
status: response.status,
|
|
2041
|
+
...response.statusText ? { statusText: response.statusText } : {},
|
|
2042
|
+
...sanitizeHeaders(response.headers, redactor) ? { headers: sanitizeHeaders(response.headers, redactor) } : {},
|
|
2043
|
+
...serializeTextBody(response.data, contentType, redactor) ? { body: serializeTextBody(response.data, contentType, redactor) } : {}
|
|
2044
|
+
}
|
|
2045
|
+
});
|
|
2046
|
+
return response;
|
|
2047
|
+
};
|
|
2048
|
+
var recordHttpTraceFromError = (error) => {
|
|
2049
|
+
let config2 = error.config;
|
|
2050
|
+
let draft = takeTraceDraft(config2);
|
|
2051
|
+
if (!draft) return;
|
|
2052
|
+
clearTraceDraft(config2, draft);
|
|
2053
|
+
let redactor = new AuthConfigSecretRedactor(draft.context._getAuthConfigForRedaction());
|
|
2054
|
+
let responseContentType = getContentType(error.response?.headers);
|
|
2055
|
+
draft.context.recordHttpTrace({
|
|
2056
|
+
startedAt: draft.startedAt,
|
|
2057
|
+
durationMs: Math.max(Date.now() - draft.startedAtMs, 0),
|
|
2058
|
+
request: draft.request,
|
|
2059
|
+
...error.response ? {
|
|
2060
|
+
response: {
|
|
2061
|
+
status: error.response.status,
|
|
2062
|
+
...error.response.statusText ? { statusText: error.response.statusText } : {},
|
|
2063
|
+
...sanitizeHeaders(error.response.headers, redactor) ? { headers: sanitizeHeaders(error.response.headers, redactor) } : {},
|
|
2064
|
+
...serializeTextBody(error.response.data, responseContentType, redactor) ? { body: serializeTextBody(error.response.data, responseContentType, redactor) } : {}
|
|
2065
|
+
}
|
|
2066
|
+
} : {},
|
|
2067
|
+
error: {
|
|
2068
|
+
...error.code ? { code: error.code } : {},
|
|
2069
|
+
message: error.message
|
|
2070
|
+
}
|
|
2071
|
+
});
|
|
2072
|
+
};
|
|
2073
|
+
|
|
2074
|
+
// src/axios/index.ts
|
|
2075
|
+
var applySlateInterceptors = (instance, errorMapping) => {
|
|
2076
|
+
instance.interceptors.request.use(
|
|
2077
|
+
(request) => {
|
|
2078
|
+
let ctx = getCurrentContext();
|
|
2079
|
+
let spec2 = ctx.specification;
|
|
2080
|
+
let providerToken = spec2.key.replace(/[^A-Za-z0-9!#$%&'*+\-.^_`|~]/g, "-");
|
|
2081
|
+
request.headers.set("User-Agent", `slates.dev/1.0.0 ${providerToken || "unknown"}`);
|
|
2082
|
+
request.headers.set("X-Slates-Provider", spec2.key);
|
|
2083
|
+
let tracedRequest = attachHttpTraceDraft(request, ctx);
|
|
2084
|
+
if (!tracedRequest.__slatesTraceAdapterWrapped) {
|
|
2085
|
+
let adapter = getAdapter(tracedRequest.adapter ?? baseAxios.defaults.adapter);
|
|
2086
|
+
tracedRequest.adapter = async (config2) => {
|
|
2087
|
+
try {
|
|
2088
|
+
let response = await adapter(config2);
|
|
2089
|
+
return recordHttpTraceFromResponse(response);
|
|
2090
|
+
} catch (error) {
|
|
2091
|
+
if (isAxiosError2(error)) {
|
|
2092
|
+
recordHttpTraceFromError(error);
|
|
2093
|
+
}
|
|
2094
|
+
throw error;
|
|
2095
|
+
}
|
|
2096
|
+
};
|
|
2097
|
+
tracedRequest.__slatesTraceAdapterWrapped = true;
|
|
2098
|
+
}
|
|
2099
|
+
return tracedRequest;
|
|
2100
|
+
},
|
|
2101
|
+
(error) => Promise.reject(error)
|
|
2102
|
+
);
|
|
2103
|
+
instance.interceptors.response.use(
|
|
2104
|
+
(response) => response,
|
|
2105
|
+
(error) => Promise.reject(SlateError.fromAxios(error, errorMapping))
|
|
2106
|
+
);
|
|
2107
|
+
};
|
|
2108
|
+
applySlateInterceptors(baseAxios);
|
|
2109
|
+
var createAxios = (config2) => {
|
|
2110
|
+
let { errorMapping, ...axiosConfig } = config2 ?? {};
|
|
2111
|
+
let instance = baseAxios.create({
|
|
2112
|
+
...axiosConfig,
|
|
2113
|
+
headers: {
|
|
2114
|
+
...axiosConfig.headers
|
|
2115
|
+
}
|
|
2116
|
+
});
|
|
2117
|
+
applySlateInterceptors(instance, errorMapping);
|
|
2118
|
+
return instance;
|
|
2119
|
+
};
|
|
2120
|
+
var createAuthenticatedAxios = (config2) => {
|
|
2121
|
+
let { authHeader, contentType = "application/json", errorAdapter, ...axiosConfig } = config2;
|
|
2122
|
+
let instance = createAxios({
|
|
2123
|
+
...axiosConfig,
|
|
2124
|
+
headers: {
|
|
2125
|
+
...contentType === false ? {} : { "Content-Type": contentType },
|
|
2126
|
+
...authHeader ? { [authHeader.name ?? "Authorization"]: authHeader.value } : {},
|
|
2127
|
+
...axiosConfig.headers
|
|
2128
|
+
}
|
|
2129
|
+
});
|
|
2130
|
+
if (errorAdapter) {
|
|
2131
|
+
instance.interceptors.response.use(
|
|
2132
|
+
(response) => response,
|
|
2133
|
+
(error) => Promise.reject(errorAdapter(error))
|
|
2134
|
+
);
|
|
2135
|
+
}
|
|
2136
|
+
return instance;
|
|
2137
|
+
};
|
|
2138
|
+
var requestAxios = async (operation, request, errorAdapter) => {
|
|
2139
|
+
try {
|
|
2140
|
+
return await request();
|
|
2141
|
+
} catch (error) {
|
|
2142
|
+
throw errorAdapter(error, operation);
|
|
2143
|
+
}
|
|
2144
|
+
};
|
|
2145
|
+
var requestAxiosData = async (operation, request, errorAdapter) => {
|
|
2146
|
+
let response = await requestAxios(operation, request, errorAdapter);
|
|
2147
|
+
return response.data;
|
|
2148
|
+
};
|
|
2149
|
+
var axios = createAxios();
|
|
2150
|
+
|
|
2151
|
+
// src/config/config.ts
|
|
2152
|
+
var SlateConfig = class _SlateConfig {
|
|
2153
|
+
#configSchema;
|
|
2154
|
+
#docs;
|
|
2155
|
+
#configChanged = null;
|
|
2156
|
+
#getDefaultConfig = null;
|
|
2157
|
+
constructor(schema) {
|
|
2158
|
+
this.#configSchema = schema;
|
|
2159
|
+
}
|
|
2160
|
+
static create(schema) {
|
|
2161
|
+
return new _SlateConfig(schema);
|
|
2162
|
+
}
|
|
2163
|
+
config(schema) {
|
|
2164
|
+
this.#configSchema = schema;
|
|
2165
|
+
return this;
|
|
2166
|
+
}
|
|
2167
|
+
docs(docs) {
|
|
2168
|
+
this.#docs = docs;
|
|
2169
|
+
return this;
|
|
2170
|
+
}
|
|
2171
|
+
onConfigChanged(handler) {
|
|
2172
|
+
this.#configChanged = handler;
|
|
2173
|
+
return this;
|
|
2174
|
+
}
|
|
2175
|
+
getDefaultConfig(getter) {
|
|
2176
|
+
this.#getDefaultConfig = getter;
|
|
2177
|
+
return this;
|
|
2178
|
+
}
|
|
2179
|
+
get configSchema() {
|
|
2180
|
+
return this.#configSchema;
|
|
2181
|
+
}
|
|
2182
|
+
get docsReferences() {
|
|
2183
|
+
return this.#docs;
|
|
2184
|
+
}
|
|
2185
|
+
get handlers() {
|
|
2186
|
+
return {
|
|
2187
|
+
configChanged: this.#configChanged,
|
|
2188
|
+
getDefaultConfig: this.#getDefaultConfig
|
|
2189
|
+
};
|
|
2190
|
+
}
|
|
2191
|
+
};
|
|
2192
|
+
var config = (schema) => SlateConfig.create(schema);
|
|
2193
|
+
|
|
2194
|
+
// src/context/context.ts
|
|
2195
|
+
import { Readable } from "stream";
|
|
2196
|
+
|
|
2197
|
+
// src/context/pQueue.ts
|
|
2198
|
+
import PQueueImport from "p-queue";
|
|
2199
|
+
|
|
2200
|
+
// src/module/resolveDefaultExport.ts
|
|
2201
|
+
var resolveDefaultExport = (value) => {
|
|
2202
|
+
let current = value;
|
|
2203
|
+
for (let i = 0; i < 4; i++) {
|
|
2204
|
+
if (typeof current === "function") return current;
|
|
2205
|
+
if (current && typeof current === "object" && "default" in current) {
|
|
2206
|
+
current = current.default;
|
|
2207
|
+
continue;
|
|
2208
|
+
}
|
|
2209
|
+
break;
|
|
2210
|
+
}
|
|
2211
|
+
throw new TypeError("Module export is not a constructor");
|
|
2212
|
+
};
|
|
2213
|
+
|
|
2214
|
+
// src/context/pQueue.ts
|
|
2215
|
+
var PQueue = resolveDefaultExport(PQueueImport);
|
|
2216
|
+
|
|
2217
|
+
// src/context/context.ts
|
|
2218
|
+
var isBufferLike = (value) => value instanceof Uint8Array || value instanceof ArrayBuffer;
|
|
2219
|
+
var toUint8Array = (value) => value instanceof ArrayBuffer ? new Uint8Array(value) : value;
|
|
2220
|
+
var isReadableStream = (value) => typeof ReadableStream !== "undefined" && value instanceof ReadableStream;
|
|
2221
|
+
var isNodeReadable = (value) => !!value && typeof value === "object" && typeof value.pipe === "function" && typeof value.on === "function";
|
|
2222
|
+
var isResponseLike = (value) => typeof Response !== "undefined" && value instanceof Response;
|
|
2223
|
+
var readStreamToBuffer = async (stream) => {
|
|
2224
|
+
let reader = stream.getReader();
|
|
2225
|
+
let chunks = [];
|
|
2226
|
+
while (true) {
|
|
2227
|
+
let { done, value } = await reader.read();
|
|
2228
|
+
if (done) break;
|
|
2229
|
+
if (value) chunks.push(value);
|
|
2230
|
+
}
|
|
2231
|
+
return Buffer.concat(chunks);
|
|
2232
|
+
};
|
|
2233
|
+
var SlatePublicContext = class {
|
|
2234
|
+
constructor(input, spec2, logger, liveInvocation = null) {
|
|
2235
|
+
this.spec = spec2;
|
|
2236
|
+
this.logger = logger;
|
|
2237
|
+
this.#input = input;
|
|
2238
|
+
this.#liveInvocation = liveInvocation;
|
|
2239
|
+
}
|
|
2240
|
+
spec;
|
|
2241
|
+
logger;
|
|
2242
|
+
#input;
|
|
2243
|
+
#httpTraces = [];
|
|
2244
|
+
#liveInvocation;
|
|
2245
|
+
#attachmentsDisabled = false;
|
|
2246
|
+
#attachments = [];
|
|
2247
|
+
#pendingUploads = [];
|
|
2248
|
+
#uploadQueue;
|
|
2249
|
+
#getUploadQueue() {
|
|
2250
|
+
if (!this.#uploadQueue) {
|
|
2251
|
+
this.#uploadQueue = new PQueue({ concurrency: 10 });
|
|
2252
|
+
}
|
|
2253
|
+
return this.#uploadQueue;
|
|
2254
|
+
}
|
|
2255
|
+
get specification() {
|
|
2256
|
+
return this.spec;
|
|
2257
|
+
}
|
|
2258
|
+
get input() {
|
|
2259
|
+
return Object.freeze(this.#input);
|
|
2260
|
+
}
|
|
2261
|
+
get event() {
|
|
2262
|
+
return Object.freeze(this.#input);
|
|
2263
|
+
}
|
|
2264
|
+
get state() {
|
|
2265
|
+
return Object.freeze(this.#input.state);
|
|
2266
|
+
}
|
|
2267
|
+
get request() {
|
|
2268
|
+
return Object.freeze(this.#input.request);
|
|
2269
|
+
}
|
|
2270
|
+
get registrationDetails() {
|
|
2271
|
+
return Object.freeze(
|
|
2272
|
+
this.#input.registrationDetails
|
|
2273
|
+
);
|
|
2274
|
+
}
|
|
2275
|
+
recordHttpTrace(trace) {
|
|
2276
|
+
this.#httpTraces.push(trace);
|
|
2277
|
+
}
|
|
2278
|
+
getHttpTraces() {
|
|
2279
|
+
return this.#httpTraces.map((trace) => ({
|
|
2280
|
+
...trace,
|
|
2281
|
+
request: {
|
|
2282
|
+
...trace.request,
|
|
2283
|
+
...trace.request.headers ? { headers: { ...trace.request.headers } } : {},
|
|
2284
|
+
...trace.request.body ? { body: { ...trace.request.body } } : {}
|
|
2285
|
+
},
|
|
2286
|
+
...trace.response ? {
|
|
2287
|
+
response: {
|
|
2288
|
+
...trace.response,
|
|
2289
|
+
...trace.response.headers ? { headers: { ...trace.response.headers } } : {},
|
|
2290
|
+
...trace.response.body ? { body: { ...trace.response.body } } : {}
|
|
2291
|
+
}
|
|
2292
|
+
} : {},
|
|
2293
|
+
...trace.error ? { error: { ...trace.error } } : {}
|
|
2294
|
+
}));
|
|
2295
|
+
}
|
|
2296
|
+
info(message) {
|
|
2297
|
+
this.logger.info(message);
|
|
2298
|
+
}
|
|
2299
|
+
warn(message) {
|
|
2300
|
+
this.logger.warn(message);
|
|
2301
|
+
}
|
|
2302
|
+
error(message) {
|
|
2303
|
+
this.logger.error(message);
|
|
2304
|
+
}
|
|
2305
|
+
progress(message) {
|
|
2306
|
+
this.logger.progress(message);
|
|
2307
|
+
}
|
|
2308
|
+
async addAttachment(input) {
|
|
2309
|
+
if (input.type === "url") {
|
|
2310
|
+
this.#attachments.push(
|
|
2311
|
+
createUrlAttachment(input.url.toString(), {
|
|
2312
|
+
mimeType: input.mimeType,
|
|
2313
|
+
headers: input.headers,
|
|
2314
|
+
query: input.query,
|
|
2315
|
+
refreshReference: input.refreshReference,
|
|
2316
|
+
refreshAt: input.refreshAt
|
|
2317
|
+
})
|
|
2318
|
+
);
|
|
2319
|
+
return;
|
|
2320
|
+
}
|
|
2321
|
+
let content = input.content;
|
|
2322
|
+
if (isBufferLike(content)) {
|
|
2323
|
+
let bytes = toUint8Array(content);
|
|
2324
|
+
this.#attachments.push(
|
|
2325
|
+
createBase64Attachment(Buffer.from(bytes).toString("base64"), input.mimeType)
|
|
2326
|
+
);
|
|
2327
|
+
return;
|
|
2328
|
+
}
|
|
2329
|
+
let normalized = await this.#normalizeStreamInput(content, {
|
|
2330
|
+
mimeType: input.mimeType,
|
|
2331
|
+
filename: input.filename
|
|
2332
|
+
});
|
|
2333
|
+
if (!normalized) return;
|
|
2334
|
+
if (!this.#liveInvocation || this.#attachmentsDisabled) {
|
|
2335
|
+
let buffer = await readStreamToBuffer(normalized.stream);
|
|
2336
|
+
this.#attachments.push(
|
|
2337
|
+
createBase64Attachment(buffer.toString("base64"), normalized.mimeType)
|
|
2338
|
+
);
|
|
2339
|
+
return;
|
|
2340
|
+
}
|
|
2341
|
+
let live = this.#liveInvocation;
|
|
2342
|
+
let task = this.#getUploadQueue().add(
|
|
2343
|
+
() => uploadAttachmentDirect({
|
|
2344
|
+
live,
|
|
2345
|
+
mimeType: normalized.mimeType,
|
|
2346
|
+
filename: normalized.filename,
|
|
2347
|
+
body: normalized.stream
|
|
2348
|
+
})
|
|
2349
|
+
).then((attachment) => {
|
|
2350
|
+
this.#attachments.push(attachment);
|
|
2351
|
+
}).catch((err) => {
|
|
2352
|
+
this.#attachmentsDisabled = true;
|
|
2353
|
+
this.warn({
|
|
2354
|
+
message: `Attachment dropped: direct upload failed (${err instanceof Error ? err.message : String(err)}).`
|
|
2355
|
+
});
|
|
2356
|
+
});
|
|
2357
|
+
this.#pendingUploads.push(task);
|
|
2358
|
+
}
|
|
2359
|
+
async #normalizeStreamInput(input, opts) {
|
|
2360
|
+
if (isResponseLike(input)) {
|
|
2361
|
+
if (!input.body) {
|
|
2362
|
+
this.warn({ message: "Attachment dropped: response has no body." });
|
|
2363
|
+
return null;
|
|
2364
|
+
}
|
|
2365
|
+
return {
|
|
2366
|
+
stream: input.body,
|
|
2367
|
+
mimeType: opts.mimeType ?? input.headers.get("content-type") ?? void 0,
|
|
2368
|
+
filename: opts.filename
|
|
2369
|
+
};
|
|
2370
|
+
}
|
|
2371
|
+
if (isReadableStream(input)) {
|
|
2372
|
+
return { stream: input, mimeType: opts.mimeType, filename: opts.filename };
|
|
2373
|
+
}
|
|
2374
|
+
if (isNodeReadable(input)) {
|
|
2375
|
+
return {
|
|
2376
|
+
stream: Readable.toWeb(input),
|
|
2377
|
+
mimeType: opts.mimeType,
|
|
2378
|
+
filename: opts.filename
|
|
2379
|
+
};
|
|
2380
|
+
}
|
|
2381
|
+
this.warn({ message: "Attachment dropped: unsupported attachment input type." });
|
|
2382
|
+
return null;
|
|
2383
|
+
}
|
|
2384
|
+
async _finalizeAttachments() {
|
|
2385
|
+
await Promise.allSettled(this.#pendingUploads);
|
|
2386
|
+
return this.#attachments;
|
|
2387
|
+
}
|
|
2388
|
+
_getAuthConfigForRedaction() {
|
|
2389
|
+
return void 0;
|
|
2390
|
+
}
|
|
2391
|
+
};
|
|
2392
|
+
var SlateContext = class extends SlatePublicContext {
|
|
2393
|
+
#config;
|
|
2394
|
+
#auth;
|
|
2395
|
+
constructor(config2, input, auth2, spec2, logger, liveInvocation = null) {
|
|
2396
|
+
super(input, spec2, logger, liveInvocation);
|
|
2397
|
+
this.#config = config2;
|
|
2398
|
+
this.#auth = auth2;
|
|
2399
|
+
}
|
|
2400
|
+
get config() {
|
|
2401
|
+
return Object.freeze(this.#config);
|
|
2402
|
+
}
|
|
2403
|
+
get auth() {
|
|
2404
|
+
return Object.freeze(this.#auth);
|
|
2405
|
+
}
|
|
2406
|
+
_getAuthConfigForRedaction() {
|
|
2407
|
+
return this.#auth;
|
|
2408
|
+
}
|
|
2409
|
+
};
|
|
2410
|
+
|
|
2411
|
+
// src/crypto/hmac.ts
|
|
2412
|
+
import { createHmac, timingSafeEqual } from "crypto";
|
|
2413
|
+
var createHmacSignature = ({
|
|
2414
|
+
secret,
|
|
2415
|
+
payload,
|
|
2416
|
+
algorithm = "sha256",
|
|
2417
|
+
digest,
|
|
2418
|
+
prefix = ""
|
|
2419
|
+
}) => `${prefix}${createHmac(algorithm, secret).update(payload).digest(digest)}`;
|
|
2420
|
+
var verifyHmacSignature = (options) => {
|
|
2421
|
+
let expected = createHmacSignature(options);
|
|
2422
|
+
let expectedBytes = Buffer.from(expected);
|
|
2423
|
+
let signatureBytes = Buffer.from(options.signature);
|
|
2424
|
+
let lengthsMatch = signatureBytes.length === expectedBytes.length;
|
|
2425
|
+
let comparableSignature = lengthsMatch ? signatureBytes : Buffer.alloc(expectedBytes.length);
|
|
2426
|
+
return timingSafeEqual(comparableSignature, expectedBytes) && lengthsMatch;
|
|
2427
|
+
};
|
|
2428
|
+
|
|
2429
|
+
// src/file/index.ts
|
|
2430
|
+
var getResponseHeaderValue = (headers, name) => {
|
|
2431
|
+
if (!headers) return void 0;
|
|
2432
|
+
if (typeof headers.get === "function") {
|
|
2433
|
+
let value = headers.get(name);
|
|
2434
|
+
return typeof value === "string" ? value : void 0;
|
|
2435
|
+
}
|
|
2436
|
+
if (typeof headers !== "object") return void 0;
|
|
2437
|
+
let lowerName = name.toLowerCase();
|
|
2438
|
+
for (let [headerName, value] of Object.entries(headers)) {
|
|
2439
|
+
if (headerName.toLowerCase() !== lowerName) continue;
|
|
2440
|
+
if (Array.isArray(value)) {
|
|
2441
|
+
let first = value.find((item) => typeof item === "string");
|
|
2442
|
+
return typeof first === "string" ? first : void 0;
|
|
2443
|
+
}
|
|
2444
|
+
return typeof value === "string" ? value : void 0;
|
|
2445
|
+
}
|
|
2446
|
+
return void 0;
|
|
2447
|
+
};
|
|
2448
|
+
var getBase64ByteLength = (contentBase64) => Buffer.from(contentBase64, "base64").byteLength;
|
|
2449
|
+
|
|
2450
|
+
// src/logger/logger.ts
|
|
2451
|
+
import { encode } from "@toon-format/toon";
|
|
2452
|
+
var isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2453
|
+
var normalizeMessage = (message) => {
|
|
2454
|
+
if (Array.isArray(message)) {
|
|
2455
|
+
let parts = message.map((part) => normalizeMessage(part));
|
|
2456
|
+
let combinedMessage = parts.map((part) => part.message).filter(Boolean).join(" ").trim();
|
|
2457
|
+
let dataParts = parts.map((part) => {
|
|
2458
|
+
if (part.data) {
|
|
2459
|
+
return {
|
|
2460
|
+
message: part.message,
|
|
2461
|
+
...part.data
|
|
2462
|
+
};
|
|
2463
|
+
}
|
|
2464
|
+
return part.message;
|
|
2465
|
+
}).filter(Boolean);
|
|
2466
|
+
return {
|
|
2467
|
+
message: combinedMessage || "Log entry",
|
|
2468
|
+
data: dataParts.length > 0 ? { parts: dataParts } : void 0
|
|
2469
|
+
};
|
|
2470
|
+
}
|
|
2471
|
+
if (typeof message === "object") {
|
|
2472
|
+
if (message === null) return { message: "null" };
|
|
2473
|
+
if (message instanceof Error) {
|
|
2474
|
+
return {
|
|
2475
|
+
message: `${message.name}: ${message.message}`,
|
|
2476
|
+
data: {
|
|
2477
|
+
error: {
|
|
2478
|
+
name: message.name,
|
|
2479
|
+
message: message.message,
|
|
2480
|
+
stack: message.stack
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
};
|
|
2484
|
+
}
|
|
2485
|
+
if (isRecord3(message) && typeof message.message === "string") {
|
|
2486
|
+
let { message: text, ...data } = message;
|
|
2487
|
+
return {
|
|
2488
|
+
message: text || "Log entry",
|
|
2489
|
+
data: Object.keys(data).length > 0 ? data : void 0
|
|
2490
|
+
};
|
|
2491
|
+
}
|
|
2492
|
+
return {
|
|
2493
|
+
message: encode(message),
|
|
2494
|
+
data: isRecord3(message) ? message : void 0
|
|
2495
|
+
};
|
|
2496
|
+
}
|
|
2497
|
+
return { message: String(message) };
|
|
2498
|
+
};
|
|
2499
|
+
var SlateLogger = class {
|
|
2500
|
+
#logs = [];
|
|
2501
|
+
#listeners = [];
|
|
2502
|
+
#timer = null;
|
|
2503
|
+
constructor(listeners = []) {
|
|
2504
|
+
this.#listeners.push(...listeners);
|
|
2505
|
+
}
|
|
2506
|
+
flush() {
|
|
2507
|
+
if (this.#timer) clearTimeout(this.#timer);
|
|
2508
|
+
if (this.#logs.length === 0) return;
|
|
2509
|
+
let logs = this.#logs.splice(0);
|
|
2510
|
+
for (let listener of this.#listeners) {
|
|
2511
|
+
listener(logs);
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
scheduleFlush() {
|
|
2515
|
+
if (this.#timer) return;
|
|
2516
|
+
this.#timer = setTimeout(() => {
|
|
2517
|
+
this.flush();
|
|
2518
|
+
this.#timer = null;
|
|
2519
|
+
}, 10);
|
|
2520
|
+
}
|
|
2521
|
+
log(type, message) {
|
|
2522
|
+
let normalized = normalizeMessage(message);
|
|
2523
|
+
this.#logs.push({
|
|
2524
|
+
type,
|
|
2525
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
2526
|
+
message: normalized.message,
|
|
2527
|
+
data: normalized.data
|
|
2528
|
+
});
|
|
2529
|
+
this.scheduleFlush();
|
|
2530
|
+
}
|
|
2531
|
+
info(...message) {
|
|
2532
|
+
this.log("info", message.length === 1 ? message[0] : message.flat());
|
|
2533
|
+
}
|
|
2534
|
+
warn(...message) {
|
|
2535
|
+
this.log("warn", message.length === 1 ? message[0] : message.flat());
|
|
2536
|
+
}
|
|
2537
|
+
error(...message) {
|
|
2538
|
+
this.log("error", message.length === 1 ? message[0] : message.flat());
|
|
2539
|
+
}
|
|
2540
|
+
progress(...message) {
|
|
2541
|
+
this.log("progress", message.length === 1 ? message[0] : message.flat());
|
|
2542
|
+
}
|
|
2543
|
+
};
|
|
2544
|
+
|
|
2545
|
+
// src/object/index.ts
|
|
2546
|
+
var pickDefined = (value) => Object.fromEntries(
|
|
2547
|
+
Object.entries(value).filter(([, child]) => child !== void 0)
|
|
2548
|
+
);
|
|
2549
|
+
var setIfDefined = (target, key, value) => {
|
|
2550
|
+
if (value !== void 0) {
|
|
2551
|
+
target[key] = value;
|
|
2552
|
+
}
|
|
2553
|
+
return target;
|
|
2554
|
+
};
|
|
2555
|
+
|
|
2556
|
+
// src/specification/slate.ts
|
|
2557
|
+
var Slate = class _Slate {
|
|
2558
|
+
constructor(_spec, _actions, _adapters) {
|
|
2559
|
+
this._spec = _spec;
|
|
2560
|
+
this._actions = _actions;
|
|
2561
|
+
this._adapters = _adapters;
|
|
2562
|
+
}
|
|
2563
|
+
_spec;
|
|
2564
|
+
_actions;
|
|
2565
|
+
_adapters;
|
|
2566
|
+
static create(params) {
|
|
2567
|
+
let adapters = params.adapters ?? [];
|
|
2568
|
+
let actions = [...params.triggers, ...params.tools];
|
|
2569
|
+
let seenAdapterIds = /* @__PURE__ */ new Set();
|
|
2570
|
+
let seenActionKeys = new Map(actions.map((action) => [action.key, action]));
|
|
2571
|
+
for (let adapter of adapters) {
|
|
2572
|
+
if (seenAdapterIds.has(adapter.id)) {
|
|
2573
|
+
throw new SlateDeclarationError(
|
|
2574
|
+
`Adapter "${adapter.id}" is registered more than once`
|
|
2575
|
+
);
|
|
2576
|
+
}
|
|
2577
|
+
seenAdapterIds.add(adapter.id);
|
|
2578
|
+
for (let action of adapter.actions) {
|
|
2579
|
+
let existing = seenActionKeys.get(action.key);
|
|
2580
|
+
if (existing && existing !== action) {
|
|
2581
|
+
throw new SlateDeclarationError(
|
|
2582
|
+
`Adapter "${adapter.id}" action "${action.key}" conflicts with another action`
|
|
2583
|
+
);
|
|
2584
|
+
}
|
|
2585
|
+
if (!existing) {
|
|
2586
|
+
actions.push(action);
|
|
2587
|
+
seenActionKeys.set(action.key, action);
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
return new _Slate(params.spec, actions, adapters);
|
|
2592
|
+
}
|
|
2593
|
+
get spec() {
|
|
2594
|
+
return this._spec;
|
|
2595
|
+
}
|
|
2596
|
+
get actions() {
|
|
2597
|
+
return this._actions;
|
|
2598
|
+
}
|
|
2599
|
+
get adapters() {
|
|
2600
|
+
return this._adapters;
|
|
2601
|
+
}
|
|
2602
|
+
};
|
|
2603
|
+
|
|
2604
|
+
// src/specification/specification.ts
|
|
2605
|
+
import z2 from "zod";
|
|
2606
|
+
var SlateSpecification = class _SlateSpecification {
|
|
2607
|
+
constructor(_config, _auth, _params) {
|
|
2608
|
+
this._config = _config;
|
|
2609
|
+
this._auth = _auth;
|
|
2610
|
+
this._params = _params;
|
|
2611
|
+
}
|
|
2612
|
+
_config;
|
|
2613
|
+
_auth;
|
|
2614
|
+
_params;
|
|
2615
|
+
static create(params) {
|
|
2616
|
+
return new _SlateSpecification(params.config, params.auth, params);
|
|
2617
|
+
}
|
|
2618
|
+
get configSchema() {
|
|
2619
|
+
return this._config.configSchema;
|
|
2620
|
+
}
|
|
2621
|
+
get authSchema() {
|
|
2622
|
+
return "outputSchema" in this._auth ? this._auth.outputSchema : z2.object({});
|
|
2623
|
+
}
|
|
2624
|
+
get config() {
|
|
2625
|
+
return this._config;
|
|
2626
|
+
}
|
|
2627
|
+
get auth() {
|
|
2628
|
+
return this._auth;
|
|
2629
|
+
}
|
|
2630
|
+
get parameters() {
|
|
2631
|
+
return this._params;
|
|
2632
|
+
}
|
|
2633
|
+
get key() {
|
|
2634
|
+
return this._params.key;
|
|
2635
|
+
}
|
|
2636
|
+
get name() {
|
|
2637
|
+
return this._params.name;
|
|
2638
|
+
}
|
|
2639
|
+
get description() {
|
|
2640
|
+
return this._params.description;
|
|
2641
|
+
}
|
|
2642
|
+
get docs() {
|
|
2643
|
+
return this._params.docs;
|
|
2644
|
+
}
|
|
2645
|
+
};
|
|
2646
|
+
var spec = (params) => SlateSpecification.create(params);
|
|
2647
|
+
|
|
2648
|
+
// src/webhook/graph.ts
|
|
2649
|
+
var graphWebhookHttp = {
|
|
2650
|
+
methods: ["POST"],
|
|
2651
|
+
sync: {
|
|
2652
|
+
mode: "match",
|
|
2653
|
+
match: [{ hasQueryParam: "validationToken" }]
|
|
2654
|
+
}
|
|
2655
|
+
};
|
|
2656
|
+
var getGraphWebhookValidationResponse = (request) => {
|
|
2657
|
+
let validationToken = new URL(request.url).searchParams.get("validationToken");
|
|
2658
|
+
if (validationToken === null) return null;
|
|
2659
|
+
return {
|
|
2660
|
+
status: 200,
|
|
2661
|
+
headers: { "content-type": "text/plain" },
|
|
2662
|
+
body: validationToken
|
|
2663
|
+
};
|
|
2664
|
+
};
|
|
2665
|
+
|
|
2666
|
+
// src/webhook/meta.ts
|
|
2667
|
+
var metaWebhookHttp = {
|
|
2668
|
+
methods: ["GET", "POST"],
|
|
2669
|
+
sync: {
|
|
2670
|
+
mode: "match",
|
|
2671
|
+
match: [{ method: "GET", hasQueryParam: "hub.mode" }]
|
|
2672
|
+
}
|
|
2673
|
+
};
|
|
2674
|
+
var getMetaWebhookVerificationResponse = (request, expectedVerifyToken) => {
|
|
2675
|
+
if (request.method !== "GET") return null;
|
|
2676
|
+
let url = new URL(request.url);
|
|
2677
|
+
let mode = url.searchParams.get("hub.mode");
|
|
2678
|
+
let verifyToken = url.searchParams.get("hub.verify_token");
|
|
2679
|
+
let challenge = url.searchParams.get("hub.challenge");
|
|
2680
|
+
if (mode !== "subscribe" || challenge === null) {
|
|
2681
|
+
return {
|
|
2682
|
+
status: 400,
|
|
2683
|
+
headers: { "content-type": "text/plain" },
|
|
2684
|
+
body: "invalid webhook verification request"
|
|
2685
|
+
};
|
|
2686
|
+
}
|
|
2687
|
+
if (expectedVerifyToken !== void 0 && verifyToken !== expectedVerifyToken) {
|
|
2688
|
+
return {
|
|
2689
|
+
status: 403,
|
|
2690
|
+
headers: { "content-type": "text/plain" },
|
|
2691
|
+
body: "invalid verify token"
|
|
2692
|
+
};
|
|
2693
|
+
}
|
|
2694
|
+
return {
|
|
2695
|
+
status: 200,
|
|
2696
|
+
headers: { "content-type": "text/plain" },
|
|
2697
|
+
body: challenge
|
|
2698
|
+
};
|
|
2699
|
+
};
|
|
2700
|
+
export {
|
|
2701
|
+
AUTH_CONFIG_SECRET_PLACEHOLDER_PREFIX,
|
|
2702
|
+
AuthConfigSecretRedactor,
|
|
2703
|
+
GET_FILE_URL_TOOL_ID,
|
|
2704
|
+
Slate,
|
|
2705
|
+
SlateAction,
|
|
2706
|
+
SlateActionBuilder,
|
|
2707
|
+
SlateAdapter,
|
|
2708
|
+
SlateAdapterSpec,
|
|
2709
|
+
SlateAuth,
|
|
2710
|
+
SlateConfig,
|
|
2711
|
+
SlateContext,
|
|
2712
|
+
SlateDeclarationError,
|
|
2713
|
+
SlateDefaultPollingIntervalSeconds,
|
|
2714
|
+
SlateError,
|
|
2715
|
+
SlateLogger,
|
|
2716
|
+
SlatePublicContext,
|
|
2717
|
+
SlatePublicTool,
|
|
2718
|
+
SlateSpecification,
|
|
2719
|
+
SlateTool,
|
|
2720
|
+
SlateTrigger,
|
|
2721
|
+
adapterSpec,
|
|
2722
|
+
allOf,
|
|
2723
|
+
anyOf,
|
|
2724
|
+
auth,
|
|
2725
|
+
axios,
|
|
2726
|
+
buildApiServiceError,
|
|
2727
|
+
collectApiErrorDetails,
|
|
2728
|
+
config,
|
|
2729
|
+
createApiServiceError,
|
|
2730
|
+
createAuthenticatedAxios,
|
|
2731
|
+
createAxios,
|
|
2732
|
+
createBase64Attachment,
|
|
2733
|
+
createHmacSignature,
|
|
2734
|
+
createSlateError,
|
|
2735
|
+
createTextAttachment,
|
|
2736
|
+
createUrlAttachment,
|
|
2737
|
+
extractApiErrorMessage,
|
|
2738
|
+
getApiErrorResponse,
|
|
2739
|
+
getApiErrorStatus,
|
|
2740
|
+
getBase64ByteLength,
|
|
2741
|
+
getCurrentContext,
|
|
2742
|
+
getFileUrlTool,
|
|
2743
|
+
getFileUrlToolInputSchema,
|
|
2744
|
+
getFileUrlToolOutputSchema,
|
|
2745
|
+
getGraphWebhookValidationResponse,
|
|
2746
|
+
getMetaWebhookVerificationResponse,
|
|
2747
|
+
getOAuthExpiresAtFromExpiresIn,
|
|
2748
|
+
getResponseHeaderValue,
|
|
2749
|
+
getServiceErrorData,
|
|
2750
|
+
graphWebhookHttp,
|
|
2751
|
+
inferSlateErrorFromAxios,
|
|
2752
|
+
isApiErrorRecord,
|
|
2753
|
+
isAxiosErrorLike,
|
|
2754
|
+
isServiceErrorData,
|
|
2755
|
+
mapServiceErrorCode,
|
|
2756
|
+
mapServiceErrorToSlateErrorInput,
|
|
2757
|
+
mergeScopes,
|
|
2758
|
+
metaWebhookHttp,
|
|
2759
|
+
normalizeOAuthTokenResponse,
|
|
2760
|
+
pickDefined,
|
|
2761
|
+
publicTool,
|
|
2762
|
+
redactUrlAttachmentSecrets,
|
|
2763
|
+
requestAxios,
|
|
2764
|
+
requestAxiosData,
|
|
2765
|
+
runWithContext,
|
|
2766
|
+
scopeClause,
|
|
2767
|
+
setIfDefined,
|
|
2768
|
+
spec,
|
|
2769
|
+
statusLabelForApiError,
|
|
2770
|
+
tool,
|
|
2771
|
+
trigger,
|
|
2772
|
+
uploadAttachmentDirect,
|
|
2773
|
+
validateScopes,
|
|
2774
|
+
verifyHmacSignature
|
|
2775
|
+
};
|