@axiom_ai/api 1.0.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.
- package/README.md +32 -0
- package/dist/cjs/index.js +1 -0
- package/dist/es/axiom-api.d.ts +39 -0
- package/dist/es/axiom-api.js +348 -0
- package/dist/es/axiom-http.d.ts +8 -0
- package/dist/es/axiom-http.js +122 -0
- package/dist/es/config.d.ts +1 -0
- package/dist/es/config.js +1 -0
- package/dist/es/index.d.ts +1 -0
- package/dist/es/index.js +1 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# 🤖 Axiom AI API Library
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
This repository contains the **Axiom AI API library**.
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
To use the library, you'll first need to import the `AxiomApi` class and then wrap your automation steps within `browserOpen()` and `browserClose()`.
|
|
10
|
+
|
|
11
|
+
### Example
|
|
12
|
+
|
|
13
|
+
Here is a basic example of how to structure your code:
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
import { AxiomApi } from 'axiom-api';
|
|
17
|
+
|
|
18
|
+
async function run() {
|
|
19
|
+
// 1. Initialize the AxiomApi class
|
|
20
|
+
const axiom = new AxiomApi('[API_KEY]');
|
|
21
|
+
|
|
22
|
+
// 2. Open the browser connection
|
|
23
|
+
await axiom.browserOpen();
|
|
24
|
+
|
|
25
|
+
// 3. Add your automation steps here (e.g., axiom.click(), axiom.type(), etc.)
|
|
26
|
+
// ... add steps ...
|
|
27
|
+
|
|
28
|
+
// 4. Close the browser connection when done
|
|
29
|
+
await axiom.browserClose();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
run();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const k="https://lar.axiom.ai";class c extends Error{constructor(t,e,n){super(t),this.name="AxiomHttpError",this.status=e,this.body=n}}class m{async post(t,e,n,i={}){const s=new AbortController;let o=null;i.timeoutMs&&i.timeoutMs>0&&(o=setTimeout(()=>s.abort(),i.timeoutMs));let r;try{r=await fetch(k+t,{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json","X-API-KEY":e},body:JSON.stringify(n),signal:s.signal})}finally{o&&clearTimeout(o)}if(!r.ok){const h=await r.text();let a=null;try{a=JSON.parse(h)}catch{}if(r.status===401)throw new c("Failed to authenticate - please check your token.",401,a);const w=a&&a.message?a.message:`HTTP ${r.status} error: ${h}`;throw new c(w,r.status,a)}return r.json()}}const y=12e4,u=36e5,f=3e3,l=3e4,d=1.5;class g{constructor(t){this.cdpLink="",this.token=t,this.http=new m}async browserOpen(){const t=await this.http.post("/api/v5/browser/open",this.token);return this.cdpLink=t.endpoint,t.endpoint}async browserClose(t=""){t||(t=this.cdpLink);const e=await this.http.post("/api/v5/browser/close",this.token,{cdpLink:t});return this.cdpLink="",e.message}async step(t,e,n,i=""){try{const s=await this.http.post("/api/v5/step",this.token,{mode:t,method:e,params:n,cdpLink:i},{timeoutMs:y});return s&&s.message!==void 0?s.message:s}catch(s){if(!i||!this._shouldFallBackToPolling(s))throw s;return this._pollStepResult(i,s)}}_shouldFallBackToPolling(t){return!!(t&&t.name==="AbortError"||t&&t.name==="TypeError"||t instanceof c&&(t.status===502||t.status===503||t.status===504||t.status===409&&typeof t.message=="string"&&t.message.indexOf("Step already in progress")!==-1))}async _pollStepResult(t,e){const n=Date.now()+u;let i=f;for(;Date.now()<n;){await this._sleep(i);try{const s=await this.http.post("/api/v5/step/result",this.token,{cdpLink:t});if(s&&s.status==="complete")return s.result;if(s&&s.status==="running"){i=Math.min(i*d,l);continue}throw s&&s.status==="none"?new Error("Step did not start on the pod. Original error: "+(e&&e.message?e.message:"unknown")):new Error("Unexpected /step/result response: "+JSON.stringify(s))}catch(s){if(s instanceof c&&s.status===409)throw new Error("Step failed on the pod — check the task report. "+(s.message||""));if(s instanceof c&&s.status>=400&&s.status<500&&s.status!==502&&s.status!==503&&s.status!==504)throw s;i=Math.min(i*d,l)}}throw new Error("Step polling exceeded "+u/1e3+"s. Original error: "+(e&&e.message?e.message:"unknown"))}async scrape(t,e,n,i,s){return this.step("browser","AxiomApiSmartScrapeV440",[t,e,n,i,s],this.cdpLink)}async integrateAI(t){return this.step("browser","AxiomApiAiGeneric",[t],this.cdpLink)}async datePicker(t,e,n,i){return this.step("driver","datePicker",[t,e,n,i],this.cdpLink)}async click(t,e,n){return this.step("driver","clickV3130",[t,e,n],this.cdpLink)}async clickEngagementButton(t,e){return this.step("driver","clickEngagementButton",[t,e],this.cdpLink)}async clickMultiple(t,e,n){return this.step("driver","multiClickV3170",[t,e,n],this.cdpLink)}async getClipboardContents(){return this.step("driver","readClipboardContents",[],this.cdpLink)}async enterText(t,e,n=0,i=!1,s=null,o=!1){return this.step("driver","enterTextV4500",[t,e,n,i,s,o],this.cdpLink)}async goto(t,e=!1,n=!1){return this.step("driver","gotoV4070",[t,null,e,n],this.cdpLink)}async pressKeys(t,e,n){return this.step("driver","keydownV3120",[t,null,e,n],this.cdpLink)}async clickAndDrag(t,e){return this.step("driver","mouseClickDragV0300",[t,e],this.cdpLink)}async scrapeMetadata(t){return this.step("driver","scrapeMetadata",[t],this.cdpLink)}async selectList(t,e){return this.step("driver","selectList",[t,e],this.cdpLink)}async solveCaptcha(t){return this.step("driver","solveCaptchaV450",[null,null,t],this.cdpLink)}async switchBrowserTab(t){return this.step("driver","switchBrowserTab",[t],this.cdpLink)}async wait(t){return this.cdpLink?this.step("driver","wait",[t],this.cdpLink):this._sleep(t)}_sleep(t){return new Promise(e=>setTimeout(e,t))}async hover(t){return this.step("driver","hover",[t],this.cdpLink)}async restartBrowser(){return this.step("browser","AxiomApiRestartBrowser",[],this.cdpLink)}}exports.AxiomApi=g;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @class
|
|
3
|
+
* @public
|
|
4
|
+
* A class for interacting with the Axiom API.
|
|
5
|
+
*/
|
|
6
|
+
export class AxiomApi {
|
|
7
|
+
/**
|
|
8
|
+
* @param {string} token API access token.
|
|
9
|
+
*/
|
|
10
|
+
constructor(token: string);
|
|
11
|
+
cdpLink: string;
|
|
12
|
+
token: string;
|
|
13
|
+
http: AxiomHttp;
|
|
14
|
+
browserOpen(): Promise<any>;
|
|
15
|
+
browserClose(cdpLink?: string): Promise<any>;
|
|
16
|
+
step(mode: any, method: any, params: any, cdpLink?: string): Promise<any>;
|
|
17
|
+
_shouldFallBackToPolling(error: any): boolean;
|
|
18
|
+
_pollStepResult(cdpLink: any, originalError: any): Promise<any>;
|
|
19
|
+
scrape(url: any, selector: any, pager: any, max_results: any, settings: any): Promise<any>;
|
|
20
|
+
integrateAI(aiOptions: any): Promise<any>;
|
|
21
|
+
datePicker(selectMonth: any, selectMonthChangeButton: any, changeMonthTo: any, changeDayOfMonthTo: any): Promise<any>;
|
|
22
|
+
click(select: any, leftClickRightClick: any, optionalClick: any): Promise<any>;
|
|
23
|
+
clickEngagementButton(select: any, setValueToCheck: any): Promise<any>;
|
|
24
|
+
clickMultiple(select: any, leftClickRightClick: any, maxClicks: any): Promise<any>;
|
|
25
|
+
getClipboardContents(): Promise<any>;
|
|
26
|
+
enterText(selectTextField: any, text: any, delay?: number, appendExisting?: boolean, customLineBreak?: any, optionalText?: boolean): Promise<any>;
|
|
27
|
+
goto(url: any, doNotShareLocalstorage?: boolean, openInNewTab?: boolean): Promise<any>;
|
|
28
|
+
pressKeys(key: any, delimiter: any, delay: any): Promise<any>;
|
|
29
|
+
clickAndDrag(startCoordinates: any, endCoordinates: any): Promise<any>;
|
|
30
|
+
scrapeMetadata(metadata: any): Promise<any>;
|
|
31
|
+
selectList(select: any, text: any): Promise<any>;
|
|
32
|
+
solveCaptcha(apiKey: any): Promise<any>;
|
|
33
|
+
switchBrowserTab(selectTab: any): Promise<any>;
|
|
34
|
+
wait(time: any): Promise<any>;
|
|
35
|
+
_sleep(ms: any): Promise<any>;
|
|
36
|
+
hover(select: any): Promise<any>;
|
|
37
|
+
restartBrowser(): Promise<any>;
|
|
38
|
+
}
|
|
39
|
+
import { AxiomHttp } from './axiom-http.js';
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
12
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
|
+
function step(op) {
|
|
15
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
17
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
18
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
19
|
+
switch (op[0]) {
|
|
20
|
+
case 0: case 1: t = op; break;
|
|
21
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
22
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
23
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
24
|
+
default:
|
|
25
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
26
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
27
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
28
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
29
|
+
if (t[2]) _.ops.pop();
|
|
30
|
+
_.trys.pop(); continue;
|
|
31
|
+
}
|
|
32
|
+
op = body.call(thisArg, _);
|
|
33
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
34
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
import { AxiomHttp, AxiomHttpError } from './axiom-http.js';
|
|
38
|
+
// Tuning for the transparent long-running-step polling fallback. The library POSTs
|
|
39
|
+
// /step with STEP_HTTP_TIMEOUT_MS as the abort deadline; if the POST times out, hits
|
|
40
|
+
// a gateway error, or the backend says a previous step is still in flight, the
|
|
41
|
+
// library polls /step/result with exponential backoff until the result lands or
|
|
42
|
+
// STEP_MAX_POLL_DURATION_MS elapses.
|
|
43
|
+
var STEP_HTTP_TIMEOUT_MS = 120000;
|
|
44
|
+
var STEP_MAX_POLL_DURATION_MS = 3600000;
|
|
45
|
+
var STEP_POLL_INITIAL_INTERVAL_MS = 3000;
|
|
46
|
+
var STEP_POLL_MAX_INTERVAL_MS = 30000;
|
|
47
|
+
var STEP_POLL_BACKOFF_FACTOR = 1.5;
|
|
48
|
+
/**
|
|
49
|
+
* @class
|
|
50
|
+
* @public
|
|
51
|
+
* A class for interacting with the Axiom API.
|
|
52
|
+
*/
|
|
53
|
+
var AxiomApi = /** @class */ (function () {
|
|
54
|
+
/**
|
|
55
|
+
* @param {string} token API access token.
|
|
56
|
+
*/
|
|
57
|
+
function AxiomApi(token) {
|
|
58
|
+
this.cdpLink = '';
|
|
59
|
+
this.token = token;
|
|
60
|
+
this.http = new AxiomHttp();
|
|
61
|
+
}
|
|
62
|
+
AxiomApi.prototype.browserOpen = function () {
|
|
63
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
64
|
+
var content;
|
|
65
|
+
return __generator(this, function (_a) {
|
|
66
|
+
switch (_a.label) {
|
|
67
|
+
case 0: return [4 /*yield*/, this.http.post('/api/v5/browser/open', this.token)];
|
|
68
|
+
case 1:
|
|
69
|
+
content = _a.sent();
|
|
70
|
+
this.cdpLink = content.endpoint;
|
|
71
|
+
return [2 /*return*/, content.endpoint];
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
AxiomApi.prototype.browserClose = function () {
|
|
77
|
+
return __awaiter(this, arguments, void 0, function (cdpLink) {
|
|
78
|
+
var content;
|
|
79
|
+
if (cdpLink === void 0) { cdpLink = ''; }
|
|
80
|
+
return __generator(this, function (_a) {
|
|
81
|
+
switch (_a.label) {
|
|
82
|
+
case 0:
|
|
83
|
+
if (!cdpLink) {
|
|
84
|
+
cdpLink = this.cdpLink;
|
|
85
|
+
}
|
|
86
|
+
return [4 /*yield*/, this.http.post('/api/v5/browser/close', this.token, { cdpLink: cdpLink })
|
|
87
|
+
// Reset CDPLink to avoid staleness
|
|
88
|
+
];
|
|
89
|
+
case 1:
|
|
90
|
+
content = _a.sent();
|
|
91
|
+
// Reset CDPLink to avoid staleness
|
|
92
|
+
this.cdpLink = '';
|
|
93
|
+
return [2 /*return*/, content.message];
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
// TODO: Probably should be mvoed to a non-user facing component
|
|
99
|
+
AxiomApi.prototype.step = function (mode_1, method_1, params_1) {
|
|
100
|
+
return __awaiter(this, arguments, void 0, function (mode, method, params, cdpLink) {
|
|
101
|
+
var content, e_1;
|
|
102
|
+
if (cdpLink === void 0) { cdpLink = ''; }
|
|
103
|
+
return __generator(this, function (_a) {
|
|
104
|
+
switch (_a.label) {
|
|
105
|
+
case 0:
|
|
106
|
+
_a.trys.push([0, 2, , 3]);
|
|
107
|
+
return [4 /*yield*/, this.http.post('/api/v5/step', this.token, {
|
|
108
|
+
mode: mode,
|
|
109
|
+
method: method,
|
|
110
|
+
params: params,
|
|
111
|
+
cdpLink: cdpLink
|
|
112
|
+
}, { timeoutMs: STEP_HTTP_TIMEOUT_MS })];
|
|
113
|
+
case 1:
|
|
114
|
+
content = _a.sent();
|
|
115
|
+
if (content && content.message !== undefined) {
|
|
116
|
+
return [2 /*return*/, content.message];
|
|
117
|
+
}
|
|
118
|
+
return [2 /*return*/, content];
|
|
119
|
+
case 2:
|
|
120
|
+
e_1 = _a.sent();
|
|
121
|
+
// Can only fall back to polling when there is a session to address.
|
|
122
|
+
// One-shot /step calls have no cdpLink and surface the original error.
|
|
123
|
+
if (!cdpLink || !this._shouldFallBackToPolling(e_1))
|
|
124
|
+
throw e_1;
|
|
125
|
+
return [2 /*return*/, this._pollStepResult(cdpLink, e_1)];
|
|
126
|
+
case 3: return [2 /*return*/];
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
AxiomApi.prototype._shouldFallBackToPolling = function (error) {
|
|
132
|
+
// Direct POST never reached or never returned — step may still be running on the pod.
|
|
133
|
+
if (error && error.name === 'AbortError')
|
|
134
|
+
return true;
|
|
135
|
+
// Native fetch network failure (DNS, connection reset, etc.) surfaces as TypeError.
|
|
136
|
+
if (error && error.name === 'TypeError')
|
|
137
|
+
return true;
|
|
138
|
+
if (error instanceof AxiomHttpError) {
|
|
139
|
+
if (error.status === 502 || error.status === 503 || error.status === 504)
|
|
140
|
+
return true;
|
|
141
|
+
if (error.status === 409 && typeof error.message === 'string'
|
|
142
|
+
&& error.message.indexOf('Step already in progress') !== -1)
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
return false;
|
|
146
|
+
};
|
|
147
|
+
AxiomApi.prototype._pollStepResult = function (cdpLink, originalError) {
|
|
148
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
149
|
+
var deadline, intervalMs, content, e_2;
|
|
150
|
+
return __generator(this, function (_a) {
|
|
151
|
+
switch (_a.label) {
|
|
152
|
+
case 0:
|
|
153
|
+
deadline = Date.now() + STEP_MAX_POLL_DURATION_MS;
|
|
154
|
+
intervalMs = STEP_POLL_INITIAL_INTERVAL_MS;
|
|
155
|
+
_a.label = 1;
|
|
156
|
+
case 1:
|
|
157
|
+
if (!(Date.now() < deadline)) return [3 /*break*/, 7];
|
|
158
|
+
return [4 /*yield*/, this._sleep(intervalMs)];
|
|
159
|
+
case 2:
|
|
160
|
+
_a.sent();
|
|
161
|
+
_a.label = 3;
|
|
162
|
+
case 3:
|
|
163
|
+
_a.trys.push([3, 5, , 6]);
|
|
164
|
+
return [4 /*yield*/, this.http.post('/api/v5/step/result', this.token, { cdpLink: cdpLink })];
|
|
165
|
+
case 4:
|
|
166
|
+
content = _a.sent();
|
|
167
|
+
if (content && content.status === 'complete')
|
|
168
|
+
return [2 /*return*/, content.result];
|
|
169
|
+
if (content && content.status === 'running') {
|
|
170
|
+
intervalMs = Math.min(intervalMs * STEP_POLL_BACKOFF_FACTOR, STEP_POLL_MAX_INTERVAL_MS);
|
|
171
|
+
return [3 /*break*/, 1];
|
|
172
|
+
}
|
|
173
|
+
if (content && content.status === 'none') {
|
|
174
|
+
throw new Error('Step did not start on the pod. Original error: '
|
|
175
|
+
+ (originalError && originalError.message ? originalError.message : 'unknown'));
|
|
176
|
+
}
|
|
177
|
+
throw new Error('Unexpected /step/result response: ' + JSON.stringify(content));
|
|
178
|
+
case 5:
|
|
179
|
+
e_2 = _a.sent();
|
|
180
|
+
// Executor is gone (step error → finish('Failure') removed it).
|
|
181
|
+
// Surface as a hard failure — the task report has the detail.
|
|
182
|
+
if (e_2 instanceof AxiomHttpError && e_2.status === 409) {
|
|
183
|
+
throw new Error('Step failed on the pod — check the task report. ' + (e_2.message || ''));
|
|
184
|
+
}
|
|
185
|
+
// Auth or other definite 4xx — don't keep polling.
|
|
186
|
+
if (e_2 instanceof AxiomHttpError && e_2.status >= 400 && e_2.status < 500
|
|
187
|
+
&& e_2.status !== 502 && e_2.status !== 503 && e_2.status !== 504) {
|
|
188
|
+
throw e_2;
|
|
189
|
+
}
|
|
190
|
+
// Transient network issue mid-poll — back off and retry.
|
|
191
|
+
intervalMs = Math.min(intervalMs * STEP_POLL_BACKOFF_FACTOR, STEP_POLL_MAX_INTERVAL_MS);
|
|
192
|
+
return [3 /*break*/, 6];
|
|
193
|
+
case 6: return [3 /*break*/, 1];
|
|
194
|
+
case 7: throw new Error('Step polling exceeded ' + (STEP_MAX_POLL_DURATION_MS / 1000)
|
|
195
|
+
+ 's. Original error: '
|
|
196
|
+
+ (originalError && originalError.message ? originalError.message : 'unknown'));
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
AxiomApi.prototype.scrape = function (url, selector, pager, max_results, settings) {
|
|
202
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
203
|
+
return __generator(this, function (_a) {
|
|
204
|
+
return [2 /*return*/, this.step('browser', 'AxiomApiSmartScrapeV440', [url, selector, pager, max_results, settings], this.cdpLink)];
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
};
|
|
208
|
+
AxiomApi.prototype.integrateAI = function (aiOptions) {
|
|
209
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
210
|
+
return __generator(this, function (_a) {
|
|
211
|
+
return [2 /*return*/, this.step('browser', 'AxiomApiAiGeneric', [aiOptions], this.cdpLink)];
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
AxiomApi.prototype.datePicker = function (selectMonth, selectMonthChangeButton, changeMonthTo, changeDayOfMonthTo) {
|
|
216
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
217
|
+
return __generator(this, function (_a) {
|
|
218
|
+
return [2 /*return*/, this.step('driver', 'datePicker', [selectMonth, selectMonthChangeButton, changeMonthTo, changeDayOfMonthTo], this.cdpLink)];
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
};
|
|
222
|
+
AxiomApi.prototype.click = function (select, leftClickRightClick, optionalClick) {
|
|
223
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
224
|
+
return __generator(this, function (_a) {
|
|
225
|
+
return [2 /*return*/, this.step('driver', 'clickV3130', [select, leftClickRightClick, optionalClick], this.cdpLink)];
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
};
|
|
229
|
+
AxiomApi.prototype.clickEngagementButton = function (select, setValueToCheck) {
|
|
230
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
231
|
+
return __generator(this, function (_a) {
|
|
232
|
+
return [2 /*return*/, this.step('driver', 'clickEngagementButton', [select, setValueToCheck], this.cdpLink)];
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
};
|
|
236
|
+
AxiomApi.prototype.clickMultiple = function (select, leftClickRightClick, maxClicks) {
|
|
237
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
238
|
+
return __generator(this, function (_a) {
|
|
239
|
+
return [2 /*return*/, this.step('driver', 'multiClickV3170', [select, leftClickRightClick, maxClicks], this.cdpLink)];
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
};
|
|
243
|
+
AxiomApi.prototype.getClipboardContents = function () {
|
|
244
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
245
|
+
return __generator(this, function (_a) {
|
|
246
|
+
return [2 /*return*/, this.step('driver', 'readClipboardContents', [], this.cdpLink)];
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
};
|
|
250
|
+
AxiomApi.prototype.enterText = function (selectTextField_1, text_1) {
|
|
251
|
+
return __awaiter(this, arguments, void 0, function (selectTextField, text, delay, appendExisting, customLineBreak, optionalText) {
|
|
252
|
+
if (delay === void 0) { delay = 0; }
|
|
253
|
+
if (appendExisting === void 0) { appendExisting = false; }
|
|
254
|
+
if (customLineBreak === void 0) { customLineBreak = null; }
|
|
255
|
+
if (optionalText === void 0) { optionalText = false; }
|
|
256
|
+
return __generator(this, function (_a) {
|
|
257
|
+
return [2 /*return*/, this.step('driver', 'enterTextV4500', [selectTextField, text, delay, appendExisting, customLineBreak, optionalText], this.cdpLink)];
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
};
|
|
261
|
+
AxiomApi.prototype.goto = function (url_1) {
|
|
262
|
+
return __awaiter(this, arguments, void 0, function (url, doNotShareLocalstorage, openInNewTab) {
|
|
263
|
+
if (doNotShareLocalstorage === void 0) { doNotShareLocalstorage = false; }
|
|
264
|
+
if (openInNewTab === void 0) { openInNewTab = false; }
|
|
265
|
+
return __generator(this, function (_a) {
|
|
266
|
+
return [2 /*return*/, this.step('driver', 'gotoV4070', [url, null, doNotShareLocalstorage, openInNewTab], this.cdpLink)];
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
};
|
|
270
|
+
AxiomApi.prototype.pressKeys = function (key, delimiter, delay) {
|
|
271
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
272
|
+
return __generator(this, function (_a) {
|
|
273
|
+
return [2 /*return*/, this.step('driver', 'keydownV3120', [key, null, delimiter, delay], this.cdpLink)];
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
};
|
|
277
|
+
AxiomApi.prototype.clickAndDrag = function (startCoordinates, endCoordinates) {
|
|
278
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
279
|
+
return __generator(this, function (_a) {
|
|
280
|
+
return [2 /*return*/, this.step('driver', 'mouseClickDragV0300', [startCoordinates, endCoordinates], this.cdpLink)];
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
};
|
|
284
|
+
AxiomApi.prototype.scrapeMetadata = function (metadata) {
|
|
285
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
286
|
+
return __generator(this, function (_a) {
|
|
287
|
+
return [2 /*return*/, this.step('driver', 'scrapeMetadata', [metadata], this.cdpLink)];
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
};
|
|
291
|
+
AxiomApi.prototype.selectList = function (select, text) {
|
|
292
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
293
|
+
return __generator(this, function (_a) {
|
|
294
|
+
return [2 /*return*/, this.step('driver', 'selectList', [select, text], this.cdpLink)];
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
};
|
|
298
|
+
AxiomApi.prototype.solveCaptcha = function (apiKey) {
|
|
299
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
300
|
+
return __generator(this, function (_a) {
|
|
301
|
+
return [2 /*return*/, this.step('driver', 'solveCaptchaV450', [null, null, apiKey], this.cdpLink)];
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
};
|
|
305
|
+
AxiomApi.prototype.switchBrowserTab = function (selectTab) {
|
|
306
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
307
|
+
return __generator(this, function (_a) {
|
|
308
|
+
return [2 /*return*/, this.step('driver', 'switchBrowserTab', [selectTab], this.cdpLink)];
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
};
|
|
312
|
+
// Pause on the pod, not in the client process, so the pod's session inactivity
|
|
313
|
+
// timer is reset by the step. A purely local sleep would let the session idle
|
|
314
|
+
// out and auto-close while the client was still happily waiting. Falls back to
|
|
315
|
+
// a local sleep when there is no session — nothing to keep alive.
|
|
316
|
+
AxiomApi.prototype.wait = function (time) {
|
|
317
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
318
|
+
return __generator(this, function (_a) {
|
|
319
|
+
if (this.cdpLink) {
|
|
320
|
+
return [2 /*return*/, this.step('driver', 'wait', [time], this.cdpLink)];
|
|
321
|
+
}
|
|
322
|
+
return [2 /*return*/, this._sleep(time)];
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
};
|
|
326
|
+
// Local-only sleep, used by the polling loop's backoff. Never routes to the
|
|
327
|
+
// pod — that would be circular (the polling loop's whole purpose is to wait
|
|
328
|
+
// out a pod-side step that has lost its HTTP connection).
|
|
329
|
+
AxiomApi.prototype._sleep = function (ms) {
|
|
330
|
+
return new Promise(function (resolve) { return setTimeout(resolve, ms); });
|
|
331
|
+
};
|
|
332
|
+
AxiomApi.prototype.hover = function (select) {
|
|
333
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
334
|
+
return __generator(this, function (_a) {
|
|
335
|
+
return [2 /*return*/, this.step('driver', 'hover', [select], this.cdpLink)];
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
};
|
|
339
|
+
AxiomApi.prototype.restartBrowser = function () {
|
|
340
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
341
|
+
return __generator(this, function (_a) {
|
|
342
|
+
return [2 /*return*/, this.step('browser', 'AxiomApiRestartBrowser', [], this.cdpLink)];
|
|
343
|
+
});
|
|
344
|
+
});
|
|
345
|
+
};
|
|
346
|
+
return AxiomApi;
|
|
347
|
+
}());
|
|
348
|
+
export { AxiomApi };
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
var __extends = (this && this.__extends) || (function () {
|
|
2
|
+
var extendStatics = function (d, b) {
|
|
3
|
+
extendStatics = Object.setPrototypeOf ||
|
|
4
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
5
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
6
|
+
return extendStatics(d, b);
|
|
7
|
+
};
|
|
8
|
+
return function (d, b) {
|
|
9
|
+
if (typeof b !== "function" && b !== null)
|
|
10
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
11
|
+
extendStatics(d, b);
|
|
12
|
+
function __() { this.constructor = d; }
|
|
13
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
14
|
+
};
|
|
15
|
+
})();
|
|
16
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
17
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
18
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
19
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
20
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
21
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
22
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
26
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
27
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
28
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
29
|
+
function step(op) {
|
|
30
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
31
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
32
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
33
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
34
|
+
switch (op[0]) {
|
|
35
|
+
case 0: case 1: t = op; break;
|
|
36
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
37
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
38
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
39
|
+
default:
|
|
40
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
41
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
42
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
43
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
44
|
+
if (t[2]) _.ops.pop();
|
|
45
|
+
_.trys.pop(); continue;
|
|
46
|
+
}
|
|
47
|
+
op = body.call(thisArg, _);
|
|
48
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
49
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
import { ENDPOINT } from "./config";
|
|
53
|
+
var AxiomHttpError = /** @class */ (function (_super) {
|
|
54
|
+
__extends(AxiomHttpError, _super);
|
|
55
|
+
function AxiomHttpError(message, status, body) {
|
|
56
|
+
var _this = _super.call(this, message) || this;
|
|
57
|
+
_this.name = 'AxiomHttpError';
|
|
58
|
+
_this.status = status;
|
|
59
|
+
_this.body = body;
|
|
60
|
+
return _this;
|
|
61
|
+
}
|
|
62
|
+
return AxiomHttpError;
|
|
63
|
+
}(Error));
|
|
64
|
+
export { AxiomHttpError };
|
|
65
|
+
var AxiomHttp = /** @class */ (function () {
|
|
66
|
+
function AxiomHttp() {
|
|
67
|
+
}
|
|
68
|
+
AxiomHttp.prototype.post = function (uri_1, token_1, body_1) {
|
|
69
|
+
return __awaiter(this, arguments, void 0, function (uri, token, body, options) {
|
|
70
|
+
var controller, timeoutId, rawResponse, errorText, parsed, msg;
|
|
71
|
+
if (options === void 0) { options = {}; }
|
|
72
|
+
return __generator(this, function (_a) {
|
|
73
|
+
switch (_a.label) {
|
|
74
|
+
case 0:
|
|
75
|
+
controller = new AbortController();
|
|
76
|
+
timeoutId = null;
|
|
77
|
+
if (options.timeoutMs && options.timeoutMs > 0) {
|
|
78
|
+
timeoutId = setTimeout(function () { return controller.abort(); }, options.timeoutMs);
|
|
79
|
+
}
|
|
80
|
+
_a.label = 1;
|
|
81
|
+
case 1:
|
|
82
|
+
_a.trys.push([1, , 3, 4]);
|
|
83
|
+
return [4 /*yield*/, fetch(ENDPOINT + uri, {
|
|
84
|
+
method: 'POST',
|
|
85
|
+
headers: {
|
|
86
|
+
'Accept': 'application/json',
|
|
87
|
+
'Content-Type': 'application/json',
|
|
88
|
+
'X-API-KEY': token
|
|
89
|
+
},
|
|
90
|
+
body: JSON.stringify(body),
|
|
91
|
+
signal: controller.signal
|
|
92
|
+
})];
|
|
93
|
+
case 2:
|
|
94
|
+
rawResponse = _a.sent();
|
|
95
|
+
return [3 /*break*/, 4];
|
|
96
|
+
case 3:
|
|
97
|
+
if (timeoutId)
|
|
98
|
+
clearTimeout(timeoutId);
|
|
99
|
+
return [7 /*endfinally*/];
|
|
100
|
+
case 4:
|
|
101
|
+
if (!!rawResponse.ok) return [3 /*break*/, 6];
|
|
102
|
+
return [4 /*yield*/, rawResponse.text()];
|
|
103
|
+
case 5:
|
|
104
|
+
errorText = _a.sent();
|
|
105
|
+
parsed = null;
|
|
106
|
+
try {
|
|
107
|
+
parsed = JSON.parse(errorText);
|
|
108
|
+
}
|
|
109
|
+
catch (_) { /* non-JSON body */ }
|
|
110
|
+
if (rawResponse.status === 401) {
|
|
111
|
+
throw new AxiomHttpError("Failed to authenticate - please check your token.", 401, parsed);
|
|
112
|
+
}
|
|
113
|
+
msg = (parsed && parsed.message) ? parsed.message : "HTTP ".concat(rawResponse.status, " error: ").concat(errorText);
|
|
114
|
+
throw new AxiomHttpError(msg, rawResponse.status, parsed);
|
|
115
|
+
case 6: return [2 /*return*/, rawResponse.json()];
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
return AxiomHttp;
|
|
121
|
+
}());
|
|
122
|
+
export { AxiomHttp };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const ENDPOINT: "https://lar.axiom.ai";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export var ENDPOINT = "https://lar.axiom.ai";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AxiomApi } from "./axiom-api";
|
package/dist/es/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AxiomApi } from "./axiom-api";
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@axiom_ai/api",
|
|
3
|
+
"author": "Axiom.ai",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"description": "Library for interacting with Axiom.ai browser infrastructure",
|
|
7
|
+
"main": "dist/cjs/index.js",
|
|
8
|
+
"module": "dist/es/index.js",
|
|
9
|
+
"types": "dist/es/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build:js": "vite build --mode production",
|
|
15
|
+
"build:js-dev": "vite build --mode development",
|
|
16
|
+
"build:types": "tsc --project tsconfig.json",
|
|
17
|
+
"build": "npm run build:js && npm run build:types",
|
|
18
|
+
"build-dev": "npm run build:js-dev && npm run build:types",
|
|
19
|
+
"test": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js"
|
|
20
|
+
},
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"import": "./dist/es/index.js",
|
|
24
|
+
"require": "./dist/cjs/index.js",
|
|
25
|
+
"default": "./dist/es/index.js",
|
|
26
|
+
"types": "./dist/es/index.d.ts"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"jest": {
|
|
30
|
+
"testEnvironment": "node",
|
|
31
|
+
"testMatch": [
|
|
32
|
+
"**/test/**/*.js"
|
|
33
|
+
],
|
|
34
|
+
"moduleDirectories": [
|
|
35
|
+
"node_modules",
|
|
36
|
+
"src"
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"jest": "^29.7.0",
|
|
41
|
+
"nock": "^14.0.10",
|
|
42
|
+
"typescript": "^5.8.0",
|
|
43
|
+
"vite": "^7.1.10"
|
|
44
|
+
},
|
|
45
|
+
"directories": {
|
|
46
|
+
"test": "test"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {},
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "git+https://github.com/axiom-browser-automation/axiom-api.git"
|
|
52
|
+
},
|
|
53
|
+
"keywords": [
|
|
54
|
+
"ai",
|
|
55
|
+
"api",
|
|
56
|
+
"axiom.ai",
|
|
57
|
+
"sdk",
|
|
58
|
+
"browser",
|
|
59
|
+
"automation"
|
|
60
|
+
],
|
|
61
|
+
"license": "ISC",
|
|
62
|
+
"bugs": {
|
|
63
|
+
"url": "https://github.com/axiom-browser-automation/axiom-api/issues"
|
|
64
|
+
},
|
|
65
|
+
"homepage": "https://github.com/axiom-browser-automation/axiom-api#readme"
|
|
66
|
+
}
|