@tapi-dev/sdk 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,164 +10,106 @@ npm install @tapi-dev/sdk
10
10
 
11
11
  This package is ESM-first and works in runtimes with `fetch`, including modern Node.js and browser-like server runtimes.
12
12
 
13
- ## Install Tapi Studio
14
-
15
- Tapi Studio is the desktop app used to author and test local Tapi integrations. Install the SDK first, then use the bundled CLI:
16
-
17
- ```bash
18
- npm install @tapi-dev/sdk
19
- npx tapi studio install --channel pilot
20
- npx tapi studio open
21
- ```
22
-
23
- `studio install` opens a browser sign-in before any Studio EXE download. The
24
- CLI exchanges the browser credential for Firebase auth, requests a short-lived
25
- Studio install token from the Tapi API, then fetches a protected manifest and
26
- installer download URL. If the signed-in user is not yet approved, the server
27
- submits an approval request and sends the existing email approval links to the
28
- admin. After approval, rerun the same command.
29
-
30
- You can also run the CLI directly from npm without adding the package first:
31
-
32
- ```bash
33
- npx @tapi-dev/sdk studio install --channel pilot
34
- ```
35
-
36
- The install flow talks to the Tapi API host first:
37
-
38
- ```text
39
- POST /api/sdk/v1/studio/install-token
40
- GET /api/sdk/v1/studio/releases/<channel>
41
- ```
42
-
43
- It then downloads the Windows installer, verifies the manifest SHA256, caches
44
- the installer locally, and runs it. The installer cache defaults to:
45
-
46
- ```text
47
- %LOCALAPPDATA%\Tapi\Studio\downloads
48
- ```
49
-
50
- Tapi Studio includes the matching Tapi Service build. When the installer runs,
51
- it installs or replaces the local `tapi-service` Windows service with the
52
- version declared in the Studio manifest. Developers do not pick a service
53
- version separately; updating Studio updates the service version used by that
54
- project and by apps generated from that project.
55
-
56
- Useful commands:
57
-
58
- ```bash
59
- npx tapi studio install --channel pilot
60
- npx tapi studio install --channel pilot --download-only
61
- npx tapi studio install --api-base-url https://api.example.com
62
- npx tapi studio install --install-token tsi_your_preissued_token
63
- npx tapi studio open
64
- npx tapi studio doctor
65
- ```
66
-
67
- Environment overrides:
68
-
69
- ```env
70
- TAPI_BASE_URL=https://your-tapi-api-host
71
- TAPI_STUDIO_API_BASE_URL=https://your-tapi-api-host
72
- TAPI_STUDIO_CHANNEL=pilot
73
- TAPI_STUDIO_MANIFEST_URL=https://d4xaf52nfwiok.cloudfront.net/studio/channels/pilot/latest.json
74
- TAPI_STUDIO_INSTALL_TOKEN=tsi_your_preissued_token
75
- TAPI_STUDIO_AUTH_HTML_URL=https://rsarlong-1f92fd.gitlab.io/auth.html
76
- TAPI_FIREBASE_API_KEY=AIzaSyCDZR8lWyVQcWYfFdNZa4vuL4IWEC0h6gE
77
- TAPI_STUDIO_EXE=C:\Users\you\AppData\Local\Tapi Studio\Tapi Studio.exe
78
- ```
79
-
80
- `TAPI_STUDIO_MANIFEST_URL` remains useful for `studio doctor`. Direct manifest
81
- overrides are not used by the protected installer path.
82
-
83
- Server-side protected install delivery also requires:
13
+ ## Developer Flow
84
14
 
85
- ```env
86
- STUDIO_INSTALL_TOKEN_SECRET=replace-me
87
- S3_BUCKET=your-private-release-bucket
88
- AWS_REGION=us-east-1
15
+ Tapi Studio is launched from the developer app repo. The repo's `.tapi/project.json`
16
+ is the project binding, so one developer can work on multiple Tapi projects from
17
+ different directories without a global Studio project picker.
18
+
19
+ ```bash
20
+ npm install @tapi-dev/sdk
21
+ npx tapi init --project brokerage
22
+ npx tapi studio
89
23
  ```
90
24
 
91
- If the Studio installer objects remain publicly downloadable, users can bypass
92
- the approval gate by skipping the CLI entirely.
25
+ `tapi studio` checks the required local `tapi-service`, installs it when needed,
26
+ downloads the portable Studio server release when the channel manifest uses
27
+ `installerKind: portable-server`, starts Studio locally, and opens the browser.
28
+ Legacy NSIS desktop Studio manifests still work, but the normal developer path
29
+ is the portable server launched by the CLI.
30
+
31
+ Useful commands:
93
32
 
94
- Tapi Studio desktop releases are currently published for Windows x64.
33
+ ```bash
34
+ npx tapi init --project brokerage
35
+ npx tapi link --project brokerage
36
+ npx tapi studio
37
+ npx tapi service install --channel pilot
38
+ npx tapi service status
39
+ npx tapi apis generate
40
+ npx tapi publish
41
+ ```
95
42
 
96
- Cloud Windows workers use a separate protected service runtime manifest:
43
+ Local authoring files live in the app repo:
97
44
 
98
45
  ```text
99
- GET /api/sdk/v1/service/releases/<channel>
46
+ .tapi/project.json
47
+ .tapi/sitemaps/<site>.json
48
+ .tapi/apis/<site>/<api>.json
49
+ .tapi/generated/catalog.json
50
+ src/tapi.generated.ts
100
51
  ```
101
52
 
102
- The request must include either `Authorization: Bearer
103
- $CLOUD_WORKER_BOOTSTRAP_SECRET` or `X-Tapi-Worker-Bootstrap-Secret`. The server
104
- reads `service/channels/<channel>/latest.json` from the private S3 bucket and
105
- returns a short-lived signed download URL for the Tapi Service zip.
106
-
107
- ## Quick Start
108
-
109
- Create one TAPI client in your app's server-side code:
110
-
111
- ```ts
112
- import { TapiClient } from "@tapi-dev/sdk";
113
-
114
- export const tapi = new TapiClient({
115
- baseUrl: process.env.TAPI_BASE_URL!,
116
- apiKey: process.env.TAPI_API_KEY!,
117
- appId: process.env.TAPI_APP_ID,
118
- });
119
- ```
120
-
121
- Then call a TAPI website API:
122
-
123
- ```ts
124
- const run = await tapi.websiteApis.run("brokerage.submitTrade", {
125
- inputs: {
126
- symbol: "AAPL",
127
- quantity: 1,
128
- side: "buy",
129
- },
130
- });
131
-
132
- const completedRun = await tapi.runs.wait(run.id);
133
- console.log(completedRun.status, completedRun.result);
134
- ```
135
-
136
- Generated website APIs are created in Tapi Studio by setting workflow bounds,
137
- choosing the SDK operation name, selecting inputs/outputs, and publishing the
138
- operation. Studio owns the private workflow bindings. The SDK sees the public
139
- shape as:
140
-
141
- ```text
142
- <autogenerated website namespace>.<developer operation name>
143
- ```
144
-
145
- For example, if Studio shows `SDK name: schwab.[ place_order ]`, call:
146
-
147
- ```ts
148
- const operation = await tapi.websiteApis.describe("schwab.place_order");
149
-
150
- const run = await tapi.websiteApis.run("schwab.place_order", {
151
- inputs: {
152
- symbol: "AAPL",
153
- side: "buy",
154
- quantity: 10,
155
- orderType: "limit",
156
- limitPrice: 190,
157
- },
158
- });
159
- ```
160
-
161
- You can inspect the same input/output contract from the CLI:
162
-
163
- ```bash
164
- npx tapi apis describe schwab.place_order \
165
- --api-base-url "$TAPI_BASE_URL" \
166
- --api-key "$TAPI_API_KEY" \
167
- --app "$TAPI_APP_ID"
168
- ```
169
-
170
- Do not expose `TAPI_API_KEY` in public browser bundles. Put the SDK behind your own backend route, server action, or job worker when using secret API keys.
53
+ Drafts are local. `tapi publish` uploads local sitemaps and API contracts, marks
54
+ ready requests as published, and activates one immutable server release. Runtime
55
+ SDK calls read the active release catalog, not mutable Studio drafts.
56
+
57
+ ```bash
58
+ TAPI_API_KEY=tapi_project_key npx tapi publish
59
+ TAPI_API_KEY=tapi_project_key npx tapi apis generate
60
+ ```
61
+
62
+ ## Quick Start
63
+
64
+ Create one TAPI client in server-side app code. Use a project-scoped API key and
65
+ the same project id from `.tapi/project.json`.
66
+
67
+ ```ts
68
+ import { TapiClient } from "@tapi-dev/sdk";
69
+
70
+ export const tapi = new TapiClient({
71
+ baseUrl: process.env.TAPI_BASE_URL!,
72
+ apiKey: process.env.TAPI_API_KEY!,
73
+ projectId: process.env.TAPI_PROJECT_ID!,
74
+ });
75
+ ```
76
+
77
+ Generated website APIs are authored visually in Tapi Studio by setting workflow
78
+ bounds, selecting inputs/outputs, and publishing an API. The SDK sees the public
79
+ operation name:
80
+
81
+ ```text
82
+ <namespace>.<operation>
83
+ ```
84
+
85
+ ```ts
86
+ const operation = await tapi.websiteApis.describe("schwab.place_order");
87
+
88
+ const run = await tapi.websiteApis.run("schwab.place_order", {
89
+ inputs: {
90
+ symbol: "AAPL",
91
+ side: "buy",
92
+ quantity: 10,
93
+ orderType: "limit",
94
+ limitPrice: 190,
95
+ },
96
+ });
97
+
98
+ const completedRun = await tapi.runs.wait(run.id);
99
+ console.log(completedRun.status, completedRun.result);
100
+ ```
101
+
102
+ You can inspect the same input/output contract from the CLI:
103
+
104
+ ```bash
105
+ npx tapi apis describe schwab.place_order \
106
+ --api-base-url "$TAPI_BASE_URL" \
107
+ --api-key "$TAPI_API_KEY" \
108
+ --project "$TAPI_PROJECT_ID"
109
+ ```
110
+
111
+ Do not expose `TAPI_API_KEY` in public browser bundles. Put the SDK behind your
112
+ own backend route, server action, or job worker when using secret API keys.
171
113
 
172
114
  ## Runtime Profiles and Proxies
173
115
 
@@ -238,15 +180,17 @@ const tapi = new TapiClient({
238
180
  });
239
181
  ```
240
182
 
241
- ## Configuration
242
-
243
- ```env
244
- TAPI_BASE_URL=https://your-tapi-api-host
245
- TAPI_API_KEY=tapi_your_api_key
246
- TAPI_APP_ID=your-app-id
247
- ```
248
-
249
- `appId` is optional. If provided, the SDK sends it as the `X-Tapi-App` header.
183
+ ## Configuration
184
+
185
+ ```env
186
+ TAPI_BASE_URL=https://your-tapi-api-host
187
+ TAPI_API_KEY=tapi_project_key
188
+ TAPI_PROJECT_ID=brokerage
189
+ ```
190
+
191
+ `projectId` is optional only when the API key itself is project-scoped. If
192
+ provided, the SDK sends it as the `X-Tapi-Project` header and the server rejects
193
+ mismatches.
250
194
 
251
195
  ## Common Project Setup
252
196
 
@@ -262,12 +206,12 @@ src/
262
206
  // src/lib/tapi.ts
263
207
  import { TapiClient } from "@tapi-dev/sdk";
264
208
 
265
- export const tapi = new TapiClient({
266
- baseUrl: process.env.TAPI_BASE_URL!,
267
- apiKey: process.env.TAPI_API_KEY!,
268
- appId: process.env.TAPI_APP_ID,
269
- });
270
- ```
209
+ export const tapi = new TapiClient({
210
+ baseUrl: process.env.TAPI_BASE_URL!,
211
+ apiKey: process.env.TAPI_API_KEY!,
212
+ projectId: process.env.TAPI_PROJECT_ID!,
213
+ });
214
+ ```
271
215
 
272
216
  Application code should import this shared client instead of constructing a new client in every file.
273
217
 
package/dist/catalog.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import type { HttpClient } from "./client";
2
- import type { SdkCatalog } from "./types";
1
+ import type { HttpClient } from "./client.js";
2
+ import type { SdkCatalog } from "./types.js";
3
3
  export declare class CatalogResource {
4
4
  private readonly http;
5
5
  constructor(http: HttpClient);
package/dist/cli.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { type TapiWorkspace } from "./workspace.js";
2
3
  export type StudioChannel = "pilot" | "stable" | "nightly";
3
4
  export interface StudioReleaseManifest {
4
5
  product?: string;
@@ -15,13 +16,38 @@ export interface StudioReleaseManifest {
15
16
  commitShort?: string;
16
17
  ref?: string;
17
18
  installerKind?: string;
19
+ serverExecutable?: string;
18
20
  bundledService?: {
19
21
  product?: string;
20
22
  version?: string;
21
23
  source?: string;
22
24
  manifestUrl?: string;
25
+ mobileChrome?: {
26
+ source?: string;
27
+ executable?: string;
28
+ };
23
29
  };
24
30
  }
31
+ export interface ServiceReleaseManifest {
32
+ product?: string;
33
+ version: string;
34
+ channel: string;
35
+ platform: string;
36
+ artifactName: string;
37
+ url: string;
38
+ sha256: string;
39
+ sizeBytes?: number;
40
+ serviceHostExecutable?: string;
41
+ workerExecutable?: string;
42
+ installer?: string;
43
+ uninstaller?: string;
44
+ builtAt?: string;
45
+ commit?: string;
46
+ commitShort?: string;
47
+ ref?: string;
48
+ mobileChrome?: Record<string, unknown>;
49
+ contents?: string[];
50
+ }
25
51
  interface StudioCliOptions {
26
52
  channel: StudioChannel;
27
53
  apiBaseUrl: string;
@@ -32,10 +58,16 @@ interface StudioCliOptions {
32
58
  silent: boolean;
33
59
  exePath?: string;
34
60
  installToken?: string;
61
+ workspace?: TapiWorkspace;
62
+ workspaceRoot?: string;
63
+ projectId?: string;
64
+ projectSlug?: string;
65
+ workspaceMode: boolean;
35
66
  }
36
67
  export declare function runCli(argv?: string[]): Promise<number>;
37
68
  export declare function parseStudioOptions(args: string[]): StudioCliOptions;
38
69
  export declare function getDefaultStudioCacheDir(): string;
70
+ export declare function getDefaultServiceCacheDir(): string;
39
71
  export declare class CliWideEvent {
40
72
  private readonly filePath;
41
73
  private readonly startedAt;
@@ -51,5 +83,6 @@ export declare function createCliWideEvent(eventName: string, initialFields?: Re
51
83
  export declare function getCliWideEventRoot(): string;
52
84
  export declare function getStudioExecutableCandidates(): string[];
53
85
  export declare function validateStudioManifest(input: unknown): StudioReleaseManifest;
86
+ export declare function validateServiceReleaseManifest(input: unknown): ServiceReleaseManifest;
54
87
  export declare function compareVersions(left: string, right: string): number;
55
88
  export {};