Skip to content

Commit 9976df2

Browse files
committed
feat:error handling and new region endpoint support
Signed-off-by: Amitkanswal <[email protected]>
1 parent 1922233 commit 9976df2

File tree

12 files changed

+250
-6981
lines changed

12 files changed

+250
-6981
lines changed

__test__/assetSidebarWidget.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ describe("AssetSidebarWidget", () => {
2525
user: {} as any,
2626
currentBranch: "mock_branch",
2727
region: "region",
28+
endpoints: { CMA: "", APP: "",DEVELOPER_HUB:"" },
2829
};
2930

3031
let connection: { sendToParent: (...props: any[]) => any };

__test__/fieldModifierLocation/entry.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ describe("FieldModifierLocationEntry", () => {
4747
extension_uid: "extension_uid",
4848
installation_uid: "installation_uid",
4949
region: "NA",
50+
endpoints: { CMA: "", APP: "",DEVELOPER_HUB:"" },
5051
stack: {
5152
api_key: "api_key",
5253
created_at: "created_at",

__test__/organizationFullPage.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const mockData: IOrgFullPageLocationInitData = {
77
installation_uid: "installation_uid",
88
extension_uid: "extension_uid",
99
region: "NA",
10+
endpoints:{CMA:"",APP:"",DEVELOPER_HUB:""},
1011
stack: {} as any,
1112
user: {} as any,
1213
currentBranch: "currentBranch",

__test__/uiLocation.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ const initData: IAppConfigInitData = {
6060
installation_uid: "installation_uid",
6161
extension_uid: "extension_uid",
6262
region: "NA",
63+
endpoints: { CMA: "https://api.contentstack.io", APP: "https://app.contentstack.app",DEVELOPER_HUB:"" },
6364
stack: mockStackData,
6465
user: {} as any,
6566
currentBranch: "currentBranch",

__test__/utils.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ describe("formatAppRegion", () => {
2323
});
2424

2525
it("should return unknown for any invalid region", () => {
26-
expect(formatAppRegion("invalid")).toBe(Region.UNKNOWN);
26+
expect(formatAppRegion("invalid")).toBe("invalid");
2727
});
2828
});

package-lock.json

Lines changed: 82 additions & 253 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { GenericObjectType } from "./types/common.types";
77
import { Entry } from "./types/entry.types";
88
import { Asset, ContentType, Schema, StackDetail } from "./types/stack.types";
99
import { OrganizationDetails } from "./types/organization.types";
10+
import { ContentstackEndpoints } from './types/api.type';
1011
import { User } from "./types/user.types";
1112
import Window from "./window";
1213

@@ -102,6 +103,7 @@ declare interface ICommonInitData {
102103
type: LocationType;
103104
user: User;
104105
manifest?: Manifest;
106+
endpoints: ContentstackEndpoints;
105107
}
106108

107109
export declare interface IOrgFullPageLocationInitData extends ICommonInitData {
@@ -254,4 +256,7 @@ export enum Region {
254256
AZURE_NA = "AZURE_NA",
255257
AZURE_EU = "AZURE_EU",
256258
GCP_NA = "GCP_NA",
259+
GCP_EU = "GCP_EU",
257260
}
261+
262+
export type RegionType = "UNKNOWN" | "NA" | "EU" | "AZURE_NA" | "AZURE_EU" | "GCP_NA" | string;

src/types/api.type.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1-
import { AxiosRequestConfig, AxiosResponse, } from 'axios'
2-
export type RequestConfig = AxiosRequestConfig
3-
export type ProxyResponse = AxiosResponse
1+
import { AxiosRequestConfig, AxiosResponse } from "axios";
2+
export type RequestConfig = AxiosRequestConfig;
3+
export type ProxyResponse = AxiosResponse;
4+
5+
export type ContentstackEndpoints = {
6+
APP: string;
7+
CMA: string;
8+
DEVELOPER_HUB: string;
9+
[key:string]:string;
10+
};

src/uiLocation.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { AxiosRequestConfig, AxiosResponse } from 'axios';
12
import postRobot from "post-robot";
23
import EventEmitter from "wolfy87-eventemitter";
34

@@ -26,15 +27,15 @@ import {
2627
InitializationData,
2728
LocationType,
2829
Manifest,
29-
Region,
3030
IOrgFullPageLocation,
31+
RegionType,
3132
} from "./types";
3233
import { GenericObjectType } from "./types/common.types";
3334
import { User } from "./types/user.types";
3435
import { formatAppRegion, onData, onError } from "./utils/utils";
3536
import Window from "./window";
3637
import { dispatchApiRequest, dispatchAdapter } from './utils/adapter';
37-
import { AxiosRequestConfig, AxiosResponse } from 'axios';
38+
import { ContentstackEndpoints } from "./types/api.type";
3839

3940
const emitter = new EventEmitter();
4041

@@ -69,6 +70,9 @@ class UiLocation {
6970
*/
7071
private config: GenericObjectType;
7172

73+
74+
readonly endpoints: ContentstackEndpoints
75+
7276
/**
7377
* This holds the instance of Cross-domain communication library for posting messages between windows.
7478
*/
@@ -103,7 +107,7 @@ class UiLocation {
103107
/**
104108
* The Contentstack Region on which the app is running.
105109
*/
106-
readonly region: Region;
110+
readonly region: RegionType;
107111
version: number | null;
108112

109113
ids: {
@@ -154,7 +158,7 @@ class UiLocation {
154158
});
155159

156160
this.metadata = new Metadata(postRobot);
157-
161+
158162
this.config = initializationData.config ?? {};
159163

160164
this.ids = {
@@ -184,7 +188,8 @@ class UiLocation {
184188

185189
this.modal = new Modal();
186190

187-
this.region = formatAppRegion(initializationData.region);
191+
this.region = formatAppRegion(initializationData.region);
192+
this.endpoints = initializationData.endpoints;
188193

189194
const stack = new Stack(initializationData.stack, postRobot, {
190195
currentBranch: initializationData.currentBranch,
@@ -468,10 +473,13 @@ class UiLocation {
468473
/**
469474
* Method used to get the Contentstack Region on which the app is running.
470475
*/
471-
getCurrentRegion = (): Region => {
476+
getCurrentRegion = (): RegionType => {
472477
return this.region;
473478
};
474479

480+
getEndpoints = ():ContentstackEndpoints => {
481+
return this.endpoints;
482+
}
475483
/**
476484
* Method used to make an API request to the Contentstack's CMA APIs.
477485
*/
@@ -483,7 +491,7 @@ class UiLocation {
483491
*/
484492
createAdapter = (): (config: AxiosRequestConfig) => Promise<AxiosResponse> => {
485493
return (config: AxiosRequestConfig): Promise<AxiosResponse> => {
486-
return dispatchAdapter(postRobot)(config) as Promise<AxiosResponse>;
494+
return dispatchAdapter(postRobot)(config)
487495
};
488496
};
489497

src/utils/adapter.ts

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,50 @@
1-
import PostRobot from 'post-robot';
2-
import { AxiosRequestConfig, AxiosResponse } from 'axios';
3-
import { onError, fetchToAxiosConfig } from './utils';
1+
import PostRobot from "post-robot";
2+
import { Response } from 'node-fetch';
3+
import { AxiosRequestConfig, AxiosResponse } from "axios";
4+
5+
import { onError, fetchToAxiosConfig, serializeAxiosResponse, handleApiError, sanitizeResponseHeader } from "./utils";
46

57
/**
68
* Dispatches a request using PostRobot.
79
* @param postRobot - The PostRobot instance.
810
* @returns A function that takes AxiosRequestConfig and returns a promise.
911
*/
10-
export const dispatchAdapter = (postRobot: typeof PostRobot) => (config: AxiosRequestConfig)=> {
12+
export const dispatchAdapter = (postRobot: typeof PostRobot) => (config: AxiosRequestConfig): Promise<AxiosResponse> => {
1113
return postRobot
12-
.sendToParent("apiAdapter", config )
13-
.then(({ data }) => ({ ...data, config }))
14+
.sendToParent("apiAdapter", config)
15+
.then((event:unknown) => {
16+
const { data } = event as { data: AxiosResponse };
17+
if (data.status >= 400) {
18+
throw serializeAxiosResponse(data, config);
19+
}
20+
return serializeAxiosResponse(data, config);
21+
})
1422
.catch(onError);
1523
};
16-
1724
/**
1825
* Dispatches an API request using axios and PostRobot.
1926
* @param url - The URL of the API endpoint.
2027
* @param options - Optional request options.
2128
* @returns A promise that resolves to a partial Response object.
2229
*/
23-
export const dispatchApiRequest = async (url: string, options?: RequestInit): Promise<Response> => {
24-
try {
25-
const config = fetchToAxiosConfig(url, options);
26-
const responseData = await dispatchAdapter(PostRobot)(config) as AxiosResponse;
27-
return new Response(responseData.data,{
28-
status: responseData.status,
29-
statusText: responseData.statusText,
30-
headers: new Headers(responseData.config.headers || {}),
31-
});
32-
33-
} catch (error: any) {
34-
if (error.response) {
35-
const fetchResponse = new Response(error.response.data, {
36-
status: error.response.status,
37-
statusText: error.response.statusText,
38-
headers: new Headers(error.response.headers)
39-
});
40-
return Promise.reject(fetchResponse);
41-
} else if (error.request) {
42-
return Promise.reject(new Response(null, { status: 0, statusText: 'Network Error' }));
43-
} else {
44-
return Promise.reject(new Response(null, { status: 0, statusText: error.message }));
45-
}
30+
export const dispatchApiRequest = async (
31+
url: string,
32+
options?: RequestInit,
33+
): Promise<Response> => {
34+
try {
35+
const config = fetchToAxiosConfig(url, options);
36+
const responseData = (await dispatchAdapter(PostRobot)(
37+
config
38+
)) as AxiosResponse;
39+
40+
return new Response(responseData?.data, {
41+
status: responseData.status,
42+
statusText: responseData.statusText,
43+
url: responseData.config.url,
44+
headers: new Headers(sanitizeResponseHeader(responseData.config.headers || {})),
45+
});
46+
47+
} catch (error) {
48+
return handleApiError(error);
4649
}
47-
};
50+
};

0 commit comments

Comments
 (0)