@frogbotai/piece-google-sheets 0.21.0 → 0.23.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/dist/api.d.ts ADDED
@@ -0,0 +1,161 @@
1
+ import { z } from 'zod';
2
+ import { type SheetsArgs } from './shared.js';
3
+ declare const exportInput: z.ZodObject<{
4
+ spreadsheetId: z.ZodString;
5
+ sheetId: z.ZodNumber;
6
+ format: z.ZodDefault<z.ZodEnum<{
7
+ csv: "csv";
8
+ tsv: "tsv";
9
+ }>>;
10
+ returnAsText: z.ZodDefault<z.ZodBoolean>;
11
+ }, z.core.$strip>;
12
+ export declare const exportWorksheet: {
13
+ slug: "exportWorksheet";
14
+ description: string;
15
+ input: z.ZodObject<{
16
+ spreadsheetId: z.ZodString;
17
+ sheetId: z.ZodNumber;
18
+ format: z.ZodDefault<z.ZodEnum<{
19
+ csv: "csv";
20
+ tsv: "tsv";
21
+ }>>;
22
+ returnAsText: z.ZodDefault<z.ZodBoolean>;
23
+ }, z.core.$strip>;
24
+ output: z.ZodUnion<readonly [z.ZodObject<{
25
+ text: z.ZodString;
26
+ format: z.ZodEnum<{
27
+ csv: "csv";
28
+ tsv: "tsv";
29
+ }>;
30
+ }, z.core.$strip>, z.ZodObject<{
31
+ file: z.ZodObject<{
32
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
33
+ filename: z.ZodString;
34
+ url: z.ZodOptional<z.ZodString>;
35
+ }, z.core.$strip>;
36
+ format: z.ZodEnum<{
37
+ csv: "csv";
38
+ tsv: "tsv";
39
+ }>;
40
+ }, z.core.$strip>]>;
41
+ idempotent: boolean;
42
+ run({ client, req, input }: SheetsArgs<z.output<typeof exportInput>>): Promise<{
43
+ text: string;
44
+ format: "csv" | "tsv";
45
+ file?: undefined;
46
+ } | {
47
+ file: {
48
+ url?: string | undefined;
49
+ id: string | number;
50
+ filename: string;
51
+ };
52
+ format: "csv" | "tsv";
53
+ text?: undefined;
54
+ }>;
55
+ };
56
+ declare const customInput: z.ZodObject<{
57
+ method: z.ZodDefault<z.ZodEnum<{
58
+ GET: "GET";
59
+ POST: "POST";
60
+ PUT: "PUT";
61
+ PATCH: "PATCH";
62
+ DELETE: "DELETE";
63
+ HEAD: "HEAD";
64
+ }>>;
65
+ path: z.ZodString;
66
+ query: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
67
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
68
+ body: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
69
+ type: z.ZodLiteral<"json">;
70
+ value: z.ZodJSONSchema;
71
+ }, z.core.$strip>, z.ZodObject<{
72
+ type: z.ZodLiteral<"raw">;
73
+ value: z.ZodString;
74
+ }, z.core.$strip>, z.ZodObject<{
75
+ type: z.ZodLiteral<"form">;
76
+ fields: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
77
+ name: z.ZodString;
78
+ value: z.ZodString;
79
+ }, z.core.$strip>, z.ZodObject<{
80
+ name: z.ZodString;
81
+ file: z.ZodObject<{
82
+ fileId: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
83
+ name: z.ZodOptional<z.ZodString>;
84
+ }, z.core.$strip>;
85
+ }, z.core.$strip>]>>;
86
+ }, z.core.$strip>]>>;
87
+ binary: z.ZodDefault<z.ZodBoolean>;
88
+ filename: z.ZodDefault<z.ZodString>;
89
+ failOnError: z.ZodDefault<z.ZodBoolean>;
90
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
91
+ }, z.core.$strip>;
92
+ export declare const customApiCall: {
93
+ slug: "customApiCall";
94
+ description: string;
95
+ input: z.ZodObject<{
96
+ method: z.ZodDefault<z.ZodEnum<{
97
+ GET: "GET";
98
+ POST: "POST";
99
+ PUT: "PUT";
100
+ PATCH: "PATCH";
101
+ DELETE: "DELETE";
102
+ HEAD: "HEAD";
103
+ }>>;
104
+ path: z.ZodString;
105
+ query: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
106
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
107
+ body: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
108
+ type: z.ZodLiteral<"json">;
109
+ value: z.ZodJSONSchema;
110
+ }, z.core.$strip>, z.ZodObject<{
111
+ type: z.ZodLiteral<"raw">;
112
+ value: z.ZodString;
113
+ }, z.core.$strip>, z.ZodObject<{
114
+ type: z.ZodLiteral<"form">;
115
+ fields: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
116
+ name: z.ZodString;
117
+ value: z.ZodString;
118
+ }, z.core.$strip>, z.ZodObject<{
119
+ name: z.ZodString;
120
+ file: z.ZodObject<{
121
+ fileId: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
122
+ name: z.ZodOptional<z.ZodString>;
123
+ }, z.core.$strip>;
124
+ }, z.core.$strip>]>>;
125
+ }, z.core.$strip>]>>;
126
+ binary: z.ZodDefault<z.ZodBoolean>;
127
+ filename: z.ZodDefault<z.ZodString>;
128
+ failOnError: z.ZodDefault<z.ZodBoolean>;
129
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
130
+ }, z.core.$strip>;
131
+ output: z.ZodObject<{
132
+ status: z.ZodNumber;
133
+ headers: z.ZodRecord<z.ZodString, z.ZodString>;
134
+ body: z.ZodOptional<z.ZodJSONSchema>;
135
+ file: z.ZodOptional<z.ZodObject<{
136
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
137
+ filename: z.ZodString;
138
+ url: z.ZodOptional<z.ZodString>;
139
+ }, z.core.$strip>>;
140
+ }, z.core.$strip>;
141
+ idempotent: boolean;
142
+ run({ client, req, input }: SheetsArgs<z.output<typeof customInput>>): Promise<{
143
+ file: {
144
+ url?: string | undefined;
145
+ id: string | number;
146
+ filename: string;
147
+ };
148
+ status: number;
149
+ headers: {
150
+ [k: string]: string;
151
+ };
152
+ } | {
153
+ body: z.core.util.JSONType;
154
+ status: number;
155
+ headers: {
156
+ [k: string]: string;
157
+ };
158
+ }>;
159
+ };
160
+ export {};
161
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAA8B,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1E,QAAA,MAAM,WAAW;;;;;;;;iBAGf,CAAC;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCASQ,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;;;;;;;;;;;;;CAoD3E,CAAC;AAEF,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwBf,CAAC;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAWU,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;;;;;;;;;;;;;;;;;CA2E3E,CAAC"}
package/dist/api.js ADDED
@@ -0,0 +1,168 @@
1
+ import { z } from 'zod';
2
+ import { fileReference, loadFile, savedFile, saveFile } from './files.js';
3
+ import { requestOptions, sheetInput } from './shared.js';
4
+ const exportInput = sheetInput.extend({
5
+ format: z.enum(['csv', 'tsv']).default('csv'),
6
+ returnAsText: z.boolean().default(false),
7
+ });
8
+ export const exportWorksheet = {
9
+ slug: 'exportWorksheet',
10
+ description: 'Export the selected worksheet as formatted CSV or TSV text or a saved file.',
11
+ input: exportInput,
12
+ output: z.union([
13
+ z.object({ text: z.string(), format: z.enum(['csv', 'tsv']) }),
14
+ z.object({ file: savedFile, format: z.enum(['csv', 'tsv']) }),
15
+ ]),
16
+ idempotent: true,
17
+ async run({ client, req, input }) {
18
+ let url = new URL(`https://docs.google.com/spreadsheets/d/${encodeURIComponent(input.spreadsheetId)}/export`);
19
+ url.search = new URLSearchParams({
20
+ format: input.format,
21
+ id: input.spreadsheetId,
22
+ gid: String(input.sheetId),
23
+ }).toString();
24
+ for (let redirects = 0; redirects <= 5; redirects++) {
25
+ const options = {
26
+ ...requestOptions(req),
27
+ url: url.toString(),
28
+ method: 'GET',
29
+ responseType: 'arraybuffer',
30
+ redirect: 'manual',
31
+ validateStatus: (status) => status >= 200 && status < 400,
32
+ };
33
+ const response = url.origin === 'https://docs.google.com'
34
+ ? await client.auth.request(options)
35
+ : await client.auth.transporter.request(options);
36
+ if (response.status >= 300) {
37
+ const location = response.headers.get('location');
38
+ if (!location)
39
+ throw new Error('Worksheet export redirect is missing its destination.');
40
+ url = new URL(location, url);
41
+ if (url.protocol !== 'https:' ||
42
+ url.port ||
43
+ url.username ||
44
+ url.password ||
45
+ !(url.hostname === 'docs.google.com' || url.hostname.endsWith('.googleusercontent.com'))) {
46
+ throw new Error('Worksheet export redirected outside Google.');
47
+ }
48
+ continue;
49
+ }
50
+ const data = Buffer.from(response.data);
51
+ if (input.returnAsText)
52
+ return { text: data.toString('utf8'), format: input.format };
53
+ const name = `exported_sheet.${input.format}`;
54
+ return {
55
+ file: await saveFile({
56
+ req,
57
+ data,
58
+ name,
59
+ mimeType: input.format === 'csv' ? 'text/csv' : 'text/tab-separated-values',
60
+ }),
61
+ format: input.format,
62
+ };
63
+ }
64
+ throw new Error('Worksheet export exceeded the redirect limit.');
65
+ },
66
+ };
67
+ const customInput = z.object({
68
+ method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD']).default('GET'),
69
+ path: z.string().startsWith('/'),
70
+ query: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),
71
+ headers: z.record(z.string(), z.string()).optional(),
72
+ body: z
73
+ .union([
74
+ z.object({ type: z.literal('json'), value: z.json() }),
75
+ z.object({ type: z.literal('raw'), value: z.string() }),
76
+ z.object({
77
+ type: z.literal('form'),
78
+ fields: z.array(z.union([
79
+ z.object({ name: z.string(), value: z.string() }),
80
+ z.object({ name: z.string(), file: fileReference }),
81
+ ])),
82
+ }),
83
+ ])
84
+ .optional(),
85
+ binary: z.boolean().default(false),
86
+ filename: z.string().min(1).default('response.bin'),
87
+ failOnError: z.boolean().default(true),
88
+ timeoutMs: z.number().int().positive().max(300_000).default(30_000),
89
+ });
90
+ export const customApiCall = {
91
+ slug: 'customApiCall',
92
+ description: 'Call a Sheets v4 endpoint under /spreadsheets with redirects disabled.',
93
+ input: customInput,
94
+ output: z.object({
95
+ status: z.number().int(),
96
+ headers: z.record(z.string(), z.string()),
97
+ body: z.json().optional(),
98
+ file: savedFile.optional(),
99
+ }),
100
+ idempotent: false,
101
+ async run({ client, req, input }) {
102
+ const url = new URL(`https://sheets.googleapis.com/v4${input.path}`);
103
+ if (/[\\\r\n]/.test(input.path) ||
104
+ url.origin !== 'https://sheets.googleapis.com' ||
105
+ !/^\/v4\/spreadsheets(?:\/|$|:)/.test(url.pathname) ||
106
+ url.hash ||
107
+ url.username ||
108
+ url.password) {
109
+ throw new Error('Custom API paths must remain inside the Google Sheets v4 spreadsheets API.');
110
+ }
111
+ const headers = new Headers(input.headers);
112
+ for (const name of headers.keys()) {
113
+ if (['authorization', 'cookie', 'host', 'proxy-authorization', 'x-goog-api-key'].includes(name)) {
114
+ throw new Error(`Custom header '${name}' is reserved.`);
115
+ }
116
+ }
117
+ let data;
118
+ if (input.body?.type === 'form') {
119
+ const form = new FormData();
120
+ for (const field of input.body.fields) {
121
+ if ('value' in field)
122
+ form.append(field.name, field.value);
123
+ else {
124
+ const file = await loadFile({ req, file: field.file });
125
+ form.append(field.name, file.blob, file.name);
126
+ }
127
+ }
128
+ data = form;
129
+ }
130
+ else if (input.body) {
131
+ data = input.body.value === null ? 'null' : input.body.value;
132
+ if (input.body.type === 'json' && !headers.has('content-type')) {
133
+ headers.set('content-type', 'application/json');
134
+ }
135
+ }
136
+ const response = await client.auth.request({
137
+ ...requestOptions(req),
138
+ url: url.toString(),
139
+ method: input.method,
140
+ params: input.query,
141
+ headers,
142
+ data,
143
+ timeout: input.timeoutMs,
144
+ responseType: input.binary ? 'arraybuffer' : 'json',
145
+ validateStatus: (status) => input.failOnError ? status >= 200 && status < 300 : status < 300 || status >= 400,
146
+ });
147
+ const result = {
148
+ status: response.status,
149
+ headers: Object.fromEntries(response.headers.entries()),
150
+ };
151
+ if (input.binary) {
152
+ return {
153
+ ...result,
154
+ file: await saveFile({
155
+ req,
156
+ data: Buffer.from(response.data),
157
+ name: input.filename,
158
+ mimeType: response.headers.get('content-type') ?? 'application/octet-stream',
159
+ }),
160
+ };
161
+ }
162
+ return {
163
+ ...result,
164
+ body: response.data == null || response.data === '' ? null : z.json().parse(response.data),
165
+ };
166
+ },
167
+ };
168
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,UAAU,EAAmB,MAAM,aAAa,CAAC;AAE1E,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC;IACpC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IAC7C,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;CACzC,CAAC,CAAC;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,iBAA0B;IAChC,WAAW,EAAE,6EAA6E;IAC1F,KAAK,EAAE,WAAW;IAClB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC;QACd,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;QAC9D,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;KAC9D,CAAC;IACF,UAAU,EAAE,IAAI;IAChB,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAA4C;QACxE,IAAI,GAAG,GAAG,IAAI,GAAG,CACf,0CAA0C,kBAAkB,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,CAC3F,CAAC;QACF,GAAG,CAAC,MAAM,GAAG,IAAI,eAAe,CAAC;YAC/B,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,EAAE,EAAE,KAAK,CAAC,aAAa;YACvB,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;SAC3B,CAAC,CAAC,QAAQ,EAAE,CAAC;QACd,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC;YACpD,MAAM,OAAO,GAAG;gBACd,GAAG,cAAc,CAAC,GAAG,CAAC;gBACtB,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE;gBACnB,MAAM,EAAE,KAAc;gBACtB,YAAY,EAAE,aAAsB;gBACpC,QAAQ,EAAE,QAAiB;gBAC3B,cAAc,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG;aAClE,CAAC;YACF,MAAM,QAAQ,GACZ,GAAG,CAAC,MAAM,KAAK,yBAAyB;gBACtC,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAc,OAAO,CAAC;gBACjD,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAc,OAAO,CAAC,CAAC;YAClE,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;gBAC3B,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBAClD,IAAI,CAAC,QAAQ;oBAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;gBACxF,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;gBAC7B,IACE,GAAG,CAAC,QAAQ,KAAK,QAAQ;oBACzB,GAAG,CAAC,IAAI;oBACR,GAAG,CAAC,QAAQ;oBACZ,GAAG,CAAC,QAAQ;oBACZ,CAAC,CAAC,GAAG,CAAC,QAAQ,KAAK,iBAAiB,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC,EACxF,CAAC;oBACD,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;gBACjE,CAAC;gBACD,SAAS;YACX,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,KAAK,CAAC,YAAY;gBAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;YACrF,MAAM,IAAI,GAAG,kBAAkB,KAAK,CAAC,MAAM,EAAE,CAAC;YAC9C,OAAO;gBACL,IAAI,EAAE,MAAM,QAAQ,CAAC;oBACnB,GAAG;oBACH,IAAI;oBACJ,IAAI;oBACJ,QAAQ,EAAE,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,2BAA2B;iBAC5E,CAAC;gBACF,MAAM,EAAE,KAAK,CAAC,MAAM;aACrB,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;CACF,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IAChF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;IAChC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACtF,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACpD,IAAI,EAAE,CAAC;SACJ,KAAK,CAAC;QACL,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACtD,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;QACvD,CAAC,CAAC,MAAM,CAAC;YACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;YACvB,MAAM,EAAE,CAAC,CAAC,KAAK,CACb,CAAC,CAAC,KAAK,CAAC;gBACN,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;gBACjD,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;aACpD,CAAC,CACH;SACF,CAAC;KACH,CAAC;SACD,QAAQ,EAAE;IACb,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAClC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC;IACnD,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACtC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;CACpE,CAAC,CAAC;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,eAAwB;IAC9B,WAAW,EAAE,wEAAwE;IACrF,KAAK,EAAE,WAAW;IAClB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;QACxB,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;QACzC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;QACzB,IAAI,EAAE,SAAS,CAAC,QAAQ,EAAE;KAC3B,CAAC;IACF,UAAU,EAAE,KAAK;IACjB,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAA4C;QACxE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,mCAAmC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACrE,IACE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAC3B,GAAG,CAAC,MAAM,KAAK,+BAA+B;YAC9C,CAAC,+BAA+B,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;YACnD,GAAG,CAAC,IAAI;YACR,GAAG,CAAC,QAAQ;YACZ,GAAG,CAAC,QAAQ,EACZ,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAC;QAChG,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YAClC,IACE,CAAC,eAAe,EAAE,QAAQ,EAAE,MAAM,EAAE,qBAAqB,EAAE,gBAAgB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC3F,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,gBAAgB,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;QAED,IAAI,IAAoD,CAAC;QACzD,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC5B,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACtC,IAAI,OAAO,IAAI,KAAK;oBAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;qBACtD,CAAC;oBACJ,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;oBACvD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChD,CAAC;YACH,CAAC;YACD,IAAI,GAAG,IAAI,CAAC;QACd,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACtB,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;YAC7D,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;gBAC/D,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;YACzC,GAAG,cAAc,CAAC,GAAG,CAAC;YACtB,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE;YACnB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,KAAK,CAAC,KAAK;YACnB,OAAO;YACP,IAAI;YACJ,OAAO,EAAE,KAAK,CAAC,SAAS;YACxB,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM;YACnD,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE,CACzB,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,IAAI,MAAM,IAAI,GAAG;SACpF,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG;YACb,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;SACxD,CAAC;QAEF,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO;gBACL,GAAG,MAAM;gBACT,IAAI,EAAE,MAAM,QAAQ,CAAC;oBACnB,GAAG;oBACH,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAmB,CAAC;oBAC/C,IAAI,EAAE,KAAK,CAAC,QAAQ;oBACpB,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,0BAA0B;iBAC7E,CAAC;aACH,CAAC;QACJ,CAAC;QAED,OAAO;YACL,GAAG,MAAM;YACT,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,IAAI,IAAI,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;SAC3F,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { type drive_v3, google, type sheets_v4 } from 'googleapis';
2
+ export type GoogleSheetsClient = {
3
+ auth: InstanceType<typeof google.auth.OAuth2>;
4
+ sheets: sheets_v4.Sheets;
5
+ drive: drive_v3.Drive;
6
+ };
7
+ export declare function createGoogleSheetsClient({ auth }: {
8
+ auth: unknown;
9
+ }): GoogleSheetsClient;
10
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAInE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,YAAY,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;IACzB,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC;CACvB,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG,kBAAkB,CASxF"}
package/dist/client.js ADDED
@@ -0,0 +1,13 @@
1
+ import { google } from 'googleapis';
2
+ import { googleSheetsAuth } from './config.js';
3
+ export function createGoogleSheetsClient({ auth }) {
4
+ const credential = googleSheetsAuth.parse(auth);
5
+ const oauth = new google.auth.OAuth2();
6
+ oauth.setCredentials({ access_token: credential.accessToken });
7
+ return {
8
+ auth: oauth,
9
+ sheets: google.sheets({ version: 'v4', auth: oauth, universeDomain: 'googleapis.com' }),
10
+ drive: google.drive({ version: 'v3', auth: oauth, universeDomain: 'googleapis.com' }),
11
+ };
12
+ }
13
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,MAAM,EAAkB,MAAM,YAAY,CAAC;AAEnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAQ/C,MAAM,UAAU,wBAAwB,CAAC,EAAE,IAAI,EAAqB;IAClE,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IACvC,KAAK,CAAC,cAAc,CAAC,EAAE,YAAY,EAAE,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/D,OAAO;QACL,IAAI,EAAE,KAAK;QACX,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAC;QACvF,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAC;KACtF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { z } from 'zod';
2
+ export declare const googleSheetsAuth: z.ZodObject<{
3
+ accessToken: z.ZodString;
4
+ refreshToken: z.ZodOptional<z.ZodString>;
5
+ }, z.core.$strip>;
6
+ export declare const googleSheetsScopes: readonly ["https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/drive.readonly", "https://www.googleapis.com/auth/drive"];
7
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gBAAgB;;;iBAG3B,CAAC;AAEH,eAAO,MAAM,kBAAkB,sJAIrB,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,11 @@
1
+ import { z } from 'zod';
2
+ export const googleSheetsAuth = z.object({
3
+ accessToken: z.string().min(1).meta({ label: 'Access token', secret: true }),
4
+ refreshToken: z.string().optional().meta({ label: 'Refresh token', secret: true }),
5
+ });
6
+ export const googleSheetsScopes = [
7
+ 'https://www.googleapis.com/auth/spreadsheets',
8
+ 'https://www.googleapis.com/auth/drive.readonly',
9
+ 'https://www.googleapis.com/auth/drive',
10
+ ];
11
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC5E,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;CACnF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,8CAA8C;IAC9C,gDAAgD;IAChD,uCAAuC;CAC/B,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { FrogbotRequest } from 'frogbot';
2
+ import { z } from 'zod';
3
+ export declare const fileReference: z.ZodObject<{
4
+ fileId: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
5
+ name: z.ZodOptional<z.ZodString>;
6
+ }, z.core.$strip>;
7
+ export declare const savedFile: z.ZodObject<{
8
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
9
+ filename: z.ZodString;
10
+ url: z.ZodOptional<z.ZodString>;
11
+ }, z.core.$strip>;
12
+ export declare function loadFile({ req, file, }: {
13
+ req: FrogbotRequest;
14
+ file: z.output<typeof fileReference>;
15
+ }): Promise<{
16
+ name: string;
17
+ blob: Blob;
18
+ }>;
19
+ export declare function saveFile({ req, data, name, mimeType, }: {
20
+ req: FrogbotRequest;
21
+ data: Buffer;
22
+ name: string;
23
+ mimeType: string;
24
+ }): Promise<{
25
+ url?: string | undefined;
26
+ id: string | number;
27
+ filename: string;
28
+ }>;
29
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,aAAa;;;iBAGxB,CAAC;AACH,eAAO,MAAM,SAAS;;;;iBAIpB,CAAC;AAEH,wBAAsB,QAAQ,CAAC,EAC7B,GAAG,EACH,IAAI,GACL,EAAE;IACD,GAAG,EAAE,cAAc,CAAC;IACpB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;CACtC;;;GAsCA;AAED,wBAAsB,QAAQ,CAAC,EAC7B,GAAG,EACH,IAAI,EACJ,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,GAAG,EAAE,cAAc,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;;;;GAcA"}
package/dist/files.js ADDED
@@ -0,0 +1,68 @@
1
+ import { z } from 'zod';
2
+ export const fileReference = z.object({
3
+ fileId: z.union([z.string(), z.number()]),
4
+ name: z.string().optional(),
5
+ });
6
+ export const savedFile = z.object({
7
+ id: z.union([z.string(), z.number()]),
8
+ filename: z.string(),
9
+ url: z.string().optional(),
10
+ });
11
+ export async function loadFile({ req, file, }) {
12
+ const collection = req.frogbot.config.files?.slug;
13
+ if (!collection) {
14
+ throw new Error('Google Sheets file uploads require a configured files collection.');
15
+ }
16
+ const doc = await req.frogbot.findByID({
17
+ collection,
18
+ id: file.fileId,
19
+ depth: 0,
20
+ req,
21
+ overrideAccess: false,
22
+ });
23
+ if (typeof doc.url !== 'string')
24
+ throw new Error(`File '${file.fileId}' is unavailable.`);
25
+ const config = await req.frogbot.config._internal.payloadConfig;
26
+ const base = new URL(config.serverURL || req.url);
27
+ const url = new URL(doc.url, base);
28
+ if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password) {
29
+ throw new Error('Invalid file URL.');
30
+ }
31
+ const headers = new Headers();
32
+ if (url.origin === base.origin) {
33
+ for (const name of ['authorization', 'cookie']) {
34
+ const value = req.headers.get(name);
35
+ if (value)
36
+ headers.set(name, value);
37
+ }
38
+ }
39
+ const response = await fetch(url, {
40
+ headers,
41
+ signal: req.signal ?? undefined,
42
+ redirect: 'error',
43
+ });
44
+ if (!response.ok)
45
+ throw new Error(`File '${file.fileId}' is unavailable (${response.status}).`);
46
+ return {
47
+ name: String(file.name ?? doc.filename ?? 'upload'),
48
+ blob: new Blob([await response.arrayBuffer()], {
49
+ type: String(doc.mimeType ?? 'application/octet-stream'),
50
+ }),
51
+ };
52
+ }
53
+ export async function saveFile({ req, data, name, mimeType, }) {
54
+ const collection = req.frogbot.config.files?.slug;
55
+ if (!collection) {
56
+ throw new Error('Google Sheets file downloads require a configured files collection.');
57
+ }
58
+ req.signal?.throwIfAborted();
59
+ const doc = await req.frogbot.create({
60
+ collection,
61
+ data: {},
62
+ req,
63
+ overrideAccess: false,
64
+ file: { data, name, mimetype: mimeType, size: data.length },
65
+ });
66
+ return { id: doc.id, filename: name, ...(typeof doc.url === 'string' ? { url: doc.url } : {}) };
67
+ }
68
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"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"}