@intlayer/api 4.1.8 → 4.1.10
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/cjs/IntlayerEventListener.cjs +123 -0
- package/dist/cjs/IntlayerEventListener.cjs.map +1 -0
- package/dist/cjs/fetcher.cjs +1 -3
- package/dist/cjs/fetcher.cjs.map +1 -1
- package/dist/cjs/index.cjs +3 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/IntlayerEventListener.mjs +99 -0
- package/dist/esm/IntlayerEventListener.mjs.map +1 -0
- package/dist/esm/fetcher.mjs +1 -3
- package/dist/esm/fetcher.mjs.map +1 -1
- package/dist/esm/index.mjs +1 -0
- package/dist/esm/index.mjs.map +1 -1
- package/dist/types/IntlayerEventListener.d.ts +68 -0
- package/dist/types/IntlayerEventListener.d.ts.map +1 -0
- package/dist/types/fetcher.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +8 -8
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var IntlayerEventListener_exports = {};
|
|
20
|
+
__export(IntlayerEventListener_exports, {
|
|
21
|
+
IntlayerEventListener: () => IntlayerEventListener
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(IntlayerEventListener_exports);
|
|
24
|
+
var import_api = require("@intlayer/api");
|
|
25
|
+
var import_client = require("@intlayer/config/client");
|
|
26
|
+
class IntlayerEventListener {
|
|
27
|
+
constructor(intlayerConfig) {
|
|
28
|
+
this.intlayerConfig = intlayerConfig;
|
|
29
|
+
}
|
|
30
|
+
eventSource = null;
|
|
31
|
+
/**
|
|
32
|
+
* Callback triggered when a Dictionary is ADDED.
|
|
33
|
+
*/
|
|
34
|
+
onDictionaryAdded;
|
|
35
|
+
/**
|
|
36
|
+
* Callback triggered when a Dictionary is UPDATED.
|
|
37
|
+
*/
|
|
38
|
+
onDictionaryChange;
|
|
39
|
+
/**
|
|
40
|
+
* Callback triggered when a Dictionary is DELETED.
|
|
41
|
+
*/
|
|
42
|
+
onDictionaryDeleted;
|
|
43
|
+
/**
|
|
44
|
+
* Initializes the EventSource connection using the given intlayerConfig
|
|
45
|
+
* (or the default config if none was provided).
|
|
46
|
+
*/
|
|
47
|
+
async initialize() {
|
|
48
|
+
try {
|
|
49
|
+
const config = this.intlayerConfig ?? (0, import_client.getConfiguration)();
|
|
50
|
+
const { backendURL } = config.editor;
|
|
51
|
+
const oAuth2TokenResult = await import_api.intlayerAPI.auth.getOAuth2AccessToken();
|
|
52
|
+
const accessToken = oAuth2TokenResult.data?.accessToken;
|
|
53
|
+
if (!accessToken) {
|
|
54
|
+
throw new Error("Failed to retrieve access token");
|
|
55
|
+
}
|
|
56
|
+
if (oAuth2TokenResult.data?.organization.plan?.type !== "ENTERPRISE")
|
|
57
|
+
return;
|
|
58
|
+
const API_ROUTE = `${backendURL}/api/event-listener`;
|
|
59
|
+
const url = `${API_ROUTE}/${accessToken}`;
|
|
60
|
+
this.eventSource = new EventSource(url);
|
|
61
|
+
this.eventSource.onmessage = (event) => this.handleMessage(event);
|
|
62
|
+
this.eventSource.onerror = (event) => this.handleError(event);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
console.error("Error initializing IntlayerEventListener:", error);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Cleans up (closes) the EventSource connection.
|
|
69
|
+
*/
|
|
70
|
+
cleanup() {
|
|
71
|
+
if (this.eventSource) {
|
|
72
|
+
this.eventSource.close();
|
|
73
|
+
this.eventSource = null;
|
|
74
|
+
console.log("IntlayerEventListener cleaned up.");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Handles incoming SSE messages, parses the event data,
|
|
79
|
+
* and invokes the appropriate callback.
|
|
80
|
+
*/
|
|
81
|
+
async handleMessage(event) {
|
|
82
|
+
try {
|
|
83
|
+
const { data } = event;
|
|
84
|
+
for (const dataEl of data) {
|
|
85
|
+
switch (dataEl.object) {
|
|
86
|
+
case "DICTIONARY":
|
|
87
|
+
switch (dataEl.status) {
|
|
88
|
+
case "ADDED":
|
|
89
|
+
await this.onDictionaryAdded?.(dataEl.dictionary);
|
|
90
|
+
break;
|
|
91
|
+
case "UPDATED":
|
|
92
|
+
await this.onDictionaryChange?.(dataEl.dictionary);
|
|
93
|
+
break;
|
|
94
|
+
case "DELETED":
|
|
95
|
+
await this.onDictionaryDeleted?.(dataEl.dictionary);
|
|
96
|
+
break;
|
|
97
|
+
default:
|
|
98
|
+
console.error("Unhandled dictionary status:", dataEl.status);
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
break;
|
|
102
|
+
default:
|
|
103
|
+
console.error("Unknown object type:", dataEl.object);
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.error("Error processing dictionary update:", error);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Handles any SSE errors and then performs cleanup.
|
|
113
|
+
*/
|
|
114
|
+
handleError(event) {
|
|
115
|
+
console.error("EventSource error:", event);
|
|
116
|
+
this.cleanup();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
120
|
+
0 && (module.exports = {
|
|
121
|
+
IntlayerEventListener
|
|
122
|
+
});
|
|
123
|
+
//# sourceMappingURL=IntlayerEventListener.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/IntlayerEventListener.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { intlayerAPI } from '@intlayer/api';\n// @ts-ignore: @intlayer/backend is not built yet\nimport { DictionaryAPI } from '@intlayer/backend';\nimport { getConfiguration, IntlayerConfig } from '@intlayer/config/client';\n// @ts-ignore @intlayer/backend is not built yet\n\nexport type DictionaryMessageEvent = {\n object: 'DICTIONARY';\n dictionary: DictionaryAPI;\n status: 'ADDED' | 'UPDATED' | 'DELETED' | 'CREATED';\n};\n\nexport type IntlayerMessageEvent = MessageEvent<DictionaryMessageEvent[]>;\n\n/**\n * IntlayerEventListener class to listen for dictionary changes via SSE (Server-Sent Events).\n *\n * Usage example:\n *\n * import { buildIntlayerDictionary } from './transpiler/declaration_file_to_dictionary/intlayer_dictionary';\n * import { IntlayerEventListener } from '@intlayer/api';\n *\n * export const checkDictionaryChanges = async () => {\n * // Instantiate the listener\n * const eventListener = new IntlayerEventListener();\n *\n * // Set up your callbacks\n * eventListener.onDictionaryChange = async (dictionary) => {\n * await buildIntlayerDictionary(dictionary);\n * };\n *\n * // Initialize the listener\n * await eventListener.initialize();\n *\n * // Optionally, clean up later when you’re done\n * // eventListener.cleanup();\n * };\n */\nexport class IntlayerEventListener {\n private eventSource: EventSource | null = null;\n\n /**\n * Callback triggered when a Dictionary is ADDED.\n */\n public onDictionaryAdded?: (dictionary: DictionaryAPI) => any;\n\n /**\n * Callback triggered when a Dictionary is UPDATED.\n */\n public onDictionaryChange?: (dictionary: DictionaryAPI) => any;\n\n /**\n * Callback triggered when a Dictionary is DELETED.\n */\n public onDictionaryDeleted?: (dictionary: DictionaryAPI) => any;\n\n constructor(private intlayerConfig?: IntlayerConfig) {}\n\n /**\n * Initializes the EventSource connection using the given intlayerConfig\n * (or the default config if none was provided).\n */\n public async initialize(): Promise<void> {\n try {\n const config = this.intlayerConfig ?? getConfiguration();\n const { backendURL } = config.editor;\n\n // Retrieve the access token\n const oAuth2TokenResult = await intlayerAPI.auth.getOAuth2AccessToken();\n const accessToken = oAuth2TokenResult.data?.accessToken;\n\n if (!accessToken) {\n throw new Error('Failed to retrieve access token');\n }\n\n if (oAuth2TokenResult.data?.organization.plan?.type !== 'ENTERPRISE')\n return;\n\n const API_ROUTE = `${backendURL}/api/event-listener`;\n const url = `${API_ROUTE}/${accessToken}`;\n\n this.eventSource = new EventSource(url);\n this.eventSource.onmessage = (event) => this.handleMessage(event);\n this.eventSource.onerror = (event) => this.handleError(event);\n } catch (error) {\n console.error('Error initializing IntlayerEventListener:', error);\n }\n }\n\n /**\n * Cleans up (closes) the EventSource connection.\n */\n public cleanup(): void {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n console.log('IntlayerEventListener cleaned up.');\n }\n }\n\n /**\n * Handles incoming SSE messages, parses the event data,\n * and invokes the appropriate callback.\n */\n private async handleMessage(event: IntlayerMessageEvent): Promise<void> {\n try {\n const { data } = event;\n for (const dataEl of data) {\n switch (dataEl.object) {\n case 'DICTIONARY':\n switch (dataEl.status) {\n case 'ADDED':\n await this.onDictionaryAdded?.(dataEl.dictionary);\n break;\n case 'UPDATED':\n await this.onDictionaryChange?.(dataEl.dictionary);\n break;\n case 'DELETED':\n await this.onDictionaryDeleted?.(dataEl.dictionary);\n break;\n default:\n console.error('Unhandled dictionary status:', dataEl.status);\n break;\n }\n break;\n default:\n console.error('Unknown object type:', dataEl.object);\n break;\n }\n }\n } catch (error) {\n console.error('Error processing dictionary update:', error);\n }\n }\n\n /**\n * Handles any SSE errors and then performs cleanup.\n */\n private handleError(event: Event): void {\n console.error('EventSource error:', event);\n this.cleanup();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,iBAA4B;AAG5B,oBAAiD;AAmC1C,MAAM,sBAAsB;AAAA,EAkBjC,YAAoB,gBAAiC;AAAjC;AAAA,EAAkC;AAAA,EAjB9C,cAAkC;AAAA;AAAA;AAAA;AAAA,EAKnC;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQP,MAAa,aAA4B;AACvC,QAAI;AACF,YAAM,SAAS,KAAK,sBAAkB,gCAAiB;AACvD,YAAM,EAAE,WAAW,IAAI,OAAO;AAG9B,YAAM,oBAAoB,MAAM,uBAAY,KAAK,qBAAqB;AACtE,YAAM,cAAc,kBAAkB,MAAM;AAE5C,UAAI,CAAC,aAAa;AAChB,cAAM,IAAI,MAAM,iCAAiC;AAAA,MACnD;AAEA,UAAI,kBAAkB,MAAM,aAAa,MAAM,SAAS;AACtD;AAEF,YAAM,YAAY,GAAG,UAAU;AAC/B,YAAM,MAAM,GAAG,SAAS,IAAI,WAAW;AAEvC,WAAK,cAAc,IAAI,YAAY,GAAG;AACtC,WAAK,YAAY,YAAY,CAAC,UAAU,KAAK,cAAc,KAAK;AAChE,WAAK,YAAY,UAAU,CAAC,UAAU,KAAK,YAAY,KAAK;AAAA,IAC9D,SAAS,OAAO;AACd,cAAQ,MAAM,6CAA6C,KAAK;AAAA,IAClE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,UAAgB;AACrB,QAAI,KAAK,aAAa;AACpB,WAAK,YAAY,MAAM;AACvB,WAAK,cAAc;AACnB,cAAQ,IAAI,mCAAmC;AAAA,IACjD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,cAAc,OAA4C;AACtE,QAAI;AACF,YAAM,EAAE,KAAK,IAAI;AACjB,iBAAW,UAAU,MAAM;AACzB,gBAAQ,OAAO,QAAQ;AAAA,UACrB,KAAK;AACH,oBAAQ,OAAO,QAAQ;AAAA,cACrB,KAAK;AACH,sBAAM,KAAK,oBAAoB,OAAO,UAAU;AAChD;AAAA,cACF,KAAK;AACH,sBAAM,KAAK,qBAAqB,OAAO,UAAU;AACjD;AAAA,cACF,KAAK;AACH,sBAAM,KAAK,sBAAsB,OAAO,UAAU;AAClD;AAAA,cACF;AACE,wBAAQ,MAAM,gCAAgC,OAAO,MAAM;AAC3D;AAAA,YACJ;AACA;AAAA,UACF;AACE,oBAAQ,MAAM,wBAAwB,OAAO,MAAM;AACnD;AAAA,QACJ;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,uCAAuC,KAAK;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,OAAoB;AACtC,YAAQ,MAAM,sBAAsB,KAAK;AACzC,SAAK,QAAQ;AAAA,EACf;AACF;","names":[]}
|
package/dist/cjs/fetcher.cjs
CHANGED
|
@@ -28,9 +28,7 @@ const fetcherOptions = {
|
|
|
28
28
|
headers: {
|
|
29
29
|
"Content-Type": "application/json"
|
|
30
30
|
// Default content type
|
|
31
|
-
}
|
|
32
|
-
credentials: "include"
|
|
33
|
-
// Include cookies in the request
|
|
31
|
+
}
|
|
34
32
|
};
|
|
35
33
|
const removeUndefined = (obj) => {
|
|
36
34
|
Object.keys(obj).forEach((key) => {
|
package/dist/cjs/fetcher.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fetcher.ts"],"sourcesContent":["/**\n * Type definition for options used in the fetcher function.\n * Extends the standard RequestInit interface (excluding 'body'),\n * and adds 'body' and 'params' properties for convenience.\n */\nexport type FetcherOptions = Omit<RequestInit, 'body'> & {\n /**\n * Body of the request. Should be a key-value pair object.\n */\n body?: Record<string, unknown>;\n /**\n * Query parameters to be appended to the URL.\n */\n params?:\n | Record<string, string | string[] | undefined>\n | string[]\n | URLSearchParams;\n};\n\n/**\n * Default options for the fetcher function.\n * Sets the default method to 'GET', the 'Content-Type' header to 'application/json',\n * and includes credentials in the request.\n */\nexport const fetcherOptions: FetcherOptions = {\n method: 'GET', // Default HTTP method\n headers: {\n 'Content-Type': 'application/json', // Default content type\n },\n
|
|
1
|
+
{"version":3,"sources":["../../src/fetcher.ts"],"sourcesContent":["/**\n * Type definition for options used in the fetcher function.\n * Extends the standard RequestInit interface (excluding 'body'),\n * and adds 'body' and 'params' properties for convenience.\n */\nexport type FetcherOptions = Omit<RequestInit, 'body'> & {\n /**\n * Body of the request. Should be a key-value pair object.\n */\n body?: Record<string, unknown>;\n /**\n * Query parameters to be appended to the URL.\n */\n params?:\n | Record<string, string | string[] | undefined>\n | string[]\n | URLSearchParams;\n};\n\n/**\n * Default options for the fetcher function.\n * Sets the default method to 'GET', the 'Content-Type' header to 'application/json',\n * and includes credentials in the request.\n */\nexport const fetcherOptions: FetcherOptions = {\n method: 'GET', // Default HTTP method\n headers: {\n 'Content-Type': 'application/json', // Default content type\n },\n};\n\n/**\n * Utility function to remove properties with undefined values from an object.\n * This helps prevent sending undefined values in the request options.\n *\n * @param obj - The object to clean.\n * @returns The cleaned object without undefined values.\n */\nconst removeUndefined = (obj: object) => {\n Object.keys(obj).forEach((key) => {\n if (obj[key as keyof typeof obj] === undefined) {\n delete obj[key as keyof typeof obj];\n }\n });\n return obj;\n};\n\n/**\n * Deeply merges an array of objects into a single object.\n * Later objects in the array overwrite properties of earlier ones.\n *\n * @template T - The type of objects being merged.\n * @param objects - An array of objects to merge.\n * @returns The merged object.\n */\nconst deepMerge = <T extends object>(objects: (T | undefined)[]): T =>\n objects.reduce((acc, obj) => {\n const acc1: T = (acc ?? {}) as T;\n const obj1: T = removeUndefined(obj ?? {}) as T;\n\n if (typeof acc1 === 'object' && typeof obj1 === 'object') {\n // Merge the two objects\n return { ...acc1, ...obj1 };\n }\n\n // If one of them is not an object, return the defined one\n return obj1 ?? acc1;\n }, {} as T)!;\n\n/**\n * Fetcher function to make HTTP requests.\n * It merges default options with user-provided options,\n * handles query parameters and request body,\n * and returns the parsed JSON response.\n *\n * @template T - The expected type of the response data.\n * @param url - The endpoint URL.\n * @param options - Additional options to customize the request.\n * @returns A promise that resolves with the response data of type T.\n *\n * @example\n * ```typescript\n * // Making a GET request with query parameters\n * const data = await fetcher<MyResponseType>('https://api.example.com/data', {\n * params: { search: 'query' },\n * });\n *\n * // Making a POST request with a JSON body\n * const result = await fetcher<AnotherResponseType>('https://api.example.com/submit', {\n * method: 'POST',\n * body: { key: 'value' },\n * });\n *\n * // Merge body, headers, and params\n * const result = await fetcher<AnotherResponseType>('https://api.example.com/submit', {\n * method: 'POST',\n * body: { key: 'value' },\n * headers: { 'Content-Type': 'application/json' },\n * params: { search: 'query' },\n * },\n * {\n * headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n * params: { page: 1 },\n * });\n * ```\n *\n * Result:\n * ```typescript\n * {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n * params: { page: 1, search: 'query' },\n * body: { key: 'value' },\n * }\n * ```\n */\nexport const fetcher = async <T>(\n url: string,\n ...options: FetcherOptions[]\n): Promise<T> => {\n const { signal } = new AbortController();\n\n // Initialize query parameters string and request body string\n let paramsString = '';\n let bodyString: string | undefined = undefined;\n\n // Extract other options excluding 'body', 'params', and 'headers'\n const otherOptions = options.map(\n ({ body, params, headers, ...otherOptions }) => otherOptions\n );\n\n // Merge default options with user-provided options\n const mergedOptions = deepMerge([fetcherOptions, ...otherOptions]);\n\n // Merge default headers with user-provided headers\n const mergedHeaders = deepMerge([\n fetcherOptions.headers,\n ...options.map((option) => option.headers),\n ]);\n\n // Merge query parameters\n const params = deepMerge(options.map((option) => option.params));\n\n const method = mergedOptions.method;\n\n // If the request method is not 'GET' or 'HEAD', prepare the request body\n if (method !== 'GET' && method !== 'HEAD') {\n // Merge all 'body' options\n const body = deepMerge(options.map((option) => option.body));\n if (\n mergedHeaders?.['Content-Type' as keyof HeadersInit] ===\n 'application/x-www-form-urlencoded'\n ) {\n // If the content type is 'application/x-www-form-urlencoded', encode the body accordingly\n bodyString = new URLSearchParams(\n body as Record<string, string>\n ).toString();\n } else {\n // Otherwise, stringify the body as JSON\n bodyString = JSON.stringify(body);\n }\n }\n\n // If there are query parameters, append them to the URL\n if (Object.entries(params).length > 0) {\n paramsString = `?${new URLSearchParams(\n params as Record<string, string>\n ).toString()}`;\n }\n\n // Prepare the final request options\n const formattedOptions: RequestInit = {\n ...mergedOptions,\n headers: mergedHeaders,\n body: bodyString,\n signal,\n };\n\n // Construct the full URL with query parameters\n const urlResult = `${url}${paramsString}`;\n\n // Make the HTTP request using fetch\n const response = await fetch(urlResult, formattedOptions);\n\n if (!response.ok) {\n const result = await response.json();\n\n console.error(result);\n\n // You can customize the error message or include more details\n throw new Error(JSON.stringify(result.error) ?? 'An error occurred');\n }\n return await response.json();\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBO,MAAM,iBAAiC;AAAA,EAC5C,QAAQ;AAAA;AAAA,EACR,SAAS;AAAA,IACP,gBAAgB;AAAA;AAAA,EAClB;AACF;AASA,MAAM,kBAAkB,CAAC,QAAgB;AACvC,SAAO,KAAK,GAAG,EAAE,QAAQ,CAAC,QAAQ;AAChC,QAAI,IAAI,GAAuB,MAAM,QAAW;AAC9C,aAAO,IAAI,GAAuB;AAAA,IACpC;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAUA,MAAM,YAAY,CAAmB,YACnC,QAAQ,OAAO,CAAC,KAAK,QAAQ;AAC3B,QAAM,OAAW,OAAO,CAAC;AACzB,QAAM,OAAU,gBAAgB,OAAO,CAAC,CAAC;AAEzC,MAAI,OAAO,SAAS,YAAY,OAAO,SAAS,UAAU;AAExD,WAAO,EAAE,GAAG,MAAM,GAAG,KAAK;AAAA,EAC5B;AAGA,SAAO,QAAQ;AACjB,GAAG,CAAC,CAAM;AAiDL,MAAM,UAAU,OACrB,QACG,YACY;AACf,QAAM,EAAE,OAAO,IAAI,IAAI,gBAAgB;AAGvC,MAAI,eAAe;AACnB,MAAI,aAAiC;AAGrC,QAAM,eAAe,QAAQ;AAAA,IAC3B,CAAC,EAAE,MAAM,QAAAA,SAAQ,SAAS,GAAGC,cAAa,MAAMA;AAAA,EAClD;AAGA,QAAM,gBAAgB,UAAU,CAAC,gBAAgB,GAAG,YAAY,CAAC;AAGjE,QAAM,gBAAgB,UAAU;AAAA,IAC9B,eAAe;AAAA,IACf,GAAG,QAAQ,IAAI,CAAC,WAAW,OAAO,OAAO;AAAA,EAC3C,CAAC;AAGD,QAAM,SAAS,UAAU,QAAQ,IAAI,CAAC,WAAW,OAAO,MAAM,CAAC;AAE/D,QAAM,SAAS,cAAc;AAG7B,MAAI,WAAW,SAAS,WAAW,QAAQ;AAEzC,UAAM,OAAO,UAAU,QAAQ,IAAI,CAAC,WAAW,OAAO,IAAI,CAAC;AAC3D,QACE,gBAAgB,cAAmC,MACnD,qCACA;AAEA,mBAAa,IAAI;AAAA,QACf;AAAA,MACF,EAAE,SAAS;AAAA,IACb,OAAO;AAEL,mBAAa,KAAK,UAAU,IAAI;AAAA,IAClC;AAAA,EACF;AAGA,MAAI,OAAO,QAAQ,MAAM,EAAE,SAAS,GAAG;AACrC,mBAAe,IAAI,IAAI;AAAA,MACrB;AAAA,IACF,EAAE,SAAS,CAAC;AAAA,EACd;AAGA,QAAM,mBAAgC;AAAA,IACpC,GAAG;AAAA,IACH,SAAS;AAAA,IACT,MAAM;AAAA,IACN;AAAA,EACF;AAGA,QAAM,YAAY,GAAG,GAAG,GAAG,YAAY;AAGvC,QAAM,WAAW,MAAM,MAAM,WAAW,gBAAgB;AAExD,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,SAAS,MAAM,SAAS,KAAK;AAEnC,YAAQ,MAAM,MAAM;AAGpB,UAAM,IAAI,MAAM,KAAK,UAAU,OAAO,KAAK,KAAK,mBAAmB;AAAA,EACrE;AACA,SAAO,MAAM,SAAS,KAAK;AAC7B;","names":["params","otherOptions"]}
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -18,10 +18,12 @@ module.exports = __toCommonJS(index_exports);
|
|
|
18
18
|
__reExport(index_exports, require('./getIntlayerAPI/index.cjs'), module.exports);
|
|
19
19
|
__reExport(index_exports, require('./distantDictionary/index.cjs'), module.exports);
|
|
20
20
|
__reExport(index_exports, require('./fetcher.cjs'), module.exports);
|
|
21
|
+
__reExport(index_exports, require('./IntlayerEventListener.cjs'), module.exports);
|
|
21
22
|
// Annotate the CommonJS export names for ESM import in node:
|
|
22
23
|
0 && (module.exports = {
|
|
23
24
|
...require('./getIntlayerAPI/index.cjs'),
|
|
24
25
|
...require('./distantDictionary/index.cjs'),
|
|
25
|
-
...require('./fetcher.cjs')
|
|
26
|
+
...require('./fetcher.cjs'),
|
|
27
|
+
...require('./IntlayerEventListener.cjs')
|
|
26
28
|
});
|
|
27
29
|
//# sourceMappingURL=index.cjs.map
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export * from './getIntlayerAPI/index';\nexport * from './distantDictionary/index';\nexport * from './fetcher';\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,0BAAc,mCAAd;AACA,0BAAc,sCADd;AAEA,0BAAc,sBAFd;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export * from './getIntlayerAPI/index';\nexport * from './distantDictionary/index';\nexport * from './fetcher';\nexport * from './IntlayerEventListener';\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,0BAAc,mCAAd;AACA,0BAAc,sCADd;AAEA,0BAAc,sBAFd;AAGA,0BAAc,oCAHd;","names":[]}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { intlayerAPI } from "@intlayer/api";
|
|
2
|
+
import { getConfiguration } from "@intlayer/config/client";
|
|
3
|
+
class IntlayerEventListener {
|
|
4
|
+
constructor(intlayerConfig) {
|
|
5
|
+
this.intlayerConfig = intlayerConfig;
|
|
6
|
+
}
|
|
7
|
+
eventSource = null;
|
|
8
|
+
/**
|
|
9
|
+
* Callback triggered when a Dictionary is ADDED.
|
|
10
|
+
*/
|
|
11
|
+
onDictionaryAdded;
|
|
12
|
+
/**
|
|
13
|
+
* Callback triggered when a Dictionary is UPDATED.
|
|
14
|
+
*/
|
|
15
|
+
onDictionaryChange;
|
|
16
|
+
/**
|
|
17
|
+
* Callback triggered when a Dictionary is DELETED.
|
|
18
|
+
*/
|
|
19
|
+
onDictionaryDeleted;
|
|
20
|
+
/**
|
|
21
|
+
* Initializes the EventSource connection using the given intlayerConfig
|
|
22
|
+
* (or the default config if none was provided).
|
|
23
|
+
*/
|
|
24
|
+
async initialize() {
|
|
25
|
+
try {
|
|
26
|
+
const config = this.intlayerConfig ?? getConfiguration();
|
|
27
|
+
const { backendURL } = config.editor;
|
|
28
|
+
const oAuth2TokenResult = await intlayerAPI.auth.getOAuth2AccessToken();
|
|
29
|
+
const accessToken = oAuth2TokenResult.data?.accessToken;
|
|
30
|
+
if (!accessToken) {
|
|
31
|
+
throw new Error("Failed to retrieve access token");
|
|
32
|
+
}
|
|
33
|
+
if (oAuth2TokenResult.data?.organization.plan?.type !== "ENTERPRISE")
|
|
34
|
+
return;
|
|
35
|
+
const API_ROUTE = `${backendURL}/api/event-listener`;
|
|
36
|
+
const url = `${API_ROUTE}/${accessToken}`;
|
|
37
|
+
this.eventSource = new EventSource(url);
|
|
38
|
+
this.eventSource.onmessage = (event) => this.handleMessage(event);
|
|
39
|
+
this.eventSource.onerror = (event) => this.handleError(event);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error("Error initializing IntlayerEventListener:", error);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Cleans up (closes) the EventSource connection.
|
|
46
|
+
*/
|
|
47
|
+
cleanup() {
|
|
48
|
+
if (this.eventSource) {
|
|
49
|
+
this.eventSource.close();
|
|
50
|
+
this.eventSource = null;
|
|
51
|
+
console.log("IntlayerEventListener cleaned up.");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Handles incoming SSE messages, parses the event data,
|
|
56
|
+
* and invokes the appropriate callback.
|
|
57
|
+
*/
|
|
58
|
+
async handleMessage(event) {
|
|
59
|
+
try {
|
|
60
|
+
const { data } = event;
|
|
61
|
+
for (const dataEl of data) {
|
|
62
|
+
switch (dataEl.object) {
|
|
63
|
+
case "DICTIONARY":
|
|
64
|
+
switch (dataEl.status) {
|
|
65
|
+
case "ADDED":
|
|
66
|
+
await this.onDictionaryAdded?.(dataEl.dictionary);
|
|
67
|
+
break;
|
|
68
|
+
case "UPDATED":
|
|
69
|
+
await this.onDictionaryChange?.(dataEl.dictionary);
|
|
70
|
+
break;
|
|
71
|
+
case "DELETED":
|
|
72
|
+
await this.onDictionaryDeleted?.(dataEl.dictionary);
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
console.error("Unhandled dictionary status:", dataEl.status);
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
break;
|
|
79
|
+
default:
|
|
80
|
+
console.error("Unknown object type:", dataEl.object);
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.error("Error processing dictionary update:", error);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Handles any SSE errors and then performs cleanup.
|
|
90
|
+
*/
|
|
91
|
+
handleError(event) {
|
|
92
|
+
console.error("EventSource error:", event);
|
|
93
|
+
this.cleanup();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export {
|
|
97
|
+
IntlayerEventListener
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=IntlayerEventListener.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/IntlayerEventListener.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { intlayerAPI } from '@intlayer/api';\n// @ts-ignore: @intlayer/backend is not built yet\nimport { DictionaryAPI } from '@intlayer/backend';\nimport { getConfiguration, IntlayerConfig } from '@intlayer/config/client';\n// @ts-ignore @intlayer/backend is not built yet\n\nexport type DictionaryMessageEvent = {\n object: 'DICTIONARY';\n dictionary: DictionaryAPI;\n status: 'ADDED' | 'UPDATED' | 'DELETED' | 'CREATED';\n};\n\nexport type IntlayerMessageEvent = MessageEvent<DictionaryMessageEvent[]>;\n\n/**\n * IntlayerEventListener class to listen for dictionary changes via SSE (Server-Sent Events).\n *\n * Usage example:\n *\n * import { buildIntlayerDictionary } from './transpiler/declaration_file_to_dictionary/intlayer_dictionary';\n * import { IntlayerEventListener } from '@intlayer/api';\n *\n * export const checkDictionaryChanges = async () => {\n * // Instantiate the listener\n * const eventListener = new IntlayerEventListener();\n *\n * // Set up your callbacks\n * eventListener.onDictionaryChange = async (dictionary) => {\n * await buildIntlayerDictionary(dictionary);\n * };\n *\n * // Initialize the listener\n * await eventListener.initialize();\n *\n * // Optionally, clean up later when you’re done\n * // eventListener.cleanup();\n * };\n */\nexport class IntlayerEventListener {\n private eventSource: EventSource | null = null;\n\n /**\n * Callback triggered when a Dictionary is ADDED.\n */\n public onDictionaryAdded?: (dictionary: DictionaryAPI) => any;\n\n /**\n * Callback triggered when a Dictionary is UPDATED.\n */\n public onDictionaryChange?: (dictionary: DictionaryAPI) => any;\n\n /**\n * Callback triggered when a Dictionary is DELETED.\n */\n public onDictionaryDeleted?: (dictionary: DictionaryAPI) => any;\n\n constructor(private intlayerConfig?: IntlayerConfig) {}\n\n /**\n * Initializes the EventSource connection using the given intlayerConfig\n * (or the default config if none was provided).\n */\n public async initialize(): Promise<void> {\n try {\n const config = this.intlayerConfig ?? getConfiguration();\n const { backendURL } = config.editor;\n\n // Retrieve the access token\n const oAuth2TokenResult = await intlayerAPI.auth.getOAuth2AccessToken();\n const accessToken = oAuth2TokenResult.data?.accessToken;\n\n if (!accessToken) {\n throw new Error('Failed to retrieve access token');\n }\n\n if (oAuth2TokenResult.data?.organization.plan?.type !== 'ENTERPRISE')\n return;\n\n const API_ROUTE = `${backendURL}/api/event-listener`;\n const url = `${API_ROUTE}/${accessToken}`;\n\n this.eventSource = new EventSource(url);\n this.eventSource.onmessage = (event) => this.handleMessage(event);\n this.eventSource.onerror = (event) => this.handleError(event);\n } catch (error) {\n console.error('Error initializing IntlayerEventListener:', error);\n }\n }\n\n /**\n * Cleans up (closes) the EventSource connection.\n */\n public cleanup(): void {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n console.log('IntlayerEventListener cleaned up.');\n }\n }\n\n /**\n * Handles incoming SSE messages, parses the event data,\n * and invokes the appropriate callback.\n */\n private async handleMessage(event: IntlayerMessageEvent): Promise<void> {\n try {\n const { data } = event;\n for (const dataEl of data) {\n switch (dataEl.object) {\n case 'DICTIONARY':\n switch (dataEl.status) {\n case 'ADDED':\n await this.onDictionaryAdded?.(dataEl.dictionary);\n break;\n case 'UPDATED':\n await this.onDictionaryChange?.(dataEl.dictionary);\n break;\n case 'DELETED':\n await this.onDictionaryDeleted?.(dataEl.dictionary);\n break;\n default:\n console.error('Unhandled dictionary status:', dataEl.status);\n break;\n }\n break;\n default:\n console.error('Unknown object type:', dataEl.object);\n break;\n }\n }\n } catch (error) {\n console.error('Error processing dictionary update:', error);\n }\n }\n\n /**\n * Handles any SSE errors and then performs cleanup.\n */\n private handleError(event: Event): void {\n console.error('EventSource error:', event);\n this.cleanup();\n }\n}\n"],"mappings":"AACA,SAAS,mBAAmB;AAG5B,SAAS,wBAAwC;AAmC1C,MAAM,sBAAsB;AAAA,EAkBjC,YAAoB,gBAAiC;AAAjC;AAAA,EAAkC;AAAA,EAjB9C,cAAkC;AAAA;AAAA;AAAA;AAAA,EAKnC;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQP,MAAa,aAA4B;AACvC,QAAI;AACF,YAAM,SAAS,KAAK,kBAAkB,iBAAiB;AACvD,YAAM,EAAE,WAAW,IAAI,OAAO;AAG9B,YAAM,oBAAoB,MAAM,YAAY,KAAK,qBAAqB;AACtE,YAAM,cAAc,kBAAkB,MAAM;AAE5C,UAAI,CAAC,aAAa;AAChB,cAAM,IAAI,MAAM,iCAAiC;AAAA,MACnD;AAEA,UAAI,kBAAkB,MAAM,aAAa,MAAM,SAAS;AACtD;AAEF,YAAM,YAAY,GAAG,UAAU;AAC/B,YAAM,MAAM,GAAG,SAAS,IAAI,WAAW;AAEvC,WAAK,cAAc,IAAI,YAAY,GAAG;AACtC,WAAK,YAAY,YAAY,CAAC,UAAU,KAAK,cAAc,KAAK;AAChE,WAAK,YAAY,UAAU,CAAC,UAAU,KAAK,YAAY,KAAK;AAAA,IAC9D,SAAS,OAAO;AACd,cAAQ,MAAM,6CAA6C,KAAK;AAAA,IAClE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,UAAgB;AACrB,QAAI,KAAK,aAAa;AACpB,WAAK,YAAY,MAAM;AACvB,WAAK,cAAc;AACnB,cAAQ,IAAI,mCAAmC;AAAA,IACjD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,cAAc,OAA4C;AACtE,QAAI;AACF,YAAM,EAAE,KAAK,IAAI;AACjB,iBAAW,UAAU,MAAM;AACzB,gBAAQ,OAAO,QAAQ;AAAA,UACrB,KAAK;AACH,oBAAQ,OAAO,QAAQ;AAAA,cACrB,KAAK;AACH,sBAAM,KAAK,oBAAoB,OAAO,UAAU;AAChD;AAAA,cACF,KAAK;AACH,sBAAM,KAAK,qBAAqB,OAAO,UAAU;AACjD;AAAA,cACF,KAAK;AACH,sBAAM,KAAK,sBAAsB,OAAO,UAAU;AAClD;AAAA,cACF;AACE,wBAAQ,MAAM,gCAAgC,OAAO,MAAM;AAC3D;AAAA,YACJ;AACA;AAAA,UACF;AACE,oBAAQ,MAAM,wBAAwB,OAAO,MAAM;AACnD;AAAA,QACJ;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,uCAAuC,KAAK;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAY,OAAoB;AACtC,YAAQ,MAAM,sBAAsB,KAAK;AACzC,SAAK,QAAQ;AAAA,EACf;AACF;","names":[]}
|
package/dist/esm/fetcher.mjs
CHANGED
package/dist/esm/fetcher.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fetcher.ts"],"sourcesContent":["/**\n * Type definition for options used in the fetcher function.\n * Extends the standard RequestInit interface (excluding 'body'),\n * and adds 'body' and 'params' properties for convenience.\n */\nexport type FetcherOptions = Omit<RequestInit, 'body'> & {\n /**\n * Body of the request. Should be a key-value pair object.\n */\n body?: Record<string, unknown>;\n /**\n * Query parameters to be appended to the URL.\n */\n params?:\n | Record<string, string | string[] | undefined>\n | string[]\n | URLSearchParams;\n};\n\n/**\n * Default options for the fetcher function.\n * Sets the default method to 'GET', the 'Content-Type' header to 'application/json',\n * and includes credentials in the request.\n */\nexport const fetcherOptions: FetcherOptions = {\n method: 'GET', // Default HTTP method\n headers: {\n 'Content-Type': 'application/json', // Default content type\n },\n
|
|
1
|
+
{"version":3,"sources":["../../src/fetcher.ts"],"sourcesContent":["/**\n * Type definition for options used in the fetcher function.\n * Extends the standard RequestInit interface (excluding 'body'),\n * and adds 'body' and 'params' properties for convenience.\n */\nexport type FetcherOptions = Omit<RequestInit, 'body'> & {\n /**\n * Body of the request. Should be a key-value pair object.\n */\n body?: Record<string, unknown>;\n /**\n * Query parameters to be appended to the URL.\n */\n params?:\n | Record<string, string | string[] | undefined>\n | string[]\n | URLSearchParams;\n};\n\n/**\n * Default options for the fetcher function.\n * Sets the default method to 'GET', the 'Content-Type' header to 'application/json',\n * and includes credentials in the request.\n */\nexport const fetcherOptions: FetcherOptions = {\n method: 'GET', // Default HTTP method\n headers: {\n 'Content-Type': 'application/json', // Default content type\n },\n};\n\n/**\n * Utility function to remove properties with undefined values from an object.\n * This helps prevent sending undefined values in the request options.\n *\n * @param obj - The object to clean.\n * @returns The cleaned object without undefined values.\n */\nconst removeUndefined = (obj: object) => {\n Object.keys(obj).forEach((key) => {\n if (obj[key as keyof typeof obj] === undefined) {\n delete obj[key as keyof typeof obj];\n }\n });\n return obj;\n};\n\n/**\n * Deeply merges an array of objects into a single object.\n * Later objects in the array overwrite properties of earlier ones.\n *\n * @template T - The type of objects being merged.\n * @param objects - An array of objects to merge.\n * @returns The merged object.\n */\nconst deepMerge = <T extends object>(objects: (T | undefined)[]): T =>\n objects.reduce((acc, obj) => {\n const acc1: T = (acc ?? {}) as T;\n const obj1: T = removeUndefined(obj ?? {}) as T;\n\n if (typeof acc1 === 'object' && typeof obj1 === 'object') {\n // Merge the two objects\n return { ...acc1, ...obj1 };\n }\n\n // If one of them is not an object, return the defined one\n return obj1 ?? acc1;\n }, {} as T)!;\n\n/**\n * Fetcher function to make HTTP requests.\n * It merges default options with user-provided options,\n * handles query parameters and request body,\n * and returns the parsed JSON response.\n *\n * @template T - The expected type of the response data.\n * @param url - The endpoint URL.\n * @param options - Additional options to customize the request.\n * @returns A promise that resolves with the response data of type T.\n *\n * @example\n * ```typescript\n * // Making a GET request with query parameters\n * const data = await fetcher<MyResponseType>('https://api.example.com/data', {\n * params: { search: 'query' },\n * });\n *\n * // Making a POST request with a JSON body\n * const result = await fetcher<AnotherResponseType>('https://api.example.com/submit', {\n * method: 'POST',\n * body: { key: 'value' },\n * });\n *\n * // Merge body, headers, and params\n * const result = await fetcher<AnotherResponseType>('https://api.example.com/submit', {\n * method: 'POST',\n * body: { key: 'value' },\n * headers: { 'Content-Type': 'application/json' },\n * params: { search: 'query' },\n * },\n * {\n * headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n * params: { page: 1 },\n * });\n * ```\n *\n * Result:\n * ```typescript\n * {\n * method: 'POST',\n * headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n * params: { page: 1, search: 'query' },\n * body: { key: 'value' },\n * }\n * ```\n */\nexport const fetcher = async <T>(\n url: string,\n ...options: FetcherOptions[]\n): Promise<T> => {\n const { signal } = new AbortController();\n\n // Initialize query parameters string and request body string\n let paramsString = '';\n let bodyString: string | undefined = undefined;\n\n // Extract other options excluding 'body', 'params', and 'headers'\n const otherOptions = options.map(\n ({ body, params, headers, ...otherOptions }) => otherOptions\n );\n\n // Merge default options with user-provided options\n const mergedOptions = deepMerge([fetcherOptions, ...otherOptions]);\n\n // Merge default headers with user-provided headers\n const mergedHeaders = deepMerge([\n fetcherOptions.headers,\n ...options.map((option) => option.headers),\n ]);\n\n // Merge query parameters\n const params = deepMerge(options.map((option) => option.params));\n\n const method = mergedOptions.method;\n\n // If the request method is not 'GET' or 'HEAD', prepare the request body\n if (method !== 'GET' && method !== 'HEAD') {\n // Merge all 'body' options\n const body = deepMerge(options.map((option) => option.body));\n if (\n mergedHeaders?.['Content-Type' as keyof HeadersInit] ===\n 'application/x-www-form-urlencoded'\n ) {\n // If the content type is 'application/x-www-form-urlencoded', encode the body accordingly\n bodyString = new URLSearchParams(\n body as Record<string, string>\n ).toString();\n } else {\n // Otherwise, stringify the body as JSON\n bodyString = JSON.stringify(body);\n }\n }\n\n // If there are query parameters, append them to the URL\n if (Object.entries(params).length > 0) {\n paramsString = `?${new URLSearchParams(\n params as Record<string, string>\n ).toString()}`;\n }\n\n // Prepare the final request options\n const formattedOptions: RequestInit = {\n ...mergedOptions,\n headers: mergedHeaders,\n body: bodyString,\n signal,\n };\n\n // Construct the full URL with query parameters\n const urlResult = `${url}${paramsString}`;\n\n // Make the HTTP request using fetch\n const response = await fetch(urlResult, formattedOptions);\n\n if (!response.ok) {\n const result = await response.json();\n\n console.error(result);\n\n // You can customize the error message or include more details\n throw new Error(JSON.stringify(result.error) ?? 'An error occurred');\n }\n return await response.json();\n};\n"],"mappings":"AAwBO,MAAM,iBAAiC;AAAA,EAC5C,QAAQ;AAAA;AAAA,EACR,SAAS;AAAA,IACP,gBAAgB;AAAA;AAAA,EAClB;AACF;AASA,MAAM,kBAAkB,CAAC,QAAgB;AACvC,SAAO,KAAK,GAAG,EAAE,QAAQ,CAAC,QAAQ;AAChC,QAAI,IAAI,GAAuB,MAAM,QAAW;AAC9C,aAAO,IAAI,GAAuB;AAAA,IACpC;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAUA,MAAM,YAAY,CAAmB,YACnC,QAAQ,OAAO,CAAC,KAAK,QAAQ;AAC3B,QAAM,OAAW,OAAO,CAAC;AACzB,QAAM,OAAU,gBAAgB,OAAO,CAAC,CAAC;AAEzC,MAAI,OAAO,SAAS,YAAY,OAAO,SAAS,UAAU;AAExD,WAAO,EAAE,GAAG,MAAM,GAAG,KAAK;AAAA,EAC5B;AAGA,SAAO,QAAQ;AACjB,GAAG,CAAC,CAAM;AAiDL,MAAM,UAAU,OACrB,QACG,YACY;AACf,QAAM,EAAE,OAAO,IAAI,IAAI,gBAAgB;AAGvC,MAAI,eAAe;AACnB,MAAI,aAAiC;AAGrC,QAAM,eAAe,QAAQ;AAAA,IAC3B,CAAC,EAAE,MAAM,QAAAA,SAAQ,SAAS,GAAGC,cAAa,MAAMA;AAAA,EAClD;AAGA,QAAM,gBAAgB,UAAU,CAAC,gBAAgB,GAAG,YAAY,CAAC;AAGjE,QAAM,gBAAgB,UAAU;AAAA,IAC9B,eAAe;AAAA,IACf,GAAG,QAAQ,IAAI,CAAC,WAAW,OAAO,OAAO;AAAA,EAC3C,CAAC;AAGD,QAAM,SAAS,UAAU,QAAQ,IAAI,CAAC,WAAW,OAAO,MAAM,CAAC;AAE/D,QAAM,SAAS,cAAc;AAG7B,MAAI,WAAW,SAAS,WAAW,QAAQ;AAEzC,UAAM,OAAO,UAAU,QAAQ,IAAI,CAAC,WAAW,OAAO,IAAI,CAAC;AAC3D,QACE,gBAAgB,cAAmC,MACnD,qCACA;AAEA,mBAAa,IAAI;AAAA,QACf;AAAA,MACF,EAAE,SAAS;AAAA,IACb,OAAO;AAEL,mBAAa,KAAK,UAAU,IAAI;AAAA,IAClC;AAAA,EACF;AAGA,MAAI,OAAO,QAAQ,MAAM,EAAE,SAAS,GAAG;AACrC,mBAAe,IAAI,IAAI;AAAA,MACrB;AAAA,IACF,EAAE,SAAS,CAAC;AAAA,EACd;AAGA,QAAM,mBAAgC;AAAA,IACpC,GAAG;AAAA,IACH,SAAS;AAAA,IACT,MAAM;AAAA,IACN;AAAA,EACF;AAGA,QAAM,YAAY,GAAG,GAAG,GAAG,YAAY;AAGvC,QAAM,WAAW,MAAM,MAAM,WAAW,gBAAgB;AAExD,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,SAAS,MAAM,SAAS,KAAK;AAEnC,YAAQ,MAAM,MAAM;AAGpB,UAAM,IAAI,MAAM,KAAK,UAAU,OAAO,KAAK,KAAK,mBAAmB;AAAA,EACrE;AACA,SAAO,MAAM,SAAS,KAAK;AAC7B;","names":["params","otherOptions"]}
|
package/dist/esm/index.mjs
CHANGED
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export * from './getIntlayerAPI/index';\nexport * from './distantDictionary/index';\nexport * from './fetcher';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["export * from './getIntlayerAPI/index';\nexport * from './distantDictionary/index';\nexport * from './fetcher';\nexport * from './IntlayerEventListener';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { DictionaryAPI } from '@intlayer/backend';
|
|
2
|
+
import { IntlayerConfig } from '@intlayer/config/client';
|
|
3
|
+
export type DictionaryMessageEvent = {
|
|
4
|
+
object: 'DICTIONARY';
|
|
5
|
+
dictionary: DictionaryAPI;
|
|
6
|
+
status: 'ADDED' | 'UPDATED' | 'DELETED' | 'CREATED';
|
|
7
|
+
};
|
|
8
|
+
export type IntlayerMessageEvent = MessageEvent<DictionaryMessageEvent[]>;
|
|
9
|
+
/**
|
|
10
|
+
* IntlayerEventListener class to listen for dictionary changes via SSE (Server-Sent Events).
|
|
11
|
+
*
|
|
12
|
+
* Usage example:
|
|
13
|
+
*
|
|
14
|
+
* import { buildIntlayerDictionary } from './transpiler/declaration_file_to_dictionary/intlayer_dictionary';
|
|
15
|
+
* import { IntlayerEventListener } from '@intlayer/api';
|
|
16
|
+
*
|
|
17
|
+
* export const checkDictionaryChanges = async () => {
|
|
18
|
+
* // Instantiate the listener
|
|
19
|
+
* const eventListener = new IntlayerEventListener();
|
|
20
|
+
*
|
|
21
|
+
* // Set up your callbacks
|
|
22
|
+
* eventListener.onDictionaryChange = async (dictionary) => {
|
|
23
|
+
* await buildIntlayerDictionary(dictionary);
|
|
24
|
+
* };
|
|
25
|
+
*
|
|
26
|
+
* // Initialize the listener
|
|
27
|
+
* await eventListener.initialize();
|
|
28
|
+
*
|
|
29
|
+
* // Optionally, clean up later when you’re done
|
|
30
|
+
* // eventListener.cleanup();
|
|
31
|
+
* };
|
|
32
|
+
*/
|
|
33
|
+
export declare class IntlayerEventListener {
|
|
34
|
+
private intlayerConfig?;
|
|
35
|
+
private eventSource;
|
|
36
|
+
/**
|
|
37
|
+
* Callback triggered when a Dictionary is ADDED.
|
|
38
|
+
*/
|
|
39
|
+
onDictionaryAdded?: (dictionary: DictionaryAPI) => any;
|
|
40
|
+
/**
|
|
41
|
+
* Callback triggered when a Dictionary is UPDATED.
|
|
42
|
+
*/
|
|
43
|
+
onDictionaryChange?: (dictionary: DictionaryAPI) => any;
|
|
44
|
+
/**
|
|
45
|
+
* Callback triggered when a Dictionary is DELETED.
|
|
46
|
+
*/
|
|
47
|
+
onDictionaryDeleted?: (dictionary: DictionaryAPI) => any;
|
|
48
|
+
constructor(intlayerConfig?: IntlayerConfig);
|
|
49
|
+
/**
|
|
50
|
+
* Initializes the EventSource connection using the given intlayerConfig
|
|
51
|
+
* (or the default config if none was provided).
|
|
52
|
+
*/
|
|
53
|
+
initialize(): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Cleans up (closes) the EventSource connection.
|
|
56
|
+
*/
|
|
57
|
+
cleanup(): void;
|
|
58
|
+
/**
|
|
59
|
+
* Handles incoming SSE messages, parses the event data,
|
|
60
|
+
* and invokes the appropriate callback.
|
|
61
|
+
*/
|
|
62
|
+
private handleMessage;
|
|
63
|
+
/**
|
|
64
|
+
* Handles any SSE errors and then performs cleanup.
|
|
65
|
+
*/
|
|
66
|
+
private handleError;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=IntlayerEventListener.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IntlayerEventListener.d.ts","sourceRoot":"","sources":["../../src/IntlayerEventListener.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAoB,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAG3E,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,aAAa,CAAC;IAC1B,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,YAAY,CAAC,sBAAsB,EAAE,CAAC,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,qBAAqB;IAkBpB,OAAO,CAAC,cAAc,CAAC;IAjBnC,OAAO,CAAC,WAAW,CAA4B;IAE/C;;OAEG;IACI,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,KAAK,GAAG,CAAC;IAE9D;;OAEG;IACI,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,KAAK,GAAG,CAAC;IAE/D;;OAEG;IACI,mBAAmB,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,KAAK,GAAG,CAAC;gBAE5C,cAAc,CAAC,EAAE,cAAc;IAEnD;;;OAGG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA2BxC;;OAEG;IACI,OAAO,IAAI,IAAI;IAQtB;;;OAGG;YACW,aAAa;IA+B3B;;OAEG;IACH,OAAO,CAAC,WAAW;CAIpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../src/fetcher.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG;IACvD;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B;;OAEG;IACH,MAAM,CAAC,EACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GAC7C,MAAM,EAAE,GACR,eAAe,CAAC;CACrB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,
|
|
1
|
+
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../src/fetcher.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG;IACvD;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B;;OAEG;IACH,MAAM,CAAC,EACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GAC7C,MAAM,EAAE,GACR,eAAe,CAAC;CACrB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,cAK5B,CAAC;AAwCF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,eAAO,MAAM,OAAO,GAAU,CAAC,OACxB,MAAM,cACC,cAAc,EAAE,KAC3B,OAAO,CAAC,CAAC,CA0EX,CAAC"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,WAAW,CAAC;AAC1B,cAAc,yBAAyB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/api",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.10",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "SDK for interacting with the Intlayer API, enabling content auditing, and managing organizations, projects, and users.",
|
|
6
6
|
"keywords": [
|
|
@@ -57,11 +57,11 @@
|
|
|
57
57
|
"./package.json"
|
|
58
58
|
],
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@intlayer/config": "4.1.
|
|
60
|
+
"@intlayer/config": "4.1.10"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@changesets/changelog-github": "0.5.0",
|
|
64
|
-
"@changesets/cli": "2.27.
|
|
64
|
+
"@changesets/cli": "2.27.12",
|
|
65
65
|
"@types/node": "^22.10.6",
|
|
66
66
|
"@typescript-eslint/parser": "^8.20.0",
|
|
67
67
|
"concurrently": "^9.1.2",
|
|
@@ -71,15 +71,15 @@
|
|
|
71
71
|
"tsc-alias": "^1.8.10",
|
|
72
72
|
"tsup": "^8.3.5",
|
|
73
73
|
"typescript": "^5.7.3",
|
|
74
|
-
"@utils/eslint-config": "1.0.4",
|
|
75
|
-
"@utils/tsup-config": "1.0.4",
|
|
76
74
|
"@utils/ts-config": "1.0.4",
|
|
75
|
+
"@utils/tsup-config": "1.0.4",
|
|
76
|
+
"intlayer-editor": "4.1.10",
|
|
77
|
+
"@utils/eslint-config": "1.0.4",
|
|
77
78
|
"@utils/ts-config-types": "1.0.4",
|
|
78
|
-
"@intlayer/backend": "4.1.
|
|
79
|
-
"intlayer-editor": "4.1.8"
|
|
79
|
+
"@intlayer/backend": "4.1.10"
|
|
80
80
|
},
|
|
81
81
|
"peerDependencies": {
|
|
82
|
-
"@intlayer/config": "4.1.
|
|
82
|
+
"@intlayer/config": "4.1.10"
|
|
83
83
|
},
|
|
84
84
|
"engines": {
|
|
85
85
|
"node": ">=14.18"
|