1 | Object.defineProperty(exports, '__esModule', { value: true });
|
2 | exports.gsheet =
|
3 | exports.Gsheet =
|
4 | exports.noFilter =
|
5 | exports.noChange =
|
6 | exports.trim =
|
7 | exports.gSheetDateTime =
|
8 | exports.gSheetDate =
|
9 | void 0;
|
10 |
|
11 |
|
12 | const sheets_1 = require('@googleapis/sheets');
|
13 | const promise_1 = require('@resolute/std/promise');
|
14 |
|
15 | const gSheetDate = (date = new Date()) =>
|
16 | `${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()}`;
|
17 | exports.gSheetDate = gSheetDate;
|
18 | const gSheetDateTime = (date = new Date()) =>
|
19 | `${(0, exports.gSheetDate)(date)} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;
|
20 | exports.gSheetDateTime = gSheetDateTime;
|
21 | const trim = (arg) => {
|
22 | if (typeof arg === 'string') {
|
23 | return arg.replace(/\s+/g, ' ').trim();
|
24 | }
|
25 | return arg;
|
26 | };
|
27 | exports.trim = trim;
|
28 | const noChange = (arg) => arg;
|
29 | exports.noChange = noChange;
|
30 | const noFilter = () => true;
|
31 | exports.noFilter = noFilter;
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 | class Gsheet {
|
40 | constructor(options) {
|
41 | let _a; let _b; let _c; let
|
42 | _d;
|
43 | this.auth = (() => {
|
44 | const googleAuth = new sheets_1.auth.GoogleAuth({
|
45 | scopes: ['https://www.googleapis.com/auth/spreadsheets'],
|
46 | });
|
47 | if (options.jwt) {
|
48 | const client_email =
|
49 | 'client_email' in options.jwt ? options.jwt.client_email : options.jwt.email;
|
50 | const private_key =
|
51 | 'private_key' in options.jwt ? options.jwt.private_key : options.jwt.key;
|
52 | return googleAuth.fromJSON({ client_email, private_key });
|
53 | }
|
54 | return googleAuth.getClient();
|
55 | })();
|
56 | this.client = Promise.resolve(this.auth).then((auth) => {
|
57 | let _a;
|
58 | return (0, sheets_1.sheets)({
|
59 | version: 'v4',
|
60 | auth,
|
61 | http2: (_a = options.http2) !== null && _a !== void 0 ? _a : false,
|
62 | });
|
63 | });
|
64 | this.spreadsheetId = options.spreadsheetId;
|
65 | this.range = options.range;
|
66 | this.headerRows =
|
67 | (_a = options === null || options === void 0 ? void 0 : options.headerRows) !== null &&
|
68 | _a !== void 0
|
69 | ? _a
|
70 | : 1;
|
71 | this.keyTransform =
|
72 | (_b = options === null || options === void 0 ? void 0 : options.keyTransform) !== null &&
|
73 | _b !== void 0
|
74 | ? _b
|
75 | : exports.noChange;
|
76 | this.sanitize =
|
77 | (_c = options === null || options === void 0 ? void 0 : options.sanitize) !== null &&
|
78 | _c !== void 0
|
79 | ? _c
|
80 | : exports.trim;
|
81 | this.filter =
|
82 | (_d = options === null || options === void 0 ? void 0 : options.filter) !== null &&
|
83 | _d !== void 0
|
84 | ? _d
|
85 | : exports.noFilter;
|
86 | this.keptSheet = (0, promise_1.keeper)(this.getSheet.bind(this));
|
87 | this.keptColumns = (0, promise_1.keeper)(this.getColumns.bind(this));
|
88 | if (options.preload) {
|
89 | this.refresh();
|
90 | }
|
91 | if (options.interval) {
|
92 | this.keepFresh(options.interval);
|
93 | }
|
94 | }
|
95 | async getSheet(range = this.range) {
|
96 |
|
97 | const client = await this.client;
|
98 | const response = await client.spreadsheets.values.get({
|
99 | spreadsheetId: this.spreadsheetId,
|
100 | range,
|
101 | });
|
102 | if (!response.data.values) {
|
103 | throw new Error('No data found.');
|
104 | }
|
105 | return response.data.values;
|
106 | }
|
107 | getHeaderRowsOnly() {
|
108 | return this.getSheet(`${this.range}!A${this.headerRows}:ZZZ${this.headerRows}`);
|
109 | }
|
110 | getColumnsFromSheetCache() {
|
111 | try {
|
112 | return this.keptSheet.stale();
|
113 | } catch (_a) {
|
114 | return this.getHeaderRowsOnly();
|
115 | }
|
116 | }
|
117 | async getColumns() {
|
118 | const rows = await this.getColumnsFromSheetCache();
|
119 | const columns = rows[this.headerRows - 1];
|
120 | if (!columns || !columns.length) {
|
121 | throw new Error(`Unable to turn rows into objects. Row at ${this.headerRows} is empty.`);
|
122 | }
|
123 | return columns.map(this.sanitize).map(this.keyTransform);
|
124 | }
|
125 | async columns() {
|
126 | return this.keptColumns.get();
|
127 | }
|
128 | async rows() {
|
129 | const rows = await this.keptSheet.get();
|
130 | return rows
|
131 | .slice(this.headerRows)
|
132 | .map((row) => row.map(this.sanitize))
|
133 | .filter(this.filter);
|
134 | }
|
135 | async data() {
|
136 |
|
137 |
|
138 |
|
139 | const rows = await this.rows();
|
140 | const keys = await this.columns();
|
141 | return rows
|
142 | .map((row) =>
|
143 | row.reduce((obj, value, index) => {
|
144 | if (keys[index]) {
|
145 |
|
146 | obj[keys[index]] = value;
|
147 | }
|
148 | return obj;
|
149 | }, {}))
|
150 | .filter(this.filter);
|
151 | }
|
152 | async normalizeInputData(arg) {
|
153 | if (Array.isArray(arg)) {
|
154 | return arg;
|
155 | }
|
156 |
|
157 | const entries = Object.entries(arg).map(([key, val]) => [key.toLowerCase(), val]);
|
158 | const columns = await this.columns();
|
159 | return columns
|
160 | .map((key) => (entries.find(([entryKey]) => entryKey === key.toLowerCase()) || [])[1])
|
161 | .map(this.sanitize);
|
162 | }
|
163 | async append(arg) {
|
164 | let _a; let
|
165 | _b;
|
166 | const row = await this.normalizeInputData(arg);
|
167 | if (!row) {
|
168 | throw new Error(`Unable to add ${arg}.`);
|
169 | }
|
170 | const client = await this.client;
|
171 | const response = await client.spreadsheets.values.append({
|
172 | spreadsheetId: this.spreadsheetId,
|
173 | range: this.range,
|
174 | insertDataOption: 'INSERT_ROWS',
|
175 | valueInputOption: 'USER_ENTERED',
|
176 | requestBody: { range: this.range, values: [row] },
|
177 | });
|
178 |
|
179 | this.keptSheet.fresh();
|
180 | if (
|
181 | !(
|
182 | ((_b =
|
183 | (_a = response === null || response === void 0 ? void 0 : response.data) === null ||
|
184 | _a === void 0
|
185 | ? void 0
|
186 | : _a.updates) === null || _b === void 0
|
187 | ? void 0
|
188 | : _b.updatedRows) > 0
|
189 | )
|
190 | ) {
|
191 | throw new Error('Failed to save your information. Please try again.');
|
192 | }
|
193 | return response;
|
194 | }
|
195 | refresh() {
|
196 | this.keptSheet.fresh();
|
197 | }
|
198 | keepFresh(interval) {
|
199 | this.keptSheet.start(interval);
|
200 | }
|
201 | }
|
202 | exports.Gsheet = Gsheet;
|
203 | const gsheet = (options) => {
|
204 | const instance = new Gsheet(options);
|
205 | instance.rows = instance.rows.bind(instance);
|
206 | instance.data = instance.data.bind(instance);
|
207 | instance.keepFresh = instance.keepFresh.bind(instance);
|
208 | instance.append = instance.append.bind(instance);
|
209 | instance.refresh = instance.refresh.bind(instance);
|
210 | return instance;
|
211 | };
|
212 | exports.gsheet = gsheet;
|
213 | exports.default = exports.gsheet;
|