@layr-labs/ecloud-sdk 0.1.1-dev → 0.2.0-dev
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/VERSION +2 -2
- package/dist/billing.cjs +0 -19
- package/dist/billing.cjs.map +1 -1
- package/dist/billing.d.cts +1 -2
- package/dist/billing.d.ts +1 -2
- package/dist/billing.js +2 -2
- package/dist/{chunk-AXSYVG7H.js → chunk-34DXGQ35.js} +106 -30
- package/dist/chunk-34DXGQ35.js.map +1 -0
- package/dist/{chunk-X4Y6OOUS.js → chunk-HLH3AMQF.js} +227 -2
- package/dist/chunk-HLH3AMQF.js.map +1 -0
- package/dist/chunk-LINGJMAS.js +180 -0
- package/dist/chunk-LINGJMAS.js.map +1 -0
- package/dist/compute.cjs +79 -1
- package/dist/compute.cjs.map +1 -1
- package/dist/compute.js +2 -2
- package/dist/index.cjs +782 -101
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +303 -86
- package/dist/index.d.ts +303 -86
- package/dist/index.js +616 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-2R7M3OXI.js +0 -434
- package/dist/chunk-2R7M3OXI.js.map +0 -1
- package/dist/chunk-AXSYVG7H.js.map +0 -1
- package/dist/chunk-X4Y6OOUS.js.map +0 -1
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addHexPrefix,
|
|
3
|
+
calculateBillingAuthSignature,
|
|
4
|
+
getBillingEnvironmentConfig,
|
|
5
|
+
getBuildType,
|
|
6
|
+
getLogger,
|
|
7
|
+
isSubscriptionActive,
|
|
8
|
+
withSDKTelemetry
|
|
9
|
+
} from "./chunk-34DXGQ35.js";
|
|
10
|
+
|
|
11
|
+
// src/client/common/utils/billingapi.ts
|
|
12
|
+
import axios from "axios";
|
|
13
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
14
|
+
var BillingApiClient = class {
|
|
15
|
+
constructor(config, privateKey) {
|
|
16
|
+
this.account = privateKeyToAccount(privateKey);
|
|
17
|
+
this.config = config;
|
|
18
|
+
}
|
|
19
|
+
async createSubscription(productId = "compute") {
|
|
20
|
+
const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;
|
|
21
|
+
const resp = await this.makeAuthenticatedRequest(endpoint, "POST", productId);
|
|
22
|
+
return resp.json();
|
|
23
|
+
}
|
|
24
|
+
async getSubscription(productId = "compute") {
|
|
25
|
+
const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;
|
|
26
|
+
const resp = await this.makeAuthenticatedRequest(endpoint, "GET", productId);
|
|
27
|
+
return resp.json();
|
|
28
|
+
}
|
|
29
|
+
async cancelSubscription(productId = "compute") {
|
|
30
|
+
const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;
|
|
31
|
+
await this.makeAuthenticatedRequest(endpoint, "DELETE", productId);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Make an authenticated request to the billing API
|
|
35
|
+
*/
|
|
36
|
+
async makeAuthenticatedRequest(url, method, productId) {
|
|
37
|
+
const expiry = BigInt(Math.floor(Date.now() / 1e3) + 5 * 60);
|
|
38
|
+
const { signature } = await calculateBillingAuthSignature({
|
|
39
|
+
account: this.account,
|
|
40
|
+
product: productId,
|
|
41
|
+
expiry
|
|
42
|
+
});
|
|
43
|
+
const headers = {
|
|
44
|
+
Authorization: `Bearer ${signature}`,
|
|
45
|
+
"X-Account": this.account.address,
|
|
46
|
+
"X-Expiry": expiry.toString()
|
|
47
|
+
};
|
|
48
|
+
try {
|
|
49
|
+
const response = await axios({
|
|
50
|
+
method,
|
|
51
|
+
url,
|
|
52
|
+
headers,
|
|
53
|
+
timeout: 3e4,
|
|
54
|
+
maxRedirects: 0,
|
|
55
|
+
validateStatus: () => true
|
|
56
|
+
// Don't throw on any status
|
|
57
|
+
});
|
|
58
|
+
const status = response.status;
|
|
59
|
+
const statusText = status >= 200 && status < 300 ? "OK" : "Error";
|
|
60
|
+
if (status < 200 || status >= 300) {
|
|
61
|
+
const body = typeof response.data === "string" ? response.data : JSON.stringify(response.data);
|
|
62
|
+
throw new Error(`BillingAPI request failed: ${status} ${statusText} - ${body}`);
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
json: async () => response.data,
|
|
66
|
+
text: async () => typeof response.data === "string" ? response.data : JSON.stringify(response.data)
|
|
67
|
+
};
|
|
68
|
+
} catch (error) {
|
|
69
|
+
if (error.message?.includes("fetch failed") || error.message?.includes("ECONNREFUSED") || error.message?.includes("ENOTFOUND") || error.cause) {
|
|
70
|
+
const cause = error.cause?.message || error.cause || error.message;
|
|
71
|
+
throw new Error(
|
|
72
|
+
`Failed to connect to BillingAPI at ${url}: ${cause}
|
|
73
|
+
Please check:
|
|
74
|
+
1. Your internet connection
|
|
75
|
+
2. The API server is accessible: ${this.config.billingApiServerURL}
|
|
76
|
+
3. Firewall/proxy settings`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
// src/client/modules/billing/index.ts
|
|
85
|
+
function createBillingModule(config) {
|
|
86
|
+
const { verbose = false, skipTelemetry = false } = config;
|
|
87
|
+
const privateKey = addHexPrefix(config.privateKey);
|
|
88
|
+
const logger = getLogger(verbose);
|
|
89
|
+
const billingEnvConfig = getBillingEnvironmentConfig(getBuildType());
|
|
90
|
+
const billingApi = new BillingApiClient(billingEnvConfig, privateKey);
|
|
91
|
+
return {
|
|
92
|
+
async subscribe(opts) {
|
|
93
|
+
return withSDKTelemetry(
|
|
94
|
+
{
|
|
95
|
+
functionName: "subscribe",
|
|
96
|
+
skipTelemetry,
|
|
97
|
+
// Skip if called from CLI
|
|
98
|
+
properties: { productId: opts?.productId || "compute" }
|
|
99
|
+
},
|
|
100
|
+
async () => {
|
|
101
|
+
const productId = opts?.productId || "compute";
|
|
102
|
+
logger.debug(`Checking existing subscription for ${productId}...`);
|
|
103
|
+
const currentStatus = await billingApi.getSubscription(productId);
|
|
104
|
+
if (isSubscriptionActive(currentStatus.subscriptionStatus)) {
|
|
105
|
+
logger.debug(`Subscription already active: ${currentStatus.subscriptionStatus}`);
|
|
106
|
+
return {
|
|
107
|
+
type: "already_active",
|
|
108
|
+
status: currentStatus.subscriptionStatus
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if (currentStatus.subscriptionStatus === "past_due" || currentStatus.subscriptionStatus === "unpaid") {
|
|
112
|
+
logger.debug(`Subscription has payment issue: ${currentStatus.subscriptionStatus}`);
|
|
113
|
+
return {
|
|
114
|
+
type: "payment_issue",
|
|
115
|
+
status: currentStatus.subscriptionStatus,
|
|
116
|
+
portalUrl: currentStatus.portalUrl
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
logger.debug(`Creating subscription for ${productId}...`);
|
|
120
|
+
const result = await billingApi.createSubscription(productId);
|
|
121
|
+
logger.debug(`Checkout URL: ${result.checkoutUrl}`);
|
|
122
|
+
return {
|
|
123
|
+
type: "checkout_created",
|
|
124
|
+
checkoutUrl: result.checkoutUrl
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
|
+
},
|
|
129
|
+
async getStatus(opts) {
|
|
130
|
+
return withSDKTelemetry(
|
|
131
|
+
{
|
|
132
|
+
functionName: "getStatus",
|
|
133
|
+
skipTelemetry,
|
|
134
|
+
// Skip if called from CLI
|
|
135
|
+
properties: { productId: opts?.productId || "compute" }
|
|
136
|
+
},
|
|
137
|
+
async () => {
|
|
138
|
+
const productId = opts?.productId || "compute";
|
|
139
|
+
logger.debug(`Fetching subscription status for ${productId}...`);
|
|
140
|
+
const result = await billingApi.getSubscription(productId);
|
|
141
|
+
logger.debug(`Subscription status: ${result.subscriptionStatus}`);
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
},
|
|
146
|
+
async cancel(opts) {
|
|
147
|
+
return withSDKTelemetry(
|
|
148
|
+
{
|
|
149
|
+
functionName: "cancel",
|
|
150
|
+
skipTelemetry,
|
|
151
|
+
// Skip if called from CLI
|
|
152
|
+
properties: { productId: opts?.productId || "compute" }
|
|
153
|
+
},
|
|
154
|
+
async () => {
|
|
155
|
+
const productId = opts?.productId || "compute";
|
|
156
|
+
logger.debug(`Checking subscription status for ${productId}...`);
|
|
157
|
+
const currentStatus = await billingApi.getSubscription(productId);
|
|
158
|
+
if (!isSubscriptionActive(currentStatus.subscriptionStatus)) {
|
|
159
|
+
logger.debug(`No active subscription to cancel: ${currentStatus.subscriptionStatus}`);
|
|
160
|
+
return {
|
|
161
|
+
type: "no_active_subscription",
|
|
162
|
+
status: currentStatus.subscriptionStatus
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
logger.debug(`Canceling subscription for ${productId}...`);
|
|
166
|
+
await billingApi.cancelSubscription(productId);
|
|
167
|
+
logger.debug(`Subscription canceled successfully`);
|
|
168
|
+
return {
|
|
169
|
+
type: "canceled"
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export {
|
|
178
|
+
createBillingModule
|
|
179
|
+
};
|
|
180
|
+
//# sourceMappingURL=chunk-LINGJMAS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/common/utils/billingapi.ts","../src/client/modules/billing/index.ts"],"sourcesContent":["/**\n * BillingAPI Client to manage product subscriptions\n * Standalone client - does not depend on chain infrastructure\n */\n\nimport axios, { AxiosResponse } from \"axios\";\nimport { Hex } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { ProductID, CreateSubscriptionResponse, ProductSubscriptionResponse } from \"../types\";\nimport { calculateBillingAuthSignature } from \"./auth\";\nimport { BillingEnvironmentConfig } from \"../types\";\n\nexport class BillingApiClient {\n private readonly account: ReturnType<typeof privateKeyToAccount>;\n private readonly config: BillingEnvironmentConfig;\n\n constructor(config: BillingEnvironmentConfig, privateKey: Hex) {\n this.account = privateKeyToAccount(privateKey);\n this.config = config;\n }\n\n async createSubscription(productId: ProductID = \"compute\"): Promise<CreateSubscriptionResponse> {\n const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;\n const resp = await this.makeAuthenticatedRequest(endpoint, \"POST\", productId);\n return resp.json();\n }\n\n async getSubscription(productId: ProductID = \"compute\"): Promise<ProductSubscriptionResponse> {\n const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;\n const resp = await this.makeAuthenticatedRequest(endpoint, \"GET\", productId);\n return resp.json();\n }\n\n async cancelSubscription(productId: ProductID = \"compute\"): Promise<void> {\n const endpoint = `${this.config.billingApiServerURL}/products/${productId}/subscription`;\n await this.makeAuthenticatedRequest(endpoint, \"DELETE\", productId);\n }\n\n /**\n * Make an authenticated request to the billing API\n */\n private async makeAuthenticatedRequest(\n url: string,\n method: \"GET\" | \"POST\" | \"DELETE\",\n productId: ProductID,\n ): Promise<{ json: () => Promise<any>; text: () => Promise<string> }> {\n // Calculate expiry (5 minutes from now)\n const expiry = BigInt(Math.floor(Date.now() / 1000) + 5 * 60);\n\n // Use EIP-712 typed data signature for billing auth\n const { signature } = await calculateBillingAuthSignature({\n account: this.account,\n product: productId,\n expiry,\n });\n\n // Prepare headers\n const headers: Record<string, string> = {\n Authorization: `Bearer ${signature}`,\n \"X-Account\": this.account.address,\n \"X-Expiry\": expiry.toString(),\n };\n\n try {\n // Use axios to make the request\n const response: AxiosResponse = await axios({\n method,\n url,\n headers,\n timeout: 30_000,\n maxRedirects: 0,\n validateStatus: () => true, // Don't throw on any status\n });\n\n const status = response.status;\n const statusText = status >= 200 && status < 300 ? \"OK\" : \"Error\";\n\n if (status < 200 || status >= 300) {\n const body =\n typeof response.data === \"string\" ? response.data : JSON.stringify(response.data);\n throw new Error(`BillingAPI request failed: ${status} ${statusText} - ${body}`);\n }\n\n // Return Response-like object for compatibility\n return {\n json: async () => response.data,\n text: async () =>\n typeof response.data === \"string\" ? response.data : JSON.stringify(response.data),\n };\n } catch (error: any) {\n // Handle network errors\n if (\n error.message?.includes(\"fetch failed\") ||\n error.message?.includes(\"ECONNREFUSED\") ||\n error.message?.includes(\"ENOTFOUND\") ||\n error.cause\n ) {\n const cause = error.cause?.message || error.cause || error.message;\n throw new Error(\n `Failed to connect to BillingAPI at ${url}: ${cause}\\n` +\n `Please check:\\n` +\n `1. Your internet connection\\n` +\n `2. The API server is accessible: ${this.config.billingApiServerURL}\\n` +\n `3. Firewall/proxy settings`,\n );\n }\n // Re-throw other errors as-is\n throw error;\n }\n }\n}\n","/**\n * Main Billing namespace entry point\n */\n\nimport { BillingApiClient } from \"../../common/utils/billingapi\";\nimport { getBillingEnvironmentConfig, getBuildType } from \"../../common/config/environment\";\nimport { getLogger, isSubscriptionActive, addHexPrefix } from \"../../common/utils\";\nimport { withSDKTelemetry } from \"../../common/telemetry/wrapper\";\n\nimport type { Hex } from \"viem\";\nimport type {\n ProductID,\n SubscriptionOpts,\n SubscribeResponse,\n CancelResponse,\n ProductSubscriptionResponse,\n} from \"../../common/types\";\n\nexport interface BillingModule {\n subscribe: (opts?: SubscriptionOpts) => Promise<SubscribeResponse>;\n getStatus: (opts?: SubscriptionOpts) => Promise<ProductSubscriptionResponse>;\n cancel: (opts?: SubscriptionOpts) => Promise<CancelResponse>;\n}\n\nexport interface BillingModuleConfig {\n verbose?: boolean;\n privateKey: Hex;\n skipTelemetry?: boolean; // Skip telemetry when called from CLI\n}\n\nexport function createBillingModule(config: BillingModuleConfig): BillingModule {\n const { verbose = false, skipTelemetry = false } = config;\n const privateKey = addHexPrefix(config.privateKey);\n\n const logger = getLogger(verbose);\n\n // Get billing environment configuration\n const billingEnvConfig = getBillingEnvironmentConfig(getBuildType());\n\n // Create billing API client\n const billingApi = new BillingApiClient(billingEnvConfig, privateKey);\n\n return {\n async subscribe(opts) {\n return withSDKTelemetry(\n {\n functionName: \"subscribe\",\n skipTelemetry: skipTelemetry, // Skip if called from CLI\n properties: { productId: opts?.productId || \"compute\" },\n },\n async () => {\n const productId: ProductID = opts?.productId || \"compute\";\n\n // Check existing subscription status first\n logger.debug(`Checking existing subscription for ${productId}...`);\n const currentStatus = await billingApi.getSubscription(productId);\n\n // If already active or trialing, don't create new checkout\n if (isSubscriptionActive(currentStatus.subscriptionStatus)) {\n logger.debug(`Subscription already active: ${currentStatus.subscriptionStatus}`);\n return {\n type: \"already_active\" as const,\n status: currentStatus.subscriptionStatus,\n };\n }\n\n // If subscription has payment issues, return portal URL instead\n if (\n currentStatus.subscriptionStatus === \"past_due\" ||\n currentStatus.subscriptionStatus === \"unpaid\"\n ) {\n logger.debug(`Subscription has payment issue: ${currentStatus.subscriptionStatus}`);\n return {\n type: \"payment_issue\" as const,\n status: currentStatus.subscriptionStatus,\n portalUrl: currentStatus.portalUrl,\n };\n }\n\n // Create new checkout session\n logger.debug(`Creating subscription for ${productId}...`);\n const result = await billingApi.createSubscription(productId);\n\n logger.debug(`Checkout URL: ${result.checkoutUrl}`);\n return {\n type: \"checkout_created\" as const,\n checkoutUrl: result.checkoutUrl,\n };\n },\n );\n },\n\n async getStatus(opts) {\n return withSDKTelemetry(\n {\n functionName: \"getStatus\",\n skipTelemetry: skipTelemetry, // Skip if called from CLI\n properties: { productId: opts?.productId || \"compute\" },\n },\n async () => {\n const productId: ProductID = opts?.productId || \"compute\";\n logger.debug(`Fetching subscription status for ${productId}...`);\n\n const result = await billingApi.getSubscription(productId);\n\n logger.debug(`Subscription status: ${result.subscriptionStatus}`);\n return result;\n },\n );\n },\n\n async cancel(opts) {\n return withSDKTelemetry(\n {\n functionName: \"cancel\",\n skipTelemetry: skipTelemetry, // Skip if called from CLI\n properties: { productId: opts?.productId || \"compute\" },\n },\n async () => {\n const productId: ProductID = opts?.productId || \"compute\";\n\n // Check existing subscription status first\n logger.debug(`Checking subscription status for ${productId}...`);\n const currentStatus = await billingApi.getSubscription(productId);\n\n // If no active subscription, don't attempt to cancel\n if (!isSubscriptionActive(currentStatus.subscriptionStatus)) {\n logger.debug(`No active subscription to cancel: ${currentStatus.subscriptionStatus}`);\n return {\n type: \"no_active_subscription\" as const,\n status: currentStatus.subscriptionStatus,\n };\n }\n\n // Cancel the subscription\n logger.debug(`Canceling subscription for ${productId}...`);\n await billingApi.cancelSubscription(productId);\n\n logger.debug(`Subscription canceled successfully`);\n return {\n type: \"canceled\" as const,\n };\n },\n );\n },\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/compute.cjs
CHANGED
|
@@ -2385,12 +2385,23 @@ function stripHexPrefix(value) {
|
|
|
2385
2385
|
}
|
|
2386
2386
|
|
|
2387
2387
|
// src/client/common/utils/userapi.ts
|
|
2388
|
+
function isJsonObject(value) {
|
|
2389
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2390
|
+
}
|
|
2391
|
+
function readString(obj, key) {
|
|
2392
|
+
const v = obj[key];
|
|
2393
|
+
return typeof v === "string" ? v : void 0;
|
|
2394
|
+
}
|
|
2395
|
+
function readNumber(obj, key) {
|
|
2396
|
+
const v = obj[key];
|
|
2397
|
+
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
2398
|
+
}
|
|
2388
2399
|
var MAX_ADDRESS_COUNT = 5;
|
|
2389
2400
|
var CanViewAppLogsPermission = "0x2fd3f2fe";
|
|
2390
2401
|
var CanViewSensitiveAppInfoPermission = "0x0e67b22f";
|
|
2391
2402
|
var CanUpdateAppProfilePermission = "0x036fef61";
|
|
2392
2403
|
function getDefaultClientId() {
|
|
2393
|
-
const version = true ? "0.
|
|
2404
|
+
const version = true ? "0.2.0-dev" : "0.0.0";
|
|
2394
2405
|
return `ecloud-sdk/v${version}`;
|
|
2395
2406
|
}
|
|
2396
2407
|
var UserApiClient = class {
|
|
@@ -2424,6 +2435,31 @@ var UserApiClient = class {
|
|
|
2424
2435
|
};
|
|
2425
2436
|
});
|
|
2426
2437
|
}
|
|
2438
|
+
/**
|
|
2439
|
+
* Get app details from UserAPI (includes releases and build/provenance info when available).
|
|
2440
|
+
*
|
|
2441
|
+
* Endpoint: GET /apps/:appAddress
|
|
2442
|
+
*/
|
|
2443
|
+
async getApp(appAddress) {
|
|
2444
|
+
const endpoint = `${this.config.userApiServerURL}/apps/${appAddress}`;
|
|
2445
|
+
const res = await this.makeAuthenticatedRequest(endpoint);
|
|
2446
|
+
const raw = await res.json();
|
|
2447
|
+
if (!isJsonObject(raw)) {
|
|
2448
|
+
throw new Error("Unexpected /apps/:id response: expected object");
|
|
2449
|
+
}
|
|
2450
|
+
const id = readString(raw, "id");
|
|
2451
|
+
if (!id) {
|
|
2452
|
+
throw new Error("Unexpected /apps/:id response: missing 'id'");
|
|
2453
|
+
}
|
|
2454
|
+
const releasesRaw = raw.releases;
|
|
2455
|
+
const releases = Array.isArray(releasesRaw) ? releasesRaw.map((r) => transformAppRelease(r)).filter((r) => !!r) : [];
|
|
2456
|
+
return {
|
|
2457
|
+
id,
|
|
2458
|
+
creator: readString(raw, "creator"),
|
|
2459
|
+
contractStatus: readString(raw, "contract_status") ?? readString(raw, "contractStatus"),
|
|
2460
|
+
releases
|
|
2461
|
+
};
|
|
2462
|
+
}
|
|
2427
2463
|
/**
|
|
2428
2464
|
* Get available SKUs (instance types) from UserAPI
|
|
2429
2465
|
*/
|
|
@@ -2596,6 +2632,48 @@ Please check:
|
|
|
2596
2632
|
};
|
|
2597
2633
|
}
|
|
2598
2634
|
};
|
|
2635
|
+
function transformAppReleaseBuild(raw) {
|
|
2636
|
+
if (!isJsonObject(raw)) return void 0;
|
|
2637
|
+
const depsRaw = raw.dependencies;
|
|
2638
|
+
const deps = isJsonObject(depsRaw) ? Object.fromEntries(
|
|
2639
|
+
Object.entries(depsRaw).flatMap(([digest, depRaw]) => {
|
|
2640
|
+
const parsed = transformAppReleaseBuild(depRaw);
|
|
2641
|
+
return parsed ? [[digest, parsed]] : [];
|
|
2642
|
+
})
|
|
2643
|
+
) : void 0;
|
|
2644
|
+
return {
|
|
2645
|
+
buildId: readString(raw, "build_id") ?? readString(raw, "buildId"),
|
|
2646
|
+
billingAddress: readString(raw, "billing_address") ?? readString(raw, "billingAddress"),
|
|
2647
|
+
repoUrl: readString(raw, "repo_url") ?? readString(raw, "repoUrl"),
|
|
2648
|
+
gitRef: readString(raw, "git_ref") ?? readString(raw, "gitRef"),
|
|
2649
|
+
status: readString(raw, "status"),
|
|
2650
|
+
buildType: readString(raw, "build_type") ?? readString(raw, "buildType"),
|
|
2651
|
+
imageName: readString(raw, "image_name") ?? readString(raw, "imageName"),
|
|
2652
|
+
imageDigest: readString(raw, "image_digest") ?? readString(raw, "imageDigest"),
|
|
2653
|
+
imageUrl: readString(raw, "image_url") ?? readString(raw, "imageUrl"),
|
|
2654
|
+
provenanceJson: raw.provenance_json ?? raw.provenanceJson,
|
|
2655
|
+
provenanceSignature: readString(raw, "provenance_signature") ?? readString(raw, "provenanceSignature"),
|
|
2656
|
+
createdAt: readString(raw, "created_at") ?? readString(raw, "createdAt"),
|
|
2657
|
+
updatedAt: readString(raw, "updated_at") ?? readString(raw, "updatedAt"),
|
|
2658
|
+
errorMessage: readString(raw, "error_message") ?? readString(raw, "errorMessage"),
|
|
2659
|
+
dependencies: deps
|
|
2660
|
+
};
|
|
2661
|
+
}
|
|
2662
|
+
function transformAppRelease(raw) {
|
|
2663
|
+
if (!isJsonObject(raw)) return void 0;
|
|
2664
|
+
return {
|
|
2665
|
+
appId: readString(raw, "appId") ?? readString(raw, "app_id"),
|
|
2666
|
+
rmsReleaseId: readString(raw, "rmsReleaseId") ?? readString(raw, "rms_release_id"),
|
|
2667
|
+
imageDigest: readString(raw, "imageDigest") ?? readString(raw, "image_digest"),
|
|
2668
|
+
registryUrl: readString(raw, "registryUrl") ?? readString(raw, "registry_url"),
|
|
2669
|
+
publicEnv: readString(raw, "publicEnv") ?? readString(raw, "public_env"),
|
|
2670
|
+
encryptedEnv: readString(raw, "encryptedEnv") ?? readString(raw, "encrypted_env"),
|
|
2671
|
+
upgradeByTime: readNumber(raw, "upgradeByTime") ?? readNumber(raw, "upgrade_by_time"),
|
|
2672
|
+
createdAt: readString(raw, "createdAt") ?? readString(raw, "created_at"),
|
|
2673
|
+
createdAtBlock: readString(raw, "createdAtBlock") ?? readString(raw, "created_at_block"),
|
|
2674
|
+
build: raw.build ? transformAppReleaseBuild(raw.build) : void 0
|
|
2675
|
+
};
|
|
2676
|
+
}
|
|
2599
2677
|
|
|
2600
2678
|
// src/client/common/abis/AppController.json
|
|
2601
2679
|
var AppController_default = [
|