@hira-core/sdk 1.0.4 → 1.0.5

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.
Files changed (2) hide show
  1. package/README.md +349 -243
  2. package/package.json +6 -1
package/README.md CHANGED
@@ -1,243 +1,349 @@
1
- # @hira-core/sdk
2
-
3
- SDK for building **Hira** automation flows with TypeScript. Provides type-safe base classes, browser utilities, and logger for running flows inside the Hira Agent sandbox.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install @hira-core/sdk
9
- # or
10
- pnpm add @hira-core/sdk
11
- ```
12
-
13
- > **Peer dependency:** Requires `puppeteer-core` to be available at runtime (provided by the Hira Agent).
14
-
15
- ---
16
-
17
- ## Quick Start
18
-
19
- ### 1. Define your Flow Config
20
-
21
- ```typescript
22
- import {
23
- AntidetectBaseFlow,
24
- AntidetectProvider,
25
- IFlowConfig,
26
- IScriptContext,
27
- BrowserUtils,
28
- FlowLogger,
29
- } from "@hira-core/sdk";
30
-
31
- const config = {
32
- globalInput: [
33
- {
34
- key: "targetUrl",
35
- label: "Target URL",
36
- type: "text" as const,
37
- required: true,
38
- },
39
- {
40
- key: "delay",
41
- label: "Delay (ms)",
42
- type: "number" as const,
43
- defaultValue: 2000,
44
- },
45
- ],
46
- profileInput: [
47
- { key: "username", label: "Username", type: "text" as const },
48
- { key: "password", label: "Password", type: "text" as const },
49
- ],
50
- } as const satisfies IFlowConfig;
51
-
52
- type MyConfig = typeof config;
53
- ```
54
-
55
- ### 2. Implement your Flow class
56
-
57
- ```typescript
58
- export class MyFlow extends AntidetectBaseFlow<MyConfig> {
59
- constructor() {
60
- super(AntidetectProvider.GPM, new FlowLogger(MyFlow.name), config);
61
- }
62
-
63
- async script(context: IScriptContext<MyConfig>): Promise<void> {
64
- const { page, logger, globalInput, profileInput } = context;
65
- const utils = new BrowserUtils(context);
66
-
67
- await utils.goto(globalInput.targetUrl);
68
- logger.info(`Logging in as: ${profileInput.username}`);
69
-
70
- await utils.type("#username", profileInput.username);
71
- await utils.type("#password", profileInput.password);
72
- await utils.click("#login-btn");
73
-
74
- const title = await page.title();
75
- logger.success(`✅ Done — page: ${title}`);
76
- }
77
- }
78
-
79
- export default MyFlow;
80
- ```
81
-
82
- ### 3. Run locally (for development)
83
-
84
- ```typescript
85
- import MyFlow from "./index";
86
-
87
- const flow = new MyFlow();
88
-
89
- await flow.run(
90
- flow.createRunParams({
91
- antidetect: {
92
- name: "GPM",
93
- profileSettings: [
94
- flow.createProfileSetting("ProfileA", {
95
- username: "user1",
96
- password: "pass1",
97
- }),
98
- ],
99
- },
100
- execution: { concurrency: 2, maxRetries: 1 },
101
- globalInput: { targetUrl: "https://example.com", delay: 2000 },
102
- window: { width: 1280, height: 720, scale: 1 },
103
- }),
104
- );
105
- ```
106
-
107
- ---
108
-
109
- ## API Reference
110
-
111
- ### `AntidetectBaseFlow<TConfig>`
112
-
113
- Abstract base class for browser automation flows.
114
-
115
- | Method / Property | Description |
116
- | ----------------------------------- | ------------------------------------------------ |
117
- | `abstract script(context)` | Your automation logic — implement this |
118
- | `run(params)` | Start the flow (called by Hira Agent) |
119
- | `createRunParams(params)` | Type-safe helper to build run params |
120
- | `createProfileSetting(name, data?)` | Type-safe helper to build profile settings |
121
- | `flowConfig` | The declared config schema (embedded in `.hira`) |
122
-
123
- ### `AntidetectProvider`
124
-
125
- ```typescript
126
- enum AntidetectProvider {
127
- GPM = "gpm", // GPM Login antidetect browser
128
- HIDEMIUM = "hidemium", // coming soon
129
- GENLOGIN = "genlogin", // coming soon
130
- }
131
- ```
132
-
133
- ### `IScriptContext<TConfig>`
134
-
135
- Injected into `script()` by the runtime:
136
-
137
- | Field | Type | Description |
138
- | -------------- | ---------------------------- | -------------------------------------------- |
139
- | `browser` | `Browser` | Puppeteer browser instance |
140
- | `page` | `Page` | Active page |
141
- | `profile` | `IGpmProfile` | Current GPM profile info |
142
- | `index` | `number` | Profile index in the batch |
143
- | `globalInput` | `InferGlobalInput<TConfig>` | Typed global inputs |
144
- | `profileInput` | `InferProfileInput<TConfig>` | Typed per-profile inputs |
145
- | `logger` | `ILogger` | Bound logger (auto-tagged with profile name) |
146
-
147
- ### `BrowserUtils`
148
-
149
- Helper class for common browser actions. All methods auto-log and respect the abort signal.
150
-
151
- ```typescript
152
- const utils = new BrowserUtils(context);
153
- ```
154
-
155
- | Method | Description |
156
- | ------------------------------------------ | ----------------------------- |
157
- | `utils.goto(url)` | Navigate to URL |
158
- | `utils.click(selector)` | Wait + scroll + click |
159
- | `utils.type(selector, text)` | Wait + clear + type |
160
- | `utils.getText(selector)` | Get text content |
161
- | `utils.exists(selector, timeout?)` | Check element exists |
162
- | `utils.waitForElement(selector, timeout?)` | Wait for element |
163
- | `utils.waitForNavigation()` | Wait for page navigation |
164
- | `utils.screenshot(path?)` | Take screenshot |
165
- | `utils.switchToPopup(matcher)` | Switch to popup tab |
166
- | `utils.switchToTabIndex(index)` | Switch to tab by index |
167
- | `utils.closeCurrentTab()` | Close current tab |
168
- | `utils.closeOtherTabs()` | Close all other tabs |
169
- | `utils.sleep(ms)` | Delay (respects abort signal) |
170
- | `utils.logGlobalInput()` | Log all global inputs |
171
- | `utils.logProfileInput()` | Log all profile inputs |
172
-
173
- ### `FlowLogger`
174
-
175
- Logger that works both in standalone mode (console) and inside Hira Agent worker (postMessage).
176
-
177
- ```typescript
178
- const logger = new FlowLogger("MyFlow");
179
-
180
- logger.info("message");
181
- logger.success("done");
182
- logger.warn("warning");
183
- logger.error("error");
184
- logger.debug("debug");
185
- ```
186
-
187
- ### `IFlowConfig`
188
-
189
- Schema declaration for your flow's inputs:
190
-
191
- ```typescript
192
- interface IFlowConfig {
193
- globalInput: readonly IInputField[]; // shared across all profiles
194
- profileInput: readonly IInputField[]; // per-profile data
195
- }
196
-
197
- interface IInputField {
198
- key: string;
199
- label: string;
200
- type: "text" | "number" | "boolean" | "select" | "textarea";
201
- required?: boolean;
202
- defaultValue?: string | number | boolean;
203
- placeholder?: string;
204
- options?: { label: string; value: string | number }[];
205
- }
206
- ```
207
-
208
- ---
209
-
210
- ## Type Inference
211
-
212
- The SDK automatically infers TypeScript types from your config at compile time:
213
-
214
- ```typescript
215
- const config = {
216
- globalInput: [
217
- { key: "url", type: "text" as const },
218
- { key: "count", type: "number" as const },
219
- ],
220
- profileInput: [{ key: "username", type: "text" as const }],
221
- } as const satisfies IFlowConfig;
222
-
223
- // Inside script():
224
- // globalInput.url → string ✅
225
- // globalInput.count → number ✅
226
- // profileInput.username string ✅
227
- ```
228
-
229
- ---
230
-
231
- ## Building & Publishing a Flow
232
-
233
- Use [`@hira-core/cli`](https://www.npmjs.com/package/@hira-core/cli) to package your flow:
234
-
235
- ```bash
236
- npx @hira-core/cli build
237
- ```
238
-
239
- ---
240
-
241
- ## License
242
-
243
- ISC
1
+ # @hira-core/sdk
2
+
3
+ SDK for building **Hira** automation flows with TypeScript. Provides type-safe base classes, browser utilities, and logger for running flows inside the Hira Agent sandbox.
4
+
5
+ 📖 **[Full Documentation](https://hira-sdk.vercel.app/)** — Guides, API reference, and examples.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @hira-core/sdk
11
+ # or
12
+ pnpm add @hira-core/sdk
13
+ ```
14
+
15
+ > **Peer dependency:** Requires `puppeteer-core` to be available at runtime (provided by the Hira Agent).
16
+
17
+ ---
18
+
19
+ ## Quick Start
20
+
21
+ ### 1. Define your Flow Config
22
+
23
+ ```typescript
24
+ import {
25
+ AntidetectBaseFlow,
26
+ AntidetectProvider,
27
+ defineFlowConfig,
28
+ IScriptContext,
29
+ BrowserUtils,
30
+ FlowLogger,
31
+ } from "@hira-core/sdk";
32
+
33
+ const config = defineFlowConfig({
34
+ globalInput: [
35
+ {
36
+ key: "targetUrl",
37
+ label: "Target URL",
38
+ type: "text" as const,
39
+ required: true,
40
+ },
41
+ {
42
+ key: "delay",
43
+ label: "Delay (ms)",
44
+ type: "number" as const,
45
+ defaultValue: 2000,
46
+ },
47
+ ],
48
+ profileInput: [
49
+ { key: "username", label: "Username", type: "text" as const },
50
+ { key: "password", label: "Password", type: "text" as const },
51
+ ],
52
+ output: [
53
+ { index: 0, key: "isLoggedIn", label: "Login Status" },
54
+ { index: 1, key: "pageTitle", label: "Page Title" },
55
+ ],
56
+ });
57
+
58
+ type MyConfig = typeof config;
59
+ ```
60
+
61
+ > **`defineFlowConfig()`** validates for **duplicate keys, labels, and output indices** at compile time — providing instant TS errors if any field is duplicated.
62
+
63
+ ### 2. Implement your Flow class
64
+
65
+ ```typescript
66
+ export class MyFlow extends AntidetectBaseFlow<MyConfig> {
67
+ constructor() {
68
+ super(AntidetectProvider.GPM, new FlowLogger(MyFlow.name), config);
69
+ }
70
+
71
+ async script(context: IScriptContext<MyConfig>): Promise<void> {
72
+ const { page, logger, globalInput, profileInput, output } = context;
73
+ const utils = new BrowserUtils(context);
74
+
75
+ await utils.goto(globalInput.targetUrl);
76
+ logger.info(`Logging in as: ${profileInput.username}`);
77
+
78
+ await utils.type("#username", profileInput.username);
79
+ await utils.type("#password", profileInput.password);
80
+ await utils.click("#login-btn");
81
+
82
+ const title = await page.title();
83
+
84
+ // Write typed output (validated against config.output keys)
85
+ await utils.writeOutput("isLoggedIn", true);
86
+ await utils.writeOutput("pageTitle", title);
87
+
88
+ logger.success(`✅ Done — page: ${title}`);
89
+ }
90
+ }
91
+
92
+ export default MyFlow;
93
+ ```
94
+
95
+ ### 3. Run locally (for development)
96
+
97
+ ```typescript
98
+ import MyFlow from "./index";
99
+
100
+ const flow = new MyFlow();
101
+
102
+ await flow.run(
103
+ flow.createRunParams({
104
+ antidetect: {
105
+ profileSettings: [
106
+ flow.createProfileSetting("ProfileA", {
107
+ username: "user1",
108
+ password: "pass1",
109
+ }),
110
+ ],
111
+ },
112
+ execution: { concurrency: 2, maxRetries: 1 },
113
+ globalInput: { targetUrl: "https://example.com", delay: 2000 },
114
+ window: { width: 1280, height: 720, scale: 1 },
115
+ }),
116
+ );
117
+ ```
118
+
119
+ ---
120
+
121
+ ## API Reference
122
+
123
+ ### `AntidetectBaseFlow<TConfig>`
124
+
125
+ Abstract base class for browser automation flows.
126
+
127
+ | Method / Property | Description |
128
+ | ----------------------------------- | ------------------------------------------------ |
129
+ | `abstract script(context)` | Your automation logic — implement this |
130
+ | `run(params)` | Start the flow (called by Hira Agent) |
131
+ | `createRunParams(params)` | Type-safe helper to build run params |
132
+ | `createProfileSetting(name, data?)` | Type-safe helper to build profile settings |
133
+ | `flowConfig` | The declared config schema (embedded in `.hira`) |
134
+
135
+ ### `AntidetectProvider`
136
+
137
+ ```typescript
138
+ enum AntidetectProvider {
139
+ GPM = "gpm", // GPM Login antidetect browser
140
+ HIDEMIUM = "hidemium", // Hidemium antidetect browser
141
+ GENLOGIN = "genlogin", // coming soon
142
+ }
143
+ ```
144
+
145
+ ### `IScriptContext<TConfig>`
146
+
147
+ Injected into `script()` by the runtime:
148
+
149
+ | Field | Type | Description |
150
+ | -------------- | ---------------------------- | ---------------------------------------------------- |
151
+ | `browser` | `Browser` | Puppeteer browser instance |
152
+ | `page` | `Page` | Active page |
153
+ | `profile` | `IAntidetectProfile` | Current profile info (unified across providers) |
154
+ | `index` | `number` | Profile index in the batch |
155
+ | `globalInput` | `InferGlobalInput<TConfig>` | Typed global inputs |
156
+ | `profileInput` | `InferProfileInput<TConfig>` | Typed per-profile inputs |
157
+ | `output` | `InferOutput<TConfig>` | Current output values (pre-populated from last run) |
158
+ | `logger` | `ILogger` | Bound logger (auto-tagged with profile name) |
159
+
160
+ ### `IAntidetectProfile`
161
+
162
+ Unified profile interface works across all providers (GPM, Hidemium, etc.):
163
+
164
+ ```typescript
165
+ interface IAntidetectProfile {
166
+ id: string; // Unique ID
167
+ name: string; // Human-readable name
168
+ provider: "gpm" | "hidemium" | "genlogin";
169
+ raw_proxy?: string; // Proxy string
170
+ browser_type: "chromium" | "firefox";
171
+ browser_version: string;
172
+ group_id?: string;
173
+ profile_path: string;
174
+ note: string;
175
+ created_at: string; // ISO 8601
176
+ }
177
+ ```
178
+
179
+ > **Note:** `IGpmProfile` is deprecated — use `IAntidetectProfile` instead.
180
+
181
+ ### `BrowserUtils`
182
+
183
+ Helper class for common browser actions. All methods auto-log and respect the abort signal.
184
+
185
+ ```typescript
186
+ const utils = new BrowserUtils(context);
187
+ ```
188
+
189
+ #### Navigation & Interaction
190
+
191
+ | Method | Description |
192
+ | ------------------------------------------ | ----------------------------- |
193
+ | `utils.goto(url)` | Navigate to URL |
194
+ | `utils.click(selector)` | Wait + scroll + click |
195
+ | `utils.type(selector, text)` | Wait + clear + type |
196
+ | `utils.getText(selector)` | Get text content |
197
+ | `utils.exists(selector, timeout?)` | Check element exists |
198
+ | `utils.waitForElement(selector, timeout?)` | Wait for element |
199
+ | `utils.waitForNavigation()` | Wait for page navigation |
200
+ | `utils.screenshot(path?)` | Take screenshot |
201
+ | `utils.sleep(ms)` | Delay (respects abort signal) |
202
+
203
+ #### Tab Management
204
+
205
+ | Method | Description |
206
+ | --------------------------------- | ------------------------ |
207
+ | `utils.switchToPopup(matcher)` | Switch to popup tab |
208
+ | `utils.switchToTabIndex(index)` | Switch to tab by index |
209
+ | `utils.closeCurrentTab()` | Close current tab |
210
+ | `utils.closeOtherTabs()` | Close all other tabs |
211
+
212
+ #### Output & Data
213
+
214
+ | Method | Description |
215
+ | ------------------------------------ | ------------------------------------------------ |
216
+ | `utils.writeOutput(key, value)` | Write output value (type-safe against config) |
217
+ | `utils.writeProfileInput(key, val)` | Update profile input value for next run |
218
+ | `utils.logGlobalInput()` | Log all global inputs |
219
+ | `utils.logProfileInput()` | Log all profile inputs |
220
+
221
+ ### `FlowLogger`
222
+
223
+ Logger that works both in standalone mode (console) and inside Hira Agent worker (postMessage).
224
+
225
+ ```typescript
226
+ const logger = new FlowLogger("MyFlow");
227
+
228
+ logger.info("message");
229
+ logger.success("done");
230
+ logger.warn("warning");
231
+ logger.error("error");
232
+ logger.debug("debug");
233
+ ```
234
+
235
+ ### `IFlowConfig`
236
+
237
+ Schema declaration for your flow's inputs and outputs:
238
+
239
+ ```typescript
240
+ interface IFlowConfig {
241
+ globalInput: readonly IInputField[]; // shared across all profiles
242
+ profileInput: readonly IInputField[]; // per-profile data
243
+ output?: readonly IOutputField[]; // output fields per profile
244
+ }
245
+
246
+ interface IInputField {
247
+ key: string;
248
+ label: string;
249
+ type: "text" | "number" | "boolean" | "select" | "textarea";
250
+ required?: boolean;
251
+ defaultValue?: string | number | boolean;
252
+ placeholder?: string;
253
+ options?: { label: string; value: string | number }[];
254
+ }
255
+
256
+ interface IOutputField {
257
+ index: number; // display order
258
+ key: string; // unique key for writeOutput()
259
+ label: string; // human-readable label
260
+ }
261
+ ```
262
+
263
+ ### `defineFlowConfig()`
264
+
265
+ Helper function that validates your config at compile time — catches duplicate keys, labels, indices, and option values:
266
+
267
+ ```typescript
268
+ // ✅ OK
269
+ const config = defineFlowConfig({
270
+ globalInput: [
271
+ { key: "url", label: "URL", type: "text" },
272
+ ],
273
+ profileInput: [
274
+ { key: "user", label: "User", type: "text" },
275
+ ],
276
+ output: [
277
+ { index: 0, key: "status", label: "Status" },
278
+ { index: 1, key: "title", label: "Title" },
279
+ ],
280
+ });
281
+
282
+ // ❌ TS Error — duplicate key "url" in globalInput
283
+ const bad = defineFlowConfig({
284
+ globalInput: [
285
+ { key: "url", label: "URL 1", type: "text" },
286
+ { key: "url", label: "URL 2", type: "text" }, // Error!
287
+ ],
288
+ profileInput: [],
289
+ });
290
+ ```
291
+
292
+ ### `ExcelStorage`
293
+
294
+ Read profile data from Excel files and write output back:
295
+
296
+ ```typescript
297
+ import { ExcelStorage } from "@hira-core/sdk";
298
+
299
+ const storage = new ExcelStorage("data.xlsx");
300
+
301
+ // Read rows from a sheet
302
+ const rows = await storage.readRows("Sheet1");
303
+
304
+ // Write output rows
305
+ await storage.writeRows("Output", outputData);
306
+ ```
307
+
308
+ ---
309
+
310
+ ## Type Inference
311
+
312
+ The SDK automatically infers TypeScript types from your config at compile time:
313
+
314
+ ```typescript
315
+ const config = defineFlowConfig({
316
+ globalInput: [
317
+ { key: "url", type: "text" as const, label: "URL" },
318
+ { key: "count", type: "number" as const, label: "Count" },
319
+ ],
320
+ profileInput: [
321
+ { key: "username", type: "text" as const, label: "Username" },
322
+ ],
323
+ output: [
324
+ { index: 0, key: "isLoggedIn", label: "Logged In" },
325
+ ],
326
+ });
327
+
328
+ // Inside script():
329
+ // globalInput.url → string ✅
330
+ // globalInput.count → number ✅
331
+ // profileInput.username → string ✅
332
+ // output.isLoggedIn → ProfileOutputValue | null ✅
333
+ ```
334
+
335
+ ---
336
+
337
+ ## Building & Publishing a Flow
338
+
339
+ Use [`@hira-core/cli`](https://www.npmjs.com/package/@hira-core/cli) to package your flow:
340
+
341
+ ```bash
342
+ npx @hira-core/cli build
343
+ ```
344
+
345
+ ---
346
+
347
+ ## License
348
+
349
+ ISC
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hira-core/sdk",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "SDK for building Hira automation flows with TypeScript",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -25,6 +25,11 @@
25
25
  "puppeteer"
26
26
  ],
27
27
  "author": "tttKiet",
28
+ "homepage": "https://hira-sdk.vercel.app/",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/tttKiet/hira-automation"
32
+ },
28
33
  "license": "ISC",
29
34
  "engines": {
30
35
  "node": ">=18.0.0"