@tapi-dev/sdk 0.1.17 → 0.1.21

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.d.ts CHANGED
@@ -3,6 +3,7 @@ import { CatalogResource } from "./catalog.js";
3
3
  import { RunnersResource } from "./runners.js";
4
4
  import { RunsResource } from "./runs.js";
5
5
  import { RuntimeResource } from "./runtime.js";
6
+ import { SessionsResource } from "./sessions.js";
6
7
  import { TriggersResource } from "./triggers.js";
7
8
  import type { TapiClientOptions } from "./types.js";
8
9
  import { WebsiteApisResource } from "./website-apis.js";
@@ -12,10 +13,13 @@ export declare class TapiClient {
12
13
  readonly runners: RunnersResource;
13
14
  readonly runs: RunsResource;
14
15
  readonly runtime: RuntimeResource;
16
+ readonly sessions: SessionsResource;
15
17
  readonly triggers: TriggersResource;
16
18
  readonly websiteApis: WebsiteApisResource;
17
19
  constructor(options: TapiClientOptions);
18
20
  }
19
21
  export * from "./errors.js";
22
+ export * from "./late-input.js";
23
+ export * from "./sessions.js";
20
24
  export * from "./types.js";
21
25
  export * from "./workspace.js";
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ import { CatalogResource } from "./catalog.js";
4
4
  import { RunnersResource } from "./runners.js";
5
5
  import { RunsResource } from "./runs.js";
6
6
  import { RuntimeResource } from "./runtime.js";
7
+ import { SessionsResource } from "./sessions.js";
7
8
  import { TriggersResource } from "./triggers.js";
8
9
  import { WebsiteApisResource } from "./website-apis.js";
9
10
  export class TapiClient {
@@ -12,6 +13,7 @@ export class TapiClient {
12
13
  runners;
13
14
  runs;
14
15
  runtime;
16
+ sessions;
15
17
  triggers;
16
18
  websiteApis;
17
19
  constructor(options) {
@@ -21,10 +23,13 @@ export class TapiClient {
21
23
  this.runners = new RunnersResource(http);
22
24
  this.runs = new RunsResource(http);
23
25
  this.runtime = new RuntimeResource(http, options);
26
+ this.sessions = new SessionsResource(http);
24
27
  this.triggers = new TriggersResource(http);
25
- this.websiteApis = new WebsiteApisResource(http);
28
+ this.websiteApis = new WebsiteApisResource(http, options);
26
29
  }
27
30
  }
28
31
  export * from "./errors.js";
32
+ export * from "./late-input.js";
33
+ export * from "./sessions.js";
29
34
  export * from "./types.js";
30
35
  export * from "./workspace.js";
@@ -0,0 +1,24 @@
1
+ export interface LateInputOptions<T> {
2
+ resolve?: () => T | Promise<T>;
3
+ timeoutMs?: number;
4
+ }
5
+ export interface LateInput<T = unknown> {
6
+ readonly __tapiLateInput: true;
7
+ set(value: T): Promise<void>;
8
+ waitForProvides(): Promise<void>;
9
+ }
10
+ type Provider = (runId: string, inputKey: string, value: unknown) => Promise<unknown>;
11
+ export declare function lateInput<T = unknown>(options?: LateInputOptions<T>): LateInput<T>;
12
+ export declare function isLateInput(value: unknown): value is LateInput<unknown>;
13
+ export declare function serializeInputs(inputs: Record<string, unknown> | undefined): {
14
+ bodyInputs: Record<string, unknown> | undefined;
15
+ lateInputs: Array<{
16
+ key: string;
17
+ input: LateInput<unknown>;
18
+ }>;
19
+ };
20
+ export declare function attachLateInputs(lateInputs: Array<{
21
+ key: string;
22
+ input: LateInput<unknown>;
23
+ }>, runId: string, provider: Provider): void;
24
+ export {};
@@ -0,0 +1,112 @@
1
+ class TapiLateInput {
2
+ __tapiLateInput = true;
3
+ timeoutMs;
4
+ resolver;
5
+ resolverStarted = false;
6
+ resolverPromise;
7
+ hasResolverError = false;
8
+ resolverError;
9
+ resolved = false;
10
+ resolvedValue;
11
+ bindings = [];
12
+ providePromises = [];
13
+ constructor(options = {}) {
14
+ this.resolver = options.resolve;
15
+ this.timeoutMs = options.timeoutMs;
16
+ }
17
+ async set(value) {
18
+ if (this.resolved) {
19
+ throw new Error("late input has already been set");
20
+ }
21
+ this.resolved = true;
22
+ this.resolvedValue = value;
23
+ this.provide(value);
24
+ await Promise.all(this.providePromises);
25
+ }
26
+ provide(value) {
27
+ for (const binding of this.bindings) {
28
+ this.providePromises.push(binding.provider(binding.runId, binding.inputKey, value));
29
+ }
30
+ }
31
+ async waitForProvides() {
32
+ if (this.resolverPromise) {
33
+ await this.resolverPromise;
34
+ }
35
+ if (this.hasResolverError) {
36
+ throw this.resolverError;
37
+ }
38
+ await Promise.all(this.providePromises);
39
+ }
40
+ attach(binding) {
41
+ this.bindings.push(binding);
42
+ if (this.resolved) {
43
+ this.provide(this.resolvedValue);
44
+ return;
45
+ }
46
+ this.startResolver();
47
+ }
48
+ toWire() {
49
+ return {
50
+ __tapiLateInput: true,
51
+ ...(typeof this.timeoutMs === "number" ? { timeoutMs: this.timeoutMs } : {}),
52
+ };
53
+ }
54
+ startResolver() {
55
+ if (!this.resolver || this.resolverStarted) {
56
+ return;
57
+ }
58
+ this.resolverStarted = true;
59
+ let resolverClaimedValue = false;
60
+ this.resolverPromise = Promise.resolve()
61
+ .then(() => this.resolver?.())
62
+ .then(async (value) => {
63
+ if (this.resolved) {
64
+ return;
65
+ }
66
+ resolverClaimedValue = true;
67
+ this.resolved = true;
68
+ this.resolvedValue = value;
69
+ this.provide(this.resolvedValue);
70
+ await Promise.all(this.providePromises);
71
+ })
72
+ .catch((error) => {
73
+ if (resolverClaimedValue || !this.resolved) {
74
+ this.hasResolverError = true;
75
+ this.resolverError = error;
76
+ }
77
+ });
78
+ }
79
+ }
80
+ export function lateInput(options = {}) {
81
+ return new TapiLateInput(options);
82
+ }
83
+ export function isLateInput(value) {
84
+ return Boolean(value
85
+ && typeof value === "object"
86
+ && value.__tapiLateInput === true
87
+ && typeof value.set === "function");
88
+ }
89
+ export function serializeInputs(inputs) {
90
+ if (inputs === undefined) {
91
+ return { bodyInputs: undefined, lateInputs: [] };
92
+ }
93
+ const bodyInputs = {};
94
+ const lateInputs = [];
95
+ for (const [key, value] of Object.entries(inputs)) {
96
+ if (isLateInput(value)) {
97
+ const late = value;
98
+ bodyInputs[key] = late.toWire();
99
+ lateInputs.push({ key, input: value });
100
+ }
101
+ else {
102
+ bodyInputs[key] = value;
103
+ }
104
+ }
105
+ return { bodyInputs, lateInputs };
106
+ }
107
+ export function attachLateInputs(lateInputs, runId, provider) {
108
+ for (const item of lateInputs) {
109
+ const late = item.input;
110
+ late.attach({ runId, inputKey: item.key, provider });
111
+ }
112
+ }
package/dist/runs.d.ts CHANGED
@@ -5,6 +5,7 @@ export declare class RunsResource {
5
5
  constructor(http: HttpClient);
6
6
  get(runId: string): Promise<TapiRun>;
7
7
  cancel(runId: string): Promise<TapiRun>;
8
+ provideInput(runId: string, inputKey: string, value: unknown): Promise<TapiRun>;
8
9
  wait(runId: string, options?: {
9
10
  intervalMs?: number;
10
11
  timeoutMs?: number;
package/dist/runs.js CHANGED
@@ -9,6 +9,9 @@ export class RunsResource {
9
9
  cancel(runId) {
10
10
  return this.http.post(`/api/sdk/v1/runs/${encodeURIComponent(runId)}/cancel`);
11
11
  }
12
+ provideInput(runId, inputKey, value) {
13
+ return this.http.post(`/api/sdk/v1/runs/${encodeURIComponent(runId)}/inputs/${encodeURIComponent(inputKey)}`, { value });
14
+ }
12
15
  async wait(runId, options = {}) {
13
16
  const intervalMs = options.intervalMs ?? 1000;
14
17
  const deadline = Date.now() + (options.timeoutMs ?? 300000);
@@ -0,0 +1,10 @@
1
+ import type { HttpClient } from "./client.js";
2
+ import type { TapiDevSessionsList } from "./types.js";
3
+ export interface TapiDevSessionsListOptions {
4
+ site?: string;
5
+ }
6
+ export declare class SessionsResource {
7
+ private readonly http;
8
+ constructor(http: HttpClient);
9
+ list(options?: TapiDevSessionsListOptions): Promise<TapiDevSessionsList>;
10
+ }
@@ -0,0 +1,14 @@
1
+ export class SessionsResource {
2
+ http;
3
+ constructor(http) {
4
+ this.http = http;
5
+ }
6
+ list(options = {}) {
7
+ const params = new URLSearchParams();
8
+ if (options.site) {
9
+ params.set("site", options.site);
10
+ }
11
+ const query = params.toString();
12
+ return this.http.get(`/api/sdk/v1/dev/sessions${query ? `?${query}` : ""}`);
13
+ }
14
+ }
package/dist/types.d.ts CHANGED
@@ -1,14 +1,16 @@
1
- export type RunStatus = "queued" | "running" | "completed" | "failed" | "cancelled" | "needs_developer_attention";
1
+ import type { LateInput } from "./late-input.js";
2
+ export type RunStatus = "queued" | "running" | "waiting_for_input" | "completed" | "failed" | "cancelled" | "needs_developer_attention";
2
3
  export interface TapiClientOptions {
3
4
  baseUrl: string;
4
5
  apiKey: string;
5
6
  projectId?: string;
7
+ dev?: boolean;
6
8
  fetch?: typeof fetch;
7
9
  localControlUrl?: string;
8
10
  webSocket?: LocalWebSocketConstructor;
9
11
  }
10
12
  export interface WebsiteApiRunRequest {
11
- inputs?: Record<string, unknown>;
13
+ inputs?: Record<string, unknown | LateInput<unknown>>;
12
14
  runtime?: RuntimeRunOptions;
13
15
  priority?: number;
14
16
  runnerId?: string;
@@ -156,6 +158,8 @@ export interface WebsiteApiOperation {
156
158
  version?: string;
157
159
  status?: string;
158
160
  publishedAt?: string | null;
161
+ variant?: "desktop" | "mobile" | string;
162
+ runtime?: RuntimeRunOptions | Record<string, unknown>;
159
163
  inputs: WebsiteApiInputContract[];
160
164
  outputs?: WebsiteApiOutputContract[];
161
165
  inputSchema?: Record<string, unknown>;
@@ -218,10 +222,51 @@ export interface TapiRun {
218
222
  result?: Record<string, unknown> | null;
219
223
  error?: Record<string, unknown> | null;
220
224
  runtime?: RuntimeRunOptions | Record<string, unknown> | null;
225
+ waitingInput?: WebsiteApiWaitingInput | null;
226
+ pendingInputs?: WebsiteApiWaitingInput[];
221
227
  createdAt?: string;
222
228
  updatedAt?: string;
223
229
  [key: string]: unknown;
224
230
  }
231
+ export type TapiDevSessionStatus = "queued" | "running" | "waiting_for_input" | "awaiting_takeover" | "needs_developer_attention" | "completed" | "failed" | "cancelled" | string;
232
+ export interface TapiDevSession {
233
+ id: string;
234
+ projectId: string;
235
+ sitemap: string;
236
+ site?: string;
237
+ apiName: string;
238
+ requestKey: string;
239
+ status: TapiDevSessionStatus;
240
+ stateId?: number | null;
241
+ stateLabel?: string;
242
+ currentUrl?: string;
243
+ profileRef?: string;
244
+ runtimeSessionId?: string;
245
+ deviceId?: string;
246
+ live: boolean;
247
+ openable: boolean;
248
+ dev: boolean;
249
+ updatedAt?: string;
250
+ createdAt?: string;
251
+ [key: string]: unknown;
252
+ }
253
+ export interface TapiDevSessionGroup {
254
+ sitemap: string;
255
+ sessions: TapiDevSession[];
256
+ }
257
+ export interface TapiDevSessionsList {
258
+ projectId: string;
259
+ groups: TapiDevSessionGroup[];
260
+ }
261
+ export interface WebsiteApiWaitingInput {
262
+ key: string;
263
+ label?: string;
264
+ stateId?: number;
265
+ actionId?: string;
266
+ control?: string;
267
+ timeoutMs?: number;
268
+ [key: string]: unknown;
269
+ }
225
270
  export interface TapiRunner {
226
271
  id: string;
227
272
  status: string;
@@ -322,6 +367,8 @@ export interface SdkCatalogRequest {
322
367
  status: string;
323
368
  operation?: string;
324
369
  sdkName?: string;
370
+ variant?: "desktop" | "mobile" | string;
371
+ runtime?: RuntimeRunOptions | Record<string, unknown>;
325
372
  inputs?: WebsiteApiInputContract[];
326
373
  inputSchema?: Record<string, unknown>;
327
374
  outputSchema?: Record<string, unknown>;
@@ -1,8 +1,10 @@
1
1
  import type { HttpClient } from "./client.js";
2
2
  import type { CloudBatchRun, CloudRunQuote, TapiRun, WebsiteApiCloudBatchRequest, WebsiteApiCloudQuoteRequest, WebsiteApiOperation, WebsiteApiRunRequest } from "./types.js";
3
+ import type { TapiClientOptions } from "./types.js";
3
4
  export declare class WebsiteApisResource {
4
5
  private readonly http;
5
- constructor(http: HttpClient);
6
+ private readonly dev;
7
+ constructor(http: HttpClient, options: TapiClientOptions);
6
8
  run(apiRequest: string, request?: WebsiteApiRunRequest): Promise<TapiRun>;
7
9
  quoteCloud(apiRequest: string, request?: WebsiteApiCloudQuoteRequest): Promise<CloudRunQuote>;
8
10
  runCloud(apiRequest: string, request?: WebsiteApiRunRequest & {
@@ -1,12 +1,25 @@
1
1
  import { TapiError } from "./errors.js";
2
+ import { attachLateInputs, serializeInputs } from "./late-input.js";
2
3
  export class WebsiteApisResource {
3
4
  http;
4
- constructor(http) {
5
+ dev;
6
+ constructor(http, options) {
5
7
  this.http = http;
8
+ this.dev = options.dev === true;
6
9
  }
7
- run(apiRequest, request = {}) {
10
+ async run(apiRequest, request = {}) {
8
11
  const { apiName, requestKey } = splitApiRequest(apiRequest);
9
- return this.http.post(`/api/sdk/v1/website-apis/${encodeURIComponent(apiName)}/requests/${encodeURIComponent(requestKey)}/runs`, request);
12
+ const { bodyInputs, lateInputs } = serializeInputs(request.inputs);
13
+ const body = {
14
+ ...request,
15
+ ...(bodyInputs === undefined ? {} : { inputs: bodyInputs }),
16
+ ...(this.dev ? { dev: true } : {}),
17
+ };
18
+ const run = await this.http.post(`/api/sdk/v1/website-apis/${encodeURIComponent(apiName)}/requests/${encodeURIComponent(requestKey)}/runs`, body);
19
+ if (run.id && lateInputs.length > 0) {
20
+ attachLateInputs(lateInputs, run.id, (runId, inputKey, value) => this.http.post(`/api/sdk/v1/runs/${encodeURIComponent(runId)}/inputs/${encodeURIComponent(inputKey)}`, { value }));
21
+ }
22
+ return run;
10
23
  }
11
24
  quoteCloud(apiRequest, request = {}) {
12
25
  const { apiName, requestKey } = splitApiRequest(apiRequest);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tapi-dev/sdk",
3
- "version": "0.1.17",
3
+ "version": "0.1.21",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",