@marktiderman/genesis-forms 0.3.0 → 0.3.1
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/destinations.cjs +51 -27
- package/dist/destinations.cjs.map +1 -1
- package/dist/destinations.js +51 -27
- package/dist/destinations.js.map +1 -1
- package/dist/index.cjs +3 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +3 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +3 -1
- package/dist/server.js.map +1 -1
- package/dist/testing.cjs +3 -1
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.js +3 -1
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/dist/destinations.js
CHANGED
|
@@ -60,6 +60,11 @@ async function timedFetch(deps, url, init, signal) {
|
|
|
60
60
|
const timeout = AbortSignal.timeout(deps.timeoutMs ?? REQUEST_TIMEOUT_MS);
|
|
61
61
|
const any = AbortSignal.any;
|
|
62
62
|
const combined = signal ? any ? any([timeout, signal]) : signal.aborted ? signal : timeout : timeout;
|
|
63
|
+
try {
|
|
64
|
+
new Request(url, { method: init.method ?? "GET", headers: init.headers ?? {} });
|
|
65
|
+
} catch {
|
|
66
|
+
throw new DeliveryError("Invalid request (a header value or the URL is malformed)", { retryable: false });
|
|
67
|
+
}
|
|
63
68
|
try {
|
|
64
69
|
return await (deps.fetch ?? fetch)(url, { ...init, signal: combined });
|
|
65
70
|
} catch (error) {
|
|
@@ -756,7 +761,7 @@ async function googleAccessToken(account, options = {}) {
|
|
|
756
761
|
if (!clientEmail || !privateKey) throw new DeliveryError("The Google service account email or private key is not set");
|
|
757
762
|
const scope = options.scope ?? SHEETS_SCOPE;
|
|
758
763
|
const now = options.now?.() ?? Date.now();
|
|
759
|
-
const cacheKey = `${clientEmail} ${scope}`;
|
|
764
|
+
const cacheKey = `${clientEmail} ${scope} ${await sha256Hex(privateKey.replace(/\\n/g, "\n").trim())}`;
|
|
760
765
|
const hit = cache.get(cacheKey);
|
|
761
766
|
if (hit && hit.expiresAt - 6e4 > now) return hit.token;
|
|
762
767
|
const iat = Math.floor(now / 1e3);
|
|
@@ -787,6 +792,7 @@ var SHEETS_API = "https://sheets.googleapis.com/v4/spreadsheets";
|
|
|
787
792
|
var DEFAULT_SHEET_NAME = "Responses";
|
|
788
793
|
var DEDUPE_WINDOW = 500;
|
|
789
794
|
var HEADER_SCAN_ROWS = 100;
|
|
795
|
+
var HEADER_WRITE_ATTEMPTS = 3;
|
|
790
796
|
function mergeHeader(existing, keys, width = 0) {
|
|
791
797
|
const header = existing.map((h) => h == null ? "" : String(h));
|
|
792
798
|
while (header.length < width) header.push("");
|
|
@@ -882,35 +888,52 @@ function sheetsDestination(options) {
|
|
|
882
888
|
});
|
|
883
889
|
const keys = [...new Set(rows.flatMap((r) => r.columns))];
|
|
884
890
|
async function setUp(previous) {
|
|
885
|
-
const
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
891
|
+
const readTabs = async () => {
|
|
892
|
+
const meta = await call(
|
|
893
|
+
"read",
|
|
894
|
+
`${base}?fields=${encodeURIComponent("sheets.properties(sheetId,title,gridProperties.columnCount)")}`
|
|
895
|
+
);
|
|
896
|
+
return meta.sheets?.map((s) => s.properties).find((p) => p?.title === sheetName);
|
|
897
|
+
};
|
|
898
|
+
let sheet = await readTabs();
|
|
890
899
|
if (!sheet) {
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
const existing = used.map((column) => column[0] ?? "");
|
|
900
|
-
const header = mergeHeader(existing, keys, used.length);
|
|
901
|
-
if (!header.includes("id")) {
|
|
902
|
-
if (used.length) header.push("id");
|
|
903
|
-
else header.unshift("id");
|
|
900
|
+
try {
|
|
901
|
+
const added = await batchUpdate("add tab", [{ addSheet: { properties: { title: sheetName } } }]);
|
|
902
|
+
sheet = added.replies?.[0]?.addSheet?.properties ?? { sheetId: 0, title: sheetName };
|
|
903
|
+
} catch (error) {
|
|
904
|
+
if (!(error instanceof DeliveryError) || error.status !== 400) throw error;
|
|
905
|
+
sheet = await readTabs();
|
|
906
|
+
if (!sheet) throw error;
|
|
907
|
+
}
|
|
904
908
|
}
|
|
909
|
+
const readHeader = async () => {
|
|
910
|
+
const read = await call(
|
|
911
|
+
"read header",
|
|
912
|
+
`${range(`A1:ZZZ${HEADER_SCAN_ROWS}`)}?majorDimension=COLUMNS`
|
|
913
|
+
);
|
|
914
|
+
const used2 = read.values ?? [];
|
|
915
|
+
return { used: used2.length, existing: used2.map((column) => column[0] ?? "") };
|
|
916
|
+
};
|
|
905
917
|
let columns = sheet.gridProperties?.columnCount ?? 26;
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
918
|
+
let { used, existing } = await readHeader();
|
|
919
|
+
let header = [];
|
|
920
|
+
for (let attempt = 0; ; attempt++) {
|
|
921
|
+
header = mergeHeader(existing, keys, used);
|
|
922
|
+
if (!header.includes("id")) {
|
|
923
|
+
if (used) header.push("id");
|
|
924
|
+
else header.unshift("id");
|
|
925
|
+
}
|
|
926
|
+
const changed = header.length !== existing.length || header.some((h, i) => h !== String(existing[i] ?? ""));
|
|
927
|
+
if (!changed) break;
|
|
928
|
+
if (attempt >= HEADER_WRITE_ATTEMPTS) {
|
|
929
|
+
throw new DeliveryError("Google Sheets header kept changing while it was written", { retryable: true });
|
|
930
|
+
}
|
|
931
|
+
if (header.length > columns) {
|
|
932
|
+
await batchUpdate("add columns", [
|
|
933
|
+
{ appendDimension: { sheetId: sheet.sheetId, dimension: "COLUMNS", length: header.length - columns } }
|
|
934
|
+
]);
|
|
935
|
+
columns = header.length;
|
|
936
|
+
}
|
|
914
937
|
await call("write header", `${range("A1")}?valueInputOption=RAW`, {
|
|
915
938
|
method: "PUT",
|
|
916
939
|
body: JSON.stringify({ values: [header] })
|
|
@@ -925,6 +948,7 @@ function sheetsDestination(options) {
|
|
|
925
948
|
}
|
|
926
949
|
]);
|
|
927
950
|
}
|
|
951
|
+
({ used, existing } = await readHeader());
|
|
928
952
|
}
|
|
929
953
|
return {
|
|
930
954
|
spreadsheet_id: spreadsheetId,
|