@superblocksteam/sdk 1.5.1 → 1.6.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/client.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ComponentEvent, LocalGitRepoState, SuperblocksResourceType } from "@superblocksteam/util";
2
- import { RemoteCommitDto, UserMeDto } from "./types";
2
+ import { ApiWithPb, Page, RemoteCommitDto, UserMeDto } from "./types";
3
3
  export type ViewMode = "export-deployed" | "export-latest" | "export-live";
4
4
  export interface UploadFile {
5
5
  name: string;
@@ -8,13 +8,22 @@ export interface UploadFile {
8
8
  }
9
9
  export interface ApplicationWrapper {
10
10
  application: Record<string, any>;
11
- page: Record<string, any>;
11
+ page: Page;
12
+ apis: ApiWithPb[];
13
+ }
14
+ export interface MultiPageApplicationWrapper {
15
+ application: Record<string, any>;
16
+ pages: Page[];
12
17
  apis: Record<string, any>[];
13
18
  }
14
19
  export type PushApplicationWithCommitConfig = ApplicationWrapper & {
15
20
  commitId: string;
16
21
  commitMessage: string;
17
22
  };
23
+ export type PushMultiPageApplicationWithCommitConfig = MultiPageApplicationWrapper & {
24
+ commitId: string;
25
+ commitMessage: string;
26
+ };
18
27
  export interface ApiWrapper {
19
28
  apiPb: Record<string, any>;
20
29
  name?: string;
@@ -31,7 +40,7 @@ export type Branch = {
31
40
  name: string;
32
41
  isDefault: boolean;
33
42
  };
34
- export declare function fetchApplication({ cliVersion, applicationId, branch, token, superblocksBaseUrl, viewMode, injectedHeaders, }: {
43
+ export declare function fetchApplication({ cliVersion, applicationId, branch, token, superblocksBaseUrl, viewMode, injectedHeaders, fetchSinglePageApplication, }: {
35
44
  cliVersion: string;
36
45
  applicationId: string;
37
46
  branch?: string;
@@ -39,7 +48,8 @@ export declare function fetchApplication({ cliVersion, applicationId, branch, to
39
48
  superblocksBaseUrl: string;
40
49
  viewMode: ViewMode;
41
50
  injectedHeaders: Record<string, string>;
42
- }): Promise<ApplicationWrapper | undefined>;
51
+ fetchSinglePageApplication: boolean;
52
+ }): Promise<ApplicationWrapper | MultiPageApplicationWrapper | undefined>;
43
53
  export declare function fetchApplicationBranches({ cliVersion, applicationId, token, superblocksBaseUrl, injectedHeaders, }: {
44
54
  cliVersion: string;
45
55
  applicationId: string;
@@ -47,7 +57,7 @@ export declare function fetchApplicationBranches({ cliVersion, applicationId, to
47
57
  superblocksBaseUrl: string;
48
58
  injectedHeaders: Record<string, string>;
49
59
  }): Promise<Branches | undefined>;
50
- export declare function fetchApplicationWithComponents({ cliVersion, applicationId, branch, token, superblocksBaseUrl, viewMode, injectedHeaders, }: {
60
+ export declare function fetchApplicationWithComponents({ cliVersion, applicationId, branch, token, superblocksBaseUrl, viewMode, injectedHeaders, fetchSinglePageApplication, }: {
51
61
  cliVersion: string;
52
62
  applicationId: string;
53
63
  branch: string;
@@ -55,7 +65,8 @@ export declare function fetchApplicationWithComponents({ cliVersion, application
55
65
  superblocksBaseUrl: string;
56
66
  viewMode: ViewMode;
57
67
  injectedHeaders: Record<string, string>;
58
- }): Promise<(ApplicationWrapper & {
68
+ fetchSinglePageApplication?: boolean;
69
+ }): Promise<((ApplicationWrapper | MultiPageApplicationWrapper) & {
59
70
  componentFiles: any;
60
71
  }) | undefined>;
61
72
  export declare function fetchApplications(cliVersion: string, token: string, superblocksBaseUrl: string, injectedHeaders?: Record<string, string>): Promise<any>;
@@ -75,14 +86,15 @@ export declare function uploadComponents({ cliVersion, applicationId, componentC
75
86
  branch: string | null;
76
87
  }): Promise<void>;
77
88
  export declare function fetchCurrentUser(cliVersion: string, token: string, superblocksBaseUrl: string): Promise<UserMeDto>;
78
- export declare function pushApplication({ cliVersion, applicationId, token, superblocksBaseUrl, applicationConfig, branch, injectedHeaders, }: {
89
+ export declare function pushApplication({ cliVersion, applicationId, token, superblocksBaseUrl, applicationConfig, branch, injectedHeaders, multiPage, }: {
79
90
  cliVersion: string;
80
91
  applicationId: string;
81
92
  token: string;
82
93
  superblocksBaseUrl: string;
83
94
  branch: string;
84
95
  injectedHeaders: Record<string, string>;
85
- applicationConfig: PushApplicationWithCommitConfig;
96
+ applicationConfig: PushApplicationWithCommitConfig | PushMultiPageApplicationWithCommitConfig;
97
+ multiPage?: boolean;
86
98
  }): Promise<RemoteCommitDto | undefined>;
87
99
  export declare function pushApi({ cliVersion, apiId, token, superblocksBaseUrl, apiConfig, branch, injectedHeaders, }: {
88
100
  cliVersion: string;
package/dist/client.js CHANGED
@@ -13,16 +13,19 @@ const socket_1 = require("./socket");
13
13
  const types_1 = require("./types");
14
14
  const utils_1 = require("./utils");
15
15
  const BASE_BUCKETEER_URL = "api";
16
- const BASE_SERVER_PUBLIC_API_URL = "api/v1/public";
16
+ const BASE_SERVER_PUBLIC_API_URL_V1 = "api/v1/public";
17
+ const BASE_SERVER_PUBLIC_API_URL_v2 = "api/v2/public";
17
18
  const SUPERBLOCKS_MAX_FILE_SIZE_MB = 10;
18
19
  const CLI_VERSION_HEADER = "x-superblocks-cli-version";
19
20
  const SUPERBLOCKS_URL_HEADER = "x-superblocks-url";
20
- async function fetchApplication({ cliVersion, applicationId, branch, token, superblocksBaseUrl, viewMode, injectedHeaders = {}, }) {
21
- const serverURL = branch
22
- ? new URL(`${BASE_SERVER_PUBLIC_API_URL}/applications/${applicationId}/branches/${encodeURIComponent(branch)}?viewMode=${viewMode}`, superblocksBaseUrl)
23
- : new URL(`${BASE_SERVER_PUBLIC_API_URL}/applications/${applicationId}?viewMode=${viewMode}`, superblocksBaseUrl);
24
- let serverResponse;
21
+ async function fetchApplication({ cliVersion, applicationId, branch, token, superblocksBaseUrl, viewMode, injectedHeaders = {}, fetchSinglePageApplication, }) {
25
22
  try {
23
+ const baseServerUrl = fetchSinglePageApplication
24
+ ? BASE_SERVER_PUBLIC_API_URL_V1
25
+ : BASE_SERVER_PUBLIC_API_URL_v2;
26
+ const serverURL = branch
27
+ ? new URL(`${baseServerUrl}/applications/${applicationId}/branches/${encodeURIComponent(branch)}?viewMode=${viewMode}`, superblocksBaseUrl)
28
+ : new URL(`${baseServerUrl}/applications/${applicationId}?viewMode=${viewMode}`, superblocksBaseUrl);
26
29
  const config = {
27
30
  method: "get",
28
31
  url: serverURL.toString(),
@@ -32,7 +35,9 @@ async function fetchApplication({ cliVersion, applicationId, branch, token, supe
32
35
  ...injectedHeaders,
33
36
  },
34
37
  };
35
- serverResponse = await (0, axios_1.default)(config);
38
+ const serverResponse = await (0, axios_1.default)(config);
39
+ const data = serverResponse?.data?.data;
40
+ return data;
36
41
  }
37
42
  catch (e) {
38
43
  if (axios_1.default.isAxiosError(e) && e.response?.status === 404) {
@@ -40,7 +45,6 @@ async function fetchApplication({ cliVersion, applicationId, branch, token, supe
40
45
  }
41
46
  throw new Error("Could not fetch application");
42
47
  }
43
- return serverResponse?.data?.data;
44
48
  }
45
49
  exports.fetchApplication = fetchApplication;
46
50
  async function fetchApplicationBranches({ cliVersion, applicationId, token, superblocksBaseUrl, injectedHeaders = {}, }) {
@@ -67,7 +71,7 @@ async function fetchApplicationBranches({ cliVersion, applicationId, token, supe
67
71
  return serverResponse?.data?.data;
68
72
  }
69
73
  exports.fetchApplicationBranches = fetchApplicationBranches;
70
- async function fetchApplicationWithComponents({ cliVersion, applicationId, branch, token, superblocksBaseUrl, viewMode, injectedHeaders = {}, }) {
74
+ async function fetchApplicationWithComponents({ cliVersion, applicationId, branch, token, superblocksBaseUrl, viewMode, injectedHeaders = {}, fetchSinglePageApplication = false, }) {
71
75
  const applicationWrapper = await fetchApplication({
72
76
  cliVersion,
73
77
  applicationId,
@@ -76,6 +80,7 @@ async function fetchApplicationWithComponents({ cliVersion, applicationId, branc
76
80
  superblocksBaseUrl,
77
81
  viewMode,
78
82
  injectedHeaders,
83
+ fetchSinglePageApplication,
79
84
  });
80
85
  if ((0, lodash_1.isEmpty)(applicationWrapper)) {
81
86
  return;
@@ -91,9 +96,10 @@ async function fetchApplicationWithComponents({ cliVersion, applicationId, branc
91
96
  const commitId = "latest";
92
97
  superblocksBaseUrl = superblocksBaseUrl.replace(/\/$/, "");
93
98
  const bucketeerBaseUrl = (0, util_1.getBucketeerUrlFromSuperblocksUrl)(superblocksBaseUrl);
99
+ const multiPage = fetchSinglePageApplication ? "false" : "true";
94
100
  // fetch files from bucketeer
95
101
  const branchPath = branch ? `/branches/${encodeURIComponent(branch)}` : "";
96
- const componentFileURL = new URL(`${BASE_BUCKETEER_URL}/v1/components/${applicationId}${branchPath}?commit=${commitId}&viewMode=${viewMode}`, bucketeerBaseUrl).toString();
102
+ const componentFileURL = new URL(`${BASE_BUCKETEER_URL}/v1/components/${applicationId}${branchPath}?commit=${commitId}&viewMode=${viewMode}&multiPage=${multiPage}`, bucketeerBaseUrl).toString();
97
103
  try {
98
104
  const config = {
99
105
  method: "get",
@@ -119,7 +125,7 @@ async function fetchApplications(cliVersion, token, superblocksBaseUrl, injected
119
125
  try {
120
126
  const config = {
121
127
  method: "get",
122
- url: new URL(`${BASE_SERVER_PUBLIC_API_URL}/applications`, superblocksBaseUrl).toString(),
128
+ url: new URL(`${BASE_SERVER_PUBLIC_API_URL_V1}/applications`, superblocksBaseUrl).toString(),
123
129
  headers: {
124
130
  Authorization: "Bearer " + token,
125
131
  [CLI_VERSION_HEADER]: cliVersion,
@@ -149,8 +155,8 @@ exports.fetchApplications = fetchApplications;
149
155
  async function fetchApi(cliVersion, apiId, token, superblocksBaseUrl, viewMode, branch) {
150
156
  try {
151
157
  const serverURL = branch
152
- ? new URL(`${BASE_SERVER_PUBLIC_API_URL}/apis/${apiId}/branches/${encodeURIComponent(branch)}?viewMode=${viewMode}`, superblocksBaseUrl)
153
- : new URL(`${BASE_SERVER_PUBLIC_API_URL}/apis/${apiId}?viewMode=${viewMode}`, superblocksBaseUrl);
158
+ ? new URL(`${BASE_SERVER_PUBLIC_API_URL_V1}/apis/${apiId}/branches/${encodeURIComponent(branch)}?viewMode=${viewMode}`, superblocksBaseUrl)
159
+ : new URL(`${BASE_SERVER_PUBLIC_API_URL_V1}/apis/${apiId}?viewMode=${viewMode}`, superblocksBaseUrl);
154
160
  const config = {
155
161
  method: "get",
156
162
  url: new URL(serverURL, superblocksBaseUrl).toString(),
@@ -174,7 +180,7 @@ async function fetchApis(cliVersion, token, superblocksBaseUrl) {
174
180
  try {
175
181
  const config = {
176
182
  method: "get",
177
- url: new URL(`${BASE_SERVER_PUBLIC_API_URL}/apis`, superblocksBaseUrl).toString(),
183
+ url: new URL(`${BASE_SERVER_PUBLIC_API_URL_V1}/apis`, superblocksBaseUrl).toString(),
178
184
  headers: {
179
185
  Authorization: "Bearer " + token,
180
186
  [CLI_VERSION_HEADER]: cliVersion,
@@ -210,7 +216,7 @@ async function validateGitSetup(cliVersion, resourceId, resourceType, event, loc
210
216
  }
211
217
  const config = {
212
218
  method: "post",
213
- url: new URL(`${BASE_SERVER_PUBLIC_API_URL}/${path}`, superblocksBaseUrl).toString(),
219
+ url: new URL(`${BASE_SERVER_PUBLIC_API_URL_V1}/${path}`, superblocksBaseUrl).toString(),
214
220
  headers: {
215
221
  Authorization: "Bearer " + token,
216
222
  [CLI_VERSION_HEADER]: cliVersion,
@@ -274,7 +280,7 @@ async function registerComponents(cliVersion, applicationId, componentConfigs, t
274
280
  else {
275
281
  const config = {
276
282
  method: "put",
277
- url: new URL(`${BASE_SERVER_PUBLIC_API_URL}/application/${applicationId}${branchPath}/components`, superblocksBaseUrl).toString(),
283
+ url: new URL(`${BASE_SERVER_PUBLIC_API_URL_V1}/application/${applicationId}${branchPath}/components`, superblocksBaseUrl).toString(),
278
284
  headers: {
279
285
  Authorization: "Bearer " + token,
280
286
  [CLI_VERSION_HEADER]: cliVersion,
@@ -406,7 +412,7 @@ async function fetchCurrentUser(cliVersion, token, superblocksBaseUrl) {
406
412
  try {
407
413
  const config = {
408
414
  method: "get",
409
- url: new URL(`${BASE_SERVER_PUBLIC_API_URL}/users/me`, superblocksBaseUrl).toString(),
415
+ url: new URL(`${BASE_SERVER_PUBLIC_API_URL_V1}/users/me`, superblocksBaseUrl).toString(),
410
416
  headers: {
411
417
  Authorization: "Bearer " + token,
412
418
  [CLI_VERSION_HEADER]: cliVersion,
@@ -433,9 +439,15 @@ async function fetchCurrentUser(cliVersion, token, superblocksBaseUrl) {
433
439
  }
434
440
  }
435
441
  exports.fetchCurrentUser = fetchCurrentUser;
436
- async function pushApplication({ cliVersion, applicationId, token, superblocksBaseUrl, applicationConfig, branch, injectedHeaders = {}, }) {
437
- const serverURL = new URL(`${BASE_SERVER_PUBLIC_API_URL}/applications/${applicationId}/branches/${encodeURIComponent(branch)}/push`, superblocksBaseUrl);
438
- let serverResponse;
442
+ async function pushApplication({ cliVersion, applicationId, token, superblocksBaseUrl, applicationConfig, branch, injectedHeaders = {}, multiPage = false, }) {
443
+ const handleHttpError = (status) => {
444
+ if (status === 405) {
445
+ throw new errors_1.BranchNotCheckedOutError(`Branch ${branch} is not checked out`);
446
+ }
447
+ else if (status === 409) {
448
+ throw new errors_1.CommitAlreadyExistsError(`Commit ${applicationConfig.commitId} already exists`);
449
+ }
450
+ };
439
451
  try {
440
452
  const userMe = await fetchCurrentUser(cliVersion, token, superblocksBaseUrl);
441
453
  const organization = userMe.organizations[0];
@@ -448,19 +460,40 @@ async function pushApplication({ cliVersion, applicationId, token, superblocksBa
448
460
  superblocksBaseUrl,
449
461
  token,
450
462
  });
451
- const resp = await socket.call.v1.public.application.pushCommit({
452
- applicationId,
453
- apis: applicationConfig.apis,
454
- application: applicationConfig.application,
455
- branchName: branch,
456
- commitId: applicationConfig.commitId,
457
- commitMessage: applicationConfig.commitMessage,
458
- page: applicationConfig.page,
459
- });
463
+ const resp = multiPage
464
+ ? await socket.call.v2.public.application.pushCommit({
465
+ applicationId,
466
+ apis: applicationConfig.apis,
467
+ application: applicationConfig.application,
468
+ branchName: branch,
469
+ commitId: applicationConfig.commitId,
470
+ commitMessage: applicationConfig.commitMessage,
471
+ pages: applicationConfig.pages,
472
+ })
473
+ : await socket.call.v1.public.application.pushCommit({
474
+ applicationId,
475
+ apis: applicationConfig.apis,
476
+ application: applicationConfig.application,
477
+ branchName: branch,
478
+ commitId: applicationConfig.commitId,
479
+ commitMessage: applicationConfig.commitMessage,
480
+ page: applicationConfig.page,
481
+ });
460
482
  socket.close();
483
+ handleHttpError(resp.responseMeta.status);
484
+ if (resp.responseMeta.status !== 200) {
485
+ // Get the raw error message from the server and throw it. The outer try-catch block will wrap it in a nicer error message
486
+ const message = resp?.responseMeta?.message ?? JSON.stringify(resp?.data);
487
+ throw new Error(message);
488
+ }
461
489
  return resp.data;
462
490
  }
463
491
  else {
492
+ // v1 calls can be removed once all customers move to multi page
493
+ const baseServerPublicApiUrl = multiPage
494
+ ? BASE_SERVER_PUBLIC_API_URL_v2
495
+ : BASE_SERVER_PUBLIC_API_URL_V1;
496
+ const serverURL = new URL(`${baseServerPublicApiUrl}/applications/${applicationId}/branches/${encodeURIComponent(branch)}/push`, superblocksBaseUrl);
464
497
  const config = {
465
498
  method: "post",
466
499
  url: serverURL.toString(),
@@ -471,31 +504,42 @@ async function pushApplication({ cliVersion, applicationId, token, superblocksBa
471
504
  },
472
505
  data: applicationConfig,
473
506
  };
474
- serverResponse = await (0, axios_1.default)(config);
507
+ try {
508
+ const serverResponse = await (0, axios_1.default)(config);
509
+ return serverResponse?.data?.data;
510
+ }
511
+ catch (e) {
512
+ if (!axios_1.default.isAxiosError(e)) {
513
+ throw e;
514
+ }
515
+ handleHttpError(e.response?.data?.responseMeta?.status ?? e.response?.status);
516
+ const message = e.response?.data?.responseMeta?.message ??
517
+ JSON.stringify(e.response?.data) ??
518
+ e.response?.statusText;
519
+ throw new Error(message);
520
+ }
475
521
  }
476
522
  }
477
523
  catch (e) {
478
- if (axios_1.default.isAxiosError(e)) {
479
- const respCode = e.response?.data?.responseMeta?.status ?? e.response?.status;
480
- if (respCode === 405) {
481
- throw new errors_1.BranchNotCheckedOutError(`Branch ${branch} is not checked out`);
482
- }
483
- else if (respCode === 409) {
484
- throw new errors_1.CommitAlreadyExistsError(`Commit ${applicationConfig.commitId} already exists`);
485
- }
486
- const message = e.response?.data?.responseMeta?.message ??
487
- JSON.stringify(e.response?.data) ??
488
- e.response?.statusText;
489
- throw new Error(`Could not push application ${message ? "\n" + message : ""}`);
524
+ if (e instanceof errors_1.BranchNotCheckedOutError ||
525
+ e instanceof errors_1.CommitAlreadyExistsError) {
526
+ // Rethrow these exceptions because they will be handled higher up the call stack
527
+ throw e;
490
528
  }
491
529
  throw new Error(`Could not push application ${e.message ? "\n" + e.message : ""}`);
492
530
  }
493
- return serverResponse?.data?.data;
494
531
  }
495
532
  exports.pushApplication = pushApplication;
496
533
  async function pushApi({ cliVersion, apiId, token, superblocksBaseUrl, apiConfig, branch, injectedHeaders = {}, }) {
497
- const serverURL = new URL(`${BASE_SERVER_PUBLIC_API_URL}/apis/${apiId}/branches/${encodeURIComponent(branch)}/push`, superblocksBaseUrl);
498
- let serverResponse;
534
+ const handleHttpError = (status) => {
535
+ if (status === 405) {
536
+ throw new errors_1.BranchNotCheckedOutError(`Branch ${branch} is not checked out`);
537
+ }
538
+ else if (status === 409) {
539
+ throw new errors_1.CommitAlreadyExistsError(`Commit ${apiConfig.commitId} already exists`);
540
+ }
541
+ };
542
+ const serverURL = new URL(`${BASE_SERVER_PUBLIC_API_URL_V1}/apis/${apiId}/branches/${encodeURIComponent(branch)}/push`, superblocksBaseUrl);
499
543
  try {
500
544
  const userMe = await fetchCurrentUser(cliVersion, token, superblocksBaseUrl);
501
545
  const organization = userMe.organizations[0];
@@ -515,6 +559,12 @@ async function pushApi({ cliVersion, apiId, token, superblocksBaseUrl, apiConfig
515
559
  commitMessage: apiConfig.commitMessage,
516
560
  });
517
561
  socket.close();
562
+ handleHttpError(resp.responseMeta.status);
563
+ if (resp.responseMeta.status !== 200) {
564
+ // Get the raw error message from the server and throw it. The outer try-catch block will wrap it in a nicer error message
565
+ const message = resp?.responseMeta?.message ?? JSON.stringify(resp?.data);
566
+ throw new Error(message);
567
+ }
518
568
  return resp.data;
519
569
  }
520
570
  else {
@@ -528,24 +578,32 @@ async function pushApi({ cliVersion, apiId, token, superblocksBaseUrl, apiConfig
528
578
  },
529
579
  data: apiConfig,
530
580
  };
531
- serverResponse = await (0, axios_1.default)(config);
581
+ try {
582
+ const serverResponse = await (0, axios_1.default)(config);
583
+ return serverResponse?.data?.data;
584
+ }
585
+ catch (e) {
586
+ if (!axios_1.default.isAxiosError(e)) {
587
+ throw e;
588
+ }
589
+ handleHttpError(e.response?.data?.responseMeta?.status);
590
+ const message = e.response?.data?.responseMeta?.message ??
591
+ JSON.stringify(e.response?.data) ??
592
+ e.response?.statusText;
593
+ throw new Error(message);
594
+ }
532
595
  }
533
596
  }
534
597
  catch (e) {
535
- if (axios_1.default.isAxiosError(e)) {
536
- if (e.response?.data?.responseMeta?.status === 405) {
537
- throw new errors_1.BranchNotCheckedOutError(`Branch ${branch} is not checked out`);
538
- }
539
- else if (e.response?.data?.responseMeta?.status === 409) {
540
- throw new errors_1.CommitAlreadyExistsError(`Commit ${apiConfig.commitId} already exists`);
541
- }
542
- const message = e.response?.data?.responseMeta?.message ??
543
- JSON.stringify(e.response?.data) ??
544
- e.response?.statusText;
545
- throw new Error(`Could not push api ${message ? "\n" + message : ""}`);
598
+ if (e instanceof errors_1.BranchNotCheckedOutError ||
599
+ e instanceof errors_1.CommitAlreadyExistsError) {
600
+ // Rethrow these exceptions because they will be handled higher up the call stack
601
+ throw e;
546
602
  }
547
603
  throw new Error(`Could not push api ${e.message ? "\n" + e.message : ""}`);
548
604
  }
549
- return serverResponse?.data?.data;
550
605
  }
551
606
  exports.pushApi = pushApi;
607
+ function isMultiPageApplicationWrapper(data) {
608
+ return data.pages !== undefined;
609
+ }
package/dist/sdk.d.ts CHANGED
@@ -1,24 +1,26 @@
1
1
  import { ComponentEvent, LocalGitRepoState, SuperblocksResourceType } from "@superblocksteam/util";
2
- import { PushApiWithCommitConfig, PushApplicationWithCommitConfig, ViewMode } from "./client";
2
+ import { PushApiWithCommitConfig, PushApplicationWithCommitConfig, PushMultiPageApplicationWithCommitConfig, ViewMode } from "./client";
3
3
  export * from "./errors";
4
4
  export declare class SuperblocksSdk {
5
5
  token: string;
6
6
  superblocksBaseUrl: string;
7
7
  cliVersion: string;
8
8
  constructor(accessToken: string, superblocksBaseUrl: string, cliVersion: string);
9
- fetchApplication({ applicationId, branch, headers, viewMode, }: {
9
+ fetchApplication({ applicationId, branch, headers, viewMode, fetchSinglePageApplication, }: {
10
10
  applicationId: string;
11
11
  branch?: string;
12
12
  headers?: Record<string, string>;
13
13
  viewMode?: ViewMode;
14
- }): Promise<import("./client").ApplicationWrapper | undefined>;
14
+ fetchSinglePageApplication?: boolean;
15
+ }): Promise<import("./client").ApplicationWrapper | import("./client").MultiPageApplicationWrapper | undefined>;
15
16
  fetchApplicationBranches(applicationId: string, headers?: {}): Promise<import("./client").Branches | undefined>;
16
- fetchApplicationWithComponents({ applicationId, branch, headers, viewMode, }: {
17
+ fetchApplicationWithComponents({ applicationId, branch, headers, viewMode, fetchSinglePageApplication, }: {
17
18
  applicationId: string;
18
19
  branch: string;
19
20
  headers?: Record<string, string>;
20
21
  viewMode?: ViewMode;
21
- }): Promise<(import("./client").ApplicationWrapper & {
22
+ fetchSinglePageApplication?: boolean;
23
+ }): Promise<((import("./client").ApplicationWrapper | import("./client").MultiPageApplicationWrapper) & {
22
24
  componentFiles: any;
23
25
  }) | undefined>;
24
26
  fetchApplications(headers?: Record<string, string>): Promise<any>;
@@ -30,11 +32,12 @@ export declare class SuperblocksSdk {
30
32
  registerComponents(applicationId: string, componentConfigs: Record<string, any>, branch: string | null, injectedHeaders: Record<string, string>): Promise<any>;
31
33
  uploadComponents(applicationId: string, componentConfigs: Record<string, any>, files: string[], branch: string | null): Promise<void>;
32
34
  fetchCurrentUser(): Promise<import("./types").UserMeDto>;
33
- pushApplication({ applicationId, applicationConfig, branch, headers, }: {
35
+ pushApplication({ applicationId, applicationConfig, branch, headers, multiPage, }: {
34
36
  applicationId: string;
35
- applicationConfig: PushApplicationWithCommitConfig;
37
+ applicationConfig: PushApplicationWithCommitConfig | PushMultiPageApplicationWithCommitConfig;
36
38
  branch: string;
37
39
  headers?: Record<string, string>;
40
+ multiPage?: boolean;
38
41
  }): Promise<import("./types").RemoteCommitDto | undefined>;
39
42
  pushApi({ apiId, apiConfig, branch, headers, }: {
40
43
  apiId: string;
package/dist/sdk.js CHANGED
@@ -14,7 +14,7 @@ class SuperblocksSdk {
14
14
  this.superblocksBaseUrl = superblocksBaseUrl;
15
15
  this.cliVersion = cliVersion;
16
16
  }
17
- async fetchApplication({ applicationId, branch, headers = {}, viewMode = "export-live", }) {
17
+ async fetchApplication({ applicationId, branch, headers = {}, viewMode = "export-live", fetchSinglePageApplication = false, }) {
18
18
  return (0, client_1.fetchApplication)({
19
19
  cliVersion: this.cliVersion,
20
20
  applicationId,
@@ -23,6 +23,7 @@ class SuperblocksSdk {
23
23
  superblocksBaseUrl: this.superblocksBaseUrl,
24
24
  viewMode,
25
25
  injectedHeaders: headers,
26
+ fetchSinglePageApplication,
26
27
  });
27
28
  }
28
29
  async fetchApplicationBranches(applicationId, headers = {}) {
@@ -34,7 +35,7 @@ class SuperblocksSdk {
34
35
  injectedHeaders: headers,
35
36
  });
36
37
  }
37
- async fetchApplicationWithComponents({ applicationId, branch, headers = {}, viewMode = "export-live", }) {
38
+ async fetchApplicationWithComponents({ applicationId, branch, headers = {}, viewMode = "export-live", fetchSinglePageApplication = false, }) {
38
39
  return (0, client_1.fetchApplicationWithComponents)({
39
40
  cliVersion: this.cliVersion,
40
41
  applicationId,
@@ -43,6 +44,7 @@ class SuperblocksSdk {
43
44
  superblocksBaseUrl: this.superblocksBaseUrl,
44
45
  viewMode,
45
46
  injectedHeaders: headers,
47
+ fetchSinglePageApplication,
46
48
  });
47
49
  }
48
50
  async fetchApplications(headers) {
@@ -74,7 +76,7 @@ class SuperblocksSdk {
74
76
  async fetchCurrentUser() {
75
77
  return (0, client_1.fetchCurrentUser)(this.cliVersion, this.token, this.superblocksBaseUrl);
76
78
  }
77
- async pushApplication({ applicationId, applicationConfig, branch, headers = {}, }) {
79
+ async pushApplication({ applicationId, applicationConfig, branch, headers = {}, multiPage = false, }) {
78
80
  return (0, client_1.pushApplication)({
79
81
  cliVersion: this.cliVersion,
80
82
  applicationId,
@@ -83,6 +85,7 @@ class SuperblocksSdk {
83
85
  branch,
84
86
  injectedHeaders: headers,
85
87
  applicationConfig,
88
+ multiPage,
86
89
  });
87
90
  }
88
91
  async pushApi({ apiId, apiConfig, branch, headers = {}, }) {
@@ -38,6 +38,7 @@ type ResponseDto<T> = {
38
38
  export type ResponseMeta = {
39
39
  status: number;
40
40
  success: boolean;
41
+ message?: string;
41
42
  error?: APIResponseError;
42
43
  };
43
44
  type APIResponseError = {
@@ -97,6 +98,21 @@ export interface ServerMethods {
97
98
  };
98
99
  };
99
100
  };
101
+ v2: {
102
+ public: {
103
+ application: {
104
+ pushCommit: ServerMethodSchema<{
105
+ applicationId: string;
106
+ branchName: string;
107
+ commitId: string;
108
+ commitMessage: string;
109
+ application: Record<string, unknown>;
110
+ pages: Record<string, unknown>[];
111
+ apis: Record<string, unknown>[];
112
+ }, RemoteCommitDto>;
113
+ };
114
+ };
115
+ };
100
116
  }
101
117
  export declare function createRequestHandlers({ agentUrl, token, }: {
102
118
  token: string;
@@ -6,6 +6,7 @@ export interface UserMeDto {
6
6
  }
7
7
  export interface FlagBootstrap {
8
8
  "ui.enable-resource-signing"?: boolean;
9
+ "server.multipage.enabled"?: boolean;
9
10
  }
10
11
  export type User = {
11
12
  id: string;
@@ -95,6 +96,19 @@ export type Api = {
95
96
  trigger: any;
96
97
  signature?: Signature;
97
98
  };
99
+ export type ApiWithPb = {
100
+ id: string;
101
+ pageId?: string;
102
+ apiPb: Api;
103
+ };
104
+ export type Page = {
105
+ id: string;
106
+ applicationId: string;
107
+ isHidden: boolean;
108
+ layouts: Record<string, unknown>[];
109
+ name: string;
110
+ apis: ApiWithPb[];
111
+ };
98
112
  /** A signature, as produced by the agent. */
99
113
  export interface Signature {
100
114
  /** The id of the key used to sign the data. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superblocksteam/sdk",
3
- "version": "1.5.1",
3
+ "version": "1.6.0",
4
4
  "description": "Superblocks JS SDK",
5
5
  "main": "./dist/index.js",
6
6
  "exports": {
@@ -31,7 +31,7 @@
31
31
  "typescript": "^5.1.3"
32
32
  },
33
33
  "dependencies": {
34
- "@superblocksteam/util": "1.5.1",
34
+ "@superblocksteam/util": "1.6.0",
35
35
  "axios": "^1.3.5",
36
36
  "isomorphic-ws": "^5.0.0"
37
37
  },
package/src/client.ts CHANGED
@@ -16,11 +16,18 @@ import { isEmpty } from "lodash";
16
16
  import { BranchNotCheckedOutError, CommitAlreadyExistsError } from "./errors";
17
17
  import { signingEnabled } from "./flag";
18
18
  import { connectToISocketRPCServer } from "./socket";
19
- import { AgentType, RemoteCommitDto, UserMeDto } from "./types";
19
+ import {
20
+ AgentType,
21
+ ApiWithPb,
22
+ Page,
23
+ RemoteCommitDto,
24
+ UserMeDto,
25
+ } from "./types";
20
26
  import { getAgentUrl } from "./utils";
21
27
 
22
28
  const BASE_BUCKETEER_URL = "api";
23
- const BASE_SERVER_PUBLIC_API_URL = "api/v1/public";
29
+ const BASE_SERVER_PUBLIC_API_URL_V1 = "api/v1/public";
30
+ const BASE_SERVER_PUBLIC_API_URL_v2 = "api/v2/public";
24
31
 
25
32
  const SUPERBLOCKS_MAX_FILE_SIZE_MB = 10;
26
33
 
@@ -37,7 +44,13 @@ export interface UploadFile {
37
44
 
38
45
  export interface ApplicationWrapper {
39
46
  application: Record<string, any>;
40
- page: Record<string, any>;
47
+ page: Page;
48
+ apis: ApiWithPb[];
49
+ }
50
+
51
+ export interface MultiPageApplicationWrapper {
52
+ application: Record<string, any>;
53
+ pages: Page[];
41
54
  apis: Record<string, any>[];
42
55
  }
43
56
 
@@ -46,6 +59,12 @@ export type PushApplicationWithCommitConfig = ApplicationWrapper & {
46
59
  commitMessage: string;
47
60
  };
48
61
 
62
+ export type PushMultiPageApplicationWithCommitConfig =
63
+ MultiPageApplicationWrapper & {
64
+ commitId: string;
65
+ commitMessage: string;
66
+ };
67
+
49
68
  export interface ApiWrapper {
50
69
  apiPb: Record<string, any>;
51
70
  name?: string; //@deprecated this attribute is used for getting a name for backends(jobs and workflows) that were never migrated to the new API version.
@@ -76,6 +95,7 @@ export async function fetchApplication({
76
95
  superblocksBaseUrl,
77
96
  viewMode,
78
97
  injectedHeaders = {},
98
+ fetchSinglePageApplication,
79
99
  }: {
80
100
  cliVersion: string;
81
101
  applicationId: string;
@@ -84,22 +104,24 @@ export async function fetchApplication({
84
104
  superblocksBaseUrl: string;
85
105
  viewMode: ViewMode;
86
106
  injectedHeaders: Record<string, string>;
87
- }): Promise<ApplicationWrapper | undefined> {
88
- const serverURL = branch
89
- ? new URL(
90
- `${BASE_SERVER_PUBLIC_API_URL}/applications/${applicationId}/branches/${encodeURIComponent(
91
- branch
92
- )}?viewMode=${viewMode}`,
93
- superblocksBaseUrl
94
- )
95
- : new URL(
96
- `${BASE_SERVER_PUBLIC_API_URL}/applications/${applicationId}?viewMode=${viewMode}`,
97
- superblocksBaseUrl
98
- );
99
-
100
- let serverResponse;
101
-
107
+ fetchSinglePageApplication: boolean;
108
+ }): Promise<ApplicationWrapper | MultiPageApplicationWrapper | undefined> {
102
109
  try {
110
+ const baseServerUrl = fetchSinglePageApplication
111
+ ? BASE_SERVER_PUBLIC_API_URL_V1
112
+ : BASE_SERVER_PUBLIC_API_URL_v2;
113
+
114
+ const serverURL = branch
115
+ ? new URL(
116
+ `${baseServerUrl}/applications/${applicationId}/branches/${encodeURIComponent(
117
+ branch
118
+ )}?viewMode=${viewMode}`,
119
+ superblocksBaseUrl
120
+ )
121
+ : new URL(
122
+ `${baseServerUrl}/applications/${applicationId}?viewMode=${viewMode}`,
123
+ superblocksBaseUrl
124
+ );
103
125
  const config: AxiosRequestConfig = {
104
126
  method: "get",
105
127
  url: serverURL.toString(),
@@ -109,15 +131,17 @@ export async function fetchApplication({
109
131
  ...injectedHeaders,
110
132
  },
111
133
  };
112
- serverResponse = await axios<ResponseWithMeta<ApplicationWrapper>>(config);
134
+ const serverResponse = await axios<
135
+ ResponseWithMeta<ApplicationWrapper | MultiPageApplicationWrapper>
136
+ >(config);
137
+ const data = serverResponse?.data?.data;
138
+ return data;
113
139
  } catch (e) {
114
140
  if (axios.isAxiosError(e) && e.response?.status === 404) {
115
141
  throw new NotFoundError(`Application ${applicationId} was not found`);
116
142
  }
117
143
  throw new Error("Could not fetch application");
118
144
  }
119
-
120
- return serverResponse?.data?.data;
121
145
  }
122
146
 
123
147
  export async function fetchApplicationBranches({
@@ -168,6 +192,7 @@ export async function fetchApplicationWithComponents({
168
192
  superblocksBaseUrl,
169
193
  viewMode,
170
194
  injectedHeaders = {},
195
+ fetchSinglePageApplication = false,
171
196
  }: {
172
197
  cliVersion: string;
173
198
  applicationId: string;
@@ -176,7 +201,13 @@ export async function fetchApplicationWithComponents({
176
201
  superblocksBaseUrl: string;
177
202
  viewMode: ViewMode;
178
203
  injectedHeaders: Record<string, string>;
179
- }): Promise<(ApplicationWrapper & { componentFiles: any }) | undefined> {
204
+ fetchSinglePageApplication?: boolean;
205
+ }): Promise<
206
+ | ((ApplicationWrapper | MultiPageApplicationWrapper) & {
207
+ componentFiles: any;
208
+ })
209
+ | undefined
210
+ > {
180
211
  const applicationWrapper = await fetchApplication({
181
212
  cliVersion,
182
213
  applicationId,
@@ -185,6 +216,7 @@ export async function fetchApplicationWithComponents({
185
216
  superblocksBaseUrl,
186
217
  viewMode,
187
218
  injectedHeaders,
219
+ fetchSinglePageApplication,
188
220
  });
189
221
 
190
222
  if (isEmpty(applicationWrapper)) {
@@ -205,10 +237,11 @@ export async function fetchApplicationWithComponents({
205
237
  const bucketeerBaseUrl =
206
238
  getBucketeerUrlFromSuperblocksUrl(superblocksBaseUrl);
207
239
 
240
+ const multiPage = fetchSinglePageApplication ? "false" : "true";
208
241
  // fetch files from bucketeer
209
242
  const branchPath = branch ? `/branches/${encodeURIComponent(branch)}` : "";
210
243
  const componentFileURL = new URL(
211
- `${BASE_BUCKETEER_URL}/v1/components/${applicationId}${branchPath}?commit=${commitId}&viewMode=${viewMode}`,
244
+ `${BASE_BUCKETEER_URL}/v1/components/${applicationId}${branchPath}?commit=${commitId}&viewMode=${viewMode}&multiPage=${multiPage}`,
212
245
  bucketeerBaseUrl
213
246
  ).toString();
214
247
 
@@ -242,7 +275,7 @@ export async function fetchApplications(
242
275
  const config: AxiosRequestConfig = {
243
276
  method: "get",
244
277
  url: new URL(
245
- `${BASE_SERVER_PUBLIC_API_URL}/applications`,
278
+ `${BASE_SERVER_PUBLIC_API_URL_V1}/applications`,
246
279
  superblocksBaseUrl
247
280
  ).toString(),
248
281
  headers: {
@@ -280,13 +313,13 @@ export async function fetchApi(
280
313
  try {
281
314
  const serverURL = branch
282
315
  ? new URL(
283
- `${BASE_SERVER_PUBLIC_API_URL}/apis/${apiId}/branches/${encodeURIComponent(
316
+ `${BASE_SERVER_PUBLIC_API_URL_V1}/apis/${apiId}/branches/${encodeURIComponent(
284
317
  branch
285
318
  )}?viewMode=${viewMode}`,
286
319
  superblocksBaseUrl
287
320
  )
288
321
  : new URL(
289
- `${BASE_SERVER_PUBLIC_API_URL}/apis/${apiId}?viewMode=${viewMode}`,
322
+ `${BASE_SERVER_PUBLIC_API_URL_V1}/apis/${apiId}?viewMode=${viewMode}`,
290
323
  superblocksBaseUrl
291
324
  );
292
325
 
@@ -317,7 +350,7 @@ export async function fetchApis(
317
350
  const config: AxiosRequestConfig = {
318
351
  method: "get",
319
352
  url: new URL(
320
- `${BASE_SERVER_PUBLIC_API_URL}/apis`,
353
+ `${BASE_SERVER_PUBLIC_API_URL_V1}/apis`,
321
354
  superblocksBaseUrl
322
355
  ).toString(),
323
356
  headers: {
@@ -364,7 +397,7 @@ export async function validateGitSetup(
364
397
  const config: AxiosRequestConfig = {
365
398
  method: "post",
366
399
  url: new URL(
367
- `${BASE_SERVER_PUBLIC_API_URL}/${path}`,
400
+ `${BASE_SERVER_PUBLIC_API_URL_V1}/${path}`,
368
401
  superblocksBaseUrl
369
402
  ).toString(),
370
403
  headers: {
@@ -450,7 +483,7 @@ export async function registerComponents(
450
483
  const config: AxiosRequestConfig = {
451
484
  method: "put",
452
485
  url: new URL(
453
- `${BASE_SERVER_PUBLIC_API_URL}/application/${applicationId}${branchPath}/components`,
486
+ `${BASE_SERVER_PUBLIC_API_URL_V1}/application/${applicationId}${branchPath}/components`,
454
487
  superblocksBaseUrl
455
488
  ).toString(),
456
489
  headers: {
@@ -631,7 +664,7 @@ export async function fetchCurrentUser(
631
664
  const config: AxiosRequestConfig = {
632
665
  method: "get",
633
666
  url: new URL(
634
- `${BASE_SERVER_PUBLIC_API_URL}/users/me`,
667
+ `${BASE_SERVER_PUBLIC_API_URL_V1}/users/me`,
635
668
  superblocksBaseUrl
636
669
  ).toString(),
637
670
  headers: {
@@ -666,6 +699,7 @@ export async function pushApplication({
666
699
  applicationConfig,
667
700
  branch,
668
701
  injectedHeaders = {},
702
+ multiPage = false,
669
703
  }: {
670
704
  cliVersion: string;
671
705
  applicationId: string;
@@ -673,16 +707,20 @@ export async function pushApplication({
673
707
  superblocksBaseUrl: string;
674
708
  branch: string;
675
709
  injectedHeaders: Record<string, string>;
676
- applicationConfig: PushApplicationWithCommitConfig;
710
+ applicationConfig:
711
+ | PushApplicationWithCommitConfig
712
+ | PushMultiPageApplicationWithCommitConfig;
713
+ multiPage?: boolean;
677
714
  }): Promise<RemoteCommitDto | undefined> {
678
- const serverURL = new URL(
679
- `${BASE_SERVER_PUBLIC_API_URL}/applications/${applicationId}/branches/${encodeURIComponent(
680
- branch
681
- )}/push`,
682
- superblocksBaseUrl
683
- );
684
- let serverResponse;
685
-
715
+ const handleHttpError = (status: number) => {
716
+ if (status === 405) {
717
+ throw new BranchNotCheckedOutError(`Branch ${branch} is not checked out`);
718
+ } else if (status === 409) {
719
+ throw new CommitAlreadyExistsError(
720
+ `Commit ${applicationConfig.commitId} already exists`
721
+ );
722
+ }
723
+ };
686
724
  try {
687
725
  const userMe = await fetchCurrentUser(
688
726
  cliVersion,
@@ -705,18 +743,49 @@ export async function pushApplication({
705
743
  superblocksBaseUrl,
706
744
  token,
707
745
  });
708
- const resp = await socket.call.v1.public.application.pushCommit({
709
- applicationId,
710
- apis: applicationConfig.apis,
711
- application: applicationConfig.application,
712
- branchName: branch,
713
- commitId: applicationConfig.commitId,
714
- commitMessage: applicationConfig.commitMessage,
715
- page: applicationConfig.page,
716
- });
746
+ const resp = multiPage
747
+ ? await socket.call.v2.public.application.pushCommit({
748
+ applicationId,
749
+ apis: applicationConfig.apis,
750
+ application: applicationConfig.application,
751
+ branchName: branch,
752
+ commitId: applicationConfig.commitId,
753
+ commitMessage: applicationConfig.commitMessage,
754
+ pages: (
755
+ applicationConfig as unknown as PushMultiPageApplicationWithCommitConfig
756
+ ).pages,
757
+ })
758
+ : await socket.call.v1.public.application.pushCommit({
759
+ applicationId,
760
+ apis: applicationConfig.apis,
761
+ application: applicationConfig.application,
762
+ branchName: branch,
763
+ commitId: applicationConfig.commitId,
764
+ commitMessage: applicationConfig.commitMessage,
765
+ page: (
766
+ applicationConfig as unknown as PushApplicationWithCommitConfig
767
+ ).page,
768
+ });
717
769
  socket.close();
770
+ handleHttpError(resp.responseMeta.status);
771
+ if (resp.responseMeta.status !== 200) {
772
+ // Get the raw error message from the server and throw it. The outer try-catch block will wrap it in a nicer error message
773
+ const message: string =
774
+ (resp?.responseMeta?.message as string) ?? JSON.stringify(resp?.data);
775
+ throw new Error(message);
776
+ }
718
777
  return resp.data;
719
778
  } else {
779
+ // v1 calls can be removed once all customers move to multi page
780
+ const baseServerPublicApiUrl = multiPage
781
+ ? BASE_SERVER_PUBLIC_API_URL_v2
782
+ : BASE_SERVER_PUBLIC_API_URL_V1;
783
+ const serverURL = new URL(
784
+ `${baseServerPublicApiUrl}/applications/${applicationId}/branches/${encodeURIComponent(
785
+ branch
786
+ )}/push`,
787
+ superblocksBaseUrl
788
+ );
720
789
  const config: AxiosRequestConfig = {
721
790
  method: "post",
722
791
  url: serverURL.toString(),
@@ -727,29 +796,32 @@ export async function pushApplication({
727
796
  },
728
797
  data: applicationConfig,
729
798
  };
730
- serverResponse = await axios<ResponseWithMeta<RemoteCommitDto>>(config);
731
- }
732
- } catch (e) {
733
- if (axios.isAxiosError(e)) {
734
- const respCode =
735
- e.response?.data?.responseMeta?.status ?? e.response?.status;
736
- if (respCode === 405) {
737
- throw new BranchNotCheckedOutError(
738
- `Branch ${branch} is not checked out`
799
+ try {
800
+ const serverResponse = await axios<ResponseWithMeta<RemoteCommitDto>>(
801
+ config
739
802
  );
740
- } else if (respCode === 409) {
741
- throw new CommitAlreadyExistsError(
742
- `Commit ${applicationConfig.commitId} already exists`
803
+ return serverResponse?.data?.data;
804
+ } catch (e) {
805
+ if (!axios.isAxiosError(e)) {
806
+ throw e;
807
+ }
808
+ handleHttpError(
809
+ e.response?.data?.responseMeta?.status ?? e.response?.status
743
810
  );
811
+ const message =
812
+ (e.response?.data?.responseMeta?.message as string) ??
813
+ JSON.stringify(e.response?.data) ??
814
+ e.response?.statusText;
815
+ throw new Error(message);
744
816
  }
745
- const message: string =
746
- (e.response?.data?.responseMeta?.message as string) ??
747
- JSON.stringify(e.response?.data) ??
748
- e.response?.statusText;
749
-
750
- throw new Error(
751
- `Could not push application ${message ? "\n" + message : ""}`
752
- );
817
+ }
818
+ } catch (e) {
819
+ if (
820
+ e instanceof BranchNotCheckedOutError ||
821
+ e instanceof CommitAlreadyExistsError
822
+ ) {
823
+ // Rethrow these exceptions because they will be handled higher up the call stack
824
+ throw e;
753
825
  }
754
826
  throw new Error(
755
827
  `Could not push application ${
@@ -757,8 +829,6 @@ export async function pushApplication({
757
829
  }`
758
830
  );
759
831
  }
760
-
761
- return serverResponse?.data?.data;
762
832
  }
763
833
 
764
834
  export async function pushApi({
@@ -778,14 +848,21 @@ export async function pushApi({
778
848
  branch: string;
779
849
  injectedHeaders: Record<string, string>;
780
850
  }): Promise<{ commitId: string } | undefined> {
851
+ const handleHttpError = (status: number) => {
852
+ if (status === 405) {
853
+ throw new BranchNotCheckedOutError(`Branch ${branch} is not checked out`);
854
+ } else if (status === 409) {
855
+ throw new CommitAlreadyExistsError(
856
+ `Commit ${apiConfig.commitId} already exists`
857
+ );
858
+ }
859
+ };
781
860
  const serverURL = new URL(
782
- `${BASE_SERVER_PUBLIC_API_URL}/apis/${apiId}/branches/${encodeURIComponent(
861
+ `${BASE_SERVER_PUBLIC_API_URL_V1}/apis/${apiId}/branches/${encodeURIComponent(
783
862
  branch
784
863
  )}/push`,
785
864
  superblocksBaseUrl
786
865
  );
787
- let serverResponse;
788
-
789
866
  try {
790
867
  const userMe = await fetchCurrentUser(
791
868
  cliVersion,
@@ -811,6 +888,13 @@ export async function pushApi({
811
888
  commitMessage: apiConfig.commitMessage,
812
889
  });
813
890
  socket.close();
891
+ handleHttpError(resp.responseMeta.status);
892
+ if (resp.responseMeta.status !== 200) {
893
+ // Get the raw error message from the server and throw it. The outer try-catch block will wrap it in a nicer error message
894
+ const message: string =
895
+ (resp?.responseMeta?.message as string) ?? JSON.stringify(resp?.data);
896
+ throw new Error(message);
897
+ }
814
898
  return resp.data;
815
899
  } else {
816
900
  const config: AxiosRequestConfig = {
@@ -823,27 +907,30 @@ export async function pushApi({
823
907
  },
824
908
  data: apiConfig,
825
909
  };
826
- serverResponse = await axios<ResponseWithMeta<{ commitId: string }>>(
827
- config
828
- );
910
+ try {
911
+ const serverResponse = await axios<
912
+ ResponseWithMeta<{ commitId: string }>
913
+ >(config);
914
+ return serverResponse?.data?.data;
915
+ } catch (e) {
916
+ if (!axios.isAxiosError(e)) {
917
+ throw e;
918
+ }
919
+ handleHttpError(e.response?.data?.responseMeta?.status);
920
+ const message =
921
+ (e.response?.data?.responseMeta?.message as string) ??
922
+ JSON.stringify(e.response?.data) ??
923
+ e.response?.statusText;
924
+ throw new Error(message);
925
+ }
829
926
  }
830
927
  } catch (e) {
831
- if (axios.isAxiosError(e)) {
832
- if (e.response?.data?.responseMeta?.status === 405) {
833
- throw new BranchNotCheckedOutError(
834
- `Branch ${branch} is not checked out`
835
- );
836
- } else if (e.response?.data?.responseMeta?.status === 409) {
837
- throw new CommitAlreadyExistsError(
838
- `Commit ${apiConfig.commitId} already exists`
839
- );
840
- }
841
- const message: string =
842
- (e.response?.data?.responseMeta?.message as string) ??
843
- JSON.stringify(e.response?.data) ??
844
- e.response?.statusText;
845
-
846
- throw new Error(`Could not push api ${message ? "\n" + message : ""}`);
928
+ if (
929
+ e instanceof BranchNotCheckedOutError ||
930
+ e instanceof CommitAlreadyExistsError
931
+ ) {
932
+ // Rethrow these exceptions because they will be handled higher up the call stack
933
+ throw e;
847
934
  }
848
935
  throw new Error(
849
936
  `Could not push api ${
@@ -851,6 +938,10 @@ export async function pushApi({
851
938
  }`
852
939
  );
853
940
  }
941
+ }
854
942
 
855
- return serverResponse?.data?.data;
943
+ function isMultiPageApplicationWrapper(
944
+ data: ApplicationWrapper | MultiPageApplicationWrapper
945
+ ): data is MultiPageApplicationWrapper {
946
+ return (data as MultiPageApplicationWrapper).pages !== undefined;
856
947
  }
package/src/sdk.ts CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  PushApiWithCommitConfig,
16
16
  pushApplication,
17
17
  PushApplicationWithCommitConfig,
18
+ PushMultiPageApplicationWithCommitConfig,
18
19
  registerComponents,
19
20
  uploadComponents,
20
21
  validateGitSetup,
@@ -44,11 +45,13 @@ export class SuperblocksSdk {
44
45
  branch,
45
46
  headers = {},
46
47
  viewMode = "export-live",
48
+ fetchSinglePageApplication = false,
47
49
  }: {
48
50
  applicationId: string;
49
51
  branch?: string;
50
52
  headers?: Record<string, string>;
51
53
  viewMode?: ViewMode;
54
+ fetchSinglePageApplication?: boolean;
52
55
  }) {
53
56
  return fetchApplication({
54
57
  cliVersion: this.cliVersion,
@@ -58,6 +61,7 @@ export class SuperblocksSdk {
58
61
  superblocksBaseUrl: this.superblocksBaseUrl,
59
62
  viewMode,
60
63
  injectedHeaders: headers,
64
+ fetchSinglePageApplication,
61
65
  });
62
66
  }
63
67
 
@@ -76,11 +80,13 @@ export class SuperblocksSdk {
76
80
  branch,
77
81
  headers = {},
78
82
  viewMode = "export-live",
83
+ fetchSinglePageApplication = false,
79
84
  }: {
80
85
  applicationId: string;
81
86
  branch: string;
82
87
  headers?: Record<string, string>;
83
88
  viewMode?: ViewMode;
89
+ fetchSinglePageApplication?: boolean;
84
90
  }) {
85
91
  return fetchApplicationWithComponents({
86
92
  cliVersion: this.cliVersion,
@@ -90,6 +96,7 @@ export class SuperblocksSdk {
90
96
  superblocksBaseUrl: this.superblocksBaseUrl,
91
97
  viewMode,
92
98
  injectedHeaders: headers,
99
+ fetchSinglePageApplication,
93
100
  });
94
101
  }
95
102
 
@@ -187,11 +194,15 @@ export class SuperblocksSdk {
187
194
  applicationConfig,
188
195
  branch,
189
196
  headers = {},
197
+ multiPage = false,
190
198
  }: {
191
199
  applicationId: string;
192
- applicationConfig: PushApplicationWithCommitConfig;
200
+ applicationConfig:
201
+ | PushApplicationWithCommitConfig
202
+ | PushMultiPageApplicationWithCommitConfig;
193
203
  branch: string;
194
204
  headers?: Record<string, string>;
205
+ multiPage?: boolean;
195
206
  }) {
196
207
  return pushApplication({
197
208
  cliVersion: this.cliVersion,
@@ -201,6 +212,7 @@ export class SuperblocksSdk {
201
212
  branch,
202
213
  injectedHeaders: headers,
203
214
  applicationConfig,
215
+ multiPage,
204
216
  });
205
217
  }
206
218
  async pushApi({
@@ -49,6 +49,7 @@ type ResponseDto<T> = {
49
49
  export type ResponseMeta = {
50
50
  status: number;
51
51
  success: boolean;
52
+ message?: string;
52
53
  error?: APIResponseError;
53
54
  };
54
55
 
@@ -114,6 +115,24 @@ export interface ServerMethods {
114
115
  };
115
116
  };
116
117
  };
118
+ v2: {
119
+ public: {
120
+ application: {
121
+ pushCommit: ServerMethodSchema<
122
+ {
123
+ applicationId: string;
124
+ branchName: string;
125
+ commitId: string;
126
+ commitMessage: string;
127
+ application: Record<string, unknown>;
128
+ pages: Record<string, unknown>[];
129
+ apis: Record<string, unknown>[];
130
+ },
131
+ RemoteCommitDto
132
+ >;
133
+ };
134
+ };
135
+ };
117
136
  }
118
137
 
119
138
  export function createRequestHandlers({
@@ -7,6 +7,7 @@ export interface UserMeDto {
7
7
 
8
8
  export interface FlagBootstrap {
9
9
  "ui.enable-resource-signing"?: boolean;
10
+ "server.multipage.enabled"?: boolean;
10
11
  }
11
12
 
12
13
  export type User = {
@@ -121,6 +122,21 @@ export type Api = {
121
122
  signature?: Signature;
122
123
  };
123
124
 
125
+ export type ApiWithPb = {
126
+ id: string;
127
+ pageId?: string;
128
+ apiPb: Api;
129
+ };
130
+
131
+ export type Page = {
132
+ id: string;
133
+ applicationId: string;
134
+ isHidden: boolean;
135
+ layouts: Record<string, unknown>[];
136
+ name: string;
137
+ apis: ApiWithPb[];
138
+ };
139
+
124
140
  /** A signature, as produced by the agent. */
125
141
  export interface Signature {
126
142
  /** The id of the key used to sign the data. */