@tapi-dev/sdk 0.1.30 → 0.1.31
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/cli.d.ts +2 -1
- package/dist/cli.js +47 -15
- package/package.json +1 -1
package/dist/cli.d.ts
CHANGED
|
@@ -60,6 +60,7 @@ export interface StudioCliOptions {
|
|
|
60
60
|
silent: boolean;
|
|
61
61
|
exePath?: string;
|
|
62
62
|
installToken?: string;
|
|
63
|
+
installTokenSource?: "option" | "env" | "minted";
|
|
63
64
|
workspace?: TapiWorkspace;
|
|
64
65
|
workspaceRoot?: string;
|
|
65
66
|
projectId?: string;
|
|
@@ -113,7 +114,7 @@ export declare function getStudioExecutableCandidates(): string[];
|
|
|
113
114
|
export declare function validateStudioManifest(input: unknown): StudioReleaseManifest;
|
|
114
115
|
export declare function validateServiceReleaseManifest(input: unknown): ServiceReleaseManifest;
|
|
115
116
|
export declare function compareVersions(left: string, right: string): number;
|
|
116
|
-
export declare function memoizeStudioInstallToken(options: StudioCliOptions, installToken?: string): string;
|
|
117
|
+
export declare function memoizeStudioInstallToken(options: StudioCliOptions, installToken?: string, source?: StudioCliOptions["installTokenSource"]): string;
|
|
117
118
|
export declare function closeExistingPortableStudioServersForFreshLaunch(stopProcesses?: () => Promise<number>): Promise<{
|
|
118
119
|
stopped: number;
|
|
119
120
|
recordsRemoved: number;
|
package/dist/cli.js
CHANGED
|
@@ -344,6 +344,8 @@ export function parseStudioOptions(args) {
|
|
|
344
344
|
: `${downloadsBaseUrl.replace(/\/+$/, "")}/studio/channels/${channel}/latest.json`;
|
|
345
345
|
const projectId = raw.projectId ?? envString("TAPI_PROJECT_ID") ?? workspace?.projectId;
|
|
346
346
|
const projectSlug = raw.projectSlug ?? envString("TAPI_PROJECT_SLUG") ?? workspace?.projectSlug;
|
|
347
|
+
const envInstallToken = envString("TAPI_STUDIO_INSTALL_TOKEN");
|
|
348
|
+
const installToken = raw.installToken ?? envInstallToken;
|
|
347
349
|
return {
|
|
348
350
|
channel,
|
|
349
351
|
apiBaseUrl,
|
|
@@ -354,7 +356,8 @@ export function parseStudioOptions(args) {
|
|
|
354
356
|
downloadOnly: raw.downloadOnly ?? false,
|
|
355
357
|
silent: raw.silent ?? false,
|
|
356
358
|
exePath: raw.exePath ?? envString("TAPI_STUDIO_EXE"),
|
|
357
|
-
installToken
|
|
359
|
+
installToken,
|
|
360
|
+
installTokenSource: raw.installToken ? "option" : installToken ? "env" : undefined,
|
|
358
361
|
workspace,
|
|
359
362
|
workspaceRoot: workspace?.root,
|
|
360
363
|
projectId,
|
|
@@ -1967,12 +1970,7 @@ async function installStudio(options) {
|
|
|
1967
1970
|
throw new Error("Direct Studio manifest overrides are no longer supported for install. "
|
|
1968
1971
|
+ "Use --channel with the protected install flow instead.");
|
|
1969
1972
|
}
|
|
1970
|
-
const
|
|
1971
|
-
await event.phase("manifest.fetch.start", {
|
|
1972
|
-
apiBaseUrl: options.apiBaseUrl,
|
|
1973
|
-
channel: options.channel,
|
|
1974
|
-
});
|
|
1975
|
-
const manifest = await withCliSpinner(`Fetching Tapi Studio ${options.channel} manifest`, () => fetchProtectedStudioManifest(options.apiBaseUrl, options.channel, installToken));
|
|
1973
|
+
const manifest = await fetchStudioManifestForRun(options, event, "Checking Studio install authorization");
|
|
1976
1974
|
await event.phase("manifest.fetch.success", {
|
|
1977
1975
|
manifest: manifestEventSummary(manifest),
|
|
1978
1976
|
});
|
|
@@ -2086,7 +2084,7 @@ async function obtainStudioInstallToken(options, event) {
|
|
|
2086
2084
|
const issued = await requestStudioInstallToken(options.apiBaseUrl, options.channel, firebaseCreds.idToken);
|
|
2087
2085
|
return issued.installToken;
|
|
2088
2086
|
}
|
|
2089
|
-
export function memoizeStudioInstallToken(options, installToken) {
|
|
2087
|
+
export function memoizeStudioInstallToken(options, installToken, source = "minted") {
|
|
2090
2088
|
const existing = options.installToken?.trim();
|
|
2091
2089
|
if (existing) {
|
|
2092
2090
|
options.installToken = existing;
|
|
@@ -2095,9 +2093,14 @@ export function memoizeStudioInstallToken(options, installToken) {
|
|
|
2095
2093
|
const normalized = installToken?.trim() ?? "";
|
|
2096
2094
|
if (normalized) {
|
|
2097
2095
|
options.installToken = normalized;
|
|
2096
|
+
options.installTokenSource = source;
|
|
2098
2097
|
}
|
|
2099
2098
|
return normalized;
|
|
2100
2099
|
}
|
|
2100
|
+
function clearStudioInstallTokenForRun(options) {
|
|
2101
|
+
options.installToken = undefined;
|
|
2102
|
+
options.installTokenSource = undefined;
|
|
2103
|
+
}
|
|
2101
2104
|
async function ensureStudioInstallTokenForRun(options, event, message) {
|
|
2102
2105
|
const existing = memoizeStudioInstallToken(options);
|
|
2103
2106
|
if (existing) {
|
|
@@ -2111,7 +2114,7 @@ async function ensureStudioInstallTokenForRun(options, event, message) {
|
|
|
2111
2114
|
apiBaseUrl: options.apiBaseUrl,
|
|
2112
2115
|
channel: options.channel,
|
|
2113
2116
|
});
|
|
2114
|
-
const installToken = memoizeStudioInstallToken(options, await withCliSpinner(message, () => obtainStudioInstallToken(options, event)));
|
|
2117
|
+
const installToken = memoizeStudioInstallToken(options, await withCliSpinner(message, () => obtainStudioInstallToken(options, event)), "minted");
|
|
2115
2118
|
await event.phase("auth.install_token.request.success", {
|
|
2116
2119
|
apiBaseUrl: options.apiBaseUrl,
|
|
2117
2120
|
channel: options.channel,
|
|
@@ -2119,6 +2122,39 @@ async function ensureStudioInstallTokenForRun(options, event, message) {
|
|
|
2119
2122
|
});
|
|
2120
2123
|
return installToken;
|
|
2121
2124
|
}
|
|
2125
|
+
async function fetchStudioManifestForRun(options, event, authMessage) {
|
|
2126
|
+
const installToken = await ensureStudioInstallTokenForRun(options, event, authMessage);
|
|
2127
|
+
await event.phase("manifest.fetch.start", {
|
|
2128
|
+
apiBaseUrl: options.apiBaseUrl,
|
|
2129
|
+
channel: options.channel,
|
|
2130
|
+
});
|
|
2131
|
+
try {
|
|
2132
|
+
return await withCliSpinner(`Fetching Tapi Studio ${options.channel} manifest`, () => fetchProtectedStudioManifest(options.apiBaseUrl, options.channel, installToken));
|
|
2133
|
+
}
|
|
2134
|
+
catch (error) {
|
|
2135
|
+
if (!isExpiredStudioInstallTokenError(error) || options.installTokenSource === "option") {
|
|
2136
|
+
throw error;
|
|
2137
|
+
}
|
|
2138
|
+
await event.phase("auth.install_token.expired", {
|
|
2139
|
+
apiBaseUrl: options.apiBaseUrl,
|
|
2140
|
+
channel: options.channel,
|
|
2141
|
+
tokenSource: options.installTokenSource ?? "unknown",
|
|
2142
|
+
error: errorDetails(error),
|
|
2143
|
+
});
|
|
2144
|
+
clearStudioInstallTokenForRun(options);
|
|
2145
|
+
const refreshedToken = await ensureStudioInstallTokenForRun(options, event, "Refreshing Studio install authorization");
|
|
2146
|
+
await event.phase("manifest.fetch.retry.start", {
|
|
2147
|
+
apiBaseUrl: options.apiBaseUrl,
|
|
2148
|
+
channel: options.channel,
|
|
2149
|
+
});
|
|
2150
|
+
return await withCliSpinner(`Retrying Tapi Studio ${options.channel} manifest`, () => fetchProtectedStudioManifest(options.apiBaseUrl, options.channel, refreshedToken));
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
function isExpiredStudioInstallTokenError(error) {
|
|
2154
|
+
const message = formatError(error);
|
|
2155
|
+
return (message.includes("Failed to fetch protected Studio manifest: HTTP 401")
|
|
2156
|
+
&& message.includes("Studio install token has expired"));
|
|
2157
|
+
}
|
|
2122
2158
|
async function openStudio(options) {
|
|
2123
2159
|
ensureWindowsHost();
|
|
2124
2160
|
if (options.downloadOnly) {
|
|
@@ -2180,12 +2216,7 @@ async function ensurePortableStudioServer(options) {
|
|
|
2180
2216
|
options: installEventOptions(options),
|
|
2181
2217
|
});
|
|
2182
2218
|
try {
|
|
2183
|
-
const
|
|
2184
|
-
await event.phase("manifest.fetch.start", {
|
|
2185
|
-
apiBaseUrl: options.apiBaseUrl,
|
|
2186
|
-
channel: options.channel,
|
|
2187
|
-
});
|
|
2188
|
-
const manifest = await withCliSpinner(`Fetching Tapi Studio ${options.channel} manifest`, () => fetchProtectedStudioManifest(options.apiBaseUrl, options.channel, installToken));
|
|
2219
|
+
const manifest = await fetchStudioManifestForRun(options, event, "Checking Studio install authorization");
|
|
2189
2220
|
ensureCompatibleManifest(manifest);
|
|
2190
2221
|
await event.phase("manifest.fetch.success", {
|
|
2191
2222
|
manifest: manifestEventSummary(manifest),
|
|
@@ -3416,6 +3447,7 @@ function installEventOptions(options) {
|
|
|
3416
3447
|
silent: options.silent,
|
|
3417
3448
|
exePath: options.exePath,
|
|
3418
3449
|
installTokenProvided: Boolean(options.installToken),
|
|
3450
|
+
installTokenSource: options.installTokenSource,
|
|
3419
3451
|
};
|
|
3420
3452
|
}
|
|
3421
3453
|
function serviceManifestEventSummary(manifest) {
|