@geins/core 0.3.0-canary
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/.turbo/turbo-build.log +7 -0
- package/CHANGELOG.md +13 -0
- package/README.md +1 -0
- package/__tests__/Channel.test.ts +34 -0
- package/__tests__/EventService.test.ts +32 -0
- package/__tests__/GeinsCore.test.ts +69 -0
- package/__tests__/Graphql.test.ts +43 -0
- package/dist/api-client/endpointClient.d.ts +8 -0
- package/dist/api-client/index.d.ts +4 -0
- package/dist/api-client/managementApiClient.d.ts +10 -0
- package/dist/api-client/merchantApiClient.d.ts +46 -0
- package/dist/base/baseApiService.d.ts +14 -0
- package/dist/base/basePackage.d.ts +12 -0
- package/dist/base/baseStore.d.ts +14 -0
- package/dist/base/index.d.ts +3 -0
- package/dist/constants/cookies.d.ts +11 -0
- package/dist/constants/endpoints.d.ts +14 -0
- package/dist/constants/headerNames.d.ts +3 -0
- package/dist/constants/index.d.ts +3 -0
- package/dist/geinsCore.d.ts +88 -0
- package/dist/graphql/index.d.ts +1 -0
- package/dist/graphql/queries.d.ts +5 -0
- package/dist/index.cjs +21783 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.esm.js +21749 -0
- package/dist/logic/channel.d.ts +17 -0
- package/dist/logic/index.d.ts +1 -0
- package/dist/parsers/channelParser.d.ts +8 -0
- package/dist/services/channelService.d.ts +8 -0
- package/dist/services/channelsService.d.ts +8 -0
- package/dist/services/cookieService.d.ts +88 -0
- package/dist/services/eventService.d.ts +51 -0
- package/dist/services/graphQLService.d.ts +23 -0
- package/dist/services/index.d.ts +7 -0
- package/dist/services/logService.d.ts +19 -0
- package/dist/services/routingService.d.ts +74 -0
- package/dist/stores/channelStore.d.ts +11 -0
- package/dist/stores/index.d.ts +2 -0
- package/dist/stores/routingStore.d.ts +32 -0
- package/dist/utils/helpers.d.ts +21 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/simpleCache.d.ts +9 -0
- package/eslint.config.js +3 -0
- package/jest.config.js +8 -0
- package/package.json +32 -0
- package/rollup.config.js +26 -0
- package/src/api-client/endpointClient.ts +52 -0
- package/src/api-client/index.ts +4 -0
- package/src/api-client/managementApiClient.ts +41 -0
- package/src/api-client/merchantApiClient.ts +153 -0
- package/src/base/baseApiService.ts +96 -0
- package/src/base/basePackage.ts +39 -0
- package/src/base/baseStore.ts +21 -0
- package/src/base/index.ts +3 -0
- package/src/constants/cookies.ts +12 -0
- package/src/constants/endpoints.ts +27 -0
- package/src/constants/headerNames.ts +3 -0
- package/src/constants/index.ts +3 -0
- package/src/geinsCore.ts +214 -0
- package/src/graphql/channel.gql +16 -0
- package/src/graphql/channels.gql +16 -0
- package/src/graphql/fragments/channelFields.gql +8 -0
- package/src/graphql/fragments/countryFields.gql +4 -0
- package/src/graphql/fragments/currencyFields.gql +4 -0
- package/src/graphql/fragments/languageFields.gql +5 -0
- package/src/graphql/fragments/marketFields.gql +19 -0
- package/src/graphql/graphql.d.ts +4 -0
- package/src/graphql/index.ts +1 -0
- package/src/graphql/queries.ts +9 -0
- package/src/index.ts +10 -0
- package/src/logic/channel.ts +102 -0
- package/src/logic/index.ts +1 -0
- package/src/parsers/channelParser.ts +91 -0
- package/src/services/channelService.ts +33 -0
- package/src/services/channelsService.ts +35 -0
- package/src/services/cookieService.ts +168 -0
- package/src/services/eventService.ts +89 -0
- package/src/services/graphQLService.ts +55 -0
- package/src/services/index.ts +7 -0
- package/src/services/logService.ts +434 -0
- package/src/services/routingService.ts +196 -0
- package/src/stores/channelStore.ts +34 -0
- package/src/stores/index.ts +2 -0
- package/src/stores/routingStore.ts +56 -0
- package/src/utils/helpers.ts +39 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/simpleCache.ts +27 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { GeinsSettings, GeinsChannelTypeType } from '@geins/types';
|
|
2
|
+
import { SimpleCache } from '../utils/simpleCache';
|
|
3
|
+
import { MerchantApiClient, FetchPolicyOptions } from '../api-client';
|
|
4
|
+
import { buildEndpoints } from '../utils';
|
|
5
|
+
import { ChannelStore } from '../stores';
|
|
6
|
+
import { ChannelService } from '../services';
|
|
7
|
+
|
|
8
|
+
let instance: Channel | null = null;
|
|
9
|
+
|
|
10
|
+
export class Channel {
|
|
11
|
+
private channelId: string;
|
|
12
|
+
private channelService: ChannelService | undefined;
|
|
13
|
+
private cache: SimpleCache<GeinsChannelTypeType>;
|
|
14
|
+
private store: ChannelStore | undefined;
|
|
15
|
+
private _apiClient!: () => MerchantApiClient;
|
|
16
|
+
|
|
17
|
+
constructor(private geinsSettings: GeinsSettings) {
|
|
18
|
+
if (!geinsSettings.channel) {
|
|
19
|
+
throw new Error('Channel is required');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!geinsSettings.apiKey) {
|
|
23
|
+
throw new Error('API Key is required');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
this.store = new ChannelStore();
|
|
27
|
+
this.channelId = `${geinsSettings.channel}|${geinsSettings.tld}`;
|
|
28
|
+
this.cache = new SimpleCache<GeinsChannelTypeType>(60 * 60 * 1000);
|
|
29
|
+
this.initApiClient();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private initApiClient() {
|
|
33
|
+
if (this.geinsSettings.apiKey && this.geinsSettings.accountName) {
|
|
34
|
+
const endpointsUrls = buildEndpoints(
|
|
35
|
+
this.geinsSettings.apiKey,
|
|
36
|
+
this.geinsSettings.accountName,
|
|
37
|
+
this.geinsSettings.environment,
|
|
38
|
+
);
|
|
39
|
+
const options = {
|
|
40
|
+
apiUrl: endpointsUrls.main,
|
|
41
|
+
apiKey: this.geinsSettings.apiKey,
|
|
42
|
+
requestOptions: { fetchPolicy: FetchPolicyOptions.CACHE_FIRST },
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
this._apiClient = () => new MerchantApiClient(options);
|
|
46
|
+
} else {
|
|
47
|
+
throw new Error('API Key and Account Name are required');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private initChannelService() {
|
|
52
|
+
this.channelService = new ChannelService(
|
|
53
|
+
() => this._apiClient(),
|
|
54
|
+
this.geinsSettings,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public static getInstance(geinsSettings: GeinsSettings) {
|
|
59
|
+
if (!instance) {
|
|
60
|
+
instance = new Channel(geinsSettings);
|
|
61
|
+
}
|
|
62
|
+
return instance;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
setKey(key: string, value: string): void {
|
|
66
|
+
if (!this.store) {
|
|
67
|
+
throw new Error('Store is not initialized');
|
|
68
|
+
}
|
|
69
|
+
this.store.setKey(key, value);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
getKey(key: string): Promise<string> {
|
|
73
|
+
if (!this.store) {
|
|
74
|
+
throw new Error('Store is not initialized');
|
|
75
|
+
}
|
|
76
|
+
return this.store.getKey(key);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private async setChannel() {
|
|
80
|
+
if (!this.channelService) {
|
|
81
|
+
if (!this._apiClient) {
|
|
82
|
+
this.initApiClient();
|
|
83
|
+
}
|
|
84
|
+
this.initChannelService();
|
|
85
|
+
}
|
|
86
|
+
const channel = await this.channelService?.get(this.channelId);
|
|
87
|
+
if (channel) {
|
|
88
|
+
this.cache.set(this.channelId, channel);
|
|
89
|
+
}
|
|
90
|
+
return channel;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public async get(): Promise<GeinsChannelTypeType | undefined> {
|
|
94
|
+
const cachedChannel = this.cache.get(this.channelId);
|
|
95
|
+
if (cachedChannel) {
|
|
96
|
+
return cachedChannel;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const channel = await this.setChannel();
|
|
100
|
+
return channel ?? undefined;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './channel';
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
GeinsChannelTypeType,
|
|
3
|
+
GeinsMarketTypeType,
|
|
4
|
+
GeinsCountryTypeType,
|
|
5
|
+
GeinsLanguageTypeType,
|
|
6
|
+
GeinsCurrencyTypeType,
|
|
7
|
+
} from '@geins/types';
|
|
8
|
+
|
|
9
|
+
export function parseChannelsResult(
|
|
10
|
+
result: any,
|
|
11
|
+
): GeinsChannelTypeType[] | undefined {
|
|
12
|
+
if (!result || !result.data) {
|
|
13
|
+
throw new Error('Invalid result structure for channels');
|
|
14
|
+
}
|
|
15
|
+
const channels = result.data.channels;
|
|
16
|
+
if (!channels || channels.length === 0) {
|
|
17
|
+
console.warn('No channel found');
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
return channels.map((channel: any) => parseChannel(channel));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function parseChannelResult(
|
|
24
|
+
result: any,
|
|
25
|
+
): GeinsChannelTypeType | undefined {
|
|
26
|
+
if (!result || !result.data) {
|
|
27
|
+
throw new Error('Invalid result structure for channel');
|
|
28
|
+
}
|
|
29
|
+
const channel = result.data.channel;
|
|
30
|
+
if (!channel) {
|
|
31
|
+
console.warn('No channel found');
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
return parseChannel(channel);
|
|
35
|
+
}
|
|
36
|
+
export function parseChannel(channel: any): GeinsChannelTypeType | undefined {
|
|
37
|
+
if (!channel || !channel.id) {
|
|
38
|
+
throw new Error('Invalid result structure for channel');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
id: channel.id,
|
|
43
|
+
name: channel.name,
|
|
44
|
+
type: channel.type,
|
|
45
|
+
url: channel.url,
|
|
46
|
+
defaultMarketId: channel.defaultMarketId,
|
|
47
|
+
defaultLanguageId: channel.defaultLanguageId,
|
|
48
|
+
markets: channel.markets.map((item: any) => parseMarket(item)),
|
|
49
|
+
languages: channel.languages.map((item: any) => parseLanguage(item)),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function parseMarket(market: any): GeinsMarketTypeType {
|
|
54
|
+
return {
|
|
55
|
+
id: market.id,
|
|
56
|
+
alias: market.alias,
|
|
57
|
+
allowedLanguages: market.allowedLanguages.map((item: any) =>
|
|
58
|
+
parseLanguage(item),
|
|
59
|
+
),
|
|
60
|
+
country: parseCountry(market.country),
|
|
61
|
+
currency: parseCurrency(market.currency),
|
|
62
|
+
onlyDisplayInCheckout: market.onlyDisplayInCheckout,
|
|
63
|
+
virtual: market.virtual,
|
|
64
|
+
groupKey: market.groupKey,
|
|
65
|
+
defaultLanguageId: market.defaultLanguageId,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function parseCountry(country: any): GeinsCountryTypeType {
|
|
70
|
+
return {
|
|
71
|
+
name: country.name,
|
|
72
|
+
code: country.code,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function parseLanguage(language: any): GeinsLanguageTypeType {
|
|
77
|
+
return {
|
|
78
|
+
id: language.id,
|
|
79
|
+
name: language.name,
|
|
80
|
+
code: language.code,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function parseCurrency(currency: any): GeinsCurrencyTypeType {
|
|
85
|
+
return {
|
|
86
|
+
code: currency.code,
|
|
87
|
+
symbol: currency.symbol,
|
|
88
|
+
name: currency.name,
|
|
89
|
+
rate: currency.rate,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { GeinsChannelTypeType, GeinsSettings } from '@geins/types';
|
|
2
|
+
import { SimpleCache } from '../utils/simpleCache';
|
|
3
|
+
import { BaseApiService } from '../base/baseApiService';
|
|
4
|
+
import { queries } from '../graphql';
|
|
5
|
+
import { parseChannelResult } from '../parsers/channelParser';
|
|
6
|
+
|
|
7
|
+
export class ChannelService extends BaseApiService {
|
|
8
|
+
private cache: SimpleCache<GeinsChannelTypeType>;
|
|
9
|
+
constructor(client: any, geinsSettings: GeinsSettings) {
|
|
10
|
+
super(client, geinsSettings);
|
|
11
|
+
this.cache = new SimpleCache<GeinsChannelTypeType>(15 * 60 * 1000); // 15 minutes cache
|
|
12
|
+
}
|
|
13
|
+
async get(channelId: string): Promise<GeinsChannelTypeType | undefined> {
|
|
14
|
+
const cacheKey = `channel_${channelId}`;
|
|
15
|
+
const cachedChannel = this.cache.get(cacheKey);
|
|
16
|
+
if (cachedChannel) {
|
|
17
|
+
return cachedChannel;
|
|
18
|
+
}
|
|
19
|
+
const options: any = {
|
|
20
|
+
query: queries.channel,
|
|
21
|
+
variables: { channelId },
|
|
22
|
+
};
|
|
23
|
+
const channel = await this.runQueryParsed<GeinsChannelTypeType>(options);
|
|
24
|
+
if (channel) {
|
|
25
|
+
this.cache.set(cacheKey, channel);
|
|
26
|
+
}
|
|
27
|
+
return channel;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
protected parseResult(result: any): GeinsChannelTypeType | undefined {
|
|
31
|
+
return parseChannelResult(result);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { GeinsChannelTypeType, GeinsSettings } from '@geins/types';
|
|
2
|
+
import { SimpleCache } from '../utils/simpleCache';
|
|
3
|
+
import { BaseApiService } from '../base/baseApiService';
|
|
4
|
+
import { queries } from '../graphql';
|
|
5
|
+
import { parseChannelsResult } from '../parsers/channelParser';
|
|
6
|
+
|
|
7
|
+
export class ChannelsService extends BaseApiService {
|
|
8
|
+
private cache: SimpleCache<GeinsChannelTypeType[]>;
|
|
9
|
+
|
|
10
|
+
constructor(client: any, geinsSettings: GeinsSettings) {
|
|
11
|
+
super(client, geinsSettings);
|
|
12
|
+
this.cache = new SimpleCache<GeinsChannelTypeType[]>(30 * 60 * 1000); // 30 minutes cache
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async get(): Promise<GeinsChannelTypeType[] | undefined> {
|
|
16
|
+
const cacheKey = 'all_channels';
|
|
17
|
+
const cachedChannels = this.cache.get(cacheKey);
|
|
18
|
+
|
|
19
|
+
if (cachedChannels) {
|
|
20
|
+
return cachedChannels;
|
|
21
|
+
}
|
|
22
|
+
const options: any = {
|
|
23
|
+
query: queries.channels,
|
|
24
|
+
variables: {},
|
|
25
|
+
};
|
|
26
|
+
const channels = await this.runQueryParsed<GeinsChannelTypeType[]>(options);
|
|
27
|
+
if (channels) {
|
|
28
|
+
this.cache.set(cacheKey, channels);
|
|
29
|
+
}
|
|
30
|
+
return channels;
|
|
31
|
+
}
|
|
32
|
+
protected parseResult(result: any): GeinsChannelTypeType[] | undefined {
|
|
33
|
+
return parseChannelsResult(result);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import Cookie from 'cookie-universal';
|
|
2
|
+
import { parse, type CookieSerializeOptions } from 'cookie';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options for setting cookies.
|
|
6
|
+
*/
|
|
7
|
+
export interface CookieServiceConfig {
|
|
8
|
+
/**
|
|
9
|
+
* Indicates if the cookie is HTTP only.
|
|
10
|
+
* If `true`, the cookie is inaccessible to client-side scripts.
|
|
11
|
+
*/
|
|
12
|
+
httpOnly?: boolean;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Specifies the domain for which the cookie is valid.
|
|
16
|
+
* If not specified, defaults to the host portion of the current document URL.
|
|
17
|
+
*/
|
|
18
|
+
domain?: string;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Specifies the URL path that must exist in the requested URL for the browser to send the Cookie header.
|
|
22
|
+
* Defaults to `'/'`.
|
|
23
|
+
*/
|
|
24
|
+
path?: string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Indicates if the cookie should only be transmitted over secure protocols like HTTPS.
|
|
28
|
+
* If `true`, the cookie will only be sent over secure connections.
|
|
29
|
+
*/
|
|
30
|
+
secure?: boolean;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Sets the maximum age of the cookie in seconds.
|
|
34
|
+
* Can be a number or a string representation of a number.
|
|
35
|
+
*/
|
|
36
|
+
maxAge?: number | string; // maxAge can be a number or string here
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Represents a cookie with a name and payload, extending the cookie configuration options.
|
|
41
|
+
*/
|
|
42
|
+
export interface CookieType extends CookieServiceConfig {
|
|
43
|
+
/**
|
|
44
|
+
* The name of the cookie.
|
|
45
|
+
*/
|
|
46
|
+
name: string;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The value or data stored in the cookie.
|
|
50
|
+
*/
|
|
51
|
+
payload: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Service for managing cookies.
|
|
56
|
+
*/
|
|
57
|
+
export class CookieService {
|
|
58
|
+
private path = '/';
|
|
59
|
+
private domain = '';
|
|
60
|
+
private secure = true;
|
|
61
|
+
private httpOnly = false;
|
|
62
|
+
private maxAge: number;
|
|
63
|
+
private cookie = Cookie();
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Creates an instance of CookieService.
|
|
67
|
+
* @param {CookieServiceConfig} [config] - Optional configuration for the cookie service.
|
|
68
|
+
*/
|
|
69
|
+
constructor(config?: CookieServiceConfig) {
|
|
70
|
+
this.maxAge = 0;
|
|
71
|
+
if (config) {
|
|
72
|
+
if (config.path) {
|
|
73
|
+
this.path = config.path;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (config.domain) {
|
|
77
|
+
this.domain = config.domain;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (config.secure !== undefined) {
|
|
81
|
+
this.secure = config.secure;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (config.httpOnly !== undefined) {
|
|
85
|
+
this.httpOnly = config.httpOnly;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (config.maxAge !== undefined) {
|
|
89
|
+
this.maxAge = this.parseMaxAge(config.maxAge);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Retrieves the current cookie configuration.
|
|
96
|
+
* @returns {CookieServiceConfig} - The current configuration settings.
|
|
97
|
+
*/
|
|
98
|
+
protected getConfig(): CookieServiceConfig {
|
|
99
|
+
return {
|
|
100
|
+
path: this.path,
|
|
101
|
+
domain: this.domain,
|
|
102
|
+
secure: this.secure,
|
|
103
|
+
httpOnly: this.httpOnly,
|
|
104
|
+
maxAge: this.maxAge,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private parseMaxAge(maxAge: string | number): number {
|
|
109
|
+
if (typeof maxAge === 'string') {
|
|
110
|
+
const parsed = parseInt(maxAge, 10);
|
|
111
|
+
return isNaN(parsed) ? 0 : parsed;
|
|
112
|
+
}
|
|
113
|
+
return maxAge;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private configToCookieOptions(
|
|
117
|
+
config: CookieServiceConfig,
|
|
118
|
+
): CookieSerializeOptions {
|
|
119
|
+
return {
|
|
120
|
+
path: config.path,
|
|
121
|
+
domain: config.domain,
|
|
122
|
+
secure: config.secure,
|
|
123
|
+
httpOnly: config.httpOnly,
|
|
124
|
+
maxAge:
|
|
125
|
+
config.maxAge !== undefined
|
|
126
|
+
? this.parseMaxAge(config.maxAge)
|
|
127
|
+
: undefined,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Retrieves all cookies.
|
|
133
|
+
* @returns {Record<string, string>} - An object containing all cookies.
|
|
134
|
+
*/
|
|
135
|
+
public getAll(): Record<string, string> {
|
|
136
|
+
return this.cookie.getAll() as Record<string, string>;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Retrieves the value of a specific cookie.
|
|
141
|
+
* @param {string} cookieName - The name of the cookie to retrieve.
|
|
142
|
+
* @returns {string} - The value of the cookie, or an empty string if not found.
|
|
143
|
+
*/
|
|
144
|
+
public get(cookieName: string): string {
|
|
145
|
+
return this.cookie.get(cookieName) || '';
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Removes a specific cookie.
|
|
150
|
+
* @param {string} cookieName - The name of the cookie to remove.
|
|
151
|
+
*/
|
|
152
|
+
public remove(cookieName: string): void {
|
|
153
|
+
this.cookie.remove(cookieName);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Sets a cookie with the specified options.
|
|
158
|
+
* @param {CookieType} cookie - The cookie to set, including name and payload.
|
|
159
|
+
* @param {CookieServiceConfig} [config] - Optional configuration for setting the cookie.
|
|
160
|
+
*/
|
|
161
|
+
public set(cookie: CookieType, config?: CookieServiceConfig): void {
|
|
162
|
+
const baseConfig = this.getConfig();
|
|
163
|
+
const mergedConfig = { ...baseConfig, ...config, ...cookie };
|
|
164
|
+
const options = this.configToCookieOptions(mergedConfig);
|
|
165
|
+
|
|
166
|
+
this.cookie.set(cookie.name, cookie.payload, options);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { BroadcastChannel } from 'broadcast-channel';
|
|
3
|
+
import { isServerContext } from '../utils';
|
|
4
|
+
import type { GeinsEventMessage } from '@geins/types';
|
|
5
|
+
import { logWrite } from './logService';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Event service
|
|
9
|
+
* Responsible for handling events and broadcasting them to other windows and tabs.
|
|
10
|
+
*
|
|
11
|
+
* @class
|
|
12
|
+
* @name EventService
|
|
13
|
+
*
|
|
14
|
+
*/
|
|
15
|
+
export class EventService {
|
|
16
|
+
private eventName: string = 'geins-event';
|
|
17
|
+
private emitter: any;
|
|
18
|
+
private broadcast: BroadcastChannel | undefined;
|
|
19
|
+
private broadcastChannelId: string = 'geins-channel';
|
|
20
|
+
constructor() {
|
|
21
|
+
this.emitter = new EventEmitter();
|
|
22
|
+
if (!isServerContext()) {
|
|
23
|
+
this.broadcast = new BroadcastChannel(this.broadcastChannelId);
|
|
24
|
+
this.addBroadcastListener();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private addBroadcastListener() {
|
|
29
|
+
if (this.broadcast) {
|
|
30
|
+
this.broadcast.onmessage = (data: any) => {
|
|
31
|
+
this.emitter.emit(data.eventName, data.eventMessage);
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Adds a presistent event listener to the event emitter.
|
|
38
|
+
* @param handler A callback function that handles the event data.
|
|
39
|
+
* @param eventName (optional): The name of the event to listen for. If omitted, it defaults to 'geins-event'.
|
|
40
|
+
*/
|
|
41
|
+
listnerAdd(handler: any, eventName: string = this.eventName): void {
|
|
42
|
+
this.emitter.on(eventName, handler);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Adds a one-time event listener for the specified event. This listener will be invoked only the first time the event is emitted and then automatically removed.
|
|
47
|
+
* @param handler A callback function that handles the event data.
|
|
48
|
+
* @param eventName (optional): The name of the event to listen for. If omitted, it defaults to 'geins-event'.
|
|
49
|
+
*/
|
|
50
|
+
listnerOnce(handler: any, eventName: string = this.eventName): void {
|
|
51
|
+
this.emitter.once(eventName, handler);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Removes the specified event listener from the event emitter. *
|
|
55
|
+
* @param eventName (optional): The name of the event to listen for. If omitted, it defaults to 'geins-event'.
|
|
56
|
+
*/
|
|
57
|
+
listnerRemove(eventName: string = this.eventName): void {
|
|
58
|
+
this.emitter.removeAllListeners(eventName);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Returns the number of listeners for the specified event.
|
|
62
|
+
* @param eventName (optional): The name of the event to listen for. If omitted, it defaults to 'geins-event'.
|
|
63
|
+
*/
|
|
64
|
+
listnerCount(eventName: string = this.eventName): number {
|
|
65
|
+
return this.emitter.listenerCount(eventName);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Lists the listeners for the specified event.
|
|
69
|
+
* @param eventName
|
|
70
|
+
* @returns An array of listeners for the specified event.
|
|
71
|
+
*/
|
|
72
|
+
listnersGet(eventName: string = this.eventName): any[] {
|
|
73
|
+
return this.emitter.listeners(eventName);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Pushes an event message to the event emitter.
|
|
77
|
+
* @param eventMessage - The event message to push.
|
|
78
|
+
* @param eventName - The name of the event to push the message to. If omitted, it defaults to 'geins-event'.
|
|
79
|
+
*/
|
|
80
|
+
push(
|
|
81
|
+
eventMessage: GeinsEventMessage,
|
|
82
|
+
eventName: string = this.eventName,
|
|
83
|
+
): void {
|
|
84
|
+
this.emitter.emit(eventName, eventMessage);
|
|
85
|
+
if ((eventMessage.broadcast ?? true) && this.broadcast) {
|
|
86
|
+
this.broadcast?.postMessage({ eventMessage, eventName });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { GeinsSettings } from '@geins/types';
|
|
2
|
+
import { BaseApiService } from '../base/baseApiService';
|
|
3
|
+
import { GraphQLQueryOptions } from '../api-client/merchantApiClient';
|
|
4
|
+
|
|
5
|
+
export class GraphQLService extends BaseApiService {
|
|
6
|
+
constructor(client: any, geinsSettings: GeinsSettings) {
|
|
7
|
+
super(client, geinsSettings);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Generic method to run any GraphQL query
|
|
12
|
+
* @param query - The GraphQL query DocumentNode or gql query object
|
|
13
|
+
* @param variables - Variables to pass to the query
|
|
14
|
+
* @param options - Optional options like fetchPolicy, pollInterval, etc.
|
|
15
|
+
* @returns The result data of the query or null
|
|
16
|
+
*/
|
|
17
|
+
async query<T = any>(options: GraphQLQueryOptions): Promise<T | null> {
|
|
18
|
+
try {
|
|
19
|
+
const result = this.cleanObject(await this.runQuery(options));
|
|
20
|
+
const parsedResult = this.parseResult(result);
|
|
21
|
+
return parsedResult as T;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.error('Query error:', error);
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Generic method to run any GraphQL mutation
|
|
31
|
+
* @param mutation - The GraphQL mutation DocumentNode or gql mutation object
|
|
32
|
+
* @param variables - Variables to pass to the mutation
|
|
33
|
+
* @param options - Optional options like fetchPolicy, etc.
|
|
34
|
+
* @returns The result data of the mutation or null
|
|
35
|
+
*/
|
|
36
|
+
async mutation<T = any>(options: GraphQLQueryOptions): Promise<T | null> {
|
|
37
|
+
try {
|
|
38
|
+
const result = await this.runMutation(options);
|
|
39
|
+
const parsedResult = this.parseResult(result);
|
|
40
|
+
return parsedResult as T;
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error('Mutation error:', error);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
protected parseResult(result: any): any {
|
|
47
|
+
if (result.data) {
|
|
48
|
+
return result.data;
|
|
49
|
+
}
|
|
50
|
+
if (result.errors) {
|
|
51
|
+
console.error('GraphQL errors:', result.errors);
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|