@squadbase/vite-server 0.1.10-dev.cec85c2 → 0.1.10-dev.d23e546
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/cli/index.js +689 -89218
- package/dist/connectors/azure-sql.js +1 -20213
- package/dist/connectors/cosmosdb.js +4 -4
- package/dist/connectors/google-ads.js +191 -75
- package/dist/connectors/jdbc.js +54 -20224
- package/dist/connectors/oracle.js +10 -20215
- package/dist/connectors/sqlserver.js +1 -20213
- package/dist/index.js +758 -89297
- package/dist/main.js +743 -89282
- package/dist/vite-plugin.js +638 -89177
- package/package.json +4 -2
- package/dist/cli/cpufeatures-ORCDQN2Y.node +0 -0
- package/dist/cli/sshcrypto-P3UBA7BP.node +0 -0
- package/dist/cpufeatures-ORCDQN2Y.node +0 -0
- package/dist/sshcrypto-P3UBA7BP.node +0 -0
|
@@ -109,7 +109,7 @@ function createClient(params) {
|
|
|
109
109
|
queryOptions.partitionKey = options.partitionKey;
|
|
110
110
|
}
|
|
111
111
|
const iterator = cont.items.query(sql, queryOptions);
|
|
112
|
-
const { resources } = await iterator.
|
|
112
|
+
const { resources } = await iterator.fetchAll();
|
|
113
113
|
return resources ?? [];
|
|
114
114
|
} catch (err) {
|
|
115
115
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -445,7 +445,7 @@ Use \`TOP n\` (not \`LIMIT n\`) to bound the result. Cross-partition queries are
|
|
|
445
445
|
}
|
|
446
446
|
}
|
|
447
447
|
const iterator = cont.items.query(sql, queryOptions);
|
|
448
|
-
const { resources, requestCharge } = await iterator.
|
|
448
|
+
const { resources, requestCharge } = await iterator.fetchAll();
|
|
449
449
|
const documents = resources ?? [];
|
|
450
450
|
const truncated = documents.length > MAX_DOCUMENTS;
|
|
451
451
|
return {
|
|
@@ -522,7 +522,7 @@ export default async function handler(_c: Context) {
|
|
|
522
522
|
- Queries always target a single container and reference items via the alias \`c\` (e.g. \`SELECT c.id, c.name FROM c WHERE c.status = 'active'\`).
|
|
523
523
|
- Row limiting: use \`TOP n\` (e.g. \`SELECT TOP 100 * FROM c\`). \`LIMIT\` is **not** supported. \`OFFSET m LIMIT n\` is supported on newer accounts but \`TOP\` is the safe default.
|
|
524
524
|
- System fields are prefixed with an underscore (\`c.id\`, \`c._ts\` for the modification timestamp, \`c._etag\`).
|
|
525
|
-
- Aggregates: \`COUNT(1)\`, \`SUM\`, \`AVG\`, \`MIN\`, \`MAX\`, with \`GROUP BY\` (e.g. \`SELECT c.country, COUNT(1) AS n FROM c GROUP BY c.country\`).
|
|
525
|
+
- Aggregates: \`COUNT(1)\`, \`SUM\`, \`AVG\`, \`MIN\`, \`MAX\`, with \`GROUP BY\` (e.g. \`SELECT c.country, COUNT(1) AS n FROM c GROUP BY c.country\`). Cross-partition \`GROUP BY\` is fully supported \u2014 the connector drains all result pages internally, so trust the returned rows even for queries that span many partitions. Do **not** work around perceived missing rows by re-fetching all items and aggregating in TypeScript.
|
|
526
526
|
- Joins: only **intra-document** joins via \`JOIN\` over arrays inside the same item; there is no cross-container/cross-document join.
|
|
527
527
|
- Always bound results with \`TOP n\` and prefer scoped queries with a \`partitionKey\` value when possible \u2014 cross-partition queries cost more RUs.`,
|
|
528
528
|
ja: `### \u30C4\u30FC\u30EB
|
|
@@ -568,7 +568,7 @@ export default async function handler(_c: Context) {
|
|
|
568
568
|
- \u30AF\u30A8\u30EA\u306F\u5E38\u306B\u5358\u4E00\u30B3\u30F3\u30C6\u30CA\u3092\u5BFE\u8C61\u3068\u3057\u3001\u30A2\u30A4\u30C6\u30E0\u306F\u5225\u540D \`c\` \u3067\u53C2\u7167\u3057\u307E\u3059\uFF08\u4F8B: \`SELECT c.id, c.name FROM c WHERE c.status = 'active'\`\uFF09\u3002
|
|
569
569
|
- \u884C\u6570\u5236\u9650: \`TOP n\` \u3092\u4F7F\u7528\u3057\u307E\u3059\uFF08\u4F8B: \`SELECT TOP 100 * FROM c\`\uFF09\u3002\`LIMIT\` \u306F **\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093**\u3002\u65B0\u3057\u3044\u30A2\u30AB\u30A6\u30F3\u30C8\u3067\u306F \`OFFSET m LIMIT n\` \u304C\u4F7F\u3048\u307E\u3059\u304C\u3001\u5B89\u5168\u5074\u306E\u65E2\u5B9A\u306F \`TOP\` \u3067\u3059\u3002
|
|
570
570
|
- \u30B7\u30B9\u30C6\u30E0\u30D5\u30A3\u30FC\u30EB\u30C9\u306F\u30A2\u30F3\u30C0\u30FC\u30B9\u30B3\u30A2\u59CB\u307E\u308A\uFF08\`c.id\`\u3001\u5909\u66F4\u6642\u523B\u306E \`c._ts\`\u3001\`c._etag\`\uFF09\u3002
|
|
571
|
-
- \u96C6\u7D04: \`COUNT(1)\`\u3001\`SUM\`\u3001\`AVG\`\u3001\`MIN\`\u3001\`MAX\` \u3092 \`GROUP BY\` \u3068\u7D44\u307F\u5408\u308F\u305B\u307E\u3059\uFF08\u4F8B: \`SELECT c.country, COUNT(1) AS n FROM c GROUP BY c.country\`\uFF09\u3002
|
|
571
|
+
- \u96C6\u7D04: \`COUNT(1)\`\u3001\`SUM\`\u3001\`AVG\`\u3001\`MIN\`\u3001\`MAX\` \u3092 \`GROUP BY\` \u3068\u7D44\u307F\u5408\u308F\u305B\u307E\u3059\uFF08\u4F8B: \`SELECT c.country, COUNT(1) AS n FROM c GROUP BY c.country\`\uFF09\u3002\u30AF\u30ED\u30B9\u30D1\u30FC\u30C6\u30A3\u30B7\u30E7\u30F3\u306E \`GROUP BY\` \u3082\u5B8C\u5168\u306B\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u304A\u308A\u3001\u30B3\u30CD\u30AF\u30BF\u304C\u5185\u90E8\u3067\u5168\u7D50\u679C\u30DA\u30FC\u30B8\u3092\u30C9\u30EC\u30A4\u30F3\u3059\u308B\u305F\u3081\u3001\u591A\u30D1\u30FC\u30C6\u30A3\u30B7\u30E7\u30F3\u306B\u307E\u305F\u304C\u308B\u30AF\u30A8\u30EA\u3067\u3082\u8FD4\u3063\u3066\u304D\u305F\u884C\u6570\u3092\u305D\u306E\u307E\u307E\u4FE1\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002**\u300C\u7D50\u679C\u304C\u6B20\u3051\u3066\u3044\u308B\u3088\u3046\u306B\u898B\u3048\u308B\u300D\u304B\u3089\u3068\u3044\u3063\u3066\u5168\u4EF6\u53D6\u5F97\u2192TS \u5074\u3067\u96C6\u8A08\u3059\u308B\u8FC2\u56DE\u306F\u3057\u306A\u3044\u3053\u3068\u3002**
|
|
572
572
|
- \u7D50\u5408: \u540C\u4E00\u30A2\u30A4\u30C6\u30E0\u5185\u306E\u914D\u5217\u306B\u5BFE\u3059\u308B **\u30A4\u30F3\u30C8\u30E9\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8** \`JOIN\` \u306E\u307F\u3067\u3001\u30B3\u30F3\u30C6\u30CA\u9593\uFF0F\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u9593\u306E\u7D50\u5408\u306F\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u307E\u305B\u3093\u3002
|
|
573
573
|
- \u7D50\u679C\u4EF6\u6570\u306F\u5FC5\u305A \`TOP n\` \u3067\u5236\u9650\u3057\u3001\u53EF\u80FD\u3067\u3042\u308C\u3070 \`partitionKey\` \u3067\u5358\u4E00\u30D1\u30FC\u30C6\u30A3\u30B7\u30E7\u30F3\u306B\u30B9\u30B3\u30FC\u30D7\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u30AF\u30ED\u30B9\u30D1\u30FC\u30C6\u30A3\u30B7\u30E7\u30F3\u30AF\u30A8\u30EA\u306F RU \u3092\u591A\u304F\u6D88\u8CBB\u3057\u307E\u3059\uFF09\u3002`
|
|
574
574
|
},
|
|
@@ -42,6 +42,39 @@ var ParameterDefinition = class {
|
|
|
42
42
|
}
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
+
// ../connectors/src/connectors/google-ads/constants.ts
|
|
46
|
+
var VERSION_FALLBACK_ORDER = ["v22", "v23", "v24"];
|
|
47
|
+
var cachedWorkingVersion = VERSION_FALLBACK_ORDER[0];
|
|
48
|
+
var looksSunset = (contentType) => {
|
|
49
|
+
return contentType != null && contentType.toLowerCase().includes("text/html");
|
|
50
|
+
};
|
|
51
|
+
async function fetchGoogleAdsWithVersionFallback(attempt) {
|
|
52
|
+
const order = [
|
|
53
|
+
cachedWorkingVersion,
|
|
54
|
+
...VERSION_FALLBACK_ORDER.filter((v) => v !== cachedWorkingVersion)
|
|
55
|
+
];
|
|
56
|
+
let lastResponse = null;
|
|
57
|
+
for (let i = 0; i < order.length; i++) {
|
|
58
|
+
const version = order[i];
|
|
59
|
+
const baseUrl = `https://googleads.googleapis.com/${version}/`;
|
|
60
|
+
const response = await attempt(baseUrl);
|
|
61
|
+
const contentType = response.headers.get("content-type");
|
|
62
|
+
if (looksSunset(contentType) && i < order.length - 1) {
|
|
63
|
+
console.warn(
|
|
64
|
+
`[google-ads] version ${version} returned a sunset/HTML response (status ${response.status}); retrying with newer version`
|
|
65
|
+
);
|
|
66
|
+
lastResponse = response;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
cachedWorkingVersion = version;
|
|
70
|
+
return response;
|
|
71
|
+
}
|
|
72
|
+
return lastResponse ?? new Response(null, {
|
|
73
|
+
status: 502,
|
|
74
|
+
statusText: "All Google Ads API versions returned sunset responses"
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
45
78
|
// ../connectors/src/connectors/google-ads/parameters.ts
|
|
46
79
|
var parameters = {
|
|
47
80
|
customerId: new ParameterDefinition({
|
|
@@ -56,7 +89,6 @@ var parameters = {
|
|
|
56
89
|
};
|
|
57
90
|
|
|
58
91
|
// ../connectors/src/connectors/google-ads/sdk/index.ts
|
|
59
|
-
var BASE_URL = "https://googleads.googleapis.com/v18/";
|
|
60
92
|
function createClient(params, fetchFn = fetch) {
|
|
61
93
|
const rawCustomerId = params[parameters.customerId.slug];
|
|
62
94
|
const defaultCustomerId = rawCustomerId?.replace(/-/g, "") ?? "";
|
|
@@ -71,24 +103,26 @@ function createClient(params, fetchFn = fetch) {
|
|
|
71
103
|
}
|
|
72
104
|
function request(path2, init) {
|
|
73
105
|
const resolvedPath = defaultCustomerId ? path2.replace(/\{customerId\}/g, defaultCustomerId) : path2;
|
|
74
|
-
const url = `${BASE_URL}${resolvedPath}`;
|
|
75
106
|
const headers = new Headers(init?.headers);
|
|
76
107
|
if (defaultCustomerId) {
|
|
77
108
|
headers.set("login-customer-id", defaultCustomerId);
|
|
78
109
|
}
|
|
79
|
-
return
|
|
110
|
+
return fetchGoogleAdsWithVersionFallback(
|
|
111
|
+
(baseUrl) => fetchFn(`${baseUrl}${resolvedPath}`, { ...init, headers })
|
|
112
|
+
);
|
|
80
113
|
}
|
|
81
114
|
async function search(query, customerId) {
|
|
82
115
|
const cid = resolveCustomerId(customerId);
|
|
83
|
-
const url = `${BASE_URL}customers/${cid}/googleAds:searchStream`;
|
|
84
116
|
const headers = new Headers();
|
|
85
117
|
headers.set("Content-Type", "application/json");
|
|
86
118
|
headers.set("login-customer-id", cid);
|
|
87
|
-
const response = await
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
119
|
+
const response = await fetchGoogleAdsWithVersionFallback(
|
|
120
|
+
(baseUrl) => fetchFn(`${baseUrl}customers/${cid}/googleAds:searchStream`, {
|
|
121
|
+
method: "POST",
|
|
122
|
+
headers,
|
|
123
|
+
body: JSON.stringify({ query })
|
|
124
|
+
})
|
|
125
|
+
);
|
|
92
126
|
if (!response.ok) {
|
|
93
127
|
const body = await response.text();
|
|
94
128
|
throw new Error(
|
|
@@ -99,8 +133,9 @@ function createClient(params, fetchFn = fetch) {
|
|
|
99
133
|
return data.flatMap((chunk) => chunk.results ?? []);
|
|
100
134
|
}
|
|
101
135
|
async function listAccessibleCustomers() {
|
|
102
|
-
const
|
|
103
|
-
|
|
136
|
+
const response = await fetchGoogleAdsWithVersionFallback(
|
|
137
|
+
(baseUrl) => fetchFn(`${baseUrl}customers:listAccessibleCustomers`, { method: "GET" })
|
|
138
|
+
);
|
|
104
139
|
if (!response.ok) {
|
|
105
140
|
const body = await response.text();
|
|
106
141
|
throw new Error(
|
|
@@ -270,7 +305,65 @@ var AUTH_TYPES = {
|
|
|
270
305
|
|
|
271
306
|
// ../connectors/src/connectors/google-ads/tools/list-customers.ts
|
|
272
307
|
import { z } from "zod";
|
|
273
|
-
|
|
308
|
+
|
|
309
|
+
// ../connectors/src/connectors/google-ads/error.ts
|
|
310
|
+
var parseJsonOrNull = (text) => {
|
|
311
|
+
if (text.length === 0) return null;
|
|
312
|
+
try {
|
|
313
|
+
return JSON.parse(text);
|
|
314
|
+
} catch {
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
319
|
+
var collectGoogleAdsErrorCodes = (details) => {
|
|
320
|
+
if (!Array.isArray(details)) return [];
|
|
321
|
+
const codes = [];
|
|
322
|
+
for (const detail of details) {
|
|
323
|
+
if (!isRecord(detail)) continue;
|
|
324
|
+
const errors = detail.errors;
|
|
325
|
+
if (!Array.isArray(errors)) continue;
|
|
326
|
+
for (const e of errors) {
|
|
327
|
+
if (!isRecord(e)) continue;
|
|
328
|
+
const errorCode = e.errorCode;
|
|
329
|
+
if (!isRecord(errorCode)) continue;
|
|
330
|
+
for (const [k, v] of Object.entries(errorCode)) {
|
|
331
|
+
if (typeof v === "string") codes.push(`${k}=${v}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return codes;
|
|
336
|
+
};
|
|
337
|
+
var extractGoogleAdsErrorMessage = (status, statusText, parsedBody, rawText) => {
|
|
338
|
+
const fallback = `HTTP ${status} ${statusText}`;
|
|
339
|
+
if (isRecord(parsedBody)) {
|
|
340
|
+
const errorField = parsedBody.error;
|
|
341
|
+
if (typeof errorField === "string") return errorField;
|
|
342
|
+
if (isRecord(errorField)) {
|
|
343
|
+
const message = typeof errorField.message === "string" ? errorField.message : null;
|
|
344
|
+
const errorStatus = typeof errorField.status === "string" ? errorField.status : null;
|
|
345
|
+
const codes = collectGoogleAdsErrorCodes(errorField.details);
|
|
346
|
+
const parts = [
|
|
347
|
+
fallback,
|
|
348
|
+
errorStatus,
|
|
349
|
+
message,
|
|
350
|
+
codes.length > 0 ? `[${codes.join(", ")}]` : null
|
|
351
|
+
].filter((p) => p != null && p.length > 0);
|
|
352
|
+
if (parts.length > 1) return parts.join(": ");
|
|
353
|
+
}
|
|
354
|
+
if (typeof parsedBody.message === "string") {
|
|
355
|
+
return `${fallback}: ${parsedBody.message}`;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (rawText.length > 0) {
|
|
359
|
+
const trimmed = rawText.trim();
|
|
360
|
+
const preview = trimmed.length > 500 ? `${trimmed.slice(0, 500)}\u2026` : trimmed;
|
|
361
|
+
return `${fallback}: ${preview}`;
|
|
362
|
+
}
|
|
363
|
+
return fallback;
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
// ../connectors/src/connectors/google-ads/tools/list-customers.ts
|
|
274
367
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
275
368
|
var cachedToken = null;
|
|
276
369
|
async function getProxyToken(config) {
|
|
@@ -346,48 +439,60 @@ var listCustomersTool = new ConnectorTool({
|
|
|
346
439
|
const controller = new AbortController();
|
|
347
440
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
348
441
|
try {
|
|
349
|
-
const response = await
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
442
|
+
const response = await fetchGoogleAdsWithVersionFallback(
|
|
443
|
+
(baseUrl) => fetch(proxyUrl, {
|
|
444
|
+
method: "POST",
|
|
445
|
+
headers: {
|
|
446
|
+
"Content-Type": "application/json",
|
|
447
|
+
Authorization: `Bearer ${token}`
|
|
448
|
+
},
|
|
449
|
+
body: JSON.stringify({
|
|
450
|
+
url: `${baseUrl}customers:listAccessibleCustomers`,
|
|
451
|
+
method: "GET"
|
|
452
|
+
}),
|
|
453
|
+
signal: controller.signal
|
|
454
|
+
})
|
|
455
|
+
);
|
|
456
|
+
const rawText = await response.text();
|
|
457
|
+
const data = parseJsonOrNull(rawText);
|
|
362
458
|
if (!response.ok) {
|
|
363
|
-
|
|
364
|
-
|
|
459
|
+
return {
|
|
460
|
+
success: false,
|
|
461
|
+
error: extractGoogleAdsErrorMessage(
|
|
462
|
+
response.status,
|
|
463
|
+
response.statusText,
|
|
464
|
+
data,
|
|
465
|
+
rawText
|
|
466
|
+
)
|
|
467
|
+
};
|
|
365
468
|
}
|
|
366
|
-
const customerIds = (data
|
|
469
|
+
const customerIds = (data?.resourceNames ?? []).map(
|
|
367
470
|
(rn) => rn.replace(/^customers\//, "")
|
|
368
471
|
);
|
|
369
472
|
const customers = [];
|
|
370
473
|
for (const cid of customerIds) {
|
|
371
474
|
try {
|
|
372
|
-
const detailResponse = await
|
|
373
|
-
|
|
374
|
-
headers: {
|
|
375
|
-
"Content-Type": "application/json",
|
|
376
|
-
Authorization: `Bearer ${token}`
|
|
377
|
-
},
|
|
378
|
-
body: JSON.stringify({
|
|
379
|
-
url: `${BASE_URL2}customers/${cid}/googleAds:searchStream`,
|
|
475
|
+
const detailResponse = await fetchGoogleAdsWithVersionFallback(
|
|
476
|
+
(baseUrl) => fetch(proxyUrl, {
|
|
380
477
|
method: "POST",
|
|
381
478
|
headers: {
|
|
382
479
|
"Content-Type": "application/json",
|
|
383
|
-
|
|
480
|
+
Authorization: `Bearer ${token}`
|
|
384
481
|
},
|
|
385
482
|
body: JSON.stringify({
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
483
|
+
url: `${baseUrl}customers/${cid}/googleAds:searchStream`,
|
|
484
|
+
method: "POST",
|
|
485
|
+
headers: {
|
|
486
|
+
"Content-Type": "application/json",
|
|
487
|
+
"login-customer-id": cid
|
|
488
|
+
},
|
|
489
|
+
body: JSON.stringify({
|
|
490
|
+
query: "SELECT customer.id, customer.descriptive_name FROM customer LIMIT 1"
|
|
491
|
+
})
|
|
492
|
+
}),
|
|
493
|
+
signal: controller.signal
|
|
494
|
+
})
|
|
495
|
+
);
|
|
391
496
|
if (detailResponse.ok) {
|
|
392
497
|
const detailData = await detailResponse.json();
|
|
393
498
|
const customer = detailData?.[0]?.results?.[0]?.customer;
|
|
@@ -458,7 +563,6 @@ var googleAdsOnboarding = new ConnectorOnboarding({
|
|
|
458
563
|
|
|
459
564
|
// ../connectors/src/connectors/google-ads/tools/request.ts
|
|
460
565
|
import { z as z2 } from "zod";
|
|
461
|
-
var BASE_URL3 = "https://googleads.googleapis.com/v18/";
|
|
462
566
|
var REQUEST_TIMEOUT_MS2 = 6e4;
|
|
463
567
|
var cachedToken2 = null;
|
|
464
568
|
async function getProxyToken2(config) {
|
|
@@ -498,7 +602,7 @@ var inputSchema2 = z2.object({
|
|
|
498
602
|
connectionId: z2.string().describe("ID of the Google Ads OAuth connection to use"),
|
|
499
603
|
method: z2.enum(["GET", "POST"]).describe("HTTP method"),
|
|
500
604
|
path: z2.string().describe(
|
|
501
|
-
"API path appended to https://googleads.googleapis.com
|
|
605
|
+
"API path appended to https://googleads.googleapis.com/<version>/ (e.g., 'customers/{customerId}/googleAds:searchStream'). The API version is auto-managed and {customerId} is automatically replaced."
|
|
502
606
|
),
|
|
503
607
|
body: z2.record(z2.string(), z2.unknown()).optional().describe("POST request body (JSON)")
|
|
504
608
|
});
|
|
@@ -515,7 +619,7 @@ var outputSchema2 = z2.discriminatedUnion("success", [
|
|
|
515
619
|
]);
|
|
516
620
|
var requestTool = new ConnectorTool({
|
|
517
621
|
name: "request",
|
|
518
|
-
description: `Send authenticated requests to the Google Ads API
|
|
622
|
+
description: `Send authenticated requests to the Google Ads API.
|
|
519
623
|
Authentication is handled automatically via OAuth proxy.
|
|
520
624
|
{customerId} in the path is automatically replaced with the connection's customer ID (hyphens removed).`,
|
|
521
625
|
inputSchema: inputSchema2,
|
|
@@ -535,34 +639,42 @@ Authentication is handled automatically via OAuth proxy.
|
|
|
535
639
|
const rawCustomerId = parameters.customerId.tryGetValue(connection2);
|
|
536
640
|
const customerId = rawCustomerId?.replace(/-/g, "") ?? "";
|
|
537
641
|
const resolvedPath = customerId ? path2.replace(/\{customerId\}/g, customerId) : path2;
|
|
538
|
-
const url = `${BASE_URL3}${resolvedPath}`;
|
|
539
642
|
const token = await getProxyToken2(config.oauthProxy);
|
|
540
643
|
const proxyUrl = `https://${config.oauthProxy.sandboxId}.${config.oauthProxy.previewBaseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
541
644
|
const controller = new AbortController();
|
|
542
645
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS2);
|
|
543
646
|
try {
|
|
544
|
-
const response = await
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
"Content-Type": "application/json",
|
|
548
|
-
Authorization: `Bearer ${token}`
|
|
549
|
-
},
|
|
550
|
-
body: JSON.stringify({
|
|
551
|
-
url,
|
|
552
|
-
method,
|
|
647
|
+
const response = await fetchGoogleAdsWithVersionFallback(
|
|
648
|
+
(baseUrl) => fetch(proxyUrl, {
|
|
649
|
+
method: "POST",
|
|
553
650
|
headers: {
|
|
554
651
|
"Content-Type": "application/json",
|
|
555
|
-
|
|
652
|
+
Authorization: `Bearer ${token}`
|
|
556
653
|
},
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
654
|
+
body: JSON.stringify({
|
|
655
|
+
url: `${baseUrl}${resolvedPath}`,
|
|
656
|
+
method,
|
|
657
|
+
headers: {
|
|
658
|
+
"Content-Type": "application/json",
|
|
659
|
+
...customerId ? { "login-customer-id": customerId } : {}
|
|
660
|
+
},
|
|
661
|
+
...method === "POST" && body ? { body: JSON.stringify(body) } : {}
|
|
662
|
+
}),
|
|
663
|
+
signal: controller.signal
|
|
664
|
+
})
|
|
665
|
+
);
|
|
666
|
+
const rawText = await response.text();
|
|
667
|
+
const data = parseJsonOrNull(rawText);
|
|
562
668
|
if (!response.ok) {
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
669
|
+
return {
|
|
670
|
+
success: false,
|
|
671
|
+
error: extractGoogleAdsErrorMessage(
|
|
672
|
+
response.status,
|
|
673
|
+
response.statusText,
|
|
674
|
+
data,
|
|
675
|
+
rawText
|
|
676
|
+
)
|
|
677
|
+
};
|
|
566
678
|
}
|
|
567
679
|
return { success: true, status: response.status, data };
|
|
568
680
|
} finally {
|
|
@@ -732,18 +844,22 @@ const customerIds = await ads.listAccessibleCustomers();
|
|
|
732
844
|
if (!customerId) {
|
|
733
845
|
return { success: true };
|
|
734
846
|
}
|
|
735
|
-
const url = `https://googleads.googleapis.com/v18/customers/${customerId}/googleAds:searchStream`;
|
|
736
847
|
try {
|
|
737
|
-
const res = await
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
848
|
+
const res = await fetchGoogleAdsWithVersionFallback(
|
|
849
|
+
(baseUrl) => proxyFetch(
|
|
850
|
+
`${baseUrl}customers/${customerId}/googleAds:searchStream`,
|
|
851
|
+
{
|
|
852
|
+
method: "POST",
|
|
853
|
+
headers: {
|
|
854
|
+
"Content-Type": "application/json",
|
|
855
|
+
"login-customer-id": customerId
|
|
856
|
+
},
|
|
857
|
+
body: JSON.stringify({
|
|
858
|
+
query: "SELECT customer.id FROM customer LIMIT 1"
|
|
859
|
+
})
|
|
860
|
+
}
|
|
861
|
+
)
|
|
862
|
+
);
|
|
747
863
|
if (!res.ok) {
|
|
748
864
|
const errorText = await res.text().catch(() => res.statusText);
|
|
749
865
|
return {
|