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