@hszrdm/core 1.6.0 → 1.8.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/.medusa/server/src/admin/index.js +7481 -5872
- package/.medusa/server/src/admin/index.mjs +7482 -5873
- package/.medusa/server/src/api/admin/arukereso/marketplace-preview/route.d.ts +2 -0
- package/.medusa/server/src/api/admin/arukereso/marketplace-preview/route.js +26 -0
- package/.medusa/server/src/api/admin/billingo/advance/route.d.ts +8 -0
- package/.medusa/server/src/api/admin/billingo/advance/route.js +55 -0
- package/.medusa/server/src/api/admin/billingo/partial-credit/route.d.ts +8 -0
- package/.medusa/server/src/api/admin/billingo/partial-credit/route.js +69 -0
- package/.medusa/server/src/api/admin/documents/[id]/route.d.ts +22 -0
- package/.medusa/server/src/api/admin/documents/[id]/route.js +107 -0
- package/.medusa/server/src/api/admin/documents/route.d.ts +21 -0
- package/.medusa/server/src/api/admin/documents/route.js +117 -0
- package/.medusa/server/src/api/admin/google-ads/diagnostics/route.d.ts +2 -0
- package/.medusa/server/src/api/admin/google-ads/diagnostics/route.js +26 -0
- package/.medusa/server/src/api/admin/google-ads/oauth/start/route.d.ts +2 -0
- package/.medusa/server/src/api/admin/google-ads/oauth/start/route.js +27 -0
- package/.medusa/server/src/api/admin/google-merchant/data-source/sync/route.d.ts +2 -0
- package/.medusa/server/src/api/admin/google-merchant/data-source/sync/route.js +69 -0
- package/.medusa/server/src/api/admin/google-merchant/diagnostics/route.d.ts +2 -0
- package/.medusa/server/src/api/admin/google-merchant/diagnostics/route.js +26 -0
- package/.medusa/server/src/api/admin/google-merchant/oauth/start/route.d.ts +2 -0
- package/.medusa/server/src/api/admin/google-merchant/oauth/start/route.js +25 -0
- package/.medusa/server/src/api/admin/orders/[id]/shipping/route.js +28 -28
- package/.medusa/server/src/api/admin/shipping/mpl/close/route.d.ts +1 -1
- package/.medusa/server/src/api/admin/shipping/mpl/close/route.js +48 -70
- package/.medusa/server/src/api/auth/google-ads/callback/route.d.ts +2 -0
- package/.medusa/server/src/api/auth/google-ads/callback/route.js +58 -0
- package/.medusa/server/src/api/feeds/arukereso-marketplace.xml/route.d.ts +2 -0
- package/.medusa/server/src/api/feeds/arukereso-marketplace.xml/route.js +33 -0
- package/.medusa/server/src/api/feeds/google-merchant.xml/route.js +5 -3
- package/.medusa/server/src/api/hooks/arukereso/marketplace/order/route.d.ts +2 -0
- package/.medusa/server/src/api/hooks/arukereso/marketplace/order/route.js +211 -0
- package/.medusa/server/src/api/hooks/simplepay/ipn/route.js +113 -23
- package/.medusa/server/src/api/store/account/orders/[id]/reorder/route.d.ts +2 -0
- package/.medusa/server/src/api/store/account/orders/[id]/reorder/route.js +113 -0
- package/.medusa/server/src/api/store/arukereso/backlink/route.d.ts +2 -0
- package/.medusa/server/src/api/store/arukereso/backlink/route.js +73 -0
- package/.medusa/server/src/api/store/arukereso/trusted-shop/[id]/route.d.ts +2 -0
- package/.medusa/server/src/api/store/arukereso/trusted-shop/[id]/route.js +84 -0
- package/.medusa/server/src/api/store/arukereso/widget/route.d.ts +2 -0
- package/.medusa/server/src/api/store/arukereso/widget/route.js +64 -0
- package/.medusa/server/src/api/store/documents/route.d.ts +2 -0
- package/.medusa/server/src/api/store/documents/route.js +84 -0
- package/.medusa/server/src/api/store/google-merchant/oauth/callback/route.d.ts +2 -0
- package/.medusa/server/src/api/store/google-merchant/oauth/callback/route.js +50 -0
- package/.medusa/server/src/config.d.ts +3 -3
- package/.medusa/server/src/config.js +64 -87
- package/.medusa/server/src/core/documents.d.ts +31 -0
- package/.medusa/server/src/core/documents.js +47 -0
- package/.medusa/server/src/core/version.d.ts +2 -2
- package/.medusa/server/src/core/version.js +2 -2
- package/.medusa/server/src/lib/modules/arukereso/index.d.ts +1 -0
- package/.medusa/server/src/lib/modules/arukereso/index.js +2 -1
- package/.medusa/server/src/lib/modules/arukereso/marketplace-feed.d.ts +19 -0
- package/.medusa/server/src/lib/modules/arukereso/marketplace-feed.js +100 -0
- package/.medusa/server/src/lib/modules/billingo/actions.js +42 -12
- package/.medusa/server/src/lib/modules/billingo/advance.d.ts +68 -0
- package/.medusa/server/src/lib/modules/billingo/advance.js +309 -0
- package/.medusa/server/src/lib/modules/billingo/automation.js +49 -9
- package/.medusa/server/src/lib/modules/billingo/client.d.ts +5 -1
- package/.medusa/server/src/lib/modules/billingo/client.js +12 -6
- package/.medusa/server/src/lib/modules/billingo/index.d.ts +2 -0
- package/.medusa/server/src/lib/modules/billingo/index.js +3 -1
- package/.medusa/server/src/lib/modules/billingo/mapper.d.ts +38 -1
- package/.medusa/server/src/lib/modules/billingo/mapper.js +32 -1
- package/.medusa/server/src/lib/modules/billingo/partial-credit.d.ts +55 -0
- package/.medusa/server/src/lib/modules/billingo/partial-credit.js +338 -0
- package/.medusa/server/src/lib/modules/billingo/types.d.ts +7 -2
- package/.medusa/server/src/lib/modules/google-ads/adjustments.d.ts +21 -0
- package/.medusa/server/src/lib/modules/google-ads/adjustments.js +146 -0
- package/.medusa/server/src/lib/modules/google-ads/api.d.ts +23 -0
- package/.medusa/server/src/lib/modules/google-ads/api.js +171 -0
- package/.medusa/server/src/lib/modules/google-ads/diagnostics.d.ts +47 -0
- package/.medusa/server/src/lib/modules/google-ads/diagnostics.js +164 -0
- package/.medusa/server/src/lib/modules/google-merchant/category-fields.d.ts +7 -0
- package/.medusa/server/src/lib/modules/google-merchant/category-fields.js +210 -0
- package/.medusa/server/src/lib/modules/google-merchant/data-source.d.ts +17 -0
- package/.medusa/server/src/lib/modules/google-merchant/data-source.js +132 -0
- package/.medusa/server/src/lib/modules/google-merchant/diagnostics.d.ts +33 -0
- package/.medusa/server/src/lib/modules/google-merchant/diagnostics.js +113 -0
- package/.medusa/server/src/lib/modules/google-merchant/index.d.ts +5 -0
- package/.medusa/server/src/lib/modules/google-merchant/index.js +6 -1
- package/.medusa/server/src/lib/modules/google-merchant/merchant-api.d.ts +18 -0
- package/.medusa/server/src/lib/modules/google-merchant/merchant-api.js +120 -0
- package/.medusa/server/src/lib/modules/google-merchant/shipping.d.ts +13 -0
- package/.medusa/server/src/lib/modules/google-merchant/shipping.js +97 -0
- package/.medusa/server/src/lib/modules/google-tag-manager/api.d.ts +1 -0
- package/.medusa/server/src/lib/modules/google-tag-manager/api.js +3 -0
- package/.medusa/server/src/lib/modules/google-tag-manager/index.d.ts +1 -0
- package/.medusa/server/src/lib/modules/google-tag-manager/index.js +3 -0
- package/.medusa/server/src/lib/modules/google-tag-manager/sync.d.ts +1 -0
- package/.medusa/server/src/lib/modules/google-tag-manager/sync.js +3 -0
- package/.medusa/server/src/lib/modules/shipping/actions.js +163 -352
- package/.medusa/server/src/lib/modules/shipping/durable-create.d.ts +2 -1
- package/.medusa/server/src/lib/modules/shipping/durable-create.js +33 -5
- package/.medusa/server/src/lib/modules/shipping/idempotency.js +4 -2
- package/.medusa/server/src/lib/modules/shipping/types.d.ts +1 -1
- package/.medusa/server/src/modules/core-documents/index.d.ts +38 -0
- package/.medusa/server/src/modules/core-documents/index.js +18 -0
- package/.medusa/server/src/modules/core-documents/migrations/Migration20261102190000.d.ts +5 -0
- package/.medusa/server/src/modules/core-documents/migrations/Migration20261102190000.js +22 -0
- package/.medusa/server/src/modules/core-documents/models/core-document-assignment.d.ts +9 -0
- package/.medusa/server/src/modules/core-documents/models/core-document-assignment.js +18 -0
- package/.medusa/server/src/modules/core-documents/models/core-document.d.ts +18 -0
- package/.medusa/server/src/modules/core-documents/models/core-document.js +27 -0
- package/.medusa/server/src/modules/core-documents/service.d.ts +38 -0
- package/.medusa/server/src/modules/core-documents/service.js +13 -0
- package/.medusa/server/src/modules/integration-operation/state.d.ts +1 -0
- package/.medusa/server/src/modules/integration-operation/state.js +11 -50
- package/.medusa/server/src/modules/integration-operation/types.d.ts +1 -1
- package/.medusa/server/src/modules/integration-settings/arukereso-registration.js +19 -2
- package/.medusa/server/src/modules/integration-settings/connection-test.js +14 -1
- package/.medusa/server/src/modules/integration-settings/csomagpiac-definition.d.ts +2 -0
- package/.medusa/server/src/modules/integration-settings/csomagpiac-definition.js +49 -0
- package/.medusa/server/src/modules/integration-settings/csomagpiac-registration.d.ts +1 -0
- package/.medusa/server/src/modules/integration-settings/csomagpiac-registration.js +35 -0
- package/.medusa/server/src/modules/integration-settings/google-merchant-registration.js +23 -2
- package/.medusa/server/src/modules/integration-settings/hot-reload-registration.d.ts +1 -0
- package/.medusa/server/src/modules/integration-settings/hot-reload-registration.js +23 -0
- package/.medusa/server/src/modules/integration-settings/index.d.ts +4 -0
- package/.medusa/server/src/modules/integration-settings/index.js +5 -1
- package/.medusa/server/src/modules/integration-settings/manager.js +38 -4
- package/.medusa/server/src/modules/integration-settings/reloadable.d.ts +10 -0
- package/.medusa/server/src/modules/integration-settings/reloadable.js +58 -0
- package/.medusa/server/src/modules/integration-settings/runtime-snapshot.d.ts +9 -0
- package/.medusa/server/src/modules/integration-settings/runtime-snapshot.js +48 -3
- package/.medusa/server/src/modules/integration-settings/simplepay-registration.d.ts +1 -0
- package/.medusa/server/src/modules/integration-settings/simplepay-registration.js +18 -0
- package/.medusa/server/src/modules/integration-settings/storefront-public-registration.js +15 -5
- package/.medusa/server/src/providers/csomagpiac/client.d.ts +25 -0
- package/.medusa/server/src/providers/csomagpiac/client.js +144 -0
- package/.medusa/server/src/providers/csomagpiac/fulfillment-provider.d.ts +45 -0
- package/.medusa/server/src/providers/csomagpiac/fulfillment-provider.js +221 -0
- package/.medusa/server/src/providers/csomagpiac/index.d.ts +7 -0
- package/.medusa/server/src/providers/csomagpiac/index.js +30 -0
- package/.medusa/server/src/providers/csomagpiac/service.d.ts +46 -0
- package/.medusa/server/src/providers/csomagpiac/service.js +226 -0
- package/.medusa/server/src/providers/csomagpiac/types.d.ts +65 -0
- package/.medusa/server/src/providers/csomagpiac/types.js +27 -0
- package/.medusa/server/src/providers/dpd/fulfillment-provider.d.ts +2 -1
- package/.medusa/server/src/providers/dpd/fulfillment-provider.js +83 -25
- package/.medusa/server/src/providers/dpd/service.js +5 -3
- package/.medusa/server/src/providers/email/service.d.ts +7 -6
- package/.medusa/server/src/providers/email/service.js +51 -25
- package/.medusa/server/src/providers/foxpost/foxpost-service.js +5 -9
- package/.medusa/server/src/providers/foxpost/fulfillment-provider.d.ts +1 -0
- package/.medusa/server/src/providers/foxpost/fulfillment-provider.js +76 -66
- package/.medusa/server/src/providers/gls/fulfillment-provider.d.ts +1 -0
- package/.medusa/server/src/providers/gls/fulfillment-provider.js +76 -13
- package/.medusa/server/src/providers/gls/gls-service.d.ts +16 -0
- package/.medusa/server/src/providers/gls/gls-service.js +26 -65
- package/.medusa/server/src/providers/gls/types.d.ts +15 -0
- package/.medusa/server/src/providers/mpl/fulfillment-provider.d.ts +1 -0
- package/.medusa/server/src/providers/mpl/fulfillment-provider.js +61 -186
- package/.medusa/server/src/providers/mpl/index.d.ts +2 -0
- package/.medusa/server/src/providers/mpl/index.js +7 -2
- package/.medusa/server/src/providers/mpl/service.d.ts +35 -1
- package/.medusa/server/src/providers/mpl/service.js +82 -370
- package/.medusa/server/src/providers/mpl/types.d.ts +18 -0
- package/.medusa/server/src/providers/mpl/types.js +1 -1
- package/.medusa/server/src/providers/packeta/client.d.ts +2 -1
- package/.medusa/server/src/providers/packeta/client.js +24 -2
- package/.medusa/server/src/providers/packeta/fulfillment-provider.d.ts +1 -0
- package/.medusa/server/src/providers/packeta/fulfillment-provider.js +73 -5
- package/.medusa/server/src/providers/packeta/service.d.ts +1 -0
- package/.medusa/server/src/providers/packeta/service.js +85 -22
- package/.medusa/server/src/providers/packeta/types.d.ts +26 -0
- package/.medusa/server/src/providers/packeta/types.js +1 -1
- package/.medusa/server/src/providers/resilient-stripe/index.d.ts +19 -1
- package/.medusa/server/src/providers/resilient-stripe/index.js +55 -3
- package/.medusa/server/src/providers/simplepay/config.js +11 -1
- package/.medusa/server/src/providers/simplepay/index.d.ts +2 -0
- package/.medusa/server/src/providers/simplepay/index.js +5 -3
- package/.medusa/server/src/providers/simplepay/runtime-service.d.ts +13 -0
- package/.medusa/server/src/providers/simplepay/runtime-service.js +55 -0
- package/.medusa/server/src/providers/simplepay/service.d.ts +2 -0
- package/.medusa/server/src/providers/simplepay/service.js +40 -5
- package/.medusa/server/src/subscribers/google-ads-order-canceled.d.ts +7 -0
- package/.medusa/server/src/subscribers/google-ads-order-canceled.js +50 -0
- package/.medusa/server/src/subscribers/google-ads-payment-refunded.d.ts +7 -0
- package/.medusa/server/src/subscribers/google-ads-payment-refunded.js +181 -0
- package/.medusa/server/src/subscribers/simplepay-paid-order-recovery.js +14 -1
- package/package.json +6 -2
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GOOGLE_ADS_SCOPE = void 0;
|
|
4
|
+
exports.buildGoogleAdsAuthorizationUrl = buildGoogleAdsAuthorizationUrl;
|
|
5
|
+
exports.exchangeGoogleAdsAuthorizationCode = exchangeGoogleAdsAuthorizationCode;
|
|
6
|
+
exports.getGoogleAdsAccessToken = getGoogleAdsAccessToken;
|
|
7
|
+
exports.testGoogleAdsApiConnection = testGoogleAdsApiConnection;
|
|
8
|
+
exports.createGoogleAdsOAuthState = createGoogleAdsOAuthState;
|
|
9
|
+
exports.verifyGoogleAdsOAuthState = verifyGoogleAdsOAuthState;
|
|
10
|
+
const node_crypto_1 = require("node:crypto");
|
|
11
|
+
exports.GOOGLE_ADS_SCOPE = "https://www.googleapis.com/auth/adwords";
|
|
12
|
+
const GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
|
|
13
|
+
const GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token";
|
|
14
|
+
const GOOGLE_ADS_API_BASE = "https://googleads.googleapis.com/v26";
|
|
15
|
+
function buildGoogleAdsAuthorizationUrl(env, state) {
|
|
16
|
+
const url = new URL(GOOGLE_AUTH_URL);
|
|
17
|
+
url.searchParams.set("client_id", required(env, "GOOGLE_ADS_OAUTH_CLIENT_ID"));
|
|
18
|
+
url.searchParams.set("redirect_uri", required(env, "GOOGLE_ADS_OAUTH_REDIRECT_URI"));
|
|
19
|
+
url.searchParams.set("response_type", "code");
|
|
20
|
+
url.searchParams.set("scope", exports.GOOGLE_ADS_SCOPE);
|
|
21
|
+
url.searchParams.set("access_type", "offline");
|
|
22
|
+
url.searchParams.set("prompt", "consent");
|
|
23
|
+
url.searchParams.set("include_granted_scopes", "true");
|
|
24
|
+
url.searchParams.set("state", state);
|
|
25
|
+
return url.toString();
|
|
26
|
+
}
|
|
27
|
+
async function exchangeGoogleAdsAuthorizationCode(env, code) {
|
|
28
|
+
const body = new URLSearchParams({
|
|
29
|
+
client_id: required(env, "GOOGLE_ADS_OAUTH_CLIENT_ID"),
|
|
30
|
+
client_secret: required(env, "GOOGLE_ADS_OAUTH_CLIENT_SECRET"),
|
|
31
|
+
redirect_uri: required(env, "GOOGLE_ADS_OAUTH_REDIRECT_URI"),
|
|
32
|
+
code: requiredValue(code, "OAuth authorization code"),
|
|
33
|
+
grant_type: "authorization_code",
|
|
34
|
+
});
|
|
35
|
+
const response = await fetch(GOOGLE_TOKEN_URL, {
|
|
36
|
+
method: "POST",
|
|
37
|
+
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
38
|
+
body,
|
|
39
|
+
signal: AbortSignal.timeout(10000),
|
|
40
|
+
});
|
|
41
|
+
const data = await json(response);
|
|
42
|
+
const refreshToken = text(data.refresh_token);
|
|
43
|
+
if (!response.ok || !refreshToken) {
|
|
44
|
+
throw new Error(text(data.error_description) || text(data.error) || "A Google Ads OAuth refresh token nem kérhető le.");
|
|
45
|
+
}
|
|
46
|
+
return { refreshToken, accessToken: text(data.access_token) || undefined };
|
|
47
|
+
}
|
|
48
|
+
async function getGoogleAdsAccessToken(env) {
|
|
49
|
+
const body = new URLSearchParams({
|
|
50
|
+
client_id: required(env, "GOOGLE_ADS_OAUTH_CLIENT_ID"),
|
|
51
|
+
client_secret: required(env, "GOOGLE_ADS_OAUTH_CLIENT_SECRET"),
|
|
52
|
+
refresh_token: required(env, "GOOGLE_ADS_OAUTH_REFRESH_TOKEN"),
|
|
53
|
+
grant_type: "refresh_token",
|
|
54
|
+
});
|
|
55
|
+
const response = await fetch(GOOGLE_TOKEN_URL, {
|
|
56
|
+
method: "POST",
|
|
57
|
+
headers: { "content-type": "application/x-www-form-urlencoded" },
|
|
58
|
+
body,
|
|
59
|
+
signal: AbortSignal.timeout(10000),
|
|
60
|
+
});
|
|
61
|
+
const data = await json(response);
|
|
62
|
+
const accessToken = text(data.access_token);
|
|
63
|
+
if (!response.ok || !accessToken) {
|
|
64
|
+
throw new Error(text(data.error_description) || text(data.error) || "A Google Ads OAuth access token nem kérhető le.");
|
|
65
|
+
}
|
|
66
|
+
return accessToken;
|
|
67
|
+
}
|
|
68
|
+
async function testGoogleAdsApiConnection(env) {
|
|
69
|
+
if (env.GOOGLE_ADS_API_ENABLED !== "true") {
|
|
70
|
+
throw new Error("A Google Ads API kapcsolat nincs bekapcsolva.");
|
|
71
|
+
}
|
|
72
|
+
const customerId = digits(required(env, "GOOGLE_ADS_CUSTOMER_ID"));
|
|
73
|
+
const loginCustomerId = digits(env.GOOGLE_ADS_LOGIN_CUSTOMER_ID);
|
|
74
|
+
const developerToken = required(env, "GOOGLE_ADS_DEVELOPER_TOKEN");
|
|
75
|
+
const accessToken = await getGoogleAdsAccessToken(env);
|
|
76
|
+
const headers = {
|
|
77
|
+
authorization: `Bearer ${accessToken}`,
|
|
78
|
+
"developer-token": developerToken,
|
|
79
|
+
"content-type": "application/json",
|
|
80
|
+
};
|
|
81
|
+
if (loginCustomerId)
|
|
82
|
+
headers["login-customer-id"] = loginCustomerId;
|
|
83
|
+
const response = await fetch(`${GOOGLE_ADS_API_BASE}/customers/${customerId}/googleAds:search`, {
|
|
84
|
+
method: "POST",
|
|
85
|
+
headers,
|
|
86
|
+
body: JSON.stringify({
|
|
87
|
+
query: "SELECT customer.id, customer.descriptive_name, customer.currency_code, customer.time_zone, customer.status FROM customer LIMIT 1",
|
|
88
|
+
}),
|
|
89
|
+
signal: AbortSignal.timeout(15000),
|
|
90
|
+
});
|
|
91
|
+
const data = await json(response);
|
|
92
|
+
if (!response.ok) {
|
|
93
|
+
throw new Error(`Google Ads API hiba (${response.status}): ${googleAdsErrorMessage(data)}`);
|
|
94
|
+
}
|
|
95
|
+
const rows = Array.isArray(data.results) ? data.results : [];
|
|
96
|
+
const customer = record(record(rows[0])?.customer);
|
|
97
|
+
if (!customer) {
|
|
98
|
+
throw new Error("A Google Ads API kapcsolat létrejött, de a cél customer adatai nem érkeztek vissza.");
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
customer_id: text(customer.id) || customerId,
|
|
102
|
+
descriptive_name: text(customer.descriptiveName) || null,
|
|
103
|
+
currency_code: text(customer.currencyCode) || null,
|
|
104
|
+
time_zone: text(customer.timeZone) || null,
|
|
105
|
+
status: text(customer.status) || null,
|
|
106
|
+
request_id: response.headers.get("request-id") || null,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function createGoogleAdsOAuthState(input) {
|
|
110
|
+
const payload = Buffer.from(JSON.stringify({ ts: Date.now(), actorId: input.actorId || null })).toString("base64url");
|
|
111
|
+
const signature = (0, node_crypto_1.createHmac)("sha256", oauthStateSecret()).update(payload).digest("base64url");
|
|
112
|
+
return `${payload}.${signature}`;
|
|
113
|
+
}
|
|
114
|
+
function verifyGoogleAdsOAuthState(state) {
|
|
115
|
+
const [payload, signature] = String(state || "").split(".");
|
|
116
|
+
if (!payload || !signature)
|
|
117
|
+
throw new Error("Érvénytelen Google Ads OAuth state.");
|
|
118
|
+
const expected = (0, node_crypto_1.createHmac)("sha256", oauthStateSecret()).update(payload).digest();
|
|
119
|
+
let supplied;
|
|
120
|
+
try {
|
|
121
|
+
supplied = Buffer.from(signature, "base64url");
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
throw new Error("Érvénytelen Google Ads OAuth state.");
|
|
125
|
+
}
|
|
126
|
+
if (expected.length !== supplied.length || !(0, node_crypto_1.timingSafeEqual)(expected, supplied)) {
|
|
127
|
+
throw new Error("Érvénytelen Google Ads OAuth state aláírás.");
|
|
128
|
+
}
|
|
129
|
+
const parsed = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
|
|
130
|
+
if (!parsed.ts || Date.now() - parsed.ts > 10 * 60 * 1000) {
|
|
131
|
+
throw new Error("A Google Ads OAuth state lejárt.");
|
|
132
|
+
}
|
|
133
|
+
return parsed;
|
|
134
|
+
}
|
|
135
|
+
function required(env, key) {
|
|
136
|
+
return requiredValue(env[key], key);
|
|
137
|
+
}
|
|
138
|
+
function requiredValue(value, label) {
|
|
139
|
+
const result = text(value);
|
|
140
|
+
if (!result)
|
|
141
|
+
throw new Error(`Hiányzó Google Ads API beállítás: ${label}`);
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
function oauthStateSecret() {
|
|
145
|
+
const secret = text(process.env.COOKIE_SECRET) || text(process.env.JWT_SECRET);
|
|
146
|
+
if (!secret)
|
|
147
|
+
throw new Error("COOKIE_SECRET vagy JWT_SECRET szükséges a Google Ads OAuth state aláírásához.");
|
|
148
|
+
return secret;
|
|
149
|
+
}
|
|
150
|
+
function digits(value) {
|
|
151
|
+
return text(value).replace(/[^0-9]/g, "");
|
|
152
|
+
}
|
|
153
|
+
function text(value) {
|
|
154
|
+
return typeof value === "string" || typeof value === "number" ? String(value).trim() : "";
|
|
155
|
+
}
|
|
156
|
+
function record(value) {
|
|
157
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
158
|
+
}
|
|
159
|
+
async function json(response) {
|
|
160
|
+
return await response.json().catch(() => ({}));
|
|
161
|
+
}
|
|
162
|
+
function googleAdsErrorMessage(data) {
|
|
163
|
+
const direct = text(data.message) || text(data.error_description);
|
|
164
|
+
if (direct)
|
|
165
|
+
return direct;
|
|
166
|
+
const error = record(data.error);
|
|
167
|
+
if (error)
|
|
168
|
+
return text(error.message) || text(error.status) || JSON.stringify(error).slice(0, 1000);
|
|
169
|
+
return JSON.stringify(data).slice(0, 1000);
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9tb2R1bGVzL2dvb2dsZS1hZHMvYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQVNBLHdFQVdDO0FBRUQsZ0ZBcUJDO0FBRUQsMERBb0JDO0FBRUQsZ0VBMkNDO0FBRUQsOERBSUM7QUFFRCw4REF1QkM7QUE3SUQsNkNBQXlEO0FBRTVDLFFBQUEsZ0JBQWdCLEdBQUcseUNBQXlDLENBQUE7QUFDekUsTUFBTSxlQUFlLEdBQUcsOENBQThDLENBQUE7QUFDdEUsTUFBTSxnQkFBZ0IsR0FBRyxxQ0FBcUMsQ0FBQTtBQUM5RCxNQUFNLG1CQUFtQixHQUFHLHNDQUFzQyxDQUFBO0FBSWxFLFNBQWdCLDhCQUE4QixDQUFDLEdBQW9CLEVBQUUsS0FBYTtJQUNoRixNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxlQUFlLENBQUMsQ0FBQTtJQUNwQyxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLEdBQUcsRUFBRSw0QkFBNEIsQ0FBQyxDQUFDLENBQUE7SUFDOUUsR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsY0FBYyxFQUFFLFFBQVEsQ0FBQyxHQUFHLEVBQUUsK0JBQStCLENBQUMsQ0FBQyxDQUFBO0lBQ3BGLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUM3QyxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsd0JBQWdCLENBQUMsQ0FBQTtJQUMvQyxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsU0FBUyxDQUFDLENBQUE7SUFDOUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFBO0lBQ3pDLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FB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
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type GoogleAdsApiEnv } from "./api";
|
|
2
|
+
export type GoogleAdsConversionDiagnostic = {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
type: string;
|
|
6
|
+
category: string;
|
|
7
|
+
status: string;
|
|
8
|
+
origin: string;
|
|
9
|
+
primaryForGoal: boolean;
|
|
10
|
+
countingType: string;
|
|
11
|
+
tagSnippetCount: number;
|
|
12
|
+
allConversions: number;
|
|
13
|
+
allConversionsValue: number;
|
|
14
|
+
lastConversionDate?: string;
|
|
15
|
+
lastReceivedRequestDateTime?: string;
|
|
16
|
+
configuredPurchaseAction: boolean;
|
|
17
|
+
severity: "ok" | "warning" | "error";
|
|
18
|
+
messages: string[];
|
|
19
|
+
};
|
|
20
|
+
export type GoogleAdsConversionDiagnostics = {
|
|
21
|
+
customerId: string;
|
|
22
|
+
actions: GoogleAdsConversionDiagnostic[];
|
|
23
|
+
summary: {
|
|
24
|
+
total: number;
|
|
25
|
+
enabled: number;
|
|
26
|
+
purchase: number;
|
|
27
|
+
errors: number;
|
|
28
|
+
warnings: number;
|
|
29
|
+
primary: number;
|
|
30
|
+
};
|
|
31
|
+
generatedAt: string;
|
|
32
|
+
requestId?: string | null;
|
|
33
|
+
};
|
|
34
|
+
export declare function getGoogleAdsConversionDiagnostics(env: GoogleAdsApiEnv): Promise<{
|
|
35
|
+
customerId: string;
|
|
36
|
+
actions: GoogleAdsConversionDiagnostic[];
|
|
37
|
+
summary: {
|
|
38
|
+
total: number;
|
|
39
|
+
enabled: number;
|
|
40
|
+
purchase: number;
|
|
41
|
+
errors: number;
|
|
42
|
+
warnings: number;
|
|
43
|
+
primary: number;
|
|
44
|
+
};
|
|
45
|
+
generatedAt: string;
|
|
46
|
+
requestId: string | null;
|
|
47
|
+
}>;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getGoogleAdsConversionDiagnostics = getGoogleAdsConversionDiagnostics;
|
|
4
|
+
const api_1 = require("./api");
|
|
5
|
+
const GOOGLE_ADS_API_BASE = "https://googleads.googleapis.com/v26";
|
|
6
|
+
async function getGoogleAdsConversionDiagnostics(env) {
|
|
7
|
+
if (env.GOOGLE_ADS_API_ENABLED !== "true") {
|
|
8
|
+
throw new Error("A Google Ads API kapcsolat nincs bekapcsolva.");
|
|
9
|
+
}
|
|
10
|
+
const customerId = digits(required(env, "GOOGLE_ADS_CUSTOMER_ID"));
|
|
11
|
+
const loginCustomerId = digits(env.GOOGLE_ADS_LOGIN_CUSTOMER_ID);
|
|
12
|
+
const developerToken = required(env, "GOOGLE_ADS_DEVELOPER_TOKEN");
|
|
13
|
+
const configuredActionId = digits(env.GOOGLE_ADS_CONVERSION_ACTION_ID);
|
|
14
|
+
const accessToken = await (0, api_1.getGoogleAdsAccessToken)(env);
|
|
15
|
+
const headers = {
|
|
16
|
+
authorization: `Bearer ${accessToken}`,
|
|
17
|
+
"developer-token": developerToken,
|
|
18
|
+
"content-type": "application/json",
|
|
19
|
+
};
|
|
20
|
+
if (loginCustomerId)
|
|
21
|
+
headers["login-customer-id"] = loginCustomerId;
|
|
22
|
+
const query = [
|
|
23
|
+
"SELECT",
|
|
24
|
+
"conversion_action.id,",
|
|
25
|
+
"conversion_action.name,",
|
|
26
|
+
"conversion_action.type,",
|
|
27
|
+
"conversion_action.category,",
|
|
28
|
+
"conversion_action.status,",
|
|
29
|
+
"conversion_action.origin,",
|
|
30
|
+
"conversion_action.primary_for_goal,",
|
|
31
|
+
"conversion_action.counting_type,",
|
|
32
|
+
"conversion_action.tag_snippets,",
|
|
33
|
+
"metrics.all_conversions,",
|
|
34
|
+
"metrics.all_conversions_value,",
|
|
35
|
+
"metrics.conversion_last_conversion_date,",
|
|
36
|
+
"metrics.conversion_last_received_request_date_time",
|
|
37
|
+
"FROM conversion_action",
|
|
38
|
+
"WHERE conversion_action.status != 'REMOVED'",
|
|
39
|
+
].join(" ");
|
|
40
|
+
const response = await fetch(`${GOOGLE_ADS_API_BASE}/customers/${customerId}/googleAds:search`, {
|
|
41
|
+
method: "POST",
|
|
42
|
+
headers,
|
|
43
|
+
body: JSON.stringify({ query, pageSize: 1000 }),
|
|
44
|
+
signal: AbortSignal.timeout(20000),
|
|
45
|
+
});
|
|
46
|
+
const data = await json(response);
|
|
47
|
+
if (!response.ok) {
|
|
48
|
+
throw new Error(`Google Ads diagnostics hiba (${response.status}): ${errorMessage(data)}`);
|
|
49
|
+
}
|
|
50
|
+
const rows = Array.isArray(data.results) ? data.results : [];
|
|
51
|
+
const actions = rows
|
|
52
|
+
.map((row) => normalizeAction(row, configuredActionId))
|
|
53
|
+
.filter((item) => Boolean(item));
|
|
54
|
+
return {
|
|
55
|
+
customerId,
|
|
56
|
+
actions,
|
|
57
|
+
summary: {
|
|
58
|
+
total: actions.length,
|
|
59
|
+
enabled: actions.filter((item) => item.status === "ENABLED").length,
|
|
60
|
+
purchase: actions.filter((item) => item.category === "PURCHASE").length,
|
|
61
|
+
errors: actions.filter((item) => item.severity === "error").length,
|
|
62
|
+
warnings: actions.filter((item) => item.severity === "warning").length,
|
|
63
|
+
primary: actions.filter((item) => item.primaryForGoal).length,
|
|
64
|
+
},
|
|
65
|
+
generatedAt: new Date().toISOString(),
|
|
66
|
+
requestId: response.headers.get("request-id"),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function normalizeAction(row, configuredActionId) {
|
|
70
|
+
const root = record(row);
|
|
71
|
+
const action = record(root?.conversionAction);
|
|
72
|
+
const metrics = record(root?.metrics);
|
|
73
|
+
if (!action)
|
|
74
|
+
return null;
|
|
75
|
+
const id = text(action.id);
|
|
76
|
+
const status = text(action.status).toUpperCase() || "UNKNOWN";
|
|
77
|
+
const category = text(action.category).toUpperCase() || "UNKNOWN";
|
|
78
|
+
const type = text(action.type).toUpperCase() || "UNKNOWN";
|
|
79
|
+
const origin = text(action.origin).toUpperCase() || "UNKNOWN";
|
|
80
|
+
const primaryForGoal = Boolean(action.primaryForGoal);
|
|
81
|
+
const tagSnippetCount = Array.isArray(action.tagSnippets) ? action.tagSnippets.length : 0;
|
|
82
|
+
const configuredPurchaseAction = Boolean(configuredActionId && id === configuredActionId);
|
|
83
|
+
const messages = [];
|
|
84
|
+
let severity = "ok";
|
|
85
|
+
if (status !== "ENABLED") {
|
|
86
|
+
severity = "error";
|
|
87
|
+
messages.push(`A conversion action státusza ${status}.`);
|
|
88
|
+
}
|
|
89
|
+
if (!primaryForGoal) {
|
|
90
|
+
if (severity !== "error")
|
|
91
|
+
severity = "warning";
|
|
92
|
+
messages.push("Secondary conversion action: standard bidding optimalizációban nem primary cél.");
|
|
93
|
+
}
|
|
94
|
+
if (category === "PURCHASE" && type.includes("WEB") && tagSnippetCount === 0) {
|
|
95
|
+
if (severity !== "error")
|
|
96
|
+
severity = "warning";
|
|
97
|
+
messages.push("Webes purchase action, de a Google Ads API nem adott vissza tag snippetet.");
|
|
98
|
+
}
|
|
99
|
+
const lastReceivedRequestDateTime = text(metrics?.conversionLastReceivedRequestDateTime) || undefined;
|
|
100
|
+
const lastConversionDate = text(metrics?.conversionLastConversionDate) || undefined;
|
|
101
|
+
if (status === "ENABLED" && !lastReceivedRequestDateTime) {
|
|
102
|
+
if (severity !== "error")
|
|
103
|
+
severity = "warning";
|
|
104
|
+
messages.push("Nincs visszaadott utolsó conversion request időpont.");
|
|
105
|
+
}
|
|
106
|
+
if (configuredPurchaseAction && category !== "PURCHASE") {
|
|
107
|
+
severity = "error";
|
|
108
|
+
messages.push("A Core-ban purchase conversion actionként beállított ID Google Ads szerint nem PURCHASE kategória.");
|
|
109
|
+
}
|
|
110
|
+
if (!messages.length)
|
|
111
|
+
messages.push("Nem látszik konfigurációs probléma a Google Ads API által visszaadott jelek alapján.");
|
|
112
|
+
return {
|
|
113
|
+
id,
|
|
114
|
+
name: text(action.name) || `Conversion ${id}`,
|
|
115
|
+
type,
|
|
116
|
+
category,
|
|
117
|
+
status,
|
|
118
|
+
origin,
|
|
119
|
+
primaryForGoal,
|
|
120
|
+
countingType: text(action.countingType).toUpperCase() || "UNKNOWN",
|
|
121
|
+
tagSnippetCount,
|
|
122
|
+
allConversions: number(metrics?.allConversions),
|
|
123
|
+
allConversionsValue: number(metrics?.allConversionsValue),
|
|
124
|
+
lastConversionDate,
|
|
125
|
+
lastReceivedRequestDateTime,
|
|
126
|
+
configuredPurchaseAction,
|
|
127
|
+
severity,
|
|
128
|
+
messages,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function required(env, key) {
|
|
132
|
+
const value = text(env[key]);
|
|
133
|
+
if (!value)
|
|
134
|
+
throw new Error(`Hiányzó Google Ads API beállítás: ${key}`);
|
|
135
|
+
return value;
|
|
136
|
+
}
|
|
137
|
+
function digits(value) {
|
|
138
|
+
return text(value).replace(/[^0-9]/g, "");
|
|
139
|
+
}
|
|
140
|
+
function text(value) {
|
|
141
|
+
return typeof value === "string" || typeof value === "number" ? String(value).trim() : "";
|
|
142
|
+
}
|
|
143
|
+
function number(value) {
|
|
144
|
+
const parsed = Number(value);
|
|
145
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
146
|
+
}
|
|
147
|
+
function record(value) {
|
|
148
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
149
|
+
? value
|
|
150
|
+
: null;
|
|
151
|
+
}
|
|
152
|
+
async function json(response) {
|
|
153
|
+
return await response.json().catch(() => ({}));
|
|
154
|
+
}
|
|
155
|
+
function errorMessage(data) {
|
|
156
|
+
const direct = text(data.message) || text(data.error_description);
|
|
157
|
+
if (direct)
|
|
158
|
+
return direct;
|
|
159
|
+
const error = record(data.error);
|
|
160
|
+
if (error)
|
|
161
|
+
return text(error.message) || text(error.status) || JSON.stringify(error).slice(0, 1000);
|
|
162
|
+
return JSON.stringify(data).slice(0, 1000);
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlhZ25vc3RpY3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL21vZHVsZXMvZ29vZ2xlLWFkcy9kaWFnbm9zdGljcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQXNDQSw4RUFzRUM7QUE1R0QsK0JBQXFFO0FBRXJFLE1BQU0sbUJBQW1CLEdBQUcsc0NBQXNDLENBQUE7QUFvQzNELEtBQUssVUFBVSxpQ0FBaUMsQ0FBQyxHQUFvQjtJQUMxRSxJQUFJLEdBQUcsQ0FBQyxzQkFBc0IsS0FBSyxNQUFNLEVBQUUsQ0FBQztRQUMxQyxNQUFNLElBQUksS0FBSyxDQUFDLCtDQUErQyxDQUFDLENBQUE7SUFDbEUsQ0FBQztJQUVELE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLHdCQUF3QixDQUFDLENBQUMsQ0FBQTtJQUNsRSxNQUFNLGVBQWUsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDLENBQUE7SUFDaEUsTUFBTSxjQUFjLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSw0QkFBNEIsQ0FBQyxDQUFBO0lBQ2xFLE1BQU0sa0JBQWtCLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQywrQkFBK0IsQ0FBQyxDQUFBO0lBQ3RFLE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBQSw2QkFBdUIsRUFBQyxHQUFHLENBQUMsQ0FBQTtJQUV0RCxNQUFNLE9BQU8sR0FBMkI7UUFDdEMsYUFBYSxFQUFFLFVBQVUsV0FBVyxFQUFFO1FBQ3RDLGlCQUFpQixFQUFFLGNBQWM7UUFDakMsY0FBYyxFQUFFLGtCQUFrQjtLQUNuQyxDQUFBO0lBQ0QsSUFBSSxlQUFlO1FBQUUsT0FBTyxDQUFDLG1CQUFtQixDQUFDLEdBQUcsZUFBZSxDQUFBO0lBRW5FLE1BQU0sS0FBSyxHQUFHO1FBQ1osUUFBUTtRQUNSLHVCQUF1QjtRQUN2Qix5QkFBeUI7UUFDekIseUJBQXlCO1FBQ3pCLDZCQUE2QjtRQUM3QiwyQkFBMkI7UUFDM0IsMkJBQTJCO1FBQzNCLHFDQUFxQztRQUNyQyxrQ0FBa0M7UUFDbEMsaUNBQWlDO1FBQ2pDLDBCQUEwQjtRQUMxQixnQ0FBZ0M7UUFDaEMsMENBQTBDO1FBQzFDLG9EQUFvRDtRQUNwRCx3QkFBd0I7UUFDeEIsNkNBQTZDO0tBQzlDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBRVgsTUFBTSxRQUFRLEdBQUcsTUFBTSxLQUFLLENBQzFCLEdBQUcsbUJBQW1CLGNBQWMsVUFBVSxtQkFBbUIsRUFDakU7UUFDRSxNQUFNLEVBQUUsTUFBTTtRQUNkLE9BQU87UUFDUCxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDL0MsTUFBTSxFQUFFLFdBQVcsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO0tBQ25DLENBQ0YsQ0FBQTtJQUNELE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQ2pDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQ0FBZ0MsUUFBUSxDQUFDLE1BQU0sTUFBTSxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQzVGLENBQUM7SUFFRCxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFBO0lBQzVELE1BQU0sT0FBTyxHQUFHLElBQUk7U0FDakIsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxlQUFlLENBQUMsR0FBRyxFQUFFLGtCQUFrQixDQUFDLENBQUM7U0FDdEQsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUF5QyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7SUFFekUsT0FBTztRQUNMLFVBQVU7UUFDVixPQUFPO1FBQ1AsT0FBTyxFQUFFO1lBQ1AsS0FBSyxFQUFFLE9BQU8sQ0FBQyxNQUFNO1lBQ3JCLE9BQU8sRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDLE1BQU07WUFDbkUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLEtBQUssVUFBVSxDQUFDLENBQUMsTUFBTTtZQUN2RSxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsS0FBSyxPQUFPLENBQUMsQ0FBQyxNQUFNO1lBQ2xFLFFBQVEsRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxDQUFDLE1BQU07WUFDdEUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxNQUFNO1NBQzlEO1FBQ0QsV0FBVyxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFO1FBQ3JDLFNBQVMsRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUM7S0FDTCxDQUFBO0FBQzVDLENBQUM7QUFFRCxTQUFTLGVBQWUsQ0FBQyxHQUFZLEVBQUUsa0JBQTBCO0lBQy9ELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUN4QixNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsSUFBSSxFQUFFLGdCQUFnQixDQUFDLENBQUE7SUFDN0MsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQTtJQUNyQyxJQUFJLENBQUMsTUFBTTtRQUFFLE9BQU8sSUFBSSxDQUFBO0lBRXhCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDMUIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxXQUFXLEVBQUUsSUFBSSxTQUFTLENBQUE7SUFDN0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxXQUFXLEVBQUUsSUFBSSxTQUFTLENBQUE7SUFDakUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXLEVBQUUsSUFBSSxTQUFTLENBQUE7SUFDekQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxXQUFXLEVBQUUsSUFBSSxTQUFTLENBQUE7SUFDN0QsTUFBTSxjQUFjLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQTtJQUNyRCxNQUFNLGVBQWUsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUN6RixNQUFNLHdCQUF3QixHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsSUFBSSxFQUFFLEtBQUssa0JBQWtCLENBQUMsQ0FBQTtJQUN6RixNQUFNLFFBQVEsR0FBYSxFQUFFLENBQUE7SUFDN0IsSUFBSSxRQUFRLEdBQThDLElBQUksQ0FBQTtJQUU5RCxJQUFJLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUN6QixRQUFRLEdBQUcsT0FBTyxDQUFBO1FBQ2xCLFFBQVEsQ0FBQyxJQUFJLENBQUMsZ0NBQWdDLE1BQU0sR0FBRyxDQUFDLENBQUE7SUFDMUQsQ0FBQztJQUVELElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUNwQixJQUFJLFFBQVEsS0FBSyxPQUFPO1lBQUUsUUFBUSxHQUFHLFNBQVMsQ0FBQTtRQUM5QyxRQUFRLENBQUMsSUFBSSxDQUFDLGlGQUFpRixDQUFDLENBQUE7SUFDbEcsQ0FBQztJQUVELElBQUksUUFBUSxLQUFLLFVBQVUsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLGVBQWUsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUM3RSxJQUFJLFFBQVEsS0FBSyxPQUFPO1lBQUUsUUFBUSxHQUFHLFNBQVMsQ0FBQTtRQUM5QyxRQUFRLENBQUMsSUFBSSxDQUFDLDRFQUE0RSxDQUFDLENBQUE7SUFDN0YsQ0FBQztJQUVELE1BQU0sMkJBQTJCLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxxQ0FBcUMsQ0FBQyxJQUFJLFNBQVMsQ0FBQTtJQUNyRyxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsNEJBQTRCLENBQUMsSUFBSSxTQUFTLENBQUE7SUFFbkYsSUFBSSxNQUFNLEtBQUssU0FBUyxJQUFJLENBQUMsMkJBQTJCLEVBQUUsQ0FBQztRQUN6RCxJQUFJLFFBQVEsS0FBSyxPQUFPO1lBQUUsUUFBUSxHQUFHLFNBQVMsQ0FBQTtRQUM5QyxRQUFRLENBQUMsSUFBSSxDQUFDLHNEQUFzRCxDQUFDLENBQUE7SUFDdkUsQ0FBQztJQUVELElBQUksd0JBQXdCLElBQUksUUFBUSxLQUFLLFVBQVUsRUFBRSxDQUFDO1FBQ3hELFFBQVEsR0FBRyxPQUFPLENBQUE7UUFDbEIsUUFBUSxDQUFDLElBQUksQ0FBQyxvR0FBb0csQ0FBQyxDQUFBO0lBQ3JILENBQUM7SUFFRCxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU07UUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLHNGQUFzRixDQUFDLENBQUE7SUFFM0gsT0FBTztRQUNMLEVBQUU7UUFDRixJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxjQUFjLEVBQUUsRUFBRTtRQUM3QyxJQUFJO1FBQ0osUUFBUTtRQUNSLE1BQU07UUFDTixNQUFNO1FBQ04sY0FBYztRQUNkLFlBQVksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLFdBQVcsRUFBRSxJQUFJLFNBQVM7UUFDbEUsZUFBZTtRQUNmLGNBQWMsRUFBRSxNQUFNLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQztRQUMvQyxtQkFBbUIsRUFBRSxNQUFNLENBQUMsT0FBTyxFQUFFLG1CQUFtQixDQUFDO1FBQ3pELGtCQUFrQjtRQUNsQiwyQkFBMkI7UUFDM0Isd0JBQXdCO1FBQ3hCLFFBQVE7UUFDUixRQUFRO0tBQ1QsQ0FBQTtBQUNILENBQUM7QUFFRCxTQUFTLFFBQVEsQ0FBQyxHQUFvQixFQUFFLEdBQVc7SUFDakQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0lBQzVCLElBQUksQ0FBQyxLQUFLO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQ0FBcUMsR0FBRyxFQUFFLENBQUMsQ0FBQTtJQUN2RSxPQUFPLEtBQUssQ0FBQTtBQUNkLENBQUM7QUFFRCxTQUFTLE1BQU0sQ0FBQyxLQUFjO0lBQzVCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUE7QUFDM0MsQ0FBQztBQUVELFNBQVMsSUFBSSxDQUFDLEtBQWM7SUFDMUIsT0FBTyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtBQUMzRixDQUFDO0FBRUQsU0FBUyxNQUFNLENBQUMsS0FBYztJQUM1QixNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDNUIsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtBQUM3QyxDQUFDO0FBRUQsU0FBUyxNQUFNLENBQUMsS0FBYztJQUM1QixPQUFPLEtBQUssSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztRQUNoRSxDQUFDLENBQUMsS0FBNEI7UUFDOUIsQ0FBQyxDQUFDLElBQUksQ0FBQTtBQUNWLENBQUM7QUFFRCxLQUFLLFVBQVUsSUFBSSxDQUFDLFFBQWtCO0lBQ3BDLE9BQU8sTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQXdCLENBQUE7QUFDdkUsQ0FBQztBQUVELFNBQVMsWUFBWSxDQUFDLElBQXlCO0lBQzdDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO0lBQ2pFLElBQUksTUFBTTtRQUFFLE9BQU8sTUFBTSxDQUFBO0lBQ3pCLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDaEMsSUFBSSxLQUFLO1FBQUUsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO0lBQ25HLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFBO0FBQzVDLENBQUMifQ==
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applyGoogleMerchantCategoryFields = applyGoogleMerchantCategoryFields;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const SIZE_SYSTEMS = new Set([
|
|
6
|
+
"AU", "BR", "CN", "DE", "EU", "FR", "IT", "JP", "MEX", "UK", "US",
|
|
7
|
+
]);
|
|
8
|
+
const SIZE_TYPES = new Set(["regular", "petite", "plus", "tall", "big", "maternity"]);
|
|
9
|
+
async function applyGoogleMerchantCategoryFields(container, xml, items) {
|
|
10
|
+
if (!items.length)
|
|
11
|
+
return xml;
|
|
12
|
+
const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
13
|
+
const ids = items.map((item) => item.id).filter(Boolean);
|
|
14
|
+
const { data: variants } = await query.graph({
|
|
15
|
+
entity: "variant",
|
|
16
|
+
fields: ["id", "metadata", "product.metadata"],
|
|
17
|
+
filters: { id: ids },
|
|
18
|
+
});
|
|
19
|
+
let result = xml;
|
|
20
|
+
for (const variant of variants || []) {
|
|
21
|
+
const id = String(variant.id || "");
|
|
22
|
+
if (!id)
|
|
23
|
+
continue;
|
|
24
|
+
const variantMetadata = asMetadata(variant.metadata);
|
|
25
|
+
const productMetadata = asMetadata(variant.product?.metadata);
|
|
26
|
+
const fragment = buildCategorySpecificXml(productMetadata, variantMetadata);
|
|
27
|
+
if (!fragment)
|
|
28
|
+
continue;
|
|
29
|
+
const marker = `<g:id>${xmlEscape(id)}</g:id>`;
|
|
30
|
+
result = result.replace(marker, `${marker}${fragment}`);
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
function buildCategorySpecificXml(productMetadata, variantMetadata) {
|
|
35
|
+
const out = [];
|
|
36
|
+
const sizeSystem = firstString(metadataString(variantMetadata, "google_size_system"), metadataString(productMetadata, "google_size_system"))?.toUpperCase();
|
|
37
|
+
if (sizeSystem && SIZE_SYSTEMS.has(sizeSystem)) {
|
|
38
|
+
out.push(tag("size_system", sizeSystem));
|
|
39
|
+
}
|
|
40
|
+
const sizeTypes = firstList(variantMetadata.google_size_type, productMetadata.google_size_type)
|
|
41
|
+
.map((value) => value.toLowerCase())
|
|
42
|
+
.filter((value) => SIZE_TYPES.has(value))
|
|
43
|
+
.slice(0, 2);
|
|
44
|
+
for (const value of sizeTypes)
|
|
45
|
+
out.push(tag("size_type", value));
|
|
46
|
+
const adult = firstBoolean(metadataBoolean(variantMetadata, "google_adult"), metadataBoolean(productMetadata, "google_adult"));
|
|
47
|
+
if (adult !== undefined)
|
|
48
|
+
out.push(tag("adult", adult ? "yes" : "no"));
|
|
49
|
+
const isBundle = firstBoolean(metadataBoolean(variantMetadata, "google_is_bundle"), metadataBoolean(productMetadata, "google_is_bundle"));
|
|
50
|
+
if (isBundle !== undefined)
|
|
51
|
+
out.push(tag("is_bundle", isBundle ? "yes" : "no"));
|
|
52
|
+
const multipack = firstPositiveInteger(variantMetadata.google_multipack, productMetadata.google_multipack);
|
|
53
|
+
if (multipack !== undefined)
|
|
54
|
+
out.push(tag("multipack", String(multipack)));
|
|
55
|
+
const unitPricingMeasure = firstString(metadataString(variantMetadata, "google_unit_pricing_measure"), metadataString(productMetadata, "google_unit_pricing_measure"));
|
|
56
|
+
if (unitPricingMeasure)
|
|
57
|
+
out.push(tag("unit_pricing_measure", truncate(unitPricingMeasure, 50)));
|
|
58
|
+
const unitPricingBaseMeasure = firstString(metadataString(variantMetadata, "google_unit_pricing_base_measure"), metadataString(productMetadata, "google_unit_pricing_base_measure"));
|
|
59
|
+
if (unitPricingBaseMeasure) {
|
|
60
|
+
out.push(tag("unit_pricing_base_measure", truncate(unitPricingBaseMeasure, 50)));
|
|
61
|
+
}
|
|
62
|
+
const eprelCode = firstString(metadataString(variantMetadata, "google_eprel_code"), metadataString(productMetadata, "google_eprel_code"));
|
|
63
|
+
if (eprelCode) {
|
|
64
|
+
out.push(`<g:certification>` +
|
|
65
|
+
`<g:certification_authority>EC</g:certification_authority>` +
|
|
66
|
+
`<g:certification_name>EPREL</g:certification_name>` +
|
|
67
|
+
`<g:certification_code>${xmlEscape(truncate(eprelCode, 100))}</g:certification_code>` +
|
|
68
|
+
`</g:certification>`);
|
|
69
|
+
}
|
|
70
|
+
const highlights = firstList(variantMetadata.google_product_highlights, productMetadata.google_product_highlights)
|
|
71
|
+
.map((value) => truncate(value, 150))
|
|
72
|
+
.filter(Boolean)
|
|
73
|
+
.slice(0, 100);
|
|
74
|
+
for (const highlight of highlights)
|
|
75
|
+
out.push(tag("product_highlight", highlight));
|
|
76
|
+
const details = firstProductDetails(variantMetadata.google_product_details, productMetadata.google_product_details).slice(0, 100);
|
|
77
|
+
for (const detail of details) {
|
|
78
|
+
out.push(`<g:product_detail>` +
|
|
79
|
+
(detail.sectionName ? tag("section_name", truncate(detail.sectionName, 140)) : "") +
|
|
80
|
+
tag("attribute_name", truncate(detail.attributeName, 140)) +
|
|
81
|
+
tag("attribute_value", truncate(detail.attributeValue, 1000)) +
|
|
82
|
+
`</g:product_detail>`);
|
|
83
|
+
}
|
|
84
|
+
return out.join("");
|
|
85
|
+
}
|
|
86
|
+
function firstProductDetails(...values) {
|
|
87
|
+
for (const value of values) {
|
|
88
|
+
const parsed = parseProductDetails(value);
|
|
89
|
+
if (parsed.length)
|
|
90
|
+
return parsed;
|
|
91
|
+
}
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
function parseProductDetails(value) {
|
|
95
|
+
let source = value;
|
|
96
|
+
if (typeof source === "string") {
|
|
97
|
+
const trimmed = source.trim();
|
|
98
|
+
if (!trimmed)
|
|
99
|
+
return [];
|
|
100
|
+
try {
|
|
101
|
+
source = JSON.parse(trimmed);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (!Array.isArray(source))
|
|
108
|
+
return [];
|
|
109
|
+
return source
|
|
110
|
+
.map((entry) => {
|
|
111
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry))
|
|
112
|
+
return null;
|
|
113
|
+
const row = entry;
|
|
114
|
+
const attributeName = stringValue(row.attribute_name ?? row.attributeName);
|
|
115
|
+
const attributeValue = stringValue(row.attribute_value ?? row.attributeValue);
|
|
116
|
+
if (!attributeName || !attributeValue)
|
|
117
|
+
return null;
|
|
118
|
+
return {
|
|
119
|
+
sectionName: stringValue(row.section_name ?? row.sectionName) || undefined,
|
|
120
|
+
attributeName,
|
|
121
|
+
attributeValue,
|
|
122
|
+
};
|
|
123
|
+
})
|
|
124
|
+
.filter(Boolean);
|
|
125
|
+
}
|
|
126
|
+
function firstList(...values) {
|
|
127
|
+
for (const value of values) {
|
|
128
|
+
const parsed = parseList(value);
|
|
129
|
+
if (parsed.length)
|
|
130
|
+
return parsed;
|
|
131
|
+
}
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
function parseList(value) {
|
|
135
|
+
if (Array.isArray(value)) {
|
|
136
|
+
return value.map(stringValue).filter(Boolean);
|
|
137
|
+
}
|
|
138
|
+
if (typeof value !== "string")
|
|
139
|
+
return [];
|
|
140
|
+
const trimmed = value.trim();
|
|
141
|
+
if (!trimmed)
|
|
142
|
+
return [];
|
|
143
|
+
try {
|
|
144
|
+
const parsed = JSON.parse(trimmed);
|
|
145
|
+
if (Array.isArray(parsed)) {
|
|
146
|
+
return parsed.map(stringValue).filter(Boolean);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
// Accept human-friendly newline/pipe/comma separated metadata too.
|
|
151
|
+
}
|
|
152
|
+
return trimmed
|
|
153
|
+
.split(/\r?\n|\||,/)
|
|
154
|
+
.map((item) => item.trim())
|
|
155
|
+
.filter(Boolean);
|
|
156
|
+
}
|
|
157
|
+
function firstPositiveInteger(...values) {
|
|
158
|
+
for (const value of values) {
|
|
159
|
+
if (value === null || value === undefined || value === "")
|
|
160
|
+
continue;
|
|
161
|
+
const parsed = Number(value);
|
|
162
|
+
if (Number.isInteger(parsed) && parsed > 0)
|
|
163
|
+
return parsed;
|
|
164
|
+
}
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
function metadataString(metadata, key) {
|
|
168
|
+
return stringValue(metadata[key]);
|
|
169
|
+
}
|
|
170
|
+
function metadataBoolean(metadata, key) {
|
|
171
|
+
const value = metadata[key];
|
|
172
|
+
if (value === true || value === "true" || value === "yes" || value === 1)
|
|
173
|
+
return true;
|
|
174
|
+
if (value === false || value === "false" || value === "no" || value === 0)
|
|
175
|
+
return false;
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
function firstString(...values) {
|
|
179
|
+
return values.find((value) => Boolean(value?.trim()))?.trim();
|
|
180
|
+
}
|
|
181
|
+
function firstBoolean(...values) {
|
|
182
|
+
return values.find((value) => value !== undefined);
|
|
183
|
+
}
|
|
184
|
+
function stringValue(value) {
|
|
185
|
+
if (typeof value === "string" && value.trim())
|
|
186
|
+
return value.trim();
|
|
187
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
188
|
+
return String(value);
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
function asMetadata(value) {
|
|
192
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
193
|
+
? value
|
|
194
|
+
: {};
|
|
195
|
+
}
|
|
196
|
+
function tag(name, value) {
|
|
197
|
+
return `<g:${name}>${xmlEscape(value)}</g:${name}>`;
|
|
198
|
+
}
|
|
199
|
+
function truncate(value, max) {
|
|
200
|
+
return value.replace(/\s+/g, " ").trim().slice(0, max);
|
|
201
|
+
}
|
|
202
|
+
function xmlEscape(value) {
|
|
203
|
+
return value
|
|
204
|
+
.replace(/&/g, "&")
|
|
205
|
+
.replace(/</g, "<")
|
|
206
|
+
.replace(/>/g, ">")
|
|
207
|
+
.replace(/"/g, """)
|
|
208
|
+
.replace(/'/g, "'");
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2F0ZWdvcnktZmllbGRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9tb2R1bGVzL2dvb2dsZS1tZXJjaGFudC9jYXRlZ29yeS1maWVsZHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFxQkEsOEVBOEJDO0FBbkRELHFEQUFxRTtBQUVyRSxNQUFNLFlBQVksR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUMzQixJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSTtDQUNsRSxDQUFDLENBQUE7QUFDRixNQUFNLFVBQVUsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQTtBQWdCOUUsS0FBSyxVQUFVLGlDQUFpQyxDQUNyRCxTQUE2QyxFQUM3QyxHQUFXLEVBQ1gsS0FBeUI7SUFFekIsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNO1FBQUUsT0FBTyxHQUFHLENBQUE7SUFFN0IsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxLQUFLLENBQXlCLENBQUE7SUFDeEYsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUN4RCxNQUFNLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxHQUFHLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQztRQUMzQyxNQUFNLEVBQUUsU0FBUztRQUNqQixNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLGtCQUFrQixDQUFDO1FB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
|