@graph8/sdk 0.13.1 → 0.14.0

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
@@ -23,9 +23,12 @@ __export(index_exports, {
23
23
  DEFAULT_APP_API: () => DEFAULT_APP_API,
24
24
  G8Error: () => G8Error,
25
25
  KNOWN_WEBHOOK_EVENTS: () => KNOWN_WEBHOOK_EVENTS,
26
+ MAX_TAIL_LINES: () => MAX_TAIL_LINES,
27
+ MIN_TAIL_LINES: () => MIN_TAIL_LINES,
26
28
  WebhookSignatureError: () => WebhookSignatureError,
27
29
  backoffDelayMs: () => backoffDelayMs,
28
30
  constructEvent: () => constructEvent,
31
+ createAppPlatformClient: () => createAppPlatformClient,
29
32
  createAppRequester: () => createAppRequester,
30
33
  createGraph8AppClient: () => createGraph8AppClient,
31
34
  createGraph8ServiceClient: () => createGraph8ServiceClient,
@@ -1258,10 +1261,284 @@ var createAppsClient = (apiKey, apiUrl) => {
1258
1261
  };
1259
1262
  };
1260
1263
 
1261
- // src/fields.ts
1264
+ // src/appPlatform.ts
1262
1265
  var DEFAULT_API18 = "https://be.graph8.com";
1263
- var createFieldsClient = (apiKey, apiUrl) => {
1266
+ var MIN_TAIL_LINES = 1;
1267
+ var MAX_TAIL_LINES = 2e3;
1268
+ var createAppPlatformClient = (apiKey, apiUrl) => {
1264
1269
  const baseUrl = apiUrl || DEFAULT_API18;
1270
+ const unwrap = (resp) => resp.data ?? resp;
1271
+ return {
1272
+ // ---- source binding -------------------------------------------------
1273
+ /**
1274
+ * Bind the repository an app builds from.
1275
+ *
1276
+ * `repo_url` must be fetchable -- `https://`, `ssh://` or `git@`, with no
1277
+ * whitespace. A `file://` or bare path is refused with 422, because a build
1278
+ * that can read the builder's filesystem is a build that can read ours.
1279
+ *
1280
+ * `credential_ref` is a POINTER into your secret manager, not a token.
1281
+ */
1282
+ async setSource(appId, params) {
1283
+ const resp = await request(
1284
+ baseUrl,
1285
+ `/api/v1/apps/${appId}/source`,
1286
+ apiKey,
1287
+ {
1288
+ method: "PUT",
1289
+ body: {
1290
+ repo_url: params.repo_url,
1291
+ provider: params.provider,
1292
+ default_branch: params.default_branch ?? null,
1293
+ credential_ref: params.credential_ref ?? null
1294
+ }
1295
+ }
1296
+ );
1297
+ return unwrap(resp);
1298
+ },
1299
+ /** Unbind the source. Returns the full app with every source field null. */
1300
+ async clearSource(appId) {
1301
+ const resp = await request(
1302
+ baseUrl,
1303
+ `/api/v1/apps/${appId}/source`,
1304
+ apiKey,
1305
+ { method: "DELETE" }
1306
+ );
1307
+ return unwrap(resp);
1308
+ },
1309
+ // ---- deployments ----------------------------------------------------
1310
+ /** Every deployment for this app, newest first. Never 404s for an app with none. */
1311
+ async listDeployments(appId) {
1312
+ return request(baseUrl, `/api/v1/apps/${appId}/deployments`, apiKey);
1313
+ },
1314
+ /**
1315
+ * Queue a deployment. Returns `201` with `status: "queued"` -- nothing builds
1316
+ * as a side effect of this call; the build controller picks it up.
1317
+ *
1318
+ * NOT idempotent: two identical calls create two deployments.
1319
+ */
1320
+ async deploy(appId, params) {
1321
+ const body = { source_ref: params.source_ref };
1322
+ if (params.schema_version_id) body.schema_version_id = params.schema_version_id;
1323
+ const resp = await request(
1324
+ baseUrl,
1325
+ `/api/v1/apps/${appId}/deployments`,
1326
+ apiKey,
1327
+ { method: "POST", body }
1328
+ );
1329
+ return unwrap(resp);
1330
+ },
1331
+ /** Fetch one deployment. The polling endpoint for a build loop. */
1332
+ async getDeployment(appId, deploymentId) {
1333
+ const resp = await request(
1334
+ baseUrl,
1335
+ `/api/v1/apps/${appId}/deployments/${deploymentId}`,
1336
+ apiKey
1337
+ );
1338
+ return unwrap(resp);
1339
+ },
1340
+ /**
1341
+ * The deployment currently serving traffic, or `null`.
1342
+ *
1343
+ * `null` is a real answer with a 200, not a 404: "this app has never shipped"
1344
+ * is information, while a 404 would read as "no such app".
1345
+ */
1346
+ async activeDeployment(appId) {
1347
+ const resp = await request(
1348
+ baseUrl,
1349
+ `/api/v1/apps/${appId}/deployments/active`,
1350
+ apiKey
1351
+ );
1352
+ return resp.data ?? null;
1353
+ },
1354
+ /**
1355
+ * Promote a built deployment to serve traffic. Anything it displaces moves to
1356
+ * `rolled_back` in the same transaction, so there is never a moment with two
1357
+ * live deployments.
1358
+ *
1359
+ * `409` when the state machine forbids it -- a deployment cannot become
1360
+ * `deployed` without having been built, and a `failed` one cannot be revived.
1361
+ * A retry is a new deployment, not a resurrection.
1362
+ */
1363
+ async promote(appId, deploymentId, imageDigest) {
1364
+ const resp = await request(
1365
+ baseUrl,
1366
+ `/api/v1/apps/${appId}/deployments/${deploymentId}/promote`,
1367
+ apiKey,
1368
+ { method: "POST", body: { image_digest: imageDigest } }
1369
+ );
1370
+ return unwrap(resp);
1371
+ },
1372
+ /** Roll back a deployment that is currently serving. Only a `deployed` one may be. */
1373
+ async rollback(appId, deploymentId) {
1374
+ const resp = await request(
1375
+ baseUrl,
1376
+ `/api/v1/apps/${appId}/deployments/${deploymentId}/rollback`,
1377
+ apiKey,
1378
+ { method: "POST", body: {} }
1379
+ );
1380
+ return unwrap(resp);
1381
+ },
1382
+ // ---- logs -----------------------------------------------------------
1383
+ /**
1384
+ * Why a build failed. Returns every step of the build pod in the order
1385
+ * Kubernetes runs them; a step that has not started yet is omitted rather
1386
+ * than returned empty.
1387
+ *
1388
+ * An empty `containers` list is not an error -- build pods are reaped an hour
1389
+ * after they finish, so logs for an older deployment are genuinely gone.
1390
+ * `last_error_sanitized` on the deployment is what survives.
1391
+ *
1392
+ * `503` means graph8 could not reach the cluster, which is deliberately
1393
+ * different from an empty `200`: one means we could not look, the other means
1394
+ * your build produced no output.
1395
+ */
1396
+ async deploymentLogs(appId, deploymentId, tailLines) {
1397
+ const resp = await request(
1398
+ baseUrl,
1399
+ `/api/v1/apps/${appId}/deployments/${deploymentId}/logs`,
1400
+ apiKey,
1401
+ { query: tailLines === void 0 ? void 0 : { tail_lines: tailLines } }
1402
+ );
1403
+ return unwrap(resp);
1404
+ },
1405
+ /**
1406
+ * What the running app is printing. The app's own pods only -- the per-app
1407
+ * egress proxy shares the namespace and is deliberately excluded.
1408
+ *
1409
+ * Empty until a deployment reaches `deployed`.
1410
+ */
1411
+ async logs(appId, tailLines) {
1412
+ const resp = await request(
1413
+ baseUrl,
1414
+ `/api/v1/apps/${appId}/logs`,
1415
+ apiKey,
1416
+ { query: tailLines === void 0 ? void 0 : { tail_lines: tailLines } }
1417
+ );
1418
+ return unwrap(resp);
1419
+ },
1420
+ // ---- domains --------------------------------------------------------
1421
+ /** Every hostname claimed for this app, whatever its verification state. */
1422
+ async listDomains(appId) {
1423
+ return request(baseUrl, `/api/v1/apps/${appId}/domains`, apiKey);
1424
+ },
1425
+ /**
1426
+ * Claim a hostname and get the TXT record that proves you own it.
1427
+ *
1428
+ * Returns `201`, and the domain is NESTED at `data.domain` -- this is the one
1429
+ * route on the surface whose payload is not the record itself. Hostnames are
1430
+ * globally unique, so a host another app holds is refused.
1431
+ */
1432
+ async claimDomain(appId, hostname) {
1433
+ const resp = await request(
1434
+ baseUrl,
1435
+ `/api/v1/apps/${appId}/domains`,
1436
+ apiKey,
1437
+ { method: "POST", body: { hostname } }
1438
+ );
1439
+ return unwrap(resp);
1440
+ },
1441
+ /**
1442
+ * Check DNS for the TXT record and advance the domain to `verified`.
1443
+ *
1444
+ * Idempotent: verifying an already-verified domain re-checks and stays
1445
+ * verified, so it is safe to re-run after a DNS change. Send no body -- the
1446
+ * record in DNS is the payload.
1447
+ */
1448
+ async verifyDomain(appId, hostname) {
1449
+ const resp = await request(
1450
+ baseUrl,
1451
+ `/api/v1/apps/${appId}/domains/${encodeURIComponent(hostname)}/verify`,
1452
+ apiKey,
1453
+ { method: "POST", body: {} }
1454
+ );
1455
+ return unwrap(resp);
1456
+ },
1457
+ /**
1458
+ * Release a claimed hostname.
1459
+ *
1460
+ * A HARD delete. Hostnames are globally unique, so a row left behind in any
1461
+ * status keeps the host burned for every other builder. Releasing one you
1462
+ * already released is a `404`, because after the first call the claim
1463
+ * genuinely does not exist.
1464
+ *
1465
+ * Returns the NORMALIZED hostname, which may differ from what you passed.
1466
+ */
1467
+ async releaseDomain(appId, hostname) {
1468
+ const resp = await request(
1469
+ baseUrl,
1470
+ `/api/v1/apps/${appId}/domains/${encodeURIComponent(hostname)}`,
1471
+ apiKey,
1472
+ { method: "DELETE" }
1473
+ );
1474
+ return unwrap(resp);
1475
+ },
1476
+ // ---- secrets --------------------------------------------------------
1477
+ /**
1478
+ * Which secrets this app declares, and when each was last rotated.
1479
+ *
1480
+ * NEVER returns a value. graph8 stores a POINTER into your secret manager and
1481
+ * has no column for the secret itself.
1482
+ */
1483
+ async listSecrets(appId) {
1484
+ return request(baseUrl, `/api/v1/apps/${appId}/secrets`, apiKey);
1485
+ },
1486
+ /**
1487
+ * Declare a secret, or rotate the pointer to it.
1488
+ *
1489
+ * `providerRef` is a REFERENCE, and the server rejects anything that looks
1490
+ * like a credential -- a value starting `bearer `, `sk-`, `ghp_`, `xox` and
1491
+ * friends is a 422. That refusal is the feature: it catches the mistake of
1492
+ * pasting the secret where its address belongs.
1493
+ */
1494
+ async putSecret(appId, secretKey, providerRef) {
1495
+ const resp = await request(
1496
+ baseUrl,
1497
+ `/api/v1/apps/${appId}/secrets/${encodeURIComponent(secretKey)}`,
1498
+ apiKey,
1499
+ { method: "PUT", body: { provider_ref: providerRef ?? null } }
1500
+ );
1501
+ return unwrap(resp);
1502
+ },
1503
+ /** Undeclare a secret. A key the app never declared is a 404, so a typo is
1504
+ * never reported as a successful removal. */
1505
+ async deleteSecret(appId, secretKey) {
1506
+ const resp = await request(
1507
+ baseUrl,
1508
+ `/api/v1/apps/${appId}/secrets/${encodeURIComponent(secretKey)}`,
1509
+ apiKey,
1510
+ { method: "DELETE" }
1511
+ );
1512
+ return unwrap(resp);
1513
+ },
1514
+ // ---- schema versions ------------------------------------------------
1515
+ /**
1516
+ * Publish a custom-object schema version. Returns `201`.
1517
+ *
1518
+ * Takes only the `objects` list, not a whole `graph8.app.yaml`: the rest of
1519
+ * that file is app metadata the control plane already holds, and accepting it
1520
+ * here would create a second place for it to disagree.
1521
+ */
1522
+ async publishSchemaVersion(appId, objects) {
1523
+ const resp = await request(
1524
+ baseUrl,
1525
+ `/api/v1/apps/${appId}/schema-versions`,
1526
+ apiKey,
1527
+ { method: "POST", body: { objects } }
1528
+ );
1529
+ return unwrap(resp);
1530
+ },
1531
+ /** Every schema version this app has published. Empty array, never 404. */
1532
+ async listSchemaVersions(appId) {
1533
+ return request(baseUrl, `/api/v1/apps/${appId}/schema-versions`, apiKey);
1534
+ }
1535
+ };
1536
+ };
1537
+
1538
+ // src/fields.ts
1539
+ var DEFAULT_API19 = "https://be.graph8.com";
1540
+ var createFieldsClient = (apiKey, apiUrl) => {
1541
+ const baseUrl = apiUrl || DEFAULT_API19;
1265
1542
  return {
1266
1543
  /** List contact fields (base + custom). Pass listId to include list-specific custom fields. */
1267
1544
  async listContactFields(listId) {
@@ -1303,9 +1580,9 @@ var createFieldsClient = (apiKey, apiUrl) => {
1303
1580
  };
1304
1581
 
1305
1582
  // src/objects.ts
1306
- var DEFAULT_API19 = "https://be.graph8.com";
1583
+ var DEFAULT_API20 = "https://be.graph8.com";
1307
1584
  var createObjectsClient = (apiKey, apiUrl) => {
1308
- const baseUrl = apiUrl || DEFAULT_API19;
1585
+ const baseUrl = apiUrl || DEFAULT_API20;
1309
1586
  const encode = (value) => encodeURIComponent(value);
1310
1587
  return {
1311
1588
  /** List the custom object types in your workspace. */
@@ -1415,9 +1692,9 @@ var createObjectsClient = (apiKey, apiUrl) => {
1415
1692
  };
1416
1693
 
1417
1694
  // src/deals.ts
1418
- var DEFAULT_API20 = "https://be.graph8.com";
1695
+ var DEFAULT_API21 = "https://be.graph8.com";
1419
1696
  var createDealsClient = (apiKey, apiUrl) => {
1420
- const baseUrl = apiUrl || DEFAULT_API20;
1697
+ const baseUrl = apiUrl || DEFAULT_API21;
1421
1698
  return {
1422
1699
  /** List all deal pipelines and their stages. */
1423
1700
  async pipelines() {
@@ -1461,9 +1738,9 @@ var createDealsClient = (apiKey, apiUrl) => {
1461
1738
  };
1462
1739
 
1463
1740
  // src/inbox.ts
1464
- var DEFAULT_API21 = "https://be.graph8.com";
1741
+ var DEFAULT_API22 = "https://be.graph8.com";
1465
1742
  var createInboxClient = (apiKey, apiUrl) => {
1466
- const baseUrl = apiUrl || DEFAULT_API21;
1743
+ const baseUrl = apiUrl || DEFAULT_API22;
1467
1744
  return {
1468
1745
  /** List inbox threads across email, SMS, and LinkedIn. */
1469
1746
  async list(params = {}) {
@@ -1516,9 +1793,9 @@ var createInboxClient = (apiKey, apiUrl) => {
1516
1793
  };
1517
1794
 
1518
1795
  // src/quotes.ts
1519
- var DEFAULT_API22 = "https://be.graph8.com";
1796
+ var DEFAULT_API23 = "https://be.graph8.com";
1520
1797
  var createQuotesClient = (apiKey, apiUrl) => {
1521
- const baseUrl = apiUrl || DEFAULT_API22;
1798
+ const baseUrl = apiUrl || DEFAULT_API23;
1522
1799
  return {
1523
1800
  /** List quotes org-wide with optional filters and pagination. */
1524
1801
  async list(params = {}) {
@@ -1590,9 +1867,9 @@ var createQuotesClient = (apiKey, apiUrl) => {
1590
1867
  };
1591
1868
 
1592
1869
  // src/pipelines.ts
1593
- var DEFAULT_API23 = "https://be.graph8.com";
1870
+ var DEFAULT_API24 = "https://be.graph8.com";
1594
1871
  var createPipelinesClient = (apiKey, apiUrl) => {
1595
- const baseUrl = apiUrl || DEFAULT_API23;
1872
+ const baseUrl = apiUrl || DEFAULT_API24;
1596
1873
  return {
1597
1874
  /** List all stage-checklist pipelines with stages, evidence, scripts. */
1598
1875
  async list() {
@@ -1674,9 +1951,9 @@ var createPipelinesClient = (apiKey, apiUrl) => {
1674
1951
  };
1675
1952
 
1676
1953
  // src/workflows.ts
1677
- var DEFAULT_API24 = "https://be.graph8.com";
1954
+ var DEFAULT_API25 = "https://be.graph8.com";
1678
1955
  var createWorkflowsClient = (apiKey, apiUrl) => {
1679
- const baseUrl = apiUrl || DEFAULT_API24;
1956
+ const baseUrl = apiUrl || DEFAULT_API25;
1680
1957
  return {
1681
1958
  /** List workflows org-wide. */
1682
1959
  async list(params = {}) {
@@ -1792,9 +2069,9 @@ var createWorkflowsClient = (apiKey, apiUrl) => {
1792
2069
  };
1793
2070
 
1794
2071
  // src/skills.ts
1795
- var DEFAULT_API25 = "https://be.graph8.com";
2072
+ var DEFAULT_API26 = "https://be.graph8.com";
1796
2073
  var createSkillsClient = (apiKey, apiUrl) => {
1797
- const baseUrl = apiUrl || DEFAULT_API25;
2074
+ const baseUrl = apiUrl || DEFAULT_API26;
1798
2075
  return {
1799
2076
  /** List skills. */
1800
2077
  async list(params = {}) {
@@ -1881,9 +2158,9 @@ var createSkillsClient = (apiKey, apiUrl) => {
1881
2158
  };
1882
2159
 
1883
2160
  // src/intent.ts
1884
- var DEFAULT_API26 = "https://be.graph8.com";
2161
+ var DEFAULT_API27 = "https://be.graph8.com";
1885
2162
  var createIntentClient = (apiKey, apiUrl) => {
1886
- const baseUrl = apiUrl || DEFAULT_API26;
2163
+ const baseUrl = apiUrl || DEFAULT_API27;
1887
2164
  const get = (path) => request(baseUrl, `/api/v1${path}`, apiKey);
1888
2165
  const post = (path, body = {}) => request(baseUrl, `/api/v1${path}`, apiKey, { method: "POST", body });
1889
2166
  const del = (path) => request(baseUrl, `/api/v1${path}`, apiKey, { method: "DELETE" });
@@ -1958,9 +2235,9 @@ var createIntentClient = (apiKey, apiUrl) => {
1958
2235
  };
1959
2236
 
1960
2237
  // src/studio.ts
1961
- var DEFAULT_API27 = "https://be.graph8.com";
2238
+ var DEFAULT_API28 = "https://be.graph8.com";
1962
2239
  var createStudioClient = (apiKey, apiUrl) => {
1963
- const baseUrl = apiUrl || DEFAULT_API27;
2240
+ const baseUrl = apiUrl || DEFAULT_API28;
1964
2241
  const get = (path, params = {}) => request(baseUrl, `/api/v1${path}`, apiKey, { query: params });
1965
2242
  const post = (path, body = {}) => request(baseUrl, `/api/v1${path}`, apiKey, { method: "POST", body });
1966
2243
  const patch = (path, body = {}) => request(baseUrl, `/api/v1${path}`, apiKey, { method: "PATCH", body });
@@ -2015,9 +2292,9 @@ var createStudioClient = (apiKey, apiUrl) => {
2015
2292
  };
2016
2293
 
2017
2294
  // src/meetings.ts
2018
- var DEFAULT_API28 = "https://be.graph8.com";
2295
+ var DEFAULT_API29 = "https://be.graph8.com";
2019
2296
  var createMeetingsClient = (apiKey, apiUrl) => {
2020
- const baseUrl = apiUrl || DEFAULT_API28;
2297
+ const baseUrl = apiUrl || DEFAULT_API29;
2021
2298
  return {
2022
2299
  /** List meetings with optional filters. Returns summary rows without transcript / analysis. */
2023
2300
  async list(params = {}) {
@@ -2032,9 +2309,9 @@ var createMeetingsClient = (apiKey, apiUrl) => {
2032
2309
  };
2033
2310
 
2034
2311
  // src/audiences.ts
2035
- var DEFAULT_API29 = "https://be.graph8.com";
2312
+ var DEFAULT_API30 = "https://be.graph8.com";
2036
2313
  var createAudiencesClient = (apiKey, apiUrl) => {
2037
- const baseUrl = apiUrl || DEFAULT_API29;
2314
+ const baseUrl = apiUrl || DEFAULT_API30;
2038
2315
  const base = "/api/v1/audience-syncs";
2039
2316
  return {
2040
2317
  /** List all audience syncs for the organization. */
@@ -2082,9 +2359,9 @@ var createAudiencesClient = (apiKey, apiUrl) => {
2082
2359
  };
2083
2360
 
2084
2361
  // src/search.ts
2085
- var DEFAULT_API30 = "https://be.graph8.com";
2362
+ var DEFAULT_API31 = "https://be.graph8.com";
2086
2363
  var createSearchClient = (apiKey, apiUrl) => {
2087
- const baseUrl = apiUrl || DEFAULT_API30;
2364
+ const baseUrl = apiUrl || DEFAULT_API31;
2088
2365
  const body = (p) => ({ filters: [], page: 1, limit: 25, ...p });
2089
2366
  return {
2090
2367
  /** Search open-data contacts by filter. */
@@ -2115,9 +2392,9 @@ var createSearchClient = (apiKey, apiUrl) => {
2115
2392
  };
2116
2393
 
2117
2394
  // src/agency.ts
2118
- var DEFAULT_API31 = "https://be.graph8.com";
2395
+ var DEFAULT_API32 = "https://be.graph8.com";
2119
2396
  var createAgencyClient = (apiKey, apiUrl) => {
2120
- const baseUrl = apiUrl || DEFAULT_API31;
2397
+ const baseUrl = apiUrl || DEFAULT_API32;
2121
2398
  return {
2122
2399
  /** Describe the agency credential: agency org + authorized client count. */
2123
2400
  async me() {
@@ -2132,9 +2409,9 @@ var createAgencyClient = (apiKey, apiUrl) => {
2132
2409
  };
2133
2410
 
2134
2411
  // src/marketplace.ts
2135
- var DEFAULT_API32 = "https://be.graph8.com";
2412
+ var DEFAULT_API33 = "https://be.graph8.com";
2136
2413
  var createMarketplaceClient = (apiKey, apiUrl) => {
2137
- const baseUrl = apiUrl || DEFAULT_API32;
2414
+ const baseUrl = apiUrl || DEFAULT_API33;
2138
2415
  const base = "/api/v1/marketplace";
2139
2416
  return {
2140
2417
  /** Your own marketplace SDR profile. */
@@ -2184,9 +2461,9 @@ var createMarketplaceClient = (apiKey, apiUrl) => {
2184
2461
  };
2185
2462
 
2186
2463
  // src/snippet.ts
2187
- var DEFAULT_API33 = "https://be.graph8.com";
2464
+ var DEFAULT_API34 = "https://be.graph8.com";
2188
2465
  var createSnippetClient = (apiKey, apiUrl) => {
2189
- const baseUrl = apiUrl || DEFAULT_API33;
2466
+ const baseUrl = apiUrl || DEFAULT_API34;
2190
2467
  return {
2191
2468
  /** Get your org's tracking snippet (write key + React/script-tag embeds + config). */
2192
2469
  async get() {
@@ -2198,7 +2475,7 @@ var createSnippetClient = (apiKey, apiUrl) => {
2198
2475
 
2199
2476
  // src/core.ts
2200
2477
  var DEFAULT_HOST = "https://t.graph8.com";
2201
- var DEFAULT_API34 = "https://be.graph8.com";
2478
+ var DEFAULT_API35 = "https://be.graph8.com";
2202
2479
  var G8 = class {
2203
2480
  constructor() {
2204
2481
  /** @internal */
@@ -2242,6 +2519,8 @@ var G8 = class {
2242
2519
  /** @internal */
2243
2520
  this._apps = null;
2244
2521
  /** @internal */
2522
+ this._appPlatform = null;
2523
+ /** @internal */
2245
2524
  this._objects = null;
2246
2525
  /** @internal */
2247
2526
  this._deals = null;
@@ -2285,7 +2564,7 @@ var G8 = class {
2285
2564
  debug: config.debug
2286
2565
  });
2287
2566
  }
2288
- const apiUrl = config.apiUrl || DEFAULT_API34;
2567
+ const apiUrl = config.apiUrl || DEFAULT_API35;
2289
2568
  const writeKey = config.writeKey || "";
2290
2569
  const apiKey = config.apiKey || "";
2291
2570
  if (writeKey) {
@@ -2309,6 +2588,7 @@ var G8 = class {
2309
2588
  this._tasks = createTasksClient(apiKey, apiUrl);
2310
2589
  this._fields = createFieldsClient(apiKey, apiUrl);
2311
2590
  this._apps = createAppsClient(apiKey, apiUrl);
2591
+ this._appPlatform = createAppPlatformClient(apiKey, apiUrl);
2312
2592
  this._objects = createObjectsClient(apiKey, apiUrl);
2313
2593
  this._deals = createDealsClient(apiKey, apiUrl);
2314
2594
  this._inbox = createInboxClient(apiKey, apiUrl);
@@ -2435,6 +2715,18 @@ var G8 = class {
2435
2715
  this._assertKey("apps");
2436
2716
  return this._apps;
2437
2717
  }
2718
+ /**
2719
+ * Ship a hosted app: bind a source, deploy, promote, attach a hostname, read
2720
+ * build logs (requires API key). PREVIEW.
2721
+ *
2722
+ * Separate from `apps` on purpose. `apps` is the app's IDENTITY -- create it,
2723
+ * see who installed it, what it cost. This is its LIFECYCLE, and the two have
2724
+ * different blast radii: a mistake here takes a customer's app down.
2725
+ */
2726
+ get appPlatform() {
2727
+ this._assertKey("appPlatform");
2728
+ return this._appPlatform;
2729
+ }
2438
2730
  /** Custom object types, their schema, and their records (requires API key). PREVIEW. */
2439
2731
  get objects() {
2440
2732
  this._assertKey("objects");
@@ -2692,9 +2984,12 @@ function createGraph8ServiceClient(config) {
2692
2984
  DEFAULT_APP_API,
2693
2985
  G8Error,
2694
2986
  KNOWN_WEBHOOK_EVENTS,
2987
+ MAX_TAIL_LINES,
2988
+ MIN_TAIL_LINES,
2695
2989
  WebhookSignatureError,
2696
2990
  backoffDelayMs,
2697
2991
  constructEvent,
2992
+ createAppPlatformClient,
2698
2993
  createAppRequester,
2699
2994
  createGraph8AppClient,
2700
2995
  createGraph8ServiceClient,