@supadata/js 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
- 'use strict';var t=class extends Error{error;details;documentationUrl;constructor(r){super(r.message||"An unexpected error occurred"),this.error=r.error||"internal-error",this.details=r.details||"An unexpected error occurred",this.documentationUrl=r.documentationUrl||"",this.name="SupadataError";}};var x={"endpoint is not configured":{error:"invalid-request",message:"The requested endpoint is not configured",details:"The API endpoint you are trying to access does not exist"},"No valid access key found":{error:"invalid-request",message:"Invalid or missing API key",details:"Please ensure you have provided a valid API key"},"quota exceeded":{error:"quota-exceeded",message:"API quota exceeded",details:"You have exceeded your API quota for the current period"}},g=(s,r)=>{let o=Object.entries(x).find(([u])=>r.includes(u));return o?new t(o[1]):new t({error:"internal-error",message:"An unexpected error occurred",details:r})};var n=class{config;constructor(r){this.config=r;}async fetch(r,o){let l=`${this.config.baseUrl||"https://api.supadata.ai/v1"}${r.startsWith("/")?r:`/${r}`}`;if(o){let e=new URLSearchParams;Object.entries(o).forEach(([h,d])=>{d!=null&&e.append(h,String(d));}),l+=`?${e.toString()}`;}let a=await fetch(l,{method:"GET",headers:{"x-api-key":this.config.apiKey,"Content-Type":"application/json"}}),m=a.headers.get("content-type");if(!a.ok)if(m?.includes("application/json")){let e=await a.json();throw new t(e)}else {let e=await a.text();throw g(a.status,e)}try{if(!m?.includes("application/json"))throw new t({error:"internal-error",message:"Invalid response format",details:"Expected JSON response but received different content type"});return await a.json()}catch(e){throw new t({error:"internal-error",message:"Failed to parse response",details:e instanceof Error?e.message:"Unknown error"})}}};var c=class extends n{async transcript(r){return this.fetch("/youtube/transcript",r)}async translate(r){return this.fetch("/youtube/transcript/translate",r)}};var p=class extends n{async scrape(r){return this.fetch("/web/scrape",{url:r})}async map(r){return this.fetch("/web/map",{url:r})}};var f=class{youtube;web;constructor(r){this.youtube=new c(r),this.web=new p(r);}};
2
- exports.BaseClient=n;exports.Supadata=f;exports.SupadataError=t;exports.WebService=p;exports.YouTubeService=c;//# sourceMappingURL=index.cjs.map
1
+ 'use strict';var e=class extends Error{error;details;documentationUrl;constructor(r){super(r.message||"An unexpected error occurred"),this.error=r.error||"internal-error",this.details=r.details||"An unexpected error occurred",this.documentationUrl=r.documentationUrl||"",this.name="SupadataError";}};var o={403:{error:"invalid-request",message:"Invalid or missing API key",details:"Please ensure you have provided a valid API key"},404:{error:"invalid-request",message:"Endpoint does not exist",details:"The API endpoint you are trying to access does not exist"},429:{error:"limit-exceeded",message:"Limit exceeded",details:"You have exceeded the allowed request rate or quota limits"}},g=(t,r)=>t in o?new e({...o[t],message:o[t].message,details:r||o[t].details}):new e({error:"internal-error",message:"An unexpected error occurred",details:r});var s=class{config;constructor(r){this.config=r;}async fetch(r,l){let m=`${this.config.baseUrl||"https://api.supadata.ai/v1"}${r.startsWith("/")?r:`/${r}`}`;if(l){let a=new URLSearchParams;Object.entries(l).forEach(([h,d])=>{d!=null&&a.append(h,String(d));}),m+=`?${a.toString()}`;}let n=await fetch(m,{method:"GET",headers:{"x-api-key":this.config.apiKey,"Content-Type":"application/json"}}),u=n.headers.get("content-type");if(!n.ok){if([403,404,429].includes(n.status)){let a=await n.json();throw g(n.status,a.message)}if(u?.includes("application/json")){let a=await n.json();throw new e(a)}else throw new e({error:"internal-error",message:"Unexpected error response format",details:await n.text()})}try{if(!u?.includes("application/json"))throw new e({error:"internal-error",message:"Invalid response format",details:"Expected JSON response but received different content type"});return await n.json()}catch(a){throw new e({error:"internal-error",message:"Failed to parse response",details:a instanceof Error?a.message:"Unknown error"})}}};var c=class extends s{async transcript(r){return this.fetch("/youtube/transcript",r)}async translate(r){return this.fetch("/youtube/transcript/translate",r)}};var p=class extends s{async scrape(r){return this.fetch("/web/scrape",{url:r})}async map(r){return this.fetch("/web/map",{url:r})}};var f=class{youtube;web;constructor(r){this.youtube=new c(r),this.web=new p(r);}};
2
+ exports.BaseClient=s;exports.Supadata=f;exports.SupadataError=e;exports.WebService=p;exports.YouTubeService=c;//# sourceMappingURL=index.cjs.map
3
3
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/gateway-error-mapper.ts","../src/client.ts","../src/services/youtube.ts","../src/services/web.ts","../src/index.ts"],"names":["SupadataError","error","GATEWAY_ERROR_PATTERNS","mapGatewayError","statusCode","errorText","matchedError","pattern","BaseClient","config","endpoint","params","url","queryParams","key","value","response","contentType","errorData","YouTubeService","WebService","Supadata"],"mappings":"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","file":"index.cjs","sourcesContent":["export interface TranscriptChunk {\n text: string;\n offset: number;\n duration: number;\n lang: string;\n}\n\nexport interface Transcript {\n content: TranscriptChunk[] | string;\n lang: string;\n availableLangs: string[];\n}\n\nexport interface TranslatedTranscript {\n content: TranscriptChunk[] | string;\n lang: string;\n}\n\nexport interface Scrape {\n url: string;\n content: string;\n name: string;\n description: string;\n ogUrl: string;\n countCharacters: number;\n urls: string[];\n}\n\nexport interface Map {\n urls: string[];\n}\n\nexport interface SupadataConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport class SupadataError extends Error {\n error:\n | 'invalid-request'\n | 'missing-parameters'\n | 'internal-error'\n | 'transcript-unavailable'\n | 'video-not-found'\n | 'video-id-invalid'\n | 'youtube-api-error'\n | 'quota-exceeded'\n | 'rate-limit-exceeded';\n details: string;\n documentationUrl: string;\n\n constructor(error: {\n error: SupadataError['error'];\n message?: string;\n details?: string;\n documentationUrl?: string;\n }) {\n super(error.message || 'An unexpected error occurred');\n this.error = error.error || 'internal-error';\n this.details = error.details || 'An unexpected error occurred';\n this.documentationUrl = error.documentationUrl || '';\n this.name = 'SupadataError';\n }\n}\n","import { SupadataError } from './types';\n\n/*\nThe API gateway returns errors in text/plain content type. \nAs a temporary workaround we're mapping them to SupadataError.\n*/\n\nconst GATEWAY_ERROR_PATTERNS = {\n 'endpoint is not configured': {\n error: 'invalid-request' as const,\n message: 'The requested endpoint is not configured',\n details: 'The API endpoint you are trying to access does not exist',\n },\n 'No valid access key found': {\n error: 'invalid-request' as const,\n message: 'Invalid or missing API key',\n details: 'Please ensure you have provided a valid API key',\n },\n 'quota exceeded': {\n error: 'quota-exceeded' as const,\n message: 'API quota exceeded',\n details: 'You have exceeded your API quota for the current period',\n },\n};\n\nexport const mapGatewayError = (\n statusCode: number,\n errorText: string\n): SupadataError => {\n const matchedError = Object.entries(GATEWAY_ERROR_PATTERNS).find(\n ([pattern]) => errorText.includes(pattern)\n );\n\n if (matchedError) {\n return new SupadataError(matchedError[1]);\n }\n\n // Default error if no pattern matches\n return new SupadataError({\n error: 'internal-error',\n message: 'An unexpected error occurred',\n details: errorText,\n });\n};\n","import { SupadataConfig, SupadataError } from './types.js';\nimport { mapGatewayError } from './gateway-error-mapper.js';\n\nexport class BaseClient {\n protected config: SupadataConfig;\n\n constructor(config: SupadataConfig) {\n this.config = config;\n }\n\n async fetch<T>(\n endpoint: string,\n params: Record<string, unknown> | object\n ): Promise<T> {\n const baseUrl = this.config.baseUrl || 'https://api.supadata.ai/v1';\n let url = `${baseUrl}${\n endpoint.startsWith('/') ? endpoint : `/${endpoint}`\n }`;\n\n if (params) {\n const queryParams = new URLSearchParams();\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n queryParams.append(key, String(value));\n }\n });\n url += `?${queryParams.toString()}`;\n }\n\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'x-api-key': this.config.apiKey,\n 'Content-Type': 'application/json',\n },\n });\n\n const contentType = response.headers.get('content-type');\n\n if (!response.ok) {\n if (contentType?.includes('application/json')) {\n const errorData = await response.json();\n throw new SupadataError(errorData);\n } else {\n const errorText = await response.text();\n throw mapGatewayError(response.status, errorText);\n }\n }\n\n try {\n if (!contentType?.includes('application/json')) {\n throw new SupadataError({\n error: 'internal-error',\n message: 'Invalid response format',\n details: 'Expected JSON response but received different content type',\n });\n }\n\n return (await response.json()) as T;\n } catch (error) {\n throw new SupadataError({\n error: 'internal-error',\n message: 'Failed to parse response',\n details: error instanceof Error ? error.message : 'Unknown error',\n });\n }\n }\n}\n","import { BaseClient } from \"../client.js\";\nimport { Transcript, TranslatedTranscript } from \"../types.js\";\n\nexport interface TranscriptParams {\n videoId: string;\n lang?: string;\n text?: boolean;\n}\n\nexport interface TranslateParams extends TranscriptParams {\n lang: string;\n}\n\nexport class YouTubeService extends BaseClient {\n async transcript(params: TranscriptParams): Promise<Transcript> {\n return this.fetch<Transcript>(\"/youtube/transcript\", params);\n }\n\n async translate(params: TranslateParams): Promise<TranslatedTranscript> {\n return this.fetch<TranslatedTranscript>(\n \"/youtube/transcript/translate\",\n params\n );\n }\n}\n","import { BaseClient } from '../client.js';\nimport { Scrape, Map } from '../types.js';\n\nexport class WebService extends BaseClient {\n async scrape(url: string): Promise<Scrape> {\n return this.fetch<Scrape>('/web/scrape', { url });\n }\n\n async map(url: string): Promise<Map> {\n return this.fetch<Map>('/web/map', { url });\n }\n}","import { SupadataConfig } from './types.js';\nimport { YouTubeService } from './services/youtube.js';\nimport { WebService } from './services/web.js';\n\nexport * from './types.js';\nexport * from './client.js';\nexport * from './services/youtube.js';\nexport * from './services/web.js';\n\nexport class Supadata {\n readonly youtube: YouTubeService;\n readonly web: WebService;\n\n constructor(config: SupadataConfig) {\n this.youtube = new YouTubeService(config);\n this.web = new WebService(config);\n }\n}"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/gateway-error-mapper.ts","../src/client.ts","../src/services/youtube.ts","../src/services/web.ts","../src/index.ts"],"names":["SupadataError","error","GATEWAY_STATUS_ERRORS","mapGatewayError","statusCode","errorText","BaseClient","config","endpoint","params","url","queryParams","key","value","response","contentType","errorData","YouTubeService","WebService","Supadata"],"mappings":"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","file":"index.cjs","sourcesContent":["export interface TranscriptChunk {\n text: string;\n offset: number;\n duration: number;\n lang: string;\n}\n\nexport interface Transcript {\n content: TranscriptChunk[] | string;\n lang: string;\n availableLangs: string[];\n}\n\nexport interface TranslatedTranscript {\n content: TranscriptChunk[] | string;\n lang: string;\n}\n\nexport interface Scrape {\n url: string;\n content: string;\n name: string;\n description: string;\n ogUrl: string;\n countCharacters: number;\n urls: string[];\n}\n\nexport interface Map {\n urls: string[];\n}\n\nexport interface SupadataConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport class SupadataError extends Error {\n error:\n | 'invalid-request'\n | 'missing-parameters'\n | 'internal-error'\n | 'transcript-unavailable'\n | 'video-not-found'\n | 'video-id-invalid'\n | 'youtube-api-error'\n | 'limit-exceeded';\n details: string;\n documentationUrl: string;\n\n constructor(error: {\n error: SupadataError['error'];\n message?: string;\n details?: string;\n documentationUrl?: string;\n }) {\n super(error.message || 'An unexpected error occurred');\n this.error = error.error || 'internal-error';\n this.details = error.details || 'An unexpected error occurred';\n this.documentationUrl = error.documentationUrl || '';\n this.name = 'SupadataError';\n }\n}\n","import { SupadataError } from './types';\n\n/*\nThe API gateway returns errors in text/plain content type. \nAs a temporary workaround we're mapping them to SupadataError.\n*/\n\nconst GATEWAY_STATUS_ERRORS = {\n 403: {\n error: 'invalid-request' as const,\n message: 'Invalid or missing API key',\n details: 'Please ensure you have provided a valid API key',\n },\n 404: {\n error: 'invalid-request' as const,\n message: 'Endpoint does not exist',\n details: 'The API endpoint you are trying to access does not exist',\n },\n 429: {\n error: 'limit-exceeded' as const,\n message: 'Limit exceeded',\n details: 'You have exceeded the allowed request rate or quota limits',\n },\n};\n\nexport const mapGatewayError = (\n statusCode: number,\n errorText: string\n): SupadataError => {\n if (statusCode in GATEWAY_STATUS_ERRORS) {\n return new SupadataError({\n ...GATEWAY_STATUS_ERRORS[\n statusCode as keyof typeof GATEWAY_STATUS_ERRORS\n ],\n message:\n GATEWAY_STATUS_ERRORS[statusCode as keyof typeof GATEWAY_STATUS_ERRORS]\n .message,\n details:\n errorText ||\n GATEWAY_STATUS_ERRORS[statusCode as keyof typeof GATEWAY_STATUS_ERRORS]\n .details,\n });\n }\n\n // Default error if status code is not recognized\n return new SupadataError({\n error: 'internal-error',\n message: 'An unexpected error occurred',\n details: errorText,\n });\n};\n","import { SupadataConfig, SupadataError } from './types.js';\nimport { mapGatewayError } from './gateway-error-mapper.js';\n\nexport class BaseClient {\n protected config: SupadataConfig;\n\n constructor(config: SupadataConfig) {\n this.config = config;\n }\n\n async fetch<T>(\n endpoint: string,\n params: Record<string, unknown> | object\n ): Promise<T> {\n const baseUrl = this.config.baseUrl || 'https://api.supadata.ai/v1';\n let url = `${baseUrl}${\n endpoint.startsWith('/') ? endpoint : `/${endpoint}`\n }`;\n\n if (params) {\n const queryParams = new URLSearchParams();\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n queryParams.append(key, String(value));\n }\n });\n url += `?${queryParams.toString()}`;\n }\n\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'x-api-key': this.config.apiKey,\n 'Content-Type': 'application/json',\n },\n });\n\n const contentType = response.headers.get('content-type');\n\n if (!response.ok) {\n // First check for gateway-specific status codes\n if ([403, 404, 429].includes(response.status)) {\n const errorData = await response.json();\n throw mapGatewayError(response.status, errorData.message);\n }\n\n // Handle standard API errors\n if (contentType?.includes('application/json')) {\n const errorData = await response.json();\n throw new SupadataError(errorData);\n } else {\n // Fallback for unexpected non-JSON errors\n throw new SupadataError({\n error: 'internal-error',\n message: 'Unexpected error response format',\n details: await response.text(),\n });\n }\n }\n\n try {\n if (!contentType?.includes('application/json')) {\n throw new SupadataError({\n error: 'internal-error',\n message: 'Invalid response format',\n details: 'Expected JSON response but received different content type',\n });\n }\n\n return (await response.json()) as T;\n } catch (error) {\n throw new SupadataError({\n error: 'internal-error',\n message: 'Failed to parse response',\n details: error instanceof Error ? error.message : 'Unknown error',\n });\n }\n }\n}\n","import { BaseClient } from '../client.js';\nimport { Transcript, TranslatedTranscript } from '../types.js';\n\nexport interface TranscriptParams {\n videoId: string;\n lang?: string;\n text?: boolean;\n}\n\nexport interface TranslateParams extends TranscriptParams {\n lang: string;\n}\n\nexport class YouTubeService extends BaseClient {\n async transcript(params: TranscriptParams): Promise<Transcript> {\n return this.fetch<Transcript>('/youtube/transcript', params);\n }\n\n async translate(params: TranslateParams): Promise<TranslatedTranscript> {\n return this.fetch<TranslatedTranscript>(\n '/youtube/transcript/translate',\n params\n );\n }\n}\n","import { BaseClient } from '../client.js';\nimport { Scrape, Map } from '../types.js';\n\nexport class WebService extends BaseClient {\n async scrape(url: string): Promise<Scrape> {\n return this.fetch<Scrape>('/web/scrape', { url });\n }\n\n async map(url: string): Promise<Map> {\n return this.fetch<Map>('/web/map', { url });\n }\n}\n","import { SupadataConfig } from './types.js';\nimport { YouTubeService } from './services/youtube.js';\nimport { WebService } from './services/web.js';\n\nexport * from './types.js';\nexport * from './client.js';\nexport * from './services/youtube.js';\nexport * from './services/web.js';\n\nexport class Supadata {\n readonly youtube: YouTubeService;\n readonly web: WebService;\n\n constructor(config: SupadataConfig) {\n this.youtube = new YouTubeService(config);\n this.web = new WebService(config);\n }\n}\n"]}
package/dist/index.d.mts CHANGED
@@ -30,7 +30,7 @@ interface SupadataConfig {
30
30
  baseUrl?: string;
31
31
  }
32
32
  declare class SupadataError extends Error {
33
- error: 'invalid-request' | 'missing-parameters' | 'internal-error' | 'transcript-unavailable' | 'video-not-found' | 'video-id-invalid' | 'youtube-api-error' | 'quota-exceeded' | 'rate-limit-exceeded';
33
+ error: 'invalid-request' | 'missing-parameters' | 'internal-error' | 'transcript-unavailable' | 'video-not-found' | 'video-id-invalid' | 'youtube-api-error' | 'limit-exceeded';
34
34
  details: string;
35
35
  documentationUrl: string;
36
36
  constructor(error: {
package/dist/index.d.ts CHANGED
@@ -30,7 +30,7 @@ interface SupadataConfig {
30
30
  baseUrl?: string;
31
31
  }
32
32
  declare class SupadataError extends Error {
33
- error: 'invalid-request' | 'missing-parameters' | 'internal-error' | 'transcript-unavailable' | 'video-not-found' | 'video-id-invalid' | 'youtube-api-error' | 'quota-exceeded' | 'rate-limit-exceeded';
33
+ error: 'invalid-request' | 'missing-parameters' | 'internal-error' | 'transcript-unavailable' | 'video-not-found' | 'video-id-invalid' | 'youtube-api-error' | 'limit-exceeded';
34
34
  details: string;
35
35
  documentationUrl: string;
36
36
  constructor(error: {
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- var t=class extends Error{error;details;documentationUrl;constructor(r){super(r.message||"An unexpected error occurred"),this.error=r.error||"internal-error",this.details=r.details||"An unexpected error occurred",this.documentationUrl=r.documentationUrl||"",this.name="SupadataError";}};var T={"endpoint is not configured":{error:"invalid-request",message:"The requested endpoint is not configured",details:"The API endpoint you are trying to access does not exist"},"No valid access key found":{error:"invalid-request",message:"Invalid or missing API key",details:"Please ensure you have provided a valid API key"},"quota exceeded":{error:"quota-exceeded",message:"API quota exceeded",details:"You have exceeded your API quota for the current period"}},f=(s,r)=>{let o=Object.entries(T).find(([l])=>r.includes(l));return o?new t(o[1]):new t({error:"internal-error",message:"An unexpected error occurred",details:r})};var n=class{config;constructor(r){this.config=r;}async fetch(r,o){let m=`${this.config.baseUrl||"https://api.supadata.ai/v1"}${r.startsWith("/")?r:`/${r}`}`;if(o){let e=new URLSearchParams;Object.entries(o).forEach(([x,u])=>{u!=null&&e.append(x,String(u));}),m+=`?${e.toString()}`;}let a=await fetch(m,{method:"GET",headers:{"x-api-key":this.config.apiKey,"Content-Type":"application/json"}}),g=a.headers.get("content-type");if(!a.ok)if(g?.includes("application/json")){let e=await a.json();throw new t(e)}else {let e=await a.text();throw f(a.status,e)}try{if(!g?.includes("application/json"))throw new t({error:"internal-error",message:"Invalid response format",details:"Expected JSON response but received different content type"});return await a.json()}catch(e){throw new t({error:"internal-error",message:"Failed to parse response",details:e instanceof Error?e.message:"Unknown error"})}}};var p=class extends n{async transcript(r){return this.fetch("/youtube/transcript",r)}async translate(r){return this.fetch("/youtube/transcript/translate",r)}};var d=class extends n{async scrape(r){return this.fetch("/web/scrape",{url:r})}async map(r){return this.fetch("/web/map",{url:r})}};var h=class{youtube;web;constructor(r){this.youtube=new p(r),this.web=new d(r);}};
2
- export{n as BaseClient,h as Supadata,t as SupadataError,d as WebService,p as YouTubeService};//# sourceMappingURL=index.mjs.map
1
+ var e=class extends Error{error;details;documentationUrl;constructor(r){super(r.message||"An unexpected error occurred"),this.error=r.error||"internal-error",this.details=r.details||"An unexpected error occurred",this.documentationUrl=r.documentationUrl||"",this.name="SupadataError";}};var c={403:{error:"invalid-request",message:"Invalid or missing API key",details:"Please ensure you have provided a valid API key"},404:{error:"invalid-request",message:"Endpoint does not exist",details:"The API endpoint you are trying to access does not exist"},429:{error:"limit-exceeded",message:"Limit exceeded",details:"You have exceeded the allowed request rate or quota limits"}},f=(t,r)=>t in c?new e({...c[t],message:c[t].message,details:r||c[t].details}):new e({error:"internal-error",message:"An unexpected error occurred",details:r});var s=class{config;constructor(r){this.config=r;}async fetch(r,m){let u=`${this.config.baseUrl||"https://api.supadata.ai/v1"}${r.startsWith("/")?r:`/${r}`}`;if(m){let a=new URLSearchParams;Object.entries(m).forEach(([T,l])=>{l!=null&&a.append(T,String(l));}),u+=`?${a.toString()}`;}let n=await fetch(u,{method:"GET",headers:{"x-api-key":this.config.apiKey,"Content-Type":"application/json"}}),g=n.headers.get("content-type");if(!n.ok){if([403,404,429].includes(n.status)){let a=await n.json();throw f(n.status,a.message)}if(g?.includes("application/json")){let a=await n.json();throw new e(a)}else throw new e({error:"internal-error",message:"Unexpected error response format",details:await n.text()})}try{if(!g?.includes("application/json"))throw new e({error:"internal-error",message:"Invalid response format",details:"Expected JSON response but received different content type"});return await n.json()}catch(a){throw new e({error:"internal-error",message:"Failed to parse response",details:a instanceof Error?a.message:"Unknown error"})}}};var p=class extends s{async transcript(r){return this.fetch("/youtube/transcript",r)}async translate(r){return this.fetch("/youtube/transcript/translate",r)}};var d=class extends s{async scrape(r){return this.fetch("/web/scrape",{url:r})}async map(r){return this.fetch("/web/map",{url:r})}};var h=class{youtube;web;constructor(r){this.youtube=new p(r),this.web=new d(r);}};
2
+ export{s as BaseClient,h as Supadata,e as SupadataError,d as WebService,p as YouTubeService};//# sourceMappingURL=index.mjs.map
3
3
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/gateway-error-mapper.ts","../src/client.ts","../src/services/youtube.ts","../src/services/web.ts","../src/index.ts"],"names":["SupadataError","error","GATEWAY_ERROR_PATTERNS","mapGatewayError","statusCode","errorText","matchedError","pattern","BaseClient","config","endpoint","params","url","queryParams","key","value","response","contentType","errorData","YouTubeService","WebService","Supadata"],"mappings":"AAqCO,IAAMA,EAAN,cAA4B,KAAM,CACvC,KAUA,CAAA,OAAA,CACA,iBAEA,WAAYC,CAAAA,CAAAA,CAKT,CACD,KAAMA,CAAAA,CAAAA,CAAM,SAAW,8BAA8B,CAAA,CACrD,KAAK,KAAQA,CAAAA,CAAAA,CAAM,OAAS,gBAC5B,CAAA,IAAA,CAAK,OAAUA,CAAAA,CAAAA,CAAM,SAAW,8BAChC,CAAA,IAAA,CAAK,iBAAmBA,CAAM,CAAA,gBAAA,EAAoB,GAClD,IAAK,CAAA,IAAA,CAAO,gBACd,CACF,ECxDA,IAAMC,CAAyB,CAAA,CAC7B,6BAA8B,CAC5B,KAAA,CAAO,kBACP,OAAS,CAAA,0CAAA,CACT,OAAS,CAAA,0DACX,EACA,2BAA6B,CAAA,CAC3B,MAAO,iBACP,CAAA,OAAA,CAAS,6BACT,OAAS,CAAA,iDACX,EACA,gBAAkB,CAAA,CAChB,MAAO,gBACP,CAAA,OAAA,CAAS,qBACT,OAAS,CAAA,yDACX,CACF,CAEaC,CAAAA,CAAAA,CAAkB,CAC7BC,CACAC,CAAAA,CAAAA,GACkB,CAClB,IAAMC,CAAAA,CAAe,OAAO,OAAQJ,CAAAA,CAAsB,EAAE,IAC1D,CAAA,CAAC,CAACK,CAAO,CAAA,GAAMF,EAAU,QAASE,CAAAA,CAAO,CAC3C,CAEA,CAAA,OAAID,EACK,IAAIN,CAAAA,CAAcM,CAAa,CAAA,CAAC,CAAC,CAInC,CAAA,IAAIN,EAAc,CACvB,KAAA,CAAO,iBACP,OAAS,CAAA,8BAAA,CACT,QAASK,CACX,CAAC,CACH,CCxCO,CAAA,IAAMG,EAAN,KAAiB,CACZ,OAEV,WAAYC,CAAAA,CAAAA,CAAwB,CAClC,IAAA,CAAK,OAASA,EAChB,CAEA,MAAM,KACJC,CAAAA,CAAAA,CACAC,EACY,CAEZ,IAAIC,EAAM,CADM,EAAA,IAAA,CAAK,OAAO,OAAW,EAAA,4BACnB,GAClBF,CAAS,CAAA,UAAA,CAAW,GAAG,CAAIA,CAAAA,CAAAA,CAAW,CAAIA,CAAAA,EAAAA,CAAQ,EACpD,CAEA,CAAA,CAAA,GAAIC,EAAQ,CACV,IAAME,EAAc,IAAI,eAAA,CACxB,OAAO,OAAQF,CAAAA,CAAM,EAAE,OAAQ,CAAA,CAAC,CAACG,CAAKC,CAAAA,CAAK,IAAM,CACpBA,CAAAA,EAAU,MACnCF,CAAY,CAAA,MAAA,CAAOC,EAAK,MAAOC,CAAAA,CAAK,CAAC,EAEzC,CAAC,EACDH,CAAO,EAAA,CAAA,CAAA,EAAIC,EAAY,QAAS,EAAC,GACnC,CAEA,IAAMG,EAAW,MAAM,KAAA,CAAMJ,EAAK,CAChC,MAAA,CAAQ,KACR,CAAA,OAAA,CAAS,CACP,WAAa,CAAA,IAAA,CAAK,OAAO,MACzB,CAAA,cAAA,CAAgB,kBAClB,CACF,CAAC,EAEKK,CAAcD,CAAAA,CAAAA,CAAS,QAAQ,GAAI,CAAA,cAAc,EAEvD,GAAI,CAACA,EAAS,EACZ,CAAA,GAAIC,CAAa,EAAA,QAAA,CAAS,kBAAkB,CAAG,CAAA,CAC7C,IAAMC,CAAY,CAAA,MAAMF,EAAS,IAAK,EAAA,CACtC,MAAM,IAAIhB,CAAAA,CAAckB,CAAS,CACnC,CAAA,KAAO,CACL,IAAMb,CAAAA,CAAY,MAAMW,CAAS,CAAA,IAAA,EACjC,CAAA,MAAMb,EAAgBa,CAAS,CAAA,MAAA,CAAQX,CAAS,CAClD,CAGF,GAAI,CACF,GAAI,CAACY,CAAa,EAAA,QAAA,CAAS,kBAAkB,CAC3C,CAAA,MAAM,IAAIjB,CAAc,CAAA,CACtB,MAAO,gBACP,CAAA,OAAA,CAAS,0BACT,OAAS,CAAA,4DACX,CAAC,CAGH,CAAA,OAAQ,MAAMgB,CAAS,CAAA,IAAA,EACzB,CAASf,MAAAA,CAAAA,CAAO,CACd,MAAM,IAAID,EAAc,CACtB,KAAA,CAAO,iBACP,OAAS,CAAA,0BAAA,CACT,QAASC,CAAiB,YAAA,KAAA,CAAQA,CAAM,CAAA,OAAA,CAAU,eACpD,CAAC,CACH,CACF,CACF,MCtDakB,CAAN,CAAA,cAA6BX,CAAW,CAC7C,MAAM,WAAWG,CAA+C,CAAA,CAC9D,OAAO,IAAK,CAAA,KAAA,CAAkB,sBAAuBA,CAAM,CAC7D,CAEA,MAAM,UAAUA,CAAwD,CAAA,CACtE,OAAO,IAAK,CAAA,KAAA,CACV,gCACAA,CACF,CACF,CACF,ECrBO,IAAMS,EAAN,cAAyBZ,CAAW,CACzC,MAAM,MAAA,CAAOI,EAA8B,CACzC,OAAO,IAAK,CAAA,KAAA,CAAc,cAAe,CAAE,GAAA,CAAAA,CAAI,CAAC,CAClD,CAEA,MAAM,GAAA,CAAIA,EAA2B,CACnC,OAAO,KAAK,KAAW,CAAA,UAAA,CAAY,CAAE,GAAAA,CAAAA,CAAI,CAAC,CAC5C,CACF,ECFaS,IAAAA,CAAAA,CAAN,KAAe,CACX,OAAA,CACA,IAET,WAAYZ,CAAAA,CAAAA,CAAwB,CAClC,IAAK,CAAA,OAAA,CAAU,IAAIU,CAAeV,CAAAA,CAAM,EACxC,IAAK,CAAA,GAAA,CAAM,IAAIW,CAAWX,CAAAA,CAAM,EAClC,CACF","file":"index.mjs","sourcesContent":["export interface TranscriptChunk {\n text: string;\n offset: number;\n duration: number;\n lang: string;\n}\n\nexport interface Transcript {\n content: TranscriptChunk[] | string;\n lang: string;\n availableLangs: string[];\n}\n\nexport interface TranslatedTranscript {\n content: TranscriptChunk[] | string;\n lang: string;\n}\n\nexport interface Scrape {\n url: string;\n content: string;\n name: string;\n description: string;\n ogUrl: string;\n countCharacters: number;\n urls: string[];\n}\n\nexport interface Map {\n urls: string[];\n}\n\nexport interface SupadataConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport class SupadataError extends Error {\n error:\n | 'invalid-request'\n | 'missing-parameters'\n | 'internal-error'\n | 'transcript-unavailable'\n | 'video-not-found'\n | 'video-id-invalid'\n | 'youtube-api-error'\n | 'quota-exceeded'\n | 'rate-limit-exceeded';\n details: string;\n documentationUrl: string;\n\n constructor(error: {\n error: SupadataError['error'];\n message?: string;\n details?: string;\n documentationUrl?: string;\n }) {\n super(error.message || 'An unexpected error occurred');\n this.error = error.error || 'internal-error';\n this.details = error.details || 'An unexpected error occurred';\n this.documentationUrl = error.documentationUrl || '';\n this.name = 'SupadataError';\n }\n}\n","import { SupadataError } from './types';\n\n/*\nThe API gateway returns errors in text/plain content type. \nAs a temporary workaround we're mapping them to SupadataError.\n*/\n\nconst GATEWAY_ERROR_PATTERNS = {\n 'endpoint is not configured': {\n error: 'invalid-request' as const,\n message: 'The requested endpoint is not configured',\n details: 'The API endpoint you are trying to access does not exist',\n },\n 'No valid access key found': {\n error: 'invalid-request' as const,\n message: 'Invalid or missing API key',\n details: 'Please ensure you have provided a valid API key',\n },\n 'quota exceeded': {\n error: 'quota-exceeded' as const,\n message: 'API quota exceeded',\n details: 'You have exceeded your API quota for the current period',\n },\n};\n\nexport const mapGatewayError = (\n statusCode: number,\n errorText: string\n): SupadataError => {\n const matchedError = Object.entries(GATEWAY_ERROR_PATTERNS).find(\n ([pattern]) => errorText.includes(pattern)\n );\n\n if (matchedError) {\n return new SupadataError(matchedError[1]);\n }\n\n // Default error if no pattern matches\n return new SupadataError({\n error: 'internal-error',\n message: 'An unexpected error occurred',\n details: errorText,\n });\n};\n","import { SupadataConfig, SupadataError } from './types.js';\nimport { mapGatewayError } from './gateway-error-mapper.js';\n\nexport class BaseClient {\n protected config: SupadataConfig;\n\n constructor(config: SupadataConfig) {\n this.config = config;\n }\n\n async fetch<T>(\n endpoint: string,\n params: Record<string, unknown> | object\n ): Promise<T> {\n const baseUrl = this.config.baseUrl || 'https://api.supadata.ai/v1';\n let url = `${baseUrl}${\n endpoint.startsWith('/') ? endpoint : `/${endpoint}`\n }`;\n\n if (params) {\n const queryParams = new URLSearchParams();\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n queryParams.append(key, String(value));\n }\n });\n url += `?${queryParams.toString()}`;\n }\n\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'x-api-key': this.config.apiKey,\n 'Content-Type': 'application/json',\n },\n });\n\n const contentType = response.headers.get('content-type');\n\n if (!response.ok) {\n if (contentType?.includes('application/json')) {\n const errorData = await response.json();\n throw new SupadataError(errorData);\n } else {\n const errorText = await response.text();\n throw mapGatewayError(response.status, errorText);\n }\n }\n\n try {\n if (!contentType?.includes('application/json')) {\n throw new SupadataError({\n error: 'internal-error',\n message: 'Invalid response format',\n details: 'Expected JSON response but received different content type',\n });\n }\n\n return (await response.json()) as T;\n } catch (error) {\n throw new SupadataError({\n error: 'internal-error',\n message: 'Failed to parse response',\n details: error instanceof Error ? error.message : 'Unknown error',\n });\n }\n }\n}\n","import { BaseClient } from \"../client.js\";\nimport { Transcript, TranslatedTranscript } from \"../types.js\";\n\nexport interface TranscriptParams {\n videoId: string;\n lang?: string;\n text?: boolean;\n}\n\nexport interface TranslateParams extends TranscriptParams {\n lang: string;\n}\n\nexport class YouTubeService extends BaseClient {\n async transcript(params: TranscriptParams): Promise<Transcript> {\n return this.fetch<Transcript>(\"/youtube/transcript\", params);\n }\n\n async translate(params: TranslateParams): Promise<TranslatedTranscript> {\n return this.fetch<TranslatedTranscript>(\n \"/youtube/transcript/translate\",\n params\n );\n }\n}\n","import { BaseClient } from '../client.js';\nimport { Scrape, Map } from '../types.js';\n\nexport class WebService extends BaseClient {\n async scrape(url: string): Promise<Scrape> {\n return this.fetch<Scrape>('/web/scrape', { url });\n }\n\n async map(url: string): Promise<Map> {\n return this.fetch<Map>('/web/map', { url });\n }\n}","import { SupadataConfig } from './types.js';\nimport { YouTubeService } from './services/youtube.js';\nimport { WebService } from './services/web.js';\n\nexport * from './types.js';\nexport * from './client.js';\nexport * from './services/youtube.js';\nexport * from './services/web.js';\n\nexport class Supadata {\n readonly youtube: YouTubeService;\n readonly web: WebService;\n\n constructor(config: SupadataConfig) {\n this.youtube = new YouTubeService(config);\n this.web = new WebService(config);\n }\n}"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/gateway-error-mapper.ts","../src/client.ts","../src/services/youtube.ts","../src/services/web.ts","../src/index.ts"],"names":["SupadataError","error","GATEWAY_STATUS_ERRORS","mapGatewayError","statusCode","errorText","BaseClient","config","endpoint","params","url","queryParams","key","value","response","contentType","errorData","YouTubeService","WebService","Supadata"],"mappings":"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","file":"index.mjs","sourcesContent":["export interface TranscriptChunk {\n text: string;\n offset: number;\n duration: number;\n lang: string;\n}\n\nexport interface Transcript {\n content: TranscriptChunk[] | string;\n lang: string;\n availableLangs: string[];\n}\n\nexport interface TranslatedTranscript {\n content: TranscriptChunk[] | string;\n lang: string;\n}\n\nexport interface Scrape {\n url: string;\n content: string;\n name: string;\n description: string;\n ogUrl: string;\n countCharacters: number;\n urls: string[];\n}\n\nexport interface Map {\n urls: string[];\n}\n\nexport interface SupadataConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport class SupadataError extends Error {\n error:\n | 'invalid-request'\n | 'missing-parameters'\n | 'internal-error'\n | 'transcript-unavailable'\n | 'video-not-found'\n | 'video-id-invalid'\n | 'youtube-api-error'\n | 'limit-exceeded';\n details: string;\n documentationUrl: string;\n\n constructor(error: {\n error: SupadataError['error'];\n message?: string;\n details?: string;\n documentationUrl?: string;\n }) {\n super(error.message || 'An unexpected error occurred');\n this.error = error.error || 'internal-error';\n this.details = error.details || 'An unexpected error occurred';\n this.documentationUrl = error.documentationUrl || '';\n this.name = 'SupadataError';\n }\n}\n","import { SupadataError } from './types';\n\n/*\nThe API gateway returns errors in text/plain content type. \nAs a temporary workaround we're mapping them to SupadataError.\n*/\n\nconst GATEWAY_STATUS_ERRORS = {\n 403: {\n error: 'invalid-request' as const,\n message: 'Invalid or missing API key',\n details: 'Please ensure you have provided a valid API key',\n },\n 404: {\n error: 'invalid-request' as const,\n message: 'Endpoint does not exist',\n details: 'The API endpoint you are trying to access does not exist',\n },\n 429: {\n error: 'limit-exceeded' as const,\n message: 'Limit exceeded',\n details: 'You have exceeded the allowed request rate or quota limits',\n },\n};\n\nexport const mapGatewayError = (\n statusCode: number,\n errorText: string\n): SupadataError => {\n if (statusCode in GATEWAY_STATUS_ERRORS) {\n return new SupadataError({\n ...GATEWAY_STATUS_ERRORS[\n statusCode as keyof typeof GATEWAY_STATUS_ERRORS\n ],\n message:\n GATEWAY_STATUS_ERRORS[statusCode as keyof typeof GATEWAY_STATUS_ERRORS]\n .message,\n details:\n errorText ||\n GATEWAY_STATUS_ERRORS[statusCode as keyof typeof GATEWAY_STATUS_ERRORS]\n .details,\n });\n }\n\n // Default error if status code is not recognized\n return new SupadataError({\n error: 'internal-error',\n message: 'An unexpected error occurred',\n details: errorText,\n });\n};\n","import { SupadataConfig, SupadataError } from './types.js';\nimport { mapGatewayError } from './gateway-error-mapper.js';\n\nexport class BaseClient {\n protected config: SupadataConfig;\n\n constructor(config: SupadataConfig) {\n this.config = config;\n }\n\n async fetch<T>(\n endpoint: string,\n params: Record<string, unknown> | object\n ): Promise<T> {\n const baseUrl = this.config.baseUrl || 'https://api.supadata.ai/v1';\n let url = `${baseUrl}${\n endpoint.startsWith('/') ? endpoint : `/${endpoint}`\n }`;\n\n if (params) {\n const queryParams = new URLSearchParams();\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n queryParams.append(key, String(value));\n }\n });\n url += `?${queryParams.toString()}`;\n }\n\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'x-api-key': this.config.apiKey,\n 'Content-Type': 'application/json',\n },\n });\n\n const contentType = response.headers.get('content-type');\n\n if (!response.ok) {\n // First check for gateway-specific status codes\n if ([403, 404, 429].includes(response.status)) {\n const errorData = await response.json();\n throw mapGatewayError(response.status, errorData.message);\n }\n\n // Handle standard API errors\n if (contentType?.includes('application/json')) {\n const errorData = await response.json();\n throw new SupadataError(errorData);\n } else {\n // Fallback for unexpected non-JSON errors\n throw new SupadataError({\n error: 'internal-error',\n message: 'Unexpected error response format',\n details: await response.text(),\n });\n }\n }\n\n try {\n if (!contentType?.includes('application/json')) {\n throw new SupadataError({\n error: 'internal-error',\n message: 'Invalid response format',\n details: 'Expected JSON response but received different content type',\n });\n }\n\n return (await response.json()) as T;\n } catch (error) {\n throw new SupadataError({\n error: 'internal-error',\n message: 'Failed to parse response',\n details: error instanceof Error ? error.message : 'Unknown error',\n });\n }\n }\n}\n","import { BaseClient } from '../client.js';\nimport { Transcript, TranslatedTranscript } from '../types.js';\n\nexport interface TranscriptParams {\n videoId: string;\n lang?: string;\n text?: boolean;\n}\n\nexport interface TranslateParams extends TranscriptParams {\n lang: string;\n}\n\nexport class YouTubeService extends BaseClient {\n async transcript(params: TranscriptParams): Promise<Transcript> {\n return this.fetch<Transcript>('/youtube/transcript', params);\n }\n\n async translate(params: TranslateParams): Promise<TranslatedTranscript> {\n return this.fetch<TranslatedTranscript>(\n '/youtube/transcript/translate',\n params\n );\n }\n}\n","import { BaseClient } from '../client.js';\nimport { Scrape, Map } from '../types.js';\n\nexport class WebService extends BaseClient {\n async scrape(url: string): Promise<Scrape> {\n return this.fetch<Scrape>('/web/scrape', { url });\n }\n\n async map(url: string): Promise<Map> {\n return this.fetch<Map>('/web/map', { url });\n }\n}\n","import { SupadataConfig } from './types.js';\nimport { YouTubeService } from './services/youtube.js';\nimport { WebService } from './services/web.js';\n\nexport * from './types.js';\nexport * from './client.js';\nexport * from './services/youtube.js';\nexport * from './services/web.js';\n\nexport class Supadata {\n readonly youtube: YouTubeService;\n readonly web: WebService;\n\n constructor(config: SupadataConfig) {\n this.youtube = new YouTubeService(config);\n this.web = new WebService(config);\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supadata/js",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "TypeScript / JavaScript SDK for Supadata API",
5
5
  "homepage": "https://supadata.ai",
6
6
  "repository": "https://github.com/supadata-ai/js",