@layr-labs/ecloud-sdk 0.2.0-dev.1 → 0.2.0-dev.2

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.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  requirePrivateKey,
14
14
  storePrivateKey,
15
15
  validatePrivateKey
16
- } from "./chunk-GB4GM4C2.js";
16
+ } from "./chunk-2RORGPLX.js";
17
17
  import {
18
18
  PRIMARY_LANGUAGES,
19
19
  assertValidFilePath,
@@ -40,9 +40,7 @@ import {
40
40
  getTemplate,
41
41
  logs,
42
42
  prepareDeploy,
43
- prepareDeployFromVerifiableBuild,
44
43
  prepareUpgrade,
45
- prepareUpgradeFromVerifiableBuild,
46
44
  sanitizeString,
47
45
  sanitizeURL,
48
46
  sanitizeXURL,
@@ -64,7 +62,7 @@ import {
64
62
  validateXURL,
65
63
  watchDeployment,
66
64
  watchUpgrade
67
- } from "./chunk-O7EU5JL7.js";
65
+ } from "./chunk-4SKRNFKQ.js";
68
66
  import {
69
67
  NoopClient,
70
68
  PostHogClient,
@@ -72,7 +70,6 @@ import {
72
70
  addHexPrefix,
73
71
  addMetric,
74
72
  addMetricWithDimensions,
75
- calculateBillingAuthSignature,
76
73
  createAppEnvironment,
77
74
  createMetricsContext,
78
75
  createTelemetryClient,
@@ -80,370 +77,14 @@ import {
80
77
  getAvailableEnvironments,
81
78
  getBuildType,
82
79
  getEnvironmentConfig,
83
- getLogger,
84
80
  getPostHogAPIKey,
85
81
  getPostHogEndpoint,
86
82
  isEnvironmentAvailable,
87
83
  isMainnet,
88
84
  isNoopClient,
89
85
  isSubscriptionActive,
90
- stripHexPrefix,
91
86
  withSDKTelemetry
92
- } from "./chunk-FY7UU55U.js";
93
-
94
- // src/client/common/utils/buildapi.ts
95
- import axios from "axios";
96
- import { privateKeyToAccount } from "viem/accounts";
97
- var BuildApiClient = class {
98
- constructor(options) {
99
- this.baseUrl = options.baseUrl.replace(/\/+$/, "");
100
- this.clientId = options.clientId;
101
- if (options.privateKey) {
102
- this.account = privateKeyToAccount(options.privateKey);
103
- }
104
- }
105
- async submitBuild(payload) {
106
- return this.authenticatedJsonRequest("/builds", "POST", payload);
107
- }
108
- async getBuild(buildId) {
109
- return this.publicJsonRequest(`/builds/${encodeURIComponent(buildId)}`);
110
- }
111
- async getBuildByDigest(digest) {
112
- return this.publicJsonRequest(`/builds/image/${encodeURIComponent(digest)}`);
113
- }
114
- async verify(identifier) {
115
- return this.publicJsonRequest(`/builds/verify/${encodeURIComponent(identifier)}`);
116
- }
117
- async getLogs(buildId) {
118
- return this.authenticatedTextRequest(`/builds/${encodeURIComponent(buildId)}/logs`);
119
- }
120
- async listBuilds(params) {
121
- const res = await axios({
122
- url: `${this.baseUrl}/builds`,
123
- method: "GET",
124
- params,
125
- headers: this.clientId ? { "x-client-id": this.clientId } : void 0,
126
- timeout: 6e4,
127
- validateStatus: () => true
128
- });
129
- if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
130
- return res.data;
131
- }
132
- async publicJsonRequest(path) {
133
- const res = await axios({
134
- url: `${this.baseUrl}${path}`,
135
- method: "GET",
136
- headers: this.clientId ? { "x-client-id": this.clientId } : void 0,
137
- timeout: 6e4,
138
- validateStatus: () => true
139
- });
140
- if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
141
- return res.data;
142
- }
143
- async authenticatedJsonRequest(path, method, body) {
144
- if (!this.account) throw new Error("Private key required for authenticated requests");
145
- const headers = {
146
- "Content-Type": "application/json"
147
- };
148
- if (this.clientId) headers["x-client-id"] = this.clientId;
149
- const expiry = BigInt(Math.floor(Date.now() / 1e3) + 60);
150
- const { signature } = await calculateBillingAuthSignature({
151
- account: this.account,
152
- product: "compute",
153
- expiry
154
- });
155
- headers.Authorization = `Bearer ${signature}`;
156
- headers["X-eigenx-expiry"] = expiry.toString();
157
- headers["X-Account"] = this.account.address;
158
- const res = await axios({
159
- url: `${this.baseUrl}${path}`,
160
- method,
161
- headers,
162
- data: body,
163
- timeout: 6e4,
164
- validateStatus: () => true
165
- });
166
- if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
167
- return res.data;
168
- }
169
- async authenticatedTextRequest(path) {
170
- if (!this.account) throw new Error("Private key required for authenticated requests");
171
- const headers = {};
172
- if (this.clientId) headers["x-client-id"] = this.clientId;
173
- const expiry = BigInt(Math.floor(Date.now() / 1e3) + 60);
174
- const { signature } = await calculateBillingAuthSignature({
175
- account: this.account,
176
- product: "compute",
177
- expiry
178
- });
179
- headers.Authorization = `Bearer ${signature}`;
180
- headers["X-eigenx-expiry"] = expiry.toString();
181
- headers["X-Account"] = this.account.address;
182
- const res = await axios({
183
- url: `${this.baseUrl}${path}`,
184
- method: "GET",
185
- headers,
186
- timeout: 6e4,
187
- responseType: "text",
188
- validateStatus: () => true
189
- });
190
- if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);
191
- return typeof res.data === "string" ? res.data : JSON.stringify(res.data);
192
- }
193
- };
194
- function buildApiHttpError(res) {
195
- const status = res.status;
196
- const body = typeof res.data === "string" ? res.data : res.data ? JSON.stringify(res.data) : "";
197
- const url = res.config?.url ? ` ${res.config.url}` : "";
198
- return new Error(`BuildAPI request failed: ${status}${url} - ${body || "Unknown error"}`);
199
- }
200
-
201
- // src/client/modules/build/types.ts
202
- var BUILD_STATUS = {
203
- BUILDING: "building",
204
- SUCCESS: "success",
205
- FAILED: "failed"
206
- };
207
-
208
- // src/client/modules/build/errors.ts
209
- var BuildError = class extends Error {
210
- constructor(message) {
211
- super(message);
212
- this.name = "BuildError";
213
- }
214
- };
215
- var AuthRequiredError = class extends BuildError {
216
- constructor(message = "Authentication required") {
217
- super(message);
218
- this.name = "AuthRequiredError";
219
- }
220
- };
221
- var BuildFailedError = class extends BuildError {
222
- constructor(message, buildId) {
223
- super(message);
224
- this.buildId = buildId;
225
- this.name = "BuildFailedError";
226
- }
227
- };
228
- var ConflictError = class extends BuildError {
229
- constructor(message = "Build already in progress") {
230
- super(message);
231
- this.name = "ConflictError";
232
- }
233
- };
234
- var NotFoundError = class extends BuildError {
235
- constructor(message = "Build not found") {
236
- super(message);
237
- this.name = "NotFoundError";
238
- }
239
- };
240
- var ForbiddenError = class extends BuildError {
241
- constructor(message = "Permission denied") {
242
- super(message);
243
- this.name = "ForbiddenError";
244
- }
245
- };
246
- var TimeoutError = class extends BuildError {
247
- constructor(message = "Operation timed out") {
248
- super(message);
249
- this.name = "TimeoutError";
250
- }
251
- };
252
- var BadRequestError = class extends BuildError {
253
- constructor(message = "Bad request") {
254
- super(message);
255
- this.name = "BadRequestError";
256
- }
257
- };
258
-
259
- // src/client/modules/build/index.ts
260
- var DEFAULT_POLL_INTERVAL = 2e3;
261
- var DEFAULT_TIMEOUT = 30 * 60 * 1e3;
262
- function createBuildModule(config) {
263
- const { verbose = false, skipTelemetry = false } = config;
264
- const logger = getLogger(verbose);
265
- const environment = config.environment || "sepolia";
266
- const environmentConfig = getEnvironmentConfig(environment);
267
- const api = new BuildApiClient({
268
- baseUrl: environmentConfig.userApiServerURL,
269
- privateKey: config.privateKey ? addHexPrefix(config.privateKey) : void 0,
270
- clientId: config.clientId
271
- });
272
- return {
273
- async submit(request) {
274
- return withSDKTelemetry(
275
- {
276
- functionName: "build.submit",
277
- skipTelemetry,
278
- properties: { environment, repoUrl: request.repoUrl }
279
- },
280
- async () => {
281
- if (!config.privateKey) throw new AuthRequiredError("Private key required for submit()");
282
- const data = await api.submitBuild({
283
- repo_url: request.repoUrl,
284
- git_ref: request.gitRef,
285
- dockerfile_path: request.dockerfilePath ?? "Dockerfile",
286
- caddyfile_path: request.caddyfilePath,
287
- build_context_path: request.buildContextPath ?? ".",
288
- dependencies: request.dependencies ?? []
289
- });
290
- logger.debug(`Submitted build: ${data.build_id}`);
291
- return { buildId: data.build_id };
292
- }
293
- );
294
- },
295
- async list(options) {
296
- const { billingAddress, limit, offset } = options;
297
- return withSDKTelemetry(
298
- {
299
- functionName: "build.list",
300
- skipTelemetry,
301
- properties: {
302
- environment,
303
- billingAddress,
304
- ...limit !== void 0 ? { limit: String(limit) } : {},
305
- ...offset !== void 0 ? { offset: String(offset) } : {}
306
- }
307
- },
308
- async () => {
309
- const data = await api.listBuilds({
310
- billing_address: billingAddress,
311
- limit,
312
- offset
313
- });
314
- return Array.isArray(data) ? data.map(transformBuild) : [];
315
- }
316
- );
317
- },
318
- async get(buildId) {
319
- return withSDKTelemetry(
320
- { functionName: "build.get", skipTelemetry, properties: { environment, buildId } },
321
- async () => transformBuild(await api.getBuild(buildId))
322
- );
323
- },
324
- async getByDigest(digest) {
325
- return withSDKTelemetry(
326
- { functionName: "build.getByDigest", skipTelemetry, properties: { environment, digest } },
327
- async () => transformBuild(await api.getBuildByDigest(digest))
328
- );
329
- },
330
- async verify(identifier) {
331
- return withSDKTelemetry(
332
- { functionName: "build.verify", skipTelemetry, properties: { environment, identifier } },
333
- async () => transformVerifyResult(await api.verify(identifier))
334
- );
335
- },
336
- async getLogs(buildId) {
337
- return withSDKTelemetry(
338
- { functionName: "build.getLogs", skipTelemetry, properties: { environment, buildId } },
339
- async () => {
340
- if (!config.privateKey) throw new AuthRequiredError("Private key required for getLogs()");
341
- return api.getLogs(buildId);
342
- }
343
- );
344
- },
345
- async submitAndWait(request, options = {}) {
346
- const { buildId } = await this.submit(request);
347
- return this.waitForBuild(buildId, options);
348
- },
349
- async waitForBuild(buildId, options = {}) {
350
- const {
351
- onLog,
352
- onProgress,
353
- pollIntervalMs = DEFAULT_POLL_INTERVAL,
354
- timeoutMs = DEFAULT_TIMEOUT
355
- } = options;
356
- const startTime = Date.now();
357
- let lastLogLength = 0;
358
- while (true) {
359
- if (Date.now() - startTime > timeoutMs) {
360
- throw new TimeoutError(`Build timed out after ${timeoutMs}ms`);
361
- }
362
- const build = await this.get(buildId);
363
- let logs2 = "";
364
- try {
365
- logs2 = await this.getLogs(buildId);
366
- if (onLog && logs2.length > lastLogLength) {
367
- onLog(logs2.slice(lastLogLength));
368
- lastLogLength = logs2.length;
369
- }
370
- } catch {
371
- }
372
- onProgress?.({ build, logs: logs2 });
373
- if (build.status === BUILD_STATUS.SUCCESS) return build;
374
- if (build.status === BUILD_STATUS.FAILED) {
375
- throw new BuildFailedError(build.errorMessage ?? "Build failed", buildId);
376
- }
377
- await sleep(pollIntervalMs);
378
- }
379
- },
380
- async *streamLogs(buildId, pollIntervalMs = DEFAULT_POLL_INTERVAL) {
381
- let lastLength = 0;
382
- while (true) {
383
- const build = await this.get(buildId);
384
- let logs2 = "";
385
- try {
386
- logs2 = await this.getLogs(buildId);
387
- } catch {
388
- }
389
- if (logs2.length > lastLength) {
390
- yield {
391
- content: logs2.slice(lastLength),
392
- totalLength: logs2.length,
393
- isComplete: build.status !== BUILD_STATUS.BUILDING,
394
- finalStatus: build.status !== BUILD_STATUS.BUILDING ? build.status : void 0
395
- };
396
- lastLength = logs2.length;
397
- }
398
- if (build.status !== BUILD_STATUS.BUILDING) break;
399
- await sleep(pollIntervalMs);
400
- }
401
- }
402
- };
403
- }
404
- function sleep(ms) {
405
- return new Promise((resolve) => setTimeout(resolve, ms));
406
- }
407
- function transformBuild(raw) {
408
- return {
409
- buildId: raw.build_id,
410
- billingAddress: raw.billing_address,
411
- repoUrl: raw.repo_url,
412
- gitRef: raw.git_ref,
413
- status: raw.status,
414
- buildType: raw.build_type,
415
- imageName: raw.image_name,
416
- imageUrl: raw.image_url,
417
- imageDigest: raw.image_digest,
418
- provenanceJson: raw.provenance_json ?? void 0,
419
- provenanceSignature: raw.provenance_signature ?? void 0,
420
- errorMessage: raw.error_message ?? void 0,
421
- createdAt: raw.created_at,
422
- updatedAt: raw.updated_at,
423
- dependencies: raw.dependencies ? Object.fromEntries(Object.entries(raw.dependencies).map(([k, v]) => [k, transformBuild(v)])) : void 0
424
- };
425
- }
426
- function transformVerifyResult(raw) {
427
- if (raw.status === "verified") {
428
- return {
429
- status: "verified",
430
- buildId: raw.build_id,
431
- imageUrl: raw.image_url,
432
- imageDigest: raw.image_digest,
433
- repoUrl: raw.repo_url,
434
- gitRef: raw.git_ref,
435
- provenanceJson: raw.provenance_json,
436
- provenanceSignature: raw.provenance_signature,
437
- payloadType: raw.payload_type,
438
- payload: raw.payload
439
- };
440
- }
441
- return {
442
- status: "failed",
443
- error: raw.error,
444
- buildId: raw.build_id
445
- };
446
- }
87
+ } from "./chunk-ZEZS5CNB.js";
447
88
 
448
89
  // src/client/common/utils/instance.ts
449
90
  async function getCurrentInstanceType(preflightCtx, appID, logger, clientId) {
@@ -498,20 +139,10 @@ function createECloudClient(cfg) {
498
139
  };
499
140
  }
500
141
  export {
501
- AuthRequiredError,
502
- BUILD_STATUS,
503
- BadRequestError,
504
- BuildError,
505
- BuildFailedError,
506
- ConflictError,
507
- ForbiddenError,
508
142
  NoopClient,
509
- NotFoundError,
510
143
  PRIMARY_LANGUAGES,
511
144
  PostHogClient,
512
- TimeoutError,
513
145
  UserApiClient,
514
- addHexPrefix,
515
146
  addMetric,
516
147
  addMetricWithDimensions,
517
148
  assertValidFilePath,
@@ -521,7 +152,6 @@ export {
521
152
  createApp,
522
153
  createAppEnvironment,
523
154
  createBillingModule,
524
- createBuildModule,
525
155
  createComputeModule,
526
156
  createECloudClient,
527
157
  createMetricsContext,
@@ -565,15 +195,12 @@ export {
565
195
  listStoredKeys,
566
196
  logs,
567
197
  prepareDeploy,
568
- prepareDeployFromVerifiableBuild,
569
198
  prepareUpgrade,
570
- prepareUpgradeFromVerifiableBuild,
571
199
  requirePrivateKey,
572
200
  sanitizeString,
573
201
  sanitizeURL,
574
202
  sanitizeXURL,
575
203
  storePrivateKey,
576
- stripHexPrefix,
577
204
  validateAppID,
578
205
  validateAppName,
579
206
  validateCreateAppParams,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/common/utils/buildapi.ts","../src/client/modules/build/types.ts","../src/client/modules/build/errors.ts","../src/client/modules/build/index.ts","../src/client/common/utils/instance.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Build API Client to manage verifiable builds and provenance\n *\n * This is a standalone HTTP client that talks to the (compute) UserAPI host.\n */\n\nimport axios, { AxiosResponse } from \"axios\";\nimport { privateKeyToAccount } from \"viem/accounts\";\n\nimport type { Hex } from \"viem\";\nimport { calculateBillingAuthSignature } from \"./auth\";\n\nexport class BuildApiClient {\n private readonly baseUrl: string;\n private readonly account?: ReturnType<typeof privateKeyToAccount>;\n private readonly clientId?: string;\n\n constructor(options: { baseUrl: string; privateKey?: Hex | string; clientId?: string }) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, \"\");\n this.clientId = options.clientId;\n\n if (options.privateKey) {\n this.account = privateKeyToAccount(options.privateKey as Hex);\n }\n }\n\n async submitBuild(payload: {\n repo_url: string;\n git_ref: string;\n dockerfile_path: string;\n caddyfile_path?: string;\n build_context_path: string;\n dependencies: string[];\n }): Promise<{ build_id: string }> {\n return this.authenticatedJsonRequest<{ build_id: string }>(\"/builds\", \"POST\", payload);\n }\n\n async getBuild(buildId: string): Promise<any> {\n return this.publicJsonRequest(`/builds/${encodeURIComponent(buildId)}`);\n }\n\n async getBuildByDigest(digest: string): Promise<any> {\n return this.publicJsonRequest(`/builds/image/${encodeURIComponent(digest)}`);\n }\n\n async verify(identifier: string): Promise<any> {\n return this.publicJsonRequest(`/builds/verify/${encodeURIComponent(identifier)}`);\n }\n\n async getLogs(buildId: string): Promise<string> {\n return this.authenticatedTextRequest(`/builds/${encodeURIComponent(buildId)}/logs`);\n }\n\n async listBuilds(params: {\n billing_address: string;\n limit?: number;\n offset?: number;\n }): Promise<any[]> {\n const res: AxiosResponse = await axios({\n url: `${this.baseUrl}/builds`,\n method: \"GET\",\n params,\n headers: this.clientId ? { \"x-client-id\": this.clientId } : undefined,\n timeout: 60_000,\n validateStatus: () => true,\n });\n if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);\n return res.data as any[];\n }\n\n private async publicJsonRequest(path: string): Promise<any> {\n const res: AxiosResponse = await axios({\n url: `${this.baseUrl}${path}`,\n method: \"GET\",\n headers: this.clientId ? { \"x-client-id\": this.clientId } : undefined,\n timeout: 60_000,\n validateStatus: () => true,\n });\n if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);\n return res.data;\n }\n\n private async authenticatedJsonRequest<T>(\n path: string,\n method: \"POST\" | \"GET\",\n body?: unknown,\n ): Promise<T> {\n if (!this.account) throw new Error(\"Private key required for authenticated requests\");\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (this.clientId) headers[\"x-client-id\"] = this.clientId;\n\n // Builds API uses BillingAuth signature format (same as Billing API).\n // Keep expiry short to reduce replay window.\n const expiry = BigInt(Math.floor(Date.now() / 1000) + 60);\n const { signature } = await calculateBillingAuthSignature({\n account: this.account,\n product: \"compute\",\n expiry,\n });\n headers.Authorization = `Bearer ${signature}`;\n headers[\"X-eigenx-expiry\"] = expiry.toString();\n headers[\"X-Account\"] = this.account.address;\n\n const res: AxiosResponse = await axios({\n url: `${this.baseUrl}${path}`,\n method,\n headers,\n data: body,\n timeout: 60_000,\n validateStatus: () => true,\n });\n if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);\n return res.data as T;\n }\n\n private async authenticatedTextRequest(path: string): Promise<string> {\n if (!this.account) throw new Error(\"Private key required for authenticated requests\");\n\n const headers: Record<string, string> = {};\n if (this.clientId) headers[\"x-client-id\"] = this.clientId;\n\n const expiry = BigInt(Math.floor(Date.now() / 1000) + 60);\n const { signature } = await calculateBillingAuthSignature({\n account: this.account,\n product: \"compute\",\n expiry,\n });\n headers.Authorization = `Bearer ${signature}`;\n headers[\"X-eigenx-expiry\"] = expiry.toString();\n headers[\"X-Account\"] = this.account.address;\n\n const res: AxiosResponse = await axios({\n url: `${this.baseUrl}${path}`,\n method: \"GET\",\n headers,\n timeout: 60_000,\n responseType: \"text\",\n validateStatus: () => true,\n });\n if (res.status < 200 || res.status >= 300) throw buildApiHttpError(res);\n return typeof res.data === \"string\" ? res.data : JSON.stringify(res.data);\n }\n}\n\nfunction buildApiHttpError(res: AxiosResponse): Error {\n const status = res.status;\n const body = typeof res.data === \"string\" ? res.data : res.data ? JSON.stringify(res.data) : \"\";\n const url = res.config?.url ? ` ${res.config.url}` : \"\";\n return new Error(`BuildAPI request failed: ${status}${url} - ${body || \"Unknown error\"}`);\n}\n","// ============ Request/Response Types ============\n\nexport interface SubmitBuildRequest {\n repoUrl: string;\n gitRef: string;\n dockerfilePath?: string;\n /**\n * Path to a Caddyfile within the repository (relative to buildContextPath).\n * If omitted, the build service will not copy a Caddyfile into the image.\n */\n caddyfilePath?: string;\n buildContextPath?: string;\n dependencies?: string[];\n}\n\nexport interface SubmitBuildResponse {\n buildId: string;\n}\n\nexport const BUILD_STATUS = {\n BUILDING: \"building\",\n SUCCESS: \"success\",\n FAILED: \"failed\",\n} as const;\n\nexport type BuildStatus = (typeof BUILD_STATUS)[keyof typeof BUILD_STATUS];\n\nexport interface Build {\n buildId: string;\n billingAddress: string;\n repoUrl: string;\n gitRef: string;\n status: BuildStatus;\n /** 'application' | 'dependency' (as returned by the API) */\n buildType: string;\n imageName: string;\n imageUrl?: string;\n imageDigest?: string;\n provenanceJson?: Record<string, unknown>;\n provenanceSignature?: string;\n errorMessage?: string;\n createdAt: string;\n updatedAt: string;\n dependencies?: Record<string, Build>;\n}\n\n// ============ Verification Types ============\n\nexport type VerifyProvenanceResult = VerifyProvenanceSuccess | VerifyProvenanceFailure;\n\nexport interface VerifyProvenanceSuccess {\n status: \"verified\";\n buildId: string;\n imageUrl: string;\n imageDigest: string;\n repoUrl: string;\n gitRef: string;\n provenanceJson: Record<string, unknown>;\n provenanceSignature: string;\n payloadType: string;\n payload: string;\n}\n\nexport interface VerifyProvenanceFailure {\n status: \"failed\";\n error: string;\n buildId?: string;\n}\n\n// ============ Log Streaming ============\n\nexport interface LogChunk {\n content: string;\n totalLength: number;\n isComplete: boolean;\n finalStatus?: BuildStatus;\n}\n\nexport interface BuildProgress {\n build: Build;\n logs: string;\n}\n","export class BuildError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"BuildError\";\n }\n}\n\nexport class AuthRequiredError extends BuildError {\n constructor(message = \"Authentication required\") {\n super(message);\n this.name = \"AuthRequiredError\";\n }\n}\n\nexport class BuildFailedError extends BuildError {\n constructor(\n message: string,\n public readonly buildId: string,\n ) {\n super(message);\n this.name = \"BuildFailedError\";\n }\n}\n\nexport class ConflictError extends BuildError {\n constructor(message = \"Build already in progress\") {\n super(message);\n this.name = \"ConflictError\";\n }\n}\n\nexport class NotFoundError extends BuildError {\n constructor(message = \"Build not found\") {\n super(message);\n this.name = \"NotFoundError\";\n }\n}\n\nexport class ForbiddenError extends BuildError {\n constructor(message = \"Permission denied\") {\n super(message);\n this.name = \"ForbiddenError\";\n }\n}\n\nexport class TimeoutError extends BuildError {\n constructor(message = \"Operation timed out\") {\n super(message);\n this.name = \"TimeoutError\";\n }\n}\n\nexport class BadRequestError extends BuildError {\n constructor(message = \"Bad request\") {\n super(message);\n this.name = \"BadRequestError\";\n }\n}\n","/**\n * Build module entry point (verifiable builds + provenance)\n */\n\nimport { getEnvironmentConfig } from \"../../common/config/environment\";\nimport { withSDKTelemetry } from \"../../common/telemetry/wrapper\";\nimport { getLogger, addHexPrefix } from \"../../common/utils\";\nimport { BuildApiClient } from \"../../common/utils/buildapi\";\n\nimport { BUILD_STATUS } from \"./types\";\nimport type {\n Build,\n BuildProgress,\n BuildStatus,\n LogChunk,\n SubmitBuildRequest,\n SubmitBuildResponse,\n VerifyProvenanceResult,\n} from \"./types\";\nimport { AuthRequiredError, BuildFailedError, TimeoutError } from \"./errors\";\n\nexport interface BuildModuleConfig {\n privateKey?: string;\n environment?: string;\n verbose?: boolean;\n clientId?: string;\n skipTelemetry?: boolean;\n}\n\nexport interface BuildModule {\n submit(request: SubmitBuildRequest): Promise<SubmitBuildResponse>;\n getLogs(buildId: string): Promise<string>;\n\n list(options: { billingAddress: string; limit?: number; offset?: number }): Promise<Build[]>;\n get(buildId: string): Promise<Build>;\n getByDigest(digest: string): Promise<Build>;\n verify(identifier: string): Promise<VerifyProvenanceResult>;\n\n submitAndWait(\n request: SubmitBuildRequest,\n options?: {\n onLog?: (chunk: string) => void;\n onProgress?: (progress: BuildProgress) => void;\n pollIntervalMs?: number;\n timeoutMs?: number;\n },\n ): Promise<Build>;\n\n waitForBuild(\n buildId: string,\n options?: {\n onLog?: (chunk: string) => void;\n onProgress?: (progress: BuildProgress) => void;\n pollIntervalMs?: number;\n timeoutMs?: number;\n },\n ): Promise<Build>;\n\n streamLogs(buildId: string, pollIntervalMs?: number): AsyncGenerator<LogChunk, void, unknown>;\n}\n\nconst DEFAULT_POLL_INTERVAL = 2000;\nconst DEFAULT_TIMEOUT = 30 * 60 * 1000;\n\nexport function createBuildModule(config: BuildModuleConfig): BuildModule {\n const { verbose = false, skipTelemetry = false } = config;\n const logger = getLogger(verbose);\n\n const environment = config.environment || \"sepolia\";\n const environmentConfig = getEnvironmentConfig(environment);\n\n // NOTE: build endpoints are served from the compute UserAPI host\n const api = new BuildApiClient({\n baseUrl: environmentConfig.userApiServerURL,\n privateKey: config.privateKey ? addHexPrefix(config.privateKey) : undefined,\n clientId: config.clientId,\n });\n\n return {\n async submit(request: SubmitBuildRequest): Promise<SubmitBuildResponse> {\n return withSDKTelemetry(\n {\n functionName: \"build.submit\",\n skipTelemetry,\n properties: { environment, repoUrl: request.repoUrl },\n },\n async () => {\n if (!config.privateKey) throw new AuthRequiredError(\"Private key required for submit()\");\n\n const data = await api.submitBuild({\n repo_url: request.repoUrl,\n git_ref: request.gitRef,\n dockerfile_path: request.dockerfilePath ?? \"Dockerfile\",\n caddyfile_path: request.caddyfilePath,\n build_context_path: request.buildContextPath ?? \".\",\n dependencies: request.dependencies ?? [],\n });\n\n logger.debug(`Submitted build: ${data.build_id}`);\n return { buildId: data.build_id };\n },\n );\n },\n\n async list(options): Promise<Build[]> {\n const { billingAddress, limit, offset } = options;\n return withSDKTelemetry(\n {\n functionName: \"build.list\",\n skipTelemetry,\n properties: {\n environment,\n billingAddress,\n ...(limit !== undefined ? { limit: String(limit) } : {}),\n ...(offset !== undefined ? { offset: String(offset) } : {}),\n },\n },\n async () => {\n const data = await api.listBuilds({\n billing_address: billingAddress,\n limit,\n offset,\n });\n return Array.isArray(data) ? data.map(transformBuild) : [];\n },\n );\n },\n\n async get(buildId: string): Promise<Build> {\n return withSDKTelemetry(\n { functionName: \"build.get\", skipTelemetry, properties: { environment, buildId } },\n async () => transformBuild(await api.getBuild(buildId)),\n );\n },\n\n async getByDigest(digest: string): Promise<Build> {\n return withSDKTelemetry(\n { functionName: \"build.getByDigest\", skipTelemetry, properties: { environment, digest } },\n async () => transformBuild(await api.getBuildByDigest(digest)),\n );\n },\n\n async verify(identifier: string): Promise<VerifyProvenanceResult> {\n return withSDKTelemetry(\n { functionName: \"build.verify\", skipTelemetry, properties: { environment, identifier } },\n async () => transformVerifyResult(await api.verify(identifier)),\n );\n },\n\n async getLogs(buildId: string): Promise<string> {\n return withSDKTelemetry(\n { functionName: \"build.getLogs\", skipTelemetry, properties: { environment, buildId } },\n async () => {\n if (!config.privateKey) throw new AuthRequiredError(\"Private key required for getLogs()\");\n return api.getLogs(buildId);\n },\n );\n },\n\n async submitAndWait(request, options = {}) {\n const { buildId } = await this.submit(request);\n return this.waitForBuild(buildId, options);\n },\n\n async waitForBuild(buildId, options = {}) {\n const {\n onLog,\n onProgress,\n pollIntervalMs = DEFAULT_POLL_INTERVAL,\n timeoutMs = DEFAULT_TIMEOUT,\n } = options;\n\n const startTime = Date.now();\n let lastLogLength = 0;\n\n while (true) {\n if (Date.now() - startTime > timeoutMs) {\n throw new TimeoutError(`Build timed out after ${timeoutMs}ms`);\n }\n\n const build = await this.get(buildId);\n let logs = \"\";\n\n try {\n logs = await this.getLogs(buildId);\n if (onLog && logs.length > lastLogLength) {\n onLog(logs.slice(lastLogLength));\n lastLogLength = logs.length;\n }\n } catch {\n // ignore\n }\n\n onProgress?.({ build, logs });\n\n if (build.status === BUILD_STATUS.SUCCESS) return build;\n if (build.status === BUILD_STATUS.FAILED) {\n throw new BuildFailedError(build.errorMessage ?? \"Build failed\", buildId);\n }\n\n await sleep(pollIntervalMs);\n }\n },\n\n async *streamLogs(buildId, pollIntervalMs = DEFAULT_POLL_INTERVAL) {\n let lastLength = 0;\n while (true) {\n const build = await this.get(buildId);\n let logs = \"\";\n\n try {\n logs = await this.getLogs(buildId);\n } catch {\n // ignore\n }\n\n if (logs.length > lastLength) {\n yield {\n content: logs.slice(lastLength),\n totalLength: logs.length,\n isComplete: build.status !== BUILD_STATUS.BUILDING,\n finalStatus: build.status !== BUILD_STATUS.BUILDING ? build.status : undefined,\n };\n lastLength = logs.length;\n }\n\n if (build.status !== BUILD_STATUS.BUILDING) break;\n await sleep(pollIntervalMs);\n }\n },\n };\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction transformBuild(raw: any): Build {\n return {\n buildId: raw.build_id,\n billingAddress: raw.billing_address,\n repoUrl: raw.repo_url,\n gitRef: raw.git_ref,\n status: raw.status as BuildStatus,\n buildType: raw.build_type,\n imageName: raw.image_name,\n imageUrl: raw.image_url,\n imageDigest: raw.image_digest,\n provenanceJson: raw.provenance_json ?? undefined,\n provenanceSignature: raw.provenance_signature ?? undefined,\n errorMessage: raw.error_message ?? undefined,\n createdAt: raw.created_at,\n updatedAt: raw.updated_at,\n dependencies: raw.dependencies\n ? Object.fromEntries(Object.entries(raw.dependencies).map(([k, v]) => [k, transformBuild(v)]))\n : undefined,\n };\n}\n\nfunction transformVerifyResult(raw: any): VerifyProvenanceResult {\n if (raw.status === \"verified\") {\n return {\n status: \"verified\",\n buildId: raw.build_id,\n imageUrl: raw.image_url,\n imageDigest: raw.image_digest,\n repoUrl: raw.repo_url,\n gitRef: raw.git_ref,\n provenanceJson: raw.provenance_json,\n provenanceSignature: raw.provenance_signature,\n payloadType: raw.payload_type,\n payload: raw.payload,\n };\n }\n\n return {\n status: \"failed\",\n error: raw.error,\n buildId: raw.build_id,\n };\n}\n\n// Re-export errors/types for convenience\nexport * from \"./types\";\nexport * from \"./errors\";\n","/**\n * Instance type utilities\n */\n\nimport { Address } from \"viem\";\nimport { PreflightContext } from \"./preflight\";\nimport { Logger } from \"../types\";\nimport { UserApiClient } from \"./userapi\";\n\n/**\n * Get current instance type for an app (best-effort)\n * Returns empty string if unable to fetch (API unavailable, app info not ready, etc.).\n * This is used as a convenience default for the upgrade flow.\n */\nexport async function getCurrentInstanceType(\n preflightCtx: PreflightContext,\n appID: Address,\n logger: Logger,\n clientId?: string,\n): Promise<string> {\n try {\n const userApiClient = new UserApiClient(\n preflightCtx.environmentConfig,\n preflightCtx.privateKey,\n preflightCtx.rpcUrl,\n clientId,\n );\n\n const infos = await userApiClient.getInfos([appID], 1);\n if (infos.length === 0) {\n return \"\"; // No app info available yet\n }\n\n return infos[0].machineType || \"\";\n } catch (err: any) {\n logger.debug(`Failed to get current instance type: ${err.message}`);\n return \"\"; // API call failed, skip default\n }\n}\n","/**\n * Main SDK Client entry point\n */\n\nimport { createComputeModule, type ComputeModule } from \"./modules/compute\";\nimport {\n getEnvironmentConfig,\n isEnvironmentAvailable,\n getAvailableEnvironments,\n} from \"./common/config/environment\";\nimport { createBillingModule, type BillingModule } from \"./modules/billing\";\nimport { createBuildModule, type BuildModule, type BuildModuleConfig } from \"./modules/build\";\nimport { addHexPrefix } from \"./common/utils\";\nimport { Hex } from \"viem\";\n\n// Export all types\nexport * from \"./common/types\";\n\n// Export validation utilities (non-interactive)\nexport * from \"./common/utils/validation\";\n\n// Export common hex helpers (used by CLI as well)\nexport { addHexPrefix, stripHexPrefix } from \"./common/utils\";\n\n// Special case on createApp - we don't need the client to run it\nexport {\n createApp,\n CreateAppOpts,\n SDKCreateAppOpts,\n PRIMARY_LANGUAGES,\n getAvailableTemplates,\n} from \"./modules/compute/app/create\";\nexport { logs, LogsOptions, SDKLogsOptions } from \"./modules/compute/app/logs\";\nexport {\n SDKDeployOptions,\n prepareDeploy,\n prepareDeployFromVerifiableBuild,\n executeDeploy,\n watchDeployment,\n type PrepareDeployResult,\n} from \"./modules/compute/app/deploy\";\nexport {\n SDKUpgradeOptions,\n prepareUpgrade,\n prepareUpgradeFromVerifiableBuild,\n executeUpgrade,\n watchUpgrade,\n type PrepareUpgradeResult,\n} from \"./modules/compute/app/upgrade\";\n\n// Export compute module for standalone use\nexport {\n createComputeModule,\n type ComputeModule,\n type ComputeModuleConfig,\n encodeStartAppData,\n encodeStopAppData,\n encodeTerminateAppData,\n} from \"./modules/compute\";\nexport {\n createBillingModule,\n type BillingModule,\n type BillingModuleConfig,\n} from \"./modules/billing\";\n\n// Export environment config utilities\nexport {\n getEnvironmentConfig,\n getAvailableEnvironments,\n isEnvironmentAvailable,\n getBuildType,\n isMainnet,\n} from \"./common/config/environment\";\nexport { isSubscriptionActive } from \"./common/utils/billing\";\n\n// Export auth utilities\nexport * from \"./common/auth\";\n\n// Export telemetry\nexport * from \"./common/telemetry\";\n\n// Export template catalog utilities for CLI\nexport {\n fetchTemplateCatalog,\n getTemplate,\n getCategoryDescriptions,\n} from \"./common/templates/catalog\";\n\n// Export contract utilities\nexport {\n getAllAppsByDeveloper,\n getAppLatestReleaseBlockNumbers,\n getBlockTimestamps,\n estimateTransactionGas,\n formatETH,\n type GasEstimate,\n type EstimateGasOptions,\n} from \"./common/contract/caller\";\n\n// Export batch gas estimation and delegation check\nexport {\n estimateBatchGas,\n checkERC7702Delegation,\n type EstimateBatchGasOptions,\n} from \"./common/contract/eip7702\";\n\n// Export instance type utilities\nexport { getCurrentInstanceType } from \"./common/utils/instance\";\n\n// Export user API client\nexport {\n UserApiClient,\n type AppInfo,\n type AppProfileInfo,\n type AppMetrics,\n type AppRelease,\n type AppReleaseBuild,\n type AppResponse,\n} from \"./common/utils/userapi\";\n\nexport type Environment = \"sepolia\" | \"sepolia-dev\" | \"mainnet-alpha\";\n\nexport interface ClientConfig {\n verbose: boolean;\n privateKey: Hex;\n environment: Environment | string;\n rpcUrl?: string;\n}\n\nexport interface ECloudClient {\n compute: ComputeModule;\n billing: BillingModule;\n}\n\nexport function createECloudClient(cfg: ClientConfig): ECloudClient {\n cfg.privateKey = addHexPrefix(cfg.privateKey);\n\n // Validate environment is available in current build\n const environment = cfg.environment || \"sepolia\";\n if (!isEnvironmentAvailable(environment)) {\n throw new Error(\n `Environment \"${environment}\" is not available in this build type. ` +\n `Available environments: ${getAvailableEnvironments().join(\", \")}`,\n );\n }\n\n // Get environment config\n const environmentConfig = getEnvironmentConfig(environment);\n\n // Get rpc url from environment config or use provided rpc url\n let rpcUrl = cfg.rpcUrl;\n if (!rpcUrl) {\n rpcUrl = process.env.RPC_URL ?? environmentConfig.defaultRPCURL;\n }\n if (!rpcUrl) {\n throw new Error(\n `RPC URL is required. Provide via options.rpcUrl, RPC_URL env var, or ensure environment has default RPC URL`,\n );\n }\n\n return {\n compute: createComputeModule({\n rpcUrl,\n verbose: cfg.verbose,\n privateKey: cfg.privateKey,\n environment: cfg.environment,\n }),\n billing: createBillingModule({\n verbose: cfg.verbose,\n privateKey: cfg.privateKey,\n }),\n };\n}\n\n// ============ Build module exports ============\nexport { createBuildModule };\nexport type { BuildModule, BuildModuleConfig };\nexport * from \"./modules/build/types\";\nexport * from \"./modules/build/errors\";\n"],"mappings":"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","names":["logs"]}
1
+ {"version":3,"sources":["../src/client/common/utils/instance.ts","../src/client/index.ts"],"sourcesContent":["/**\n * Instance type utilities\n */\n\nimport { Address } from \"viem\";\nimport { PreflightContext } from \"./preflight\";\nimport { Logger } from \"../types\";\nimport { UserApiClient } from \"./userapi\";\n\n/**\n * Get current instance type for an app (best-effort)\n * Returns empty string if unable to fetch (API unavailable, app info not ready, etc.).\n * This is used as a convenience default for the upgrade flow.\n */\nexport async function getCurrentInstanceType(\n preflightCtx: PreflightContext,\n appID: Address,\n logger: Logger,\n clientId?: string,\n): Promise<string> {\n try {\n const userApiClient = new UserApiClient(\n preflightCtx.environmentConfig,\n preflightCtx.privateKey,\n preflightCtx.rpcUrl,\n clientId,\n );\n\n const infos = await userApiClient.getInfos([appID], 1);\n if (infos.length === 0) {\n return \"\"; // No app info available yet\n }\n\n return infos[0].machineType || \"\";\n } catch (err: any) {\n logger.debug(`Failed to get current instance type: ${err.message}`);\n return \"\"; // API call failed, skip default\n }\n}\n","/**\n * Main SDK Client entry point\n */\n\nimport { createComputeModule, type ComputeModule } from \"./modules/compute\";\nimport {\n getEnvironmentConfig,\n isEnvironmentAvailable,\n getAvailableEnvironments,\n} from \"./common/config/environment\";\nimport { createBillingModule, type BillingModule } from \"./modules/billing\";\nimport { addHexPrefix } from \"./common/utils\";\n\n// Export all types\nexport * from \"./common/types\";\n\n// Export validation utilities (non-interactive)\nexport * from \"./common/utils/validation\";\n\n// Special case on createApp - we don't need the client to run it\nexport {\n createApp,\n CreateAppOpts,\n SDKCreateAppOpts,\n PRIMARY_LANGUAGES,\n getAvailableTemplates,\n} from \"./modules/compute/app/create\";\nexport { logs, LogsOptions, SDKLogsOptions } from \"./modules/compute/app/logs\";\nexport {\n SDKDeployOptions,\n prepareDeploy,\n executeDeploy,\n watchDeployment,\n type PreparedDeploy,\n type PrepareDeployResult,\n} from \"./modules/compute/app/deploy\";\nexport {\n SDKUpgradeOptions,\n prepareUpgrade,\n executeUpgrade,\n watchUpgrade,\n type PreparedUpgrade,\n type PrepareUpgradeResult,\n} from \"./modules/compute/app/upgrade\";\n\n// Export compute module for standalone use\nexport {\n createComputeModule,\n type ComputeModule,\n type ComputeModuleConfig,\n encodeStartAppData,\n encodeStopAppData,\n encodeTerminateAppData,\n} from \"./modules/compute\";\nexport {\n createBillingModule,\n type BillingModule,\n type BillingModuleConfig,\n} from \"./modules/billing\";\n\n// Export environment config utilities\nexport {\n getEnvironmentConfig,\n getAvailableEnvironments,\n isEnvironmentAvailable,\n getBuildType,\n isMainnet,\n} from \"./common/config/environment\";\nexport { isSubscriptionActive } from \"./common/utils/billing\";\n\n// Export auth utilities\nexport * from \"./common/auth\";\n\n// Export telemetry\nexport * from \"./common/telemetry\";\n\n// Export template catalog utilities for CLI\nexport {\n fetchTemplateCatalog,\n getTemplate,\n getCategoryDescriptions,\n} from \"./common/templates/catalog\";\n\n// Export contract utilities\nexport {\n getAllAppsByDeveloper,\n getAppLatestReleaseBlockNumbers,\n getBlockTimestamps,\n estimateTransactionGas,\n formatETH,\n type GasEstimate,\n type EstimateGasOptions,\n} from \"./common/contract/caller\";\n\n// Export batch gas estimation and delegation check\nexport {\n estimateBatchGas,\n checkERC7702Delegation,\n type EstimateBatchGasOptions,\n} from \"./common/contract/eip7702\";\n\n// Export instance type utilities\nexport { getCurrentInstanceType } from \"./common/utils/instance\";\n\n// Export user API client\nexport {\n UserApiClient,\n type AppInfo,\n type AppProfileInfo,\n type AppMetrics,\n} from \"./common/utils/userapi\";\n\nexport type Environment = \"sepolia\" | \"sepolia-dev\" | \"mainnet-alpha\";\n\nexport interface ClientConfig {\n verbose: boolean;\n privateKey: `0x${string}`;\n environment: Environment | string;\n rpcUrl?: string;\n}\n\nexport interface ECloudClient {\n compute: ComputeModule;\n billing: BillingModule;\n}\n\nexport function createECloudClient(cfg: ClientConfig): ECloudClient {\n cfg.privateKey = addHexPrefix(cfg.privateKey);\n\n // Validate environment is available in current build\n const environment = cfg.environment || \"sepolia\";\n if (!isEnvironmentAvailable(environment)) {\n throw new Error(\n `Environment \"${environment}\" is not available in this build type. ` +\n `Available environments: ${getAvailableEnvironments().join(\", \")}`,\n );\n }\n\n // Get environment config\n const environmentConfig = getEnvironmentConfig(environment);\n\n // Get rpc url from environment config or use provided rpc url\n let rpcUrl = cfg.rpcUrl;\n if (!rpcUrl) {\n rpcUrl = process.env.RPC_URL ?? environmentConfig.defaultRPCURL;\n }\n if (!rpcUrl) {\n throw new Error(\n `RPC URL is required. Provide via options.rpcUrl, RPC_URL env var, or ensure environment has default RPC URL`,\n );\n }\n\n return {\n compute: createComputeModule({\n rpcUrl,\n verbose: cfg.verbose,\n privateKey: cfg.privateKey,\n environment: cfg.environment,\n }),\n billing: createBillingModule({\n verbose: cfg.verbose,\n privateKey: cfg.privateKey,\n }),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,eAAsB,uBACpB,cACA,OACA,QACA,UACiB;AACjB,MAAI;AACF,UAAM,gBAAgB,IAAI;AAAA,MACxB,aAAa;AAAA,MACb,aAAa;AAAA,MACb,aAAa;AAAA,MACb;AAAA,IACF;AAEA,UAAM,QAAQ,MAAM,cAAc,SAAS,CAAC,KAAK,GAAG,CAAC;AACrD,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO;AAAA,IACT;AAEA,WAAO,MAAM,CAAC,EAAE,eAAe;AAAA,EACjC,SAAS,KAAU;AACjB,WAAO,MAAM,wCAAwC,IAAI,OAAO,EAAE;AAClE,WAAO;AAAA,EACT;AACF;;;ACwFO,SAAS,mBAAmB,KAAiC;AAClE,MAAI,aAAa,aAAa,IAAI,UAAU;AAG5C,QAAM,cAAc,IAAI,eAAe;AACvC,MAAI,CAAC,uBAAuB,WAAW,GAAG;AACxC,UAAM,IAAI;AAAA,MACR,gBAAgB,WAAW,kEACE,yBAAyB,EAAE,KAAK,IAAI,CAAC;AAAA,IACpE;AAAA,EACF;AAGA,QAAM,oBAAoB,qBAAqB,WAAW;AAG1D,MAAI,SAAS,IAAI;AACjB,MAAI,CAAC,QAAQ;AACX,aAAS,QAAQ,IAAI,WAAW,kBAAkB;AAAA,EACpD;AACA,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS,oBAAoB;AAAA,MAC3B;AAAA,MACA,SAAS,IAAI;AAAA,MACb,YAAY,IAAI;AAAA,MAChB,aAAa,IAAI;AAAA,IACnB,CAAC;AAAA,IACD,SAAS,oBAAoB;AAAA,MAC3B,SAAS,IAAI;AAAA,MACb,YAAY,IAAI;AAAA,IAClB,CAAC;AAAA,EACH;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layr-labs/ecloud-sdk",
3
- "version": "0.2.0-dev.1",
3
+ "version": "0.2.0-dev.2",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -30,7 +30,6 @@
30
30
  },
31
31
  "scripts": {
32
32
  "build": "tsup",
33
- "build:dev": "BUILD_TYPE=dev tsup",
34
33
  "prepublishOnly": "cp ../../README.md .",
35
34
  "lint": "eslint .",
36
35
  "format": "prettier --check .",