@joai/warps-openapi 0.1.0

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.
@@ -0,0 +1,41 @@
1
+ import { WarpActionInput, WarpChainName, WarpClientConfig, Warp } from '@joai/warps';
2
+
3
+ type OpenApiConvertOptions = {
4
+ sourceUrl?: string;
5
+ endpoints?: string[];
6
+ chain?: WarpChainName;
7
+ };
8
+ type OpenApiMethod = 'get' | 'post' | 'put' | 'delete';
9
+ type OpenApiParameterLocation = 'path' | 'query';
10
+ type OpenApiParameter = {
11
+ name: string;
12
+ in: OpenApiParameterLocation;
13
+ required: boolean;
14
+ type: string;
15
+ description?: string;
16
+ defaultValue?: string | number | boolean;
17
+ };
18
+ type OpenApiOperation = {
19
+ identifier: string;
20
+ title: string;
21
+ description: string;
22
+ method: OpenApiMethod;
23
+ url: string;
24
+ parameters: OpenApiParameter[];
25
+ payloadInputs: WarpActionInput[];
26
+ };
27
+ type JsonLikeObject = Record<string, unknown>;
28
+
29
+ declare const extractOpenApiOperations: (schema: JsonLikeObject, sourceUrl?: string) => OpenApiOperation[];
30
+ declare const extractOpenApiEndpoints: (spec: unknown) => string[];
31
+
32
+ declare const convertOpenApiToWarps: (config: WarpClientConfig, spec: JsonLikeObject, options?: OpenApiConvertOptions) => Promise<Warp[]>;
33
+
34
+ declare class WarpOpenApi {
35
+ private readonly config;
36
+ constructor(config: WarpClientConfig);
37
+ getWarpsFromUrl(url: string, options?: OpenApiConvertOptions): Promise<Warp[]>;
38
+ getWarpsFromSpec(spec: JsonLikeObject, options?: OpenApiConvertOptions): Promise<Warp[]>;
39
+ }
40
+
41
+ export { type JsonLikeObject, type OpenApiConvertOptions, type OpenApiMethod, type OpenApiOperation, type OpenApiParameter, type OpenApiParameterLocation, WarpOpenApi, convertOpenApiToWarps, extractOpenApiEndpoints, extractOpenApiOperations };
@@ -0,0 +1,41 @@
1
+ import { WarpActionInput, WarpChainName, WarpClientConfig, Warp } from '@joai/warps';
2
+
3
+ type OpenApiConvertOptions = {
4
+ sourceUrl?: string;
5
+ endpoints?: string[];
6
+ chain?: WarpChainName;
7
+ };
8
+ type OpenApiMethod = 'get' | 'post' | 'put' | 'delete';
9
+ type OpenApiParameterLocation = 'path' | 'query';
10
+ type OpenApiParameter = {
11
+ name: string;
12
+ in: OpenApiParameterLocation;
13
+ required: boolean;
14
+ type: string;
15
+ description?: string;
16
+ defaultValue?: string | number | boolean;
17
+ };
18
+ type OpenApiOperation = {
19
+ identifier: string;
20
+ title: string;
21
+ description: string;
22
+ method: OpenApiMethod;
23
+ url: string;
24
+ parameters: OpenApiParameter[];
25
+ payloadInputs: WarpActionInput[];
26
+ };
27
+ type JsonLikeObject = Record<string, unknown>;
28
+
29
+ declare const extractOpenApiOperations: (schema: JsonLikeObject, sourceUrl?: string) => OpenApiOperation[];
30
+ declare const extractOpenApiEndpoints: (spec: unknown) => string[];
31
+
32
+ declare const convertOpenApiToWarps: (config: WarpClientConfig, spec: JsonLikeObject, options?: OpenApiConvertOptions) => Promise<Warp[]>;
33
+
34
+ declare class WarpOpenApi {
35
+ private readonly config;
36
+ constructor(config: WarpClientConfig);
37
+ getWarpsFromUrl(url: string, options?: OpenApiConvertOptions): Promise<Warp[]>;
38
+ getWarpsFromSpec(spec: JsonLikeObject, options?: OpenApiConvertOptions): Promise<Warp[]>;
39
+ }
40
+
41
+ export { type JsonLikeObject, type OpenApiConvertOptions, type OpenApiMethod, type OpenApiOperation, type OpenApiParameter, type OpenApiParameterLocation, WarpOpenApi, convertOpenApiToWarps, extractOpenApiEndpoints, extractOpenApiOperations };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";var O=Object.defineProperty;var L=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var v=(n,e)=>{for(var t in e)O(n,t,{get:e[t],enumerable:!0})},S=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of J(e))!T.call(n,o)&&o!==t&&O(n,o,{get:()=>e[o],enumerable:!(r=L(e,o))||r.enumerable});return n};var E=n=>S(O({},"__esModule",{value:!0}),n);var F={};v(F,{WarpOpenApi:()=>A,convertOpenApiToWarps:()=>d,extractOpenApiEndpoints:()=>j,extractOpenApiOperations:()=>m});module.exports=E(F);var h=["get","post","put","delete"],s=n=>typeof n=="object"&&n!==null&&!Array.isArray(n),y=n=>{if(typeof n=="string"||typeof n=="number"||typeof n=="boolean")return n},b=n=>{let e=typeof n?.type=="string"?n.type:null;return e==="boolean"?"bool":e==="integer"||e==="number"?"number":"string"},g=n=>{if(!Array.isArray(n))return[];let e=[];for(let t of n){if(!s(t))continue;let r=t.in;if(r!=="path"&&r!=="query")continue;let o=t.name;if(typeof o!="string"||!o.trim())continue;let p=s(t.schema)?t.schema:null,l=r==="path"?!0:t.required===!0;e.push({name:o.trim(),in:r,required:l,description:typeof t.description=="string"?t.description:void 0,type:b(p),defaultValue:y(p?.default)})}return e},U=(n,e)=>{let t=new Map;for(let r of n)t.set(`${r.in}:${r.name}`,r);for(let r of e)t.set(`${r.in}:${r.name}`,r);return[...t.values()]},q=n=>{if(!s(n))return[];let e=s(n.content)?n.content:null,t=e&&s(e["application/json"])?e["application/json"]:null,r=t&&s(t.schema)?t.schema:null;if(!r)return[];let o=s(r.properties)?r.properties:null;if(!o)return[];let p=new Set(Array.isArray(r.required)?r.required.filter(a=>typeof a=="string"):[]),l=[];for(let[a,c]of Object.entries(o)){let i=s(c)?c:null;i&&l.push({name:a,as:a,description:typeof i.description=="string"?i.description:void 0,type:b(i),source:"field",required:p.has(a),position:`payload:${a}`,default:y(i.default)})}return l},W=(n,e,t)=>typeof t.operationId=="string"&&t.operationId.trim()?t.operationId.trim():`${n.toUpperCase()} ${e}`,N=(n,e)=>{let r=(Array.isArray(n.servers)?n.servers:[]).find(o=>s(o)&&typeof o.url=="string"&&o.url.length>0);if(r?.url){if(e)try{return new URL(r.url,e).toString()}catch{return r.url}return r.url}if(e)try{let o=new URL(e);return`${o.protocol}//${o.host}`}catch{return e}return""},M=(n,e)=>{let t=n.replace(/\/+$/,""),o=e.replace(/^\/+/,"").replace(/\{([^}]+)\}/g,"{{$1}}");return`${t}/${o}`},P=n=>{let e=s(n.info)?n.info:null;return(e&&typeof e.title=="string"?e.title.trim():"")||"OpenAPI"},m=(n,e)=>{let t=s(n.paths)?n.paths:null;if(!t)return[];let r=N(n,e),o=[];for(let[p,l]of Object.entries(t)){if(!s(l))continue;let a=g(l.parameters);for(let c of h){let i=l[c];if(!s(i))continue;let u=W(c,p,i),w=typeof i.summary=="string"&&i.summary.trim()||u,I=typeof i.description=="string"&&i.description.trim()||`Call ${c.toUpperCase()} ${p}`,x=g(i.parameters),C=U(a,x),k=q(i.requestBody),$=M(r,p);o.push({identifier:u,title:w,description:I,method:c,url:$,parameters:C,payloadInputs:k})}}return o},j=n=>{if(!s(n)||!s(n.paths))return[];let e=[];for(let[t,r]of Object.entries(n.paths))if(s(r))for(let o of h){let p=r[o];s(p)&&e.push(W(o,t,p))}return[...new Set(e)]};var f=require("@joai/warps");var R=f.WarpChainName.Multiversx,d=async(n,e,t)=>{let r=t?.sourceUrl,o=t?.chain||R,p=m(e,r),l=t?.endpoints?.length?p.filter(i=>t.endpoints.includes(i.identifier)):p,a=P(e),c=[];for(let i of l){let u=await D(n,a,i,o,r);c.push(u)}return c},D=async(n,e,t,r,o)=>{let p=`${e}: ${t.title}`,l=[...t.parameters.map(u=>({name:u.name,as:u.name,description:u.description,type:u.type,source:"field",required:u.required,position:`${u.in==="path"?"url":"query"}:${u.name}`,default:u.defaultValue})),...t.payloadInputs],a={url:t.url,method:t.method.toUpperCase()};t.payloadInputs.length>0&&(a.headers={"Content-Type":"application/json"});let c=await new f.WarpBuilder(n).setName(p).setTitle(t.title).setDescription(t.description).addAction({type:"collect",label:t.title,destination:a,inputs:l}).build(!1),i=(0,f.buildGeneratedSourceWarpIdentifier)({type:"openapi",url:o||null,contract:null},t.identifier,p);return(0,f.stampGeneratedWarpMeta)(c,r,i,p),c};var A=class{constructor(e){this.config=e}async getWarpsFromUrl(e,t){let r=await fetch(e);if(!r.ok)throw new Error(`Failed to fetch OpenAPI schema from ${e}: ${r.status}`);let o=await r.json();if(typeof o!="object"||o===null||Array.isArray(o))throw new Error("Invalid OpenAPI schema: expected a JSON object");return this.getWarpsFromSpec(o,{sourceUrl:e,...t})}async getWarpsFromSpec(e,t){return d(this.config,e,t)}};0&&(module.exports={WarpOpenApi,convertOpenApiToWarps,extractOpenApiEndpoints,extractOpenApiOperations});
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ var O=["get","post","put","delete"],s=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),A=e=>{if(typeof e=="string"||typeof e=="number"||typeof e=="boolean")return e},g=e=>{let n=typeof e?.type=="string"?e.type:null;return n==="boolean"?"bool":n==="integer"||n==="number"?"number":"string"},d=e=>{if(!Array.isArray(e))return[];let n=[];for(let t of e){if(!s(t))continue;let r=t.in;if(r!=="path"&&r!=="query")continue;let o=t.name;if(typeof o!="string"||!o.trim())continue;let p=s(t.schema)?t.schema:null,l=r==="path"?!0:t.required===!0;n.push({name:o.trim(),in:r,required:l,description:typeof t.description=="string"?t.description:void 0,type:g(p),defaultValue:A(p?.default)})}return n},C=(e,n)=>{let t=new Map;for(let r of e)t.set(`${r.in}:${r.name}`,r);for(let r of n)t.set(`${r.in}:${r.name}`,r);return[...t.values()]},k=e=>{if(!s(e))return[];let n=s(e.content)?e.content:null,t=n&&s(n["application/json"])?n["application/json"]:null,r=t&&s(t.schema)?t.schema:null;if(!r)return[];let o=s(r.properties)?r.properties:null;if(!o)return[];let p=new Set(Array.isArray(r.required)?r.required.filter(a=>typeof a=="string"):[]),l=[];for(let[a,c]of Object.entries(o)){let i=s(c)?c:null;i&&l.push({name:a,as:a,description:typeof i.description=="string"?i.description:void 0,type:g(i),source:"field",required:p.has(a),position:`payload:${a}`,default:A(i.default)})}return l},h=(e,n,t)=>typeof t.operationId=="string"&&t.operationId.trim()?t.operationId.trim():`${e.toUpperCase()} ${n}`,$=(e,n)=>{let r=(Array.isArray(e.servers)?e.servers:[]).find(o=>s(o)&&typeof o.url=="string"&&o.url.length>0);if(r?.url){if(n)try{return new URL(r.url,n).toString()}catch{return r.url}return r.url}if(n)try{let o=new URL(n);return`${o.protocol}//${o.host}`}catch{return n}return""},L=(e,n)=>{let t=e.replace(/\/+$/,""),o=n.replace(/^\/+/,"").replace(/\{([^}]+)\}/g,"{{$1}}");return`${t}/${o}`},y=e=>{let n=s(e.info)?e.info:null;return(n&&typeof n.title=="string"?n.title.trim():"")||"OpenAPI"},f=(e,n)=>{let t=s(e.paths)?e.paths:null;if(!t)return[];let r=$(e,n),o=[];for(let[p,l]of Object.entries(t)){if(!s(l))continue;let a=d(l.parameters);for(let c of O){let i=l[c];if(!s(i))continue;let u=h(c,p,i),W=typeof i.summary=="string"&&i.summary.trim()||u,P=typeof i.description=="string"&&i.description.trim()||`Call ${c.toUpperCase()} ${p}`,j=d(i.parameters),w=C(a,j),I=k(i.requestBody),x=L(r,p);o.push({identifier:u,title:W,description:P,method:c,url:x,parameters:w,payloadInputs:I})}}return o},J=e=>{if(!s(e)||!s(e.paths))return[];let n=[];for(let[t,r]of Object.entries(e.paths))if(s(r))for(let o of O){let p=r[o];s(p)&&n.push(h(o,t,p))}return[...new Set(n)]};import{WarpBuilder as T,WarpChainName as v,buildGeneratedSourceWarpIdentifier as S,stampGeneratedWarpMeta as E}from"@joai/warps";var U=v.Multiversx,m=async(e,n,t)=>{let r=t?.sourceUrl,o=t?.chain||U,p=f(n,r),l=t?.endpoints?.length?p.filter(i=>t.endpoints.includes(i.identifier)):p,a=y(n),c=[];for(let i of l){let u=await q(e,a,i,o,r);c.push(u)}return c},q=async(e,n,t,r,o)=>{let p=`${n}: ${t.title}`,l=[...t.parameters.map(u=>({name:u.name,as:u.name,description:u.description,type:u.type,source:"field",required:u.required,position:`${u.in==="path"?"url":"query"}:${u.name}`,default:u.defaultValue})),...t.payloadInputs],a={url:t.url,method:t.method.toUpperCase()};t.payloadInputs.length>0&&(a.headers={"Content-Type":"application/json"});let c=await new T(e).setName(p).setTitle(t.title).setDescription(t.description).addAction({type:"collect",label:t.title,destination:a,inputs:l}).build(!1),i=S({type:"openapi",url:o||null,contract:null},t.identifier,p);return E(c,r,i,p),c};var b=class{constructor(n){this.config=n}async getWarpsFromUrl(n,t){let r=await fetch(n);if(!r.ok)throw new Error(`Failed to fetch OpenAPI schema from ${n}: ${r.status}`);let o=await r.json();if(typeof o!="object"||o===null||Array.isArray(o))throw new Error("Invalid OpenAPI schema: expected a JSON object");return this.getWarpsFromSpec(o,{sourceUrl:n,...t})}async getWarpsFromSpec(n,t){return m(this.config,n,t)}};export{b as WarpOpenApi,m as convertOpenApiToWarps,J as extractOpenApiEndpoints,f as extractOpenApiOperations};
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@joai/warps-openapi",
3
+ "version": "0.1.0",
4
+ "description": "OpenAPI to Warps converter",
5
+ "type": "module",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js",
12
+ "default": "./dist/index.mjs"
13
+ }
14
+ },
15
+ "sideEffects": false,
16
+ "scripts": {
17
+ "build": "tsup",
18
+ "test": "jest --config jest.config.mjs",
19
+ "lint": "tsc --noEmit",
20
+ "preversion": "npm run lint && npm run build"
21
+ },
22
+ "license": "MIT",
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "devDependencies": {
27
+ "@types/jest": "^30.0.0",
28
+ "jest": "^30.2.0",
29
+ "jest-environment-jsdom": "^30.2.0",
30
+ "jest-fetch-mock": "^3.0.3",
31
+ "ts-jest": "^29.4.6",
32
+ "tsup": "^8.5.1",
33
+ "typescript": "^5.9.3"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "peerDependencies": {
39
+ "@joai/warps": "^3.3.0"
40
+ }
41
+ }