@tapi-dev/sdk 0.1.7 → 0.1.9

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,108 @@ 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
+ If the channel still publishes a legacy NSIS desktop Studio manifest and no
29
+ Studio executable is installed yet, `tapi studio` runs the installer first, then
30
+ opens Studio. The normal developer path is the portable server launched by the
31
+ CLI.
32
+
33
+ Useful commands:
93
34
 
94
- Tapi Studio desktop releases are currently published for Windows x64.
35
+ ```bash
36
+ npx tapi init --project brokerage
37
+ npx tapi link --project brokerage
38
+ npx tapi studio
39
+ npx tapi service install --channel pilot
40
+ npx tapi service status
41
+ npx tapi apis generate
42
+ npx tapi publish
43
+ ```
95
44
 
96
- Cloud Windows workers use a separate protected service runtime manifest:
45
+ Local authoring files live in the app repo:
97
46
 
98
47
  ```text
99
- GET /api/sdk/v1/service/releases/<channel>
48
+ .tapi/project.json
49
+ .tapi/sitemaps/<site>.json
50
+ .tapi/apis/<site>/<api>.json
51
+ .tapi/generated/catalog.json
52
+ src/tapi.generated.ts
100
53
  ```
101
54
 
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.
55
+ Drafts are local. `tapi publish` uploads local sitemaps and API contracts, marks
56
+ ready requests as published, and activates one immutable server release. Runtime
57
+ SDK calls read the active release catalog, not mutable Studio drafts.
58
+
59
+ ```bash
60
+ TAPI_API_KEY=tapi_project_key npx tapi publish
61
+ TAPI_API_KEY=tapi_project_key npx tapi apis generate
62
+ ```
63
+
64
+ ## Quick Start
65
+
66
+ Create one TAPI client in server-side app code. Use a project-scoped API key and
67
+ the same project id from `.tapi/project.json`.
68
+
69
+ ```ts
70
+ import { TapiClient } from "@tapi-dev/sdk";
71
+
72
+ export const tapi = new TapiClient({
73
+ baseUrl: process.env.TAPI_BASE_URL!,
74
+ apiKey: process.env.TAPI_API_KEY!,
75
+ projectId: process.env.TAPI_PROJECT_ID!,
76
+ });
77
+ ```
78
+
79
+ Generated website APIs are authored visually in Tapi Studio by setting workflow
80
+ bounds, selecting inputs/outputs, and publishing an API. The SDK sees the public
81
+ operation name:
82
+
83
+ ```text
84
+ <namespace>.<operation>
85
+ ```
86
+
87
+ ```ts
88
+ const operation = await tapi.websiteApis.describe("schwab.place_order");
89
+
90
+ const run = await tapi.websiteApis.run("schwab.place_order", {
91
+ inputs: {
92
+ symbol: "AAPL",
93
+ side: "buy",
94
+ quantity: 10,
95
+ orderType: "limit",
96
+ limitPrice: 190,
97
+ },
98
+ });
99
+
100
+ const completedRun = await tapi.runs.wait(run.id);
101
+ console.log(completedRun.status, completedRun.result);
102
+ ```
103
+
104
+ You can inspect the same input/output contract from the CLI:
105
+
106
+ ```bash
107
+ npx tapi apis describe schwab.place_order \
108
+ --api-base-url "$TAPI_BASE_URL" \
109
+ --api-key "$TAPI_API_KEY" \
110
+ --project "$TAPI_PROJECT_ID"
111
+ ```
112
+
113
+ Do not expose `TAPI_API_KEY` in public browser bundles. Put the SDK behind your
114
+ own backend route, server action, or job worker when using secret API keys.
171
115
 
172
116
  ## Runtime Profiles and Proxies
173
117
 
@@ -238,15 +182,17 @@ const tapi = new TapiClient({
238
182
  });
239
183
  ```
240
184
 
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.
185
+ ## Configuration
186
+
187
+ ```env
188
+ TAPI_BASE_URL=https://your-tapi-api-host
189
+ TAPI_API_KEY=tapi_project_key
190
+ TAPI_PROJECT_ID=brokerage
191
+ ```
192
+
193
+ `projectId` is optional only when the API key itself is project-scoped. If
194
+ provided, the SDK sends it as the `X-Tapi-Project` header and the server rejects
195
+ mismatches.
250
196
 
251
197
  ## Common Project Setup
252
198
 
@@ -262,12 +208,12 @@ src/
262
208
  // src/lib/tapi.ts
263
209
  import { TapiClient } from "@tapi-dev/sdk";
264
210
 
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
- ```
211
+ export const tapi = new TapiClient({
212
+ baseUrl: process.env.TAPI_BASE_URL!,
213
+ apiKey: process.env.TAPI_API_KEY!,
214
+ projectId: process.env.TAPI_PROJECT_ID!,
215
+ });
216
+ ```
271
217
 
272
218
  Application code should import this shared client instead of constructing a new client in every file.
273
219
 
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,6 +16,7 @@ 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;
@@ -26,6 +28,26 @@ export interface StudioReleaseManifest {
26
28
  };
27
29
  };
28
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
+ }
29
51
  interface StudioCliOptions {
30
52
  channel: StudioChannel;
31
53
  apiBaseUrl: string;
@@ -36,10 +58,16 @@ interface StudioCliOptions {
36
58
  silent: boolean;
37
59
  exePath?: string;
38
60
  installToken?: string;
61
+ workspace?: TapiWorkspace;
62
+ workspaceRoot?: string;
63
+ projectId?: string;
64
+ projectSlug?: string;
65
+ workspaceMode: boolean;
39
66
  }
40
67
  export declare function runCli(argv?: string[]): Promise<number>;
41
68
  export declare function parseStudioOptions(args: string[]): StudioCliOptions;
42
69
  export declare function getDefaultStudioCacheDir(): string;
70
+ export declare function getDefaultServiceCacheDir(): string;
43
71
  export declare class CliWideEvent {
44
72
  private readonly filePath;
45
73
  private readonly startedAt;
@@ -55,5 +83,6 @@ export declare function createCliWideEvent(eventName: string, initialFields?: Re
55
83
  export declare function getCliWideEventRoot(): string;
56
84
  export declare function getStudioExecutableCandidates(): string[];
57
85
  export declare function validateStudioManifest(input: unknown): StudioReleaseManifest;
86
+ export declare function validateServiceReleaseManifest(input: unknown): ServiceReleaseManifest;
58
87
  export declare function compareVersions(left: string, right: string): number;
59
88
  export {};