@xyo-network/api-call-witness 2.79.5 → 2.79.8
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/browser/Config.d.cts +383 -0
- package/dist/browser/Config.d.cts.map +1 -0
- package/dist/browser/Config.d.mts +383 -0
- package/dist/browser/Config.d.mts.map +1 -0
- package/dist/browser/Config.d.ts +383 -0
- package/dist/browser/Config.d.ts.map +1 -0
- package/dist/browser/Payload.d.cts +63 -3
- package/dist/browser/Payload.d.cts.map +1 -1
- package/dist/browser/Payload.d.mts +63 -3
- package/dist/browser/Payload.d.mts.map +1 -1
- package/dist/browser/Payload.d.ts +63 -3
- package/dist/browser/Payload.d.ts.map +1 -1
- package/dist/browser/Witness.d.cts +6 -9
- package/dist/browser/Witness.d.cts.map +1 -1
- package/dist/browser/Witness.d.mts +6 -9
- package/dist/browser/Witness.d.mts.map +1 -1
- package/dist/browser/Witness.d.ts +6 -9
- package/dist/browser/Witness.d.ts.map +1 -1
- package/dist/browser/index.cjs +92 -13
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.d.cts +1 -0
- package/dist/browser/index.d.cts.map +1 -1
- package/dist/browser/index.d.mts +1 -0
- package/dist/browser/index.d.mts.map +1 -1
- package/dist/browser/index.d.ts +1 -0
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +82 -13
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/lib/checkIpfsUrl.d.cts +1 -1
- package/dist/browser/lib/checkIpfsUrl.d.cts.map +1 -1
- package/dist/browser/lib/checkIpfsUrl.d.mts +1 -1
- package/dist/browser/lib/checkIpfsUrl.d.mts.map +1 -1
- package/dist/browser/lib/checkIpfsUrl.d.ts +1 -1
- package/dist/browser/lib/checkIpfsUrl.d.ts.map +1 -1
- package/dist/node/Config.d.cts +383 -0
- package/dist/node/Config.d.cts.map +1 -0
- package/dist/node/Config.d.mts +383 -0
- package/dist/node/Config.d.mts.map +1 -0
- package/dist/node/Config.d.ts +383 -0
- package/dist/node/Config.d.ts.map +1 -0
- package/dist/node/Payload.d.cts +63 -3
- package/dist/node/Payload.d.cts.map +1 -1
- package/dist/node/Payload.d.mts +63 -3
- package/dist/node/Payload.d.mts.map +1 -1
- package/dist/node/Payload.d.ts +63 -3
- package/dist/node/Payload.d.ts.map +1 -1
- package/dist/node/Witness.d.cts +6 -9
- package/dist/node/Witness.d.cts.map +1 -1
- package/dist/node/Witness.d.mts +6 -9
- package/dist/node/Witness.d.mts.map +1 -1
- package/dist/node/Witness.d.ts +6 -9
- package/dist/node/Witness.d.ts.map +1 -1
- package/dist/node/index.cjs +105 -14
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +1 -0
- package/dist/node/index.d.cts.map +1 -1
- package/dist/node/index.d.mts +1 -0
- package/dist/node/index.d.mts.map +1 -1
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +82 -13
- package/dist/node/index.js.map +1 -1
- package/dist/node/lib/checkIpfsUrl.d.cts +1 -1
- package/dist/node/lib/checkIpfsUrl.d.cts.map +1 -1
- package/dist/node/lib/checkIpfsUrl.d.mts +1 -1
- package/dist/node/lib/checkIpfsUrl.d.mts.map +1 -1
- package/dist/node/lib/checkIpfsUrl.d.ts +1 -1
- package/dist/node/lib/checkIpfsUrl.d.ts.map +1 -1
- package/package.json +16 -11
- package/src/Config.ts +42 -0
- package/src/Payload.ts +31 -5
- package/src/Witness.ts +54 -17
- package/src/index.ts +1 -0
- package/src/lib/checkIpfsUrl.ts +17 -5
- package/src/spec/opensea.nft-call.json +41 -0
- package/src/types.d.ts +1 -0
package/dist/node/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/Payload.ts","../../src/Witness.ts","../../src/lib/checkIpfsUrl.ts"],"sourcesContent":["import { Hash } from '@xyo-network/hash'\nimport { Payload } from '@xyo-network/payload-model'\n\nexport const ApiCallSchema = 'network.xyo.api.call'\nexport type ApiCallSchema = typeof ApiCallSchema\n\nexport type Verb = 'get' | 'post'\n\nexport type ApiCall = Payload<\n {\n uri: string\n verb?: Verb\n },\n ApiCallSchema\n>\n\nexport const ApiCallResultSchema = 'network.xyo.api.call.result'\nexport type ApiCallResultSchema = typeof ApiCallResultSchema\n\nexport interface HttpMeta {\n code?: string\n status?: number\n}\n\nexport type ApiCallJsonResult<T extends object | [] = object> = Payload<\n {\n call: Hash\n contentType: 'application/json'\n data: T\n },\n ApiCallResultSchema\n>\n\nexport type ApiCallBase64Result = Payload<\n {\n call: Hash\n contentType: Exclude<string, ApiCallJsonResult['contentType']>\n data: string\n },\n ApiCallResultSchema\n>\n\nexport type ApiCallErrorResult = Payload<\n {\n call: Hash\n http?: HttpMeta\n },\n ApiCallResultSchema\n>\n\nexport type ApiCallResult = ApiCallBase64Result | ApiCallJsonResult | ApiCallErrorResult\n","import { assertEx } from '@xylabs/assert'\nimport { Axios, AxiosError, AxiosJson } from '@xylabs/axios'\nimport { Buffer } from '@xylabs/buffer'\nimport { AbstractWitness } from '@xyo-network/abstract-witness'\nimport { Hash, PayloadHasher } from '@xyo-network/hash'\nimport { JsonArray, JsonObject } from '@xyo-network/object'\nimport { isPayloadOfSchemaType } from '@xyo-network/payload-model'\nimport { WitnessConfig, WitnessParams } from '@xyo-network/witness-model'\nimport { fromByteArray } from 'base64-js'\n\nimport { checkIpfsUrl } from './lib'\nimport {\n ApiCall,\n ApiCallBase64Result,\n ApiCallErrorResult,\n ApiCallJsonResult,\n ApiCallResult,\n ApiCallResultSchema,\n ApiCallSchema,\n Verb,\n} from './Payload'\n\nexport const ApiCallWitnessConfigSchema = 'network.xyo.api.call.witness.config'\nexport type ApiCallWitnessConfigSchema = typeof ApiCallWitnessConfigSchema\n\nexport type ApiCallWitnessConfig = WitnessConfig<{\n accept: 'application/json'\n schema: ApiCallWitnessConfigSchema\n verb?: Verb\n}>\n\nexport type ApiCallWitnessParams = WitnessParams<ApiCallWitnessConfig, { ipfsGateway?: string }>\n\nexport class ApiCallWitness<TParams extends ApiCallWitnessParams = ApiCallWitnessParams> extends AbstractWitness<TParams, ApiCall, ApiCallResult> {\n static override configSchemas = [ApiCallWitnessConfigSchema]\n\n get accept() {\n return this.config.accept\n }\n\n get ipfsGateway() {\n return this.params.ipfsGateway\n }\n\n protected override async observeHandler(inPayloads: ApiCall[] = []): Promise<ApiCallResult[]> {\n await this.started('throw')\n try {\n const observations = await Promise.all(\n inPayloads.filter(isPayloadOfSchemaType(ApiCallSchema)).map(async (call) => {\n const { uri, verb } = call\n\n const validatedUri = assertEx(checkIpfsUrl(uri, this.ipfsGateway), 'Invalid URI')\n\n if (verb === 'get') {\n return this.httpGet(validatedUri, uri)\n }\n\n const observation: ApiCallResult = {\n call: await PayloadHasher.hashAsync(call),\n schema: ApiCallResultSchema,\n }\n return observation\n }),\n )\n return observations\n } catch (ex) {\n const error = ex as Error\n console.log(`Error [${this.config.name}]: ${error.message}`)\n throw error\n }\n }\n\n private async httpGet(url: string, call: Hash): Promise<ApiCallResult> {\n const result: ApiCallResult = {\n call,\n schema: ApiCallResultSchema,\n }\n try {\n switch (this.accept) {\n case 'application/json': {\n const axios = new AxiosJson()\n const response = await axios.get<JsonArray | JsonObject>(url)\n if (response.status >= 200 && response.status < 300) {\n const jsonResult = result as ApiCallJsonResult\n jsonResult.data = response.data\n jsonResult.contentType = 'application/json'\n } else {\n const errorResult = result as ApiCallErrorResult\n errorResult.http = {\n status: response.status,\n }\n }\n break\n }\n default: {\n const axios = new Axios({ responseType: 'arraybuffer' })\n const response = await axios.get(url)\n if (response.status >= 200 && response.status < 300) {\n const jsonResult = result as ApiCallBase64Result\n jsonResult.data = fromByteArray(Buffer.from(response.data, 'binary'))\n jsonResult.contentType = response.headers['content-type']?.toString() ?? 'application/octet-stream'\n } else {\n const errorResult = result as ApiCallErrorResult\n errorResult.http = {\n status: response.status,\n }\n }\n break\n }\n }\n } catch (ex) {\n const axiosError = ex as AxiosError\n if (axiosError.isAxiosError) {\n if (axiosError?.response?.status !== undefined) {\n result.http = result.http ?? {}\n result.http.status = axiosError?.response?.status\n }\n if (axiosError?.code !== undefined) {\n result.http = result.http ?? {}\n result.http.code = axiosError?.code\n }\n return result\n } else {\n throw ex\n }\n }\n return result\n }\n}\n","import { assertEx } from '@xylabs/assert'\n\n/**\n * Returns the equivalent IPFS gateway URL for the supplied URL.\n * @param urlToCheck The URL to check\n * @returns If the supplied URL is an IPFS URL, it converts the URL to the\n * equivalent IPFS gateway URL. Otherwise, returns the original URL.\n */\nexport const checkIpfsUrl = (urlToCheck: string, ipfsGateway?: string) => {\n try {\n const url = new URL(urlToCheck)\n let protocol = url.protocol\n let host = url.host\n let path = url.pathname\n const query = url.search\n if (protocol === 'ipfs:') {\n protocol = 'https:'\n host = assertEx(ipfsGateway, 'No ipfsGateway provided')\n path = url.host === 'ipfs' ? `ipfs${path}` : `ipfs/${url.host}${path}`\n const root = `${protocol}//${host}/${path}`\n return query?.length > 0 ? `${root}?${query}` : root\n } else {\n return urlToCheck\n }\n } catch (ex) {\n const error = ex as Error\n console.error(`${error.name}:${error.message} [${urlToCheck}]`)\n console.log(error.stack)\n return undefined\n }\n}\n"],"mappings":"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","names":["assertEx","assertEx"]}
|
|
1
|
+
{"version":3,"sources":["../../src/Config.ts","../../src/Payload.ts","../../src/Witness.ts","../../src/lib/checkIpfsUrl.ts"],"sourcesContent":["import { AsObjectFactory } from '@xyo-network/object'\nimport { isPayloadOfSchemaType, Payload } from '@xyo-network/payload-model'\nimport { WitnessConfig } from '@xyo-network/witness-model'\n\nimport { ApiCall, ApiUriCall, ApiUriTemplateCall } from './Payload'\n\nexport const ApiCallWitnessConfigSchema = 'network.xyo.api.call.witness.config'\nexport type ApiCallWitnessConfigSchema = typeof ApiCallWitnessConfigSchema\n\nexport type ApiCallWitnessConfigBase = WitnessConfig<{\n accept?: 'application/json'\n queries?: ApiCall['queries']\n schema: ApiCallWitnessConfigSchema\n timeout?: number\n verb?: ApiCall['verb']\n}>\n\nexport type ApiUriCallWitnessConfig = WitnessConfig<\n ApiCallWitnessConfigBase & {\n uri: ApiUriCall['uri']\n }\n>\n\nexport type ApiUriTemplateCallWitnessConfig = WitnessConfig<\n ApiCallWitnessConfigBase & {\n params?: Record<string, unknown>\n uriTemplate: ApiUriTemplateCall['uriTemplate']\n }\n>\n\nexport type ApiCallWitnessConfig = ApiUriCallWitnessConfig | ApiUriTemplateCallWitnessConfig | ApiCallWitnessConfigBase\n\nexport const isApiCallWitnessConfig = isPayloadOfSchemaType(ApiCallWitnessConfigSchema)\nexport const asApiCallWitnessConfig = AsObjectFactory.create(isApiCallWitnessConfig)\n\nexport const isApiUriCallWitnessConfig = (payload?: Payload): payload is ApiUriCallWitnessConfig =>\n isApiCallWitnessConfig(payload) && !!(payload as ApiUriCallWitnessConfig).uri\nexport const asApiUriCallWitnessConfig = AsObjectFactory.create(isApiUriCallWitnessConfig)\n\nexport const isApiUriTemplateCallWitnessConfig = (payload?: Payload): payload is ApiUriTemplateCallWitnessConfig =>\n isApiCallWitnessConfig(payload) && !!(payload as ApiUriTemplateCallWitnessConfig).uriTemplate\nexport const asApiUriTemplateCallWitnessConfig = AsObjectFactory.create(isApiUriTemplateCallWitnessConfig)\n","import { Hash } from '@xyo-network/hash'\nimport { AsObjectFactory } from '@xyo-network/object'\nimport { isPayloadOfSchemaType, Payload } from '@xyo-network/payload-model'\n\nexport const ApiCallSchema = 'network.xyo.api.call'\nexport type ApiCallSchema = typeof ApiCallSchema\n\ntype Verb = 'get' | 'post'\ntype Queries = Record<string, string>\n\nexport interface ApiCallFields {\n queries?: Queries\n verb?: Verb\n}\n\nexport type ApiUriCall = Payload<\n ApiCallFields & {\n uri: string\n },\n ApiCallSchema\n>\n\nexport type ApiUriTemplateCall = Payload<\n ApiCallFields & {\n params?: Record<string, unknown>\n uriTemplate?: string\n },\n ApiCallSchema\n>\n\nexport type ApiCall = ApiUriCall | ApiUriTemplateCall\n\nexport const ApiCallResultSchema = 'network.xyo.api.call.result'\nexport type ApiCallResultSchema = typeof ApiCallResultSchema\n\nexport interface HttpMeta {\n code?: string\n status?: number\n}\n\nexport type ApiCallJsonResult<T extends object | [] = object> = Payload<\n {\n call: Hash\n contentType: 'application/json'\n data: T\n },\n ApiCallResultSchema\n>\n\nexport type ApiCallBase64Result = Payload<\n {\n call: Hash\n contentType: Exclude<string, ApiCallJsonResult['contentType']>\n data: string\n },\n ApiCallResultSchema\n>\n\nexport type ApiCallErrorResult = Payload<\n {\n call: Hash\n http?: HttpMeta\n },\n ApiCallResultSchema\n>\n\nexport type ApiCallResult = ApiCallBase64Result | ApiCallJsonResult | ApiCallErrorResult\n\nexport const isApiCall = isPayloadOfSchemaType(ApiCallSchema)\nexport const asApiCall = AsObjectFactory.create(isApiCall)\n\nexport const isApiUriCall = (payload?: Payload): payload is ApiUriCall => isApiCall(payload) && !!(payload as ApiUriCall).uri\nexport const asApiUriCall = AsObjectFactory.create(isApiUriCall)\n\nexport const isApiUriTemplateCall = (payload?: Payload): payload is ApiUriTemplateCall =>\n isApiCall(payload) && !!((payload as ApiUriTemplateCall).uriTemplate || (payload as ApiUriTemplateCall).params)\nexport const asApiUriTemplateCall = AsObjectFactory.create(isApiUriTemplateCall)\n","import { assertEx } from '@xylabs/assert'\nimport { Axios, AxiosError, AxiosJson } from '@xylabs/axios'\nimport { Buffer } from '@xylabs/buffer'\nimport { AbstractWitness } from '@xyo-network/abstract-witness'\nimport { Hash, PayloadHasher } from '@xyo-network/hash'\nimport { JsonArray, JsonObject } from '@xyo-network/object'\nimport { isPayloadOfSchemaType } from '@xyo-network/payload-model'\nimport { WitnessParams } from '@xyo-network/witness-model'\nimport { fromByteArray } from 'base64-js'\nimport template from 'es6-template-strings'\n\nimport { ApiCallWitnessConfig, ApiCallWitnessConfigSchema, asApiUriCallWitnessConfig, asApiUriTemplateCallWitnessConfig } from './Config'\nimport { checkIpfsUrl } from './lib'\nimport {\n ApiCall,\n ApiCallBase64Result,\n ApiCallErrorResult,\n ApiCallJsonResult,\n ApiCallResult,\n ApiCallResultSchema,\n ApiCallSchema,\n asApiUriCall,\n asApiUriTemplateCall,\n} from './Payload'\n\nexport type ApiCallWitnessParams = WitnessParams<\n ApiCallWitnessConfig,\n {\n headers?: Record<string, string | undefined>\n ipfsGateway?: string\n }\n>\n\nexport class ApiCallWitness<TParams extends ApiCallWitnessParams = ApiCallWitnessParams> extends AbstractWitness<TParams, ApiCall, ApiCallResult> {\n static override configSchemas = [ApiCallWitnessConfigSchema]\n\n get accept() {\n return this.config.accept ?? 'application/json'\n }\n\n get ipfsGateway() {\n return this.params.ipfsGateway\n }\n\n get timeout() {\n return this.config.timeout\n }\n\n getFullUri(call?: ApiCall): string {\n const { uri: callUri } = asApiUriCall(call) ?? {}\n const { uriTemplate: callUriTemplate, params: callParams, queries: callQueries } = asApiUriTemplateCall(call) ?? {}\n const { uri: configUri } = asApiUriCallWitnessConfig(this.config) ?? {}\n const { uriTemplate: configUriTemplate, params: configParams, queries: configQueries } = asApiUriTemplateCallWitnessConfig(this.config) ?? {}\n\n const params = { ...configParams, ...callParams }\n\n let url: URL | undefined = undefined\n\n if (callUri) {\n url = new URL(callUri)\n } else if (callUriTemplate) {\n url = new URL(template(callUriTemplate, params))\n } else if (configUri) {\n url = new URL(configUri)\n } else if (configUriTemplate) {\n url = new URL(template(configUriTemplate, params))\n }\n\n if (url) {\n const queries = Object.entries({ ...configQueries, ...callQueries })\n queries.map(([key, value]) => url?.searchParams.set(key, value))\n return url.href\n }\n\n throw Error('Unable to determine uri. No uri/uriTemplate specified in either the call or config.')\n }\n\n protected override async observeHandler(inPayloads: ApiCall[] = []): Promise<ApiCallResult[]> {\n await this.started('throw')\n try {\n const observations = await Promise.all(\n inPayloads.filter(isPayloadOfSchemaType(ApiCallSchema)).map(async (call) => {\n const { verb: callVerb } = call\n const { verb: configVerb } = this.config\n const verb = callVerb ?? configVerb ?? 'get'\n const uri = this.getFullUri(call)\n\n const validatedUri = assertEx(checkIpfsUrl(uri, this.ipfsGateway), 'Invalid URI')\n\n if (verb === 'get') {\n return this.httpGet(validatedUri, uri)\n }\n\n const observation: ApiCallResult = {\n call: await PayloadHasher.hashAsync(call),\n schema: ApiCallResultSchema,\n }\n return observation\n }),\n )\n return observations\n } catch (ex) {\n const error = ex as Error\n console.error(`Error [${this.config.name}]: ${error.message}`)\n console.log(error.stack)\n throw error\n }\n }\n\n private async httpGet(url: string, call: Hash): Promise<ApiCallResult> {\n const result: ApiCallResult = {\n call,\n schema: ApiCallResultSchema,\n }\n try {\n switch (this.accept) {\n case 'application/json': {\n const axios = new AxiosJson({ headers: this.params.headers, timeout: this.timeout })\n const response = await axios.get<JsonArray | JsonObject>(url)\n if (response.status >= 200 && response.status < 300) {\n const jsonResult = result as ApiCallJsonResult\n jsonResult.data = response.data\n jsonResult.contentType = 'application/json'\n } else {\n const errorResult = result as ApiCallErrorResult\n errorResult.http = {\n status: response.status,\n }\n }\n break\n }\n default: {\n const axios = new Axios({ headers: this.params.headers, responseType: 'arraybuffer', timeout: this.timeout })\n const response = await axios.get(url)\n if (response.status >= 200 && response.status < 300) {\n const jsonResult = result as ApiCallBase64Result\n jsonResult.data = fromByteArray(Buffer.from(response.data, 'binary'))\n jsonResult.contentType = response.headers['content-type']?.toString() ?? 'application/octet-stream'\n } else {\n const errorResult = result as ApiCallErrorResult\n errorResult.http = {\n status: response.status,\n }\n }\n break\n }\n }\n } catch (ex) {\n const axiosError = ex as AxiosError\n if (axiosError.isAxiosError) {\n if (axiosError?.response?.status !== undefined) {\n result.http = result.http ?? {}\n result.http.status = axiosError?.response?.status\n }\n if (axiosError?.code !== undefined) {\n result.http = result.http ?? {}\n result.http.code = axiosError?.code\n }\n return result\n } else {\n throw ex\n }\n }\n return result\n }\n}\n","import { assertEx } from '@xylabs/assert'\n\nconst allowIpfsIoRepair = true\n\n/**\n * Returns the equivalent IPFS gateway URL for the supplied URL.\n * @param urlToCheck The URL to check\n * @returns If the supplied URL is an IPFS URL, it converts the URL to the\n * equivalent IPFS gateway URL. Otherwise, returns the original URL.\n */\nexport const checkIpfsUrl = (urlToCheck: string, ipfsGateway?: string): string => {\n try {\n const url = new URL(urlToCheck)\n let protocol = url.protocol\n let host = url.host\n let path = url.pathname\n const query = url.search\n if (protocol === 'ipfs:') {\n protocol = 'https:'\n host = assertEx(ipfsGateway, 'No ipfsGateway provided')\n path = url.host === 'ipfs' ? `ipfs${path}` : `ipfs/${url.host}${path}`\n const root = `${protocol}//${host}/${path}`\n return query?.length > 0 ? `${root}?${query}` : root\n } else if (allowIpfsIoRepair && protocol === 'https' && host === 'ipfs.io') {\n protocol = 'https:'\n host = assertEx(ipfsGateway, 'No ipfsGateway provided')\n const pathParts = path.split('/')\n if (pathParts[0] === 'ipfs') {\n pathParts.shift()\n }\n path = pathParts.join('/')\n const root = `${protocol}//${host}/${path}`\n return query?.length > 0 ? `${root}?${query}` : root\n } else {\n return urlToCheck\n }\n } catch (ex) {\n //const error = ex as Error\n //console.error(`${error.name}:${error.message} [${urlToCheck}]`)\n //console.log(error.stack)\n return urlToCheck\n }\n}\n"],"mappings":"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","names":["AsObjectFactory","isPayloadOfSchemaType","assertEx","isPayloadOfSchemaType","isPayloadOfSchemaType","assertEx"]}
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* @returns If the supplied URL is an IPFS URL, it converts the URL to the
|
|
5
5
|
* equivalent IPFS gateway URL. Otherwise, returns the original URL.
|
|
6
6
|
*/
|
|
7
|
-
export declare const checkIpfsUrl: (urlToCheck: string, ipfsGateway?: string) => string
|
|
7
|
+
export declare const checkIpfsUrl: (urlToCheck: string, ipfsGateway?: string) => string;
|
|
8
8
|
//# sourceMappingURL=checkIpfsUrl.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkIpfsUrl.d.ts","sourceRoot":"","sources":["../../../src/lib/checkIpfsUrl.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"checkIpfsUrl.d.ts","sourceRoot":"","sources":["../../../src/lib/checkIpfsUrl.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,eAAO,MAAM,YAAY,eAAgB,MAAM,gBAAgB,MAAM,KAAG,MAgCvE,CAAA"}
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* @returns If the supplied URL is an IPFS URL, it converts the URL to the
|
|
5
5
|
* equivalent IPFS gateway URL. Otherwise, returns the original URL.
|
|
6
6
|
*/
|
|
7
|
-
export declare const checkIpfsUrl: (urlToCheck: string, ipfsGateway?: string) => string
|
|
7
|
+
export declare const checkIpfsUrl: (urlToCheck: string, ipfsGateway?: string) => string;
|
|
8
8
|
//# sourceMappingURL=checkIpfsUrl.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkIpfsUrl.d.ts","sourceRoot":"","sources":["../../../src/lib/checkIpfsUrl.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"checkIpfsUrl.d.ts","sourceRoot":"","sources":["../../../src/lib/checkIpfsUrl.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,eAAO,MAAM,YAAY,eAAgB,MAAM,gBAAgB,MAAM,KAAG,MAgCvE,CAAA"}
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* @returns If the supplied URL is an IPFS URL, it converts the URL to the
|
|
5
5
|
* equivalent IPFS gateway URL. Otherwise, returns the original URL.
|
|
6
6
|
*/
|
|
7
|
-
export declare const checkIpfsUrl: (urlToCheck: string, ipfsGateway?: string) => string
|
|
7
|
+
export declare const checkIpfsUrl: (urlToCheck: string, ipfsGateway?: string) => string;
|
|
8
8
|
//# sourceMappingURL=checkIpfsUrl.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkIpfsUrl.d.ts","sourceRoot":"","sources":["../../../src/lib/checkIpfsUrl.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"checkIpfsUrl.d.ts","sourceRoot":"","sources":["../../../src/lib/checkIpfsUrl.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,eAAO,MAAM,YAAY,eAAgB,MAAM,gBAAgB,MAAM,KAAG,MAgCvE,CAAA"}
|
package/package.json
CHANGED
|
@@ -10,20 +10,25 @@
|
|
|
10
10
|
"url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js/issues"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@xylabs/assert": "^2.13.
|
|
14
|
-
"@xylabs/axios": "^2.13.
|
|
15
|
-
"@xylabs/buffer": "^2.13.
|
|
16
|
-
"@xyo-network/abstract-witness": "~2.79.
|
|
17
|
-
"@xyo-network/hash": "~2.79.
|
|
18
|
-
"@xyo-network/object": "~2.79.
|
|
19
|
-
"@xyo-network/payload-model": "~2.79.
|
|
20
|
-
"@xyo-network/witness-model": "~2.79.
|
|
21
|
-
"base64-js": "^1.5.1"
|
|
13
|
+
"@xylabs/assert": "^2.13.9",
|
|
14
|
+
"@xylabs/axios": "^2.13.9",
|
|
15
|
+
"@xylabs/buffer": "^2.13.9",
|
|
16
|
+
"@xyo-network/abstract-witness": "~2.79.8",
|
|
17
|
+
"@xyo-network/hash": "~2.79.8",
|
|
18
|
+
"@xyo-network/object": "~2.79.8",
|
|
19
|
+
"@xyo-network/payload-model": "~2.79.8",
|
|
20
|
+
"@xyo-network/witness-model": "~2.79.8",
|
|
21
|
+
"base64-js": "^1.5.1",
|
|
22
|
+
"es6-template-strings": "^2.0.1"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
|
-
"@xylabs/jest-helpers": "^2.13.
|
|
25
|
+
"@xylabs/jest-helpers": "^2.13.9",
|
|
25
26
|
"@xylabs/ts-scripts-yarn3": "^3.1.21",
|
|
26
27
|
"@xylabs/tsconfig": "^3.1.21",
|
|
28
|
+
"@xyo-network/account": "~2.79.8",
|
|
29
|
+
"@xyo-network/manifest": "~2.79.8",
|
|
30
|
+
"@xyo-network/module-model": "~2.79.8",
|
|
31
|
+
"@xyo-network/sentinel-model": "~2.79.8",
|
|
27
32
|
"ethers": "^5.7.2",
|
|
28
33
|
"jest": "^29.7.0",
|
|
29
34
|
"typescript": "^5.2.2"
|
|
@@ -67,6 +72,6 @@
|
|
|
67
72
|
"url": "https://github.com/XYOracleNetwork/sdk-xyo-client-js.git"
|
|
68
73
|
},
|
|
69
74
|
"sideEffects": false,
|
|
70
|
-
"version": "2.79.
|
|
75
|
+
"version": "2.79.8",
|
|
71
76
|
"type": "module"
|
|
72
77
|
}
|
package/src/Config.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { AsObjectFactory } from '@xyo-network/object'
|
|
2
|
+
import { isPayloadOfSchemaType, Payload } from '@xyo-network/payload-model'
|
|
3
|
+
import { WitnessConfig } from '@xyo-network/witness-model'
|
|
4
|
+
|
|
5
|
+
import { ApiCall, ApiUriCall, ApiUriTemplateCall } from './Payload'
|
|
6
|
+
|
|
7
|
+
export const ApiCallWitnessConfigSchema = 'network.xyo.api.call.witness.config'
|
|
8
|
+
export type ApiCallWitnessConfigSchema = typeof ApiCallWitnessConfigSchema
|
|
9
|
+
|
|
10
|
+
export type ApiCallWitnessConfigBase = WitnessConfig<{
|
|
11
|
+
accept?: 'application/json'
|
|
12
|
+
queries?: ApiCall['queries']
|
|
13
|
+
schema: ApiCallWitnessConfigSchema
|
|
14
|
+
timeout?: number
|
|
15
|
+
verb?: ApiCall['verb']
|
|
16
|
+
}>
|
|
17
|
+
|
|
18
|
+
export type ApiUriCallWitnessConfig = WitnessConfig<
|
|
19
|
+
ApiCallWitnessConfigBase & {
|
|
20
|
+
uri: ApiUriCall['uri']
|
|
21
|
+
}
|
|
22
|
+
>
|
|
23
|
+
|
|
24
|
+
export type ApiUriTemplateCallWitnessConfig = WitnessConfig<
|
|
25
|
+
ApiCallWitnessConfigBase & {
|
|
26
|
+
params?: Record<string, unknown>
|
|
27
|
+
uriTemplate: ApiUriTemplateCall['uriTemplate']
|
|
28
|
+
}
|
|
29
|
+
>
|
|
30
|
+
|
|
31
|
+
export type ApiCallWitnessConfig = ApiUriCallWitnessConfig | ApiUriTemplateCallWitnessConfig | ApiCallWitnessConfigBase
|
|
32
|
+
|
|
33
|
+
export const isApiCallWitnessConfig = isPayloadOfSchemaType(ApiCallWitnessConfigSchema)
|
|
34
|
+
export const asApiCallWitnessConfig = AsObjectFactory.create(isApiCallWitnessConfig)
|
|
35
|
+
|
|
36
|
+
export const isApiUriCallWitnessConfig = (payload?: Payload): payload is ApiUriCallWitnessConfig =>
|
|
37
|
+
isApiCallWitnessConfig(payload) && !!(payload as ApiUriCallWitnessConfig).uri
|
|
38
|
+
export const asApiUriCallWitnessConfig = AsObjectFactory.create(isApiUriCallWitnessConfig)
|
|
39
|
+
|
|
40
|
+
export const isApiUriTemplateCallWitnessConfig = (payload?: Payload): payload is ApiUriTemplateCallWitnessConfig =>
|
|
41
|
+
isApiCallWitnessConfig(payload) && !!(payload as ApiUriTemplateCallWitnessConfig).uriTemplate
|
|
42
|
+
export const asApiUriTemplateCallWitnessConfig = AsObjectFactory.create(isApiUriTemplateCallWitnessConfig)
|
package/src/Payload.ts
CHANGED
|
@@ -1,19 +1,35 @@
|
|
|
1
1
|
import { Hash } from '@xyo-network/hash'
|
|
2
|
-
import {
|
|
2
|
+
import { AsObjectFactory } from '@xyo-network/object'
|
|
3
|
+
import { isPayloadOfSchemaType, Payload } from '@xyo-network/payload-model'
|
|
3
4
|
|
|
4
5
|
export const ApiCallSchema = 'network.xyo.api.call'
|
|
5
6
|
export type ApiCallSchema = typeof ApiCallSchema
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
type Verb = 'get' | 'post'
|
|
9
|
+
type Queries = Record<string, string>
|
|
8
10
|
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
+
export interface ApiCallFields {
|
|
12
|
+
queries?: Queries
|
|
13
|
+
verb?: Verb
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type ApiUriCall = Payload<
|
|
17
|
+
ApiCallFields & {
|
|
11
18
|
uri: string
|
|
12
|
-
verb?: Verb
|
|
13
19
|
},
|
|
14
20
|
ApiCallSchema
|
|
15
21
|
>
|
|
16
22
|
|
|
23
|
+
export type ApiUriTemplateCall = Payload<
|
|
24
|
+
ApiCallFields & {
|
|
25
|
+
params?: Record<string, unknown>
|
|
26
|
+
uriTemplate?: string
|
|
27
|
+
},
|
|
28
|
+
ApiCallSchema
|
|
29
|
+
>
|
|
30
|
+
|
|
31
|
+
export type ApiCall = ApiUriCall | ApiUriTemplateCall
|
|
32
|
+
|
|
17
33
|
export const ApiCallResultSchema = 'network.xyo.api.call.result'
|
|
18
34
|
export type ApiCallResultSchema = typeof ApiCallResultSchema
|
|
19
35
|
|
|
@@ -49,3 +65,13 @@ export type ApiCallErrorResult = Payload<
|
|
|
49
65
|
>
|
|
50
66
|
|
|
51
67
|
export type ApiCallResult = ApiCallBase64Result | ApiCallJsonResult | ApiCallErrorResult
|
|
68
|
+
|
|
69
|
+
export const isApiCall = isPayloadOfSchemaType(ApiCallSchema)
|
|
70
|
+
export const asApiCall = AsObjectFactory.create(isApiCall)
|
|
71
|
+
|
|
72
|
+
export const isApiUriCall = (payload?: Payload): payload is ApiUriCall => isApiCall(payload) && !!(payload as ApiUriCall).uri
|
|
73
|
+
export const asApiUriCall = AsObjectFactory.create(isApiUriCall)
|
|
74
|
+
|
|
75
|
+
export const isApiUriTemplateCall = (payload?: Payload): payload is ApiUriTemplateCall =>
|
|
76
|
+
isApiCall(payload) && !!((payload as ApiUriTemplateCall).uriTemplate || (payload as ApiUriTemplateCall).params)
|
|
77
|
+
export const asApiUriTemplateCall = AsObjectFactory.create(isApiUriTemplateCall)
|
package/src/Witness.ts
CHANGED
|
@@ -5,9 +5,11 @@ import { AbstractWitness } from '@xyo-network/abstract-witness'
|
|
|
5
5
|
import { Hash, PayloadHasher } from '@xyo-network/hash'
|
|
6
6
|
import { JsonArray, JsonObject } from '@xyo-network/object'
|
|
7
7
|
import { isPayloadOfSchemaType } from '@xyo-network/payload-model'
|
|
8
|
-
import {
|
|
8
|
+
import { WitnessParams } from '@xyo-network/witness-model'
|
|
9
9
|
import { fromByteArray } from 'base64-js'
|
|
10
|
+
import template from 'es6-template-strings'
|
|
10
11
|
|
|
12
|
+
import { ApiCallWitnessConfig, ApiCallWitnessConfigSchema, asApiUriCallWitnessConfig, asApiUriTemplateCallWitnessConfig } from './Config'
|
|
11
13
|
import { checkIpfsUrl } from './lib'
|
|
12
14
|
import {
|
|
13
15
|
ApiCall,
|
|
@@ -17,37 +19,71 @@ import {
|
|
|
17
19
|
ApiCallResult,
|
|
18
20
|
ApiCallResultSchema,
|
|
19
21
|
ApiCallSchema,
|
|
20
|
-
|
|
22
|
+
asApiUriCall,
|
|
23
|
+
asApiUriTemplateCall,
|
|
21
24
|
} from './Payload'
|
|
22
25
|
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}>
|
|
31
|
-
|
|
32
|
-
export type ApiCallWitnessParams = WitnessParams<ApiCallWitnessConfig, { ipfsGateway?: string }>
|
|
26
|
+
export type ApiCallWitnessParams = WitnessParams<
|
|
27
|
+
ApiCallWitnessConfig,
|
|
28
|
+
{
|
|
29
|
+
headers?: Record<string, string | undefined>
|
|
30
|
+
ipfsGateway?: string
|
|
31
|
+
}
|
|
32
|
+
>
|
|
33
33
|
|
|
34
34
|
export class ApiCallWitness<TParams extends ApiCallWitnessParams = ApiCallWitnessParams> extends AbstractWitness<TParams, ApiCall, ApiCallResult> {
|
|
35
35
|
static override configSchemas = [ApiCallWitnessConfigSchema]
|
|
36
36
|
|
|
37
37
|
get accept() {
|
|
38
|
-
return this.config.accept
|
|
38
|
+
return this.config.accept ?? 'application/json'
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
get ipfsGateway() {
|
|
42
42
|
return this.params.ipfsGateway
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
get timeout() {
|
|
46
|
+
return this.config.timeout
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
getFullUri(call?: ApiCall): string {
|
|
50
|
+
const { uri: callUri } = asApiUriCall(call) ?? {}
|
|
51
|
+
const { uriTemplate: callUriTemplate, params: callParams, queries: callQueries } = asApiUriTemplateCall(call) ?? {}
|
|
52
|
+
const { uri: configUri } = asApiUriCallWitnessConfig(this.config) ?? {}
|
|
53
|
+
const { uriTemplate: configUriTemplate, params: configParams, queries: configQueries } = asApiUriTemplateCallWitnessConfig(this.config) ?? {}
|
|
54
|
+
|
|
55
|
+
const params = { ...configParams, ...callParams }
|
|
56
|
+
|
|
57
|
+
let url: URL | undefined = undefined
|
|
58
|
+
|
|
59
|
+
if (callUri) {
|
|
60
|
+
url = new URL(callUri)
|
|
61
|
+
} else if (callUriTemplate) {
|
|
62
|
+
url = new URL(template(callUriTemplate, params))
|
|
63
|
+
} else if (configUri) {
|
|
64
|
+
url = new URL(configUri)
|
|
65
|
+
} else if (configUriTemplate) {
|
|
66
|
+
url = new URL(template(configUriTemplate, params))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (url) {
|
|
70
|
+
const queries = Object.entries({ ...configQueries, ...callQueries })
|
|
71
|
+
queries.map(([key, value]) => url?.searchParams.set(key, value))
|
|
72
|
+
return url.href
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
throw Error('Unable to determine uri. No uri/uriTemplate specified in either the call or config.')
|
|
76
|
+
}
|
|
77
|
+
|
|
45
78
|
protected override async observeHandler(inPayloads: ApiCall[] = []): Promise<ApiCallResult[]> {
|
|
46
79
|
await this.started('throw')
|
|
47
80
|
try {
|
|
48
81
|
const observations = await Promise.all(
|
|
49
82
|
inPayloads.filter(isPayloadOfSchemaType(ApiCallSchema)).map(async (call) => {
|
|
50
|
-
const {
|
|
83
|
+
const { verb: callVerb } = call
|
|
84
|
+
const { verb: configVerb } = this.config
|
|
85
|
+
const verb = callVerb ?? configVerb ?? 'get'
|
|
86
|
+
const uri = this.getFullUri(call)
|
|
51
87
|
|
|
52
88
|
const validatedUri = assertEx(checkIpfsUrl(uri, this.ipfsGateway), 'Invalid URI')
|
|
53
89
|
|
|
@@ -65,7 +101,8 @@ export class ApiCallWitness<TParams extends ApiCallWitnessParams = ApiCallWitnes
|
|
|
65
101
|
return observations
|
|
66
102
|
} catch (ex) {
|
|
67
103
|
const error = ex as Error
|
|
68
|
-
console.
|
|
104
|
+
console.error(`Error [${this.config.name}]: ${error.message}`)
|
|
105
|
+
console.log(error.stack)
|
|
69
106
|
throw error
|
|
70
107
|
}
|
|
71
108
|
}
|
|
@@ -78,7 +115,7 @@ export class ApiCallWitness<TParams extends ApiCallWitnessParams = ApiCallWitnes
|
|
|
78
115
|
try {
|
|
79
116
|
switch (this.accept) {
|
|
80
117
|
case 'application/json': {
|
|
81
|
-
const axios = new AxiosJson()
|
|
118
|
+
const axios = new AxiosJson({ headers: this.params.headers, timeout: this.timeout })
|
|
82
119
|
const response = await axios.get<JsonArray | JsonObject>(url)
|
|
83
120
|
if (response.status >= 200 && response.status < 300) {
|
|
84
121
|
const jsonResult = result as ApiCallJsonResult
|
|
@@ -93,7 +130,7 @@ export class ApiCallWitness<TParams extends ApiCallWitnessParams = ApiCallWitnes
|
|
|
93
130
|
break
|
|
94
131
|
}
|
|
95
132
|
default: {
|
|
96
|
-
const axios = new Axios({ responseType: 'arraybuffer' })
|
|
133
|
+
const axios = new Axios({ headers: this.params.headers, responseType: 'arraybuffer', timeout: this.timeout })
|
|
97
134
|
const response = await axios.get(url)
|
|
98
135
|
if (response.status >= 200 && response.status < 300) {
|
|
99
136
|
const jsonResult = result as ApiCallBase64Result
|
package/src/index.ts
CHANGED
package/src/lib/checkIpfsUrl.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { assertEx } from '@xylabs/assert'
|
|
2
2
|
|
|
3
|
+
const allowIpfsIoRepair = true
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* Returns the equivalent IPFS gateway URL for the supplied URL.
|
|
5
7
|
* @param urlToCheck The URL to check
|
|
6
8
|
* @returns If the supplied URL is an IPFS URL, it converts the URL to the
|
|
7
9
|
* equivalent IPFS gateway URL. Otherwise, returns the original URL.
|
|
8
10
|
*/
|
|
9
|
-
export const checkIpfsUrl = (urlToCheck: string, ipfsGateway?: string) => {
|
|
11
|
+
export const checkIpfsUrl = (urlToCheck: string, ipfsGateway?: string): string => {
|
|
10
12
|
try {
|
|
11
13
|
const url = new URL(urlToCheck)
|
|
12
14
|
let protocol = url.protocol
|
|
@@ -19,13 +21,23 @@ export const checkIpfsUrl = (urlToCheck: string, ipfsGateway?: string) => {
|
|
|
19
21
|
path = url.host === 'ipfs' ? `ipfs${path}` : `ipfs/${url.host}${path}`
|
|
20
22
|
const root = `${protocol}//${host}/${path}`
|
|
21
23
|
return query?.length > 0 ? `${root}?${query}` : root
|
|
24
|
+
} else if (allowIpfsIoRepair && protocol === 'https' && host === 'ipfs.io') {
|
|
25
|
+
protocol = 'https:'
|
|
26
|
+
host = assertEx(ipfsGateway, 'No ipfsGateway provided')
|
|
27
|
+
const pathParts = path.split('/')
|
|
28
|
+
if (pathParts[0] === 'ipfs') {
|
|
29
|
+
pathParts.shift()
|
|
30
|
+
}
|
|
31
|
+
path = pathParts.join('/')
|
|
32
|
+
const root = `${protocol}//${host}/${path}`
|
|
33
|
+
return query?.length > 0 ? `${root}?${query}` : root
|
|
22
34
|
} else {
|
|
23
35
|
return urlToCheck
|
|
24
36
|
}
|
|
25
37
|
} catch (ex) {
|
|
26
|
-
const error = ex as Error
|
|
27
|
-
console.error(`${error.name}:${error.message} [${urlToCheck}]`)
|
|
28
|
-
console.log(error.stack)
|
|
29
|
-
return
|
|
38
|
+
//const error = ex as Error
|
|
39
|
+
//console.error(`${error.name}:${error.message} [${urlToCheck}]`)
|
|
40
|
+
//console.log(error.stack)
|
|
41
|
+
return urlToCheck
|
|
30
42
|
}
|
|
31
43
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/XYOracleNetwork/sdk-xyo-client-js/main/packages/manifest/src/schema.json",
|
|
3
|
+
"nodes": [
|
|
4
|
+
{
|
|
5
|
+
"config": {
|
|
6
|
+
"name": "ApiCall",
|
|
7
|
+
"schema": "network.xyo.node.config"
|
|
8
|
+
},
|
|
9
|
+
"modules": {
|
|
10
|
+
"public": [
|
|
11
|
+
{
|
|
12
|
+
"config": {
|
|
13
|
+
"language": "javascript",
|
|
14
|
+
"name": "ApiCallWitness",
|
|
15
|
+
"queries": {
|
|
16
|
+
"limit": 1
|
|
17
|
+
},
|
|
18
|
+
"schema": "network.xyo.api.call.witness.config",
|
|
19
|
+
"uriTemplate": "https://api.opensea.io/api/v2/chain/ethereum/account/${address}/nfts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"config": {
|
|
24
|
+
"language": "javascript",
|
|
25
|
+
"name": "ApiCallSentinel",
|
|
26
|
+
"schema": "network.xyo.sentinel.config",
|
|
27
|
+
"synchronous": "true",
|
|
28
|
+
"tasks": [
|
|
29
|
+
{
|
|
30
|
+
"input": true,
|
|
31
|
+
"module": "ApiCallWitness"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"schema": "network.xyo.manifest"
|
|
41
|
+
}
|
package/src/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module 'es6-template-strings'
|