@mcpher/gas-fakes 2.3.14 → 2.3.16
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/README.md +11 -5
- package/gf_agent/README.md +101 -0
- package/gf_agent/SKILL.md +397 -0
- package/gf_agent/documentation.md +105 -0
- package/gf_agent/gf-agent-contributor/SKILL.md +56 -0
- package/gf_agent/index.md +21 -0
- package/gf_agent/knowledge/00-execution-context.md +4 -0
- package/gf_agent/knowledge/01-drive.md +12 -0
- package/gf_agent/knowledge/02-syntax.md +13 -0
- package/gf_agent/knowledge/03-auth.md +15 -0
- package/gf_agent/knowledge/04-advanced.md +24 -0
- package/gf_agent/knowledge/05-sheets-forms.md +25 -0
- package/gf_agent/knowledge/06-jdbc-cloudsql.md +21 -0
- package/gf_agent/knowledge/07-jdbc-auth-details.md +30 -0
- package/gf_agent/knowledge/08-docs-limitations.md +4 -0
- package/gf_agent/knowledge/09-orchestrator-pattern.md +54 -0
- package/gf_agent/knowledge/10-sandbox-security.md +62 -0
- package/gf_agent/knowledge/11-chart-builder-limitations.md +15 -0
- package/gf_agent/knowledge/12-gmail-eventual-consistency.md +13 -0
- package/gf_agent/knowledge/README.md +16 -0
- package/gf_agent/scripts/SKILL.template.md +65 -0
- package/gf_agent/skills/base.md +156 -0
- package/gf_agent/skills/cache.md +20 -0
- package/gf_agent/skills/calendar.md +780 -0
- package/gf_agent/skills/charts.md +127 -0
- package/gf_agent/skills/document.md +6752 -0
- package/gf_agent/skills/drive.md +423 -0
- package/gf_agent/skills/forms.md +4036 -0
- package/gf_agent/skills/gmail.md +576 -0
- package/gf_agent/skills/jdbc.md +3101 -0
- package/gf_agent/skills/lock.md +20 -0
- package/gf_agent/skills/properties.md +19 -0
- package/gf_agent/skills/script.md +50 -0
- package/gf_agent/skills/slides.md +5054 -0
- package/gf_agent/skills/spreadsheet.md +56075 -0
- package/gf_agent/skills/urlfetch.md +28 -0
- package/gf_agent/skills/utilities.md +33 -0
- package/gf_agent/skills/xml.md +270 -0
- package/package.json +1 -1
- package/src/cli/mcp.js +82 -67
- package/src/services/advgmail/fakeadvgmailmessages.js +85 -3
- package/src/services/documentapp/fakecontainerelement.js +88 -0
- package/src/services/driveapp/fakedrivemeta.js +1 -1
- package/src/services/gmailapp/fakegmailapp.js +217 -1
- package/src/services/gmailapp/fakegmailattachment.js +5 -0
- package/src/services/gmailapp/fakegmaildraft.js +32 -4
- package/src/services/gmailapp/fakegmaillabel.js +45 -0
- package/src/services/gmailapp/fakegmailmessage.js +212 -9
- package/src/services/gmailapp/fakegmailthread.js +151 -1
- package/src/services/slidesapp/fakecolorscheme.js +29 -10
- package/src/services/slidesapp/fakepresentation.js +0 -8
- package/src/services/spreadsheetapp/fakeembeddedchartbuilder.js +113 -28
- package/src/services/spreadsheetapp/fakespreadsheetapp.js +15 -1
- package/src/support/sxgmail.js +22 -2
- package/src/support/sxjdbc.js +16 -3
- package/src/support/utils.js +2 -2
- package/docs_discovery.json +0 -4939
- package/drive_tools.js +0 -20
|
@@ -167,7 +167,7 @@ class FakeGmailThread {
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
Gmail.Users.Threads.modify({ addLabelIds: [label.getId()] }, 'me', this.getId());
|
|
170
|
-
return this;
|
|
170
|
+
return this.refresh();
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
removeLabel(label) {
|
|
@@ -215,6 +215,156 @@ class FakeGmailThread {
|
|
|
215
215
|
}
|
|
216
216
|
}
|
|
217
217
|
Gmail.Users.Threads.modify({ removeLabelIds: [label.getId()] }, 'me', this.getId());
|
|
218
|
+
return this.refresh();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
__hasLabel(label) {
|
|
222
|
+
if (!this.__threadResource.messages) return false;
|
|
223
|
+
for (const m of this.__threadResource.messages) {
|
|
224
|
+
if (m.labelIds && m.labelIds.includes(label)) return true;
|
|
225
|
+
}
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
hasStarredMessages() {
|
|
230
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'hasStarredMessages');
|
|
231
|
+
return this.__hasLabel('STARRED');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
isImportant() {
|
|
235
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'isImportant');
|
|
236
|
+
return this.__hasLabel('IMPORTANT');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
isInChats() {
|
|
240
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'isInChats');
|
|
241
|
+
return this.__hasLabel('CHAT');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
isInInbox() {
|
|
245
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'isInInbox');
|
|
246
|
+
return this.__hasLabel('INBOX');
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
isInPriorityInbox() {
|
|
250
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'isInPriorityInbox');
|
|
251
|
+
return this.__hasLabel('INBOX') && this.__hasLabel('IMPORTANT');
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
isInSpam() {
|
|
255
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'isInSpam');
|
|
256
|
+
return this.__hasLabel('SPAM');
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
isInTrash() {
|
|
260
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'isInTrash');
|
|
261
|
+
return this.__hasLabel('TRASH');
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
isUnread() {
|
|
265
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'isUnread');
|
|
266
|
+
return this.__hasLabel('UNREAD');
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
getFirstMessageSubject() {
|
|
270
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'getFirstMessageSubject');
|
|
271
|
+
const msgs = this.getMessages();
|
|
272
|
+
return msgs.length > 0 ? msgs[0].getSubject() : '';
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
getLastMessageDate() {
|
|
276
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'getLastMessageDate');
|
|
277
|
+
const msgs = this.getMessages();
|
|
278
|
+
return msgs.length > 0 ? msgs[msgs.length - 1].getDate() : new Date();
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
getMessageCount() {
|
|
282
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'getMessageCount');
|
|
283
|
+
return this.getMessages().length;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
getPermalink() {
|
|
287
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'getPermalink');
|
|
288
|
+
return `https://mail.google.com/mail/u/0/#inbox/${this.getId()}`;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
refresh() {
|
|
292
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'refresh');
|
|
293
|
+
this.__threadResource = Gmail.Users.Threads.get('me', this.getId());
|
|
294
|
+
return this;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
markImportant() {
|
|
298
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'markImportant');
|
|
299
|
+
Gmail.Users.Threads.modify({ addLabelIds: ['IMPORTANT'] }, 'me', this.getId());
|
|
300
|
+
return this.refresh();
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
markRead() {
|
|
304
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'markRead');
|
|
305
|
+
Gmail.Users.Threads.modify({ removeLabelIds: ['UNREAD'] }, 'me', this.getId());
|
|
306
|
+
return this.refresh();
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
markUnimportant() {
|
|
310
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'markUnimportant');
|
|
311
|
+
Gmail.Users.Threads.modify({ removeLabelIds: ['IMPORTANT'] }, 'me', this.getId());
|
|
312
|
+
return this.refresh();
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
markUnread() {
|
|
316
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'markUnread');
|
|
317
|
+
Gmail.Users.Threads.modify({ addLabelIds: ['UNREAD'] }, 'me', this.getId());
|
|
318
|
+
return this.refresh();
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
moveToArchive() {
|
|
322
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'moveToArchive');
|
|
323
|
+
Gmail.Users.Threads.modify({ removeLabelIds: ['INBOX'] }, 'me', this.getId());
|
|
324
|
+
return this.refresh();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
moveToInbox() {
|
|
328
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'moveToInbox');
|
|
329
|
+
Gmail.Users.Threads.modify({ addLabelIds: ['INBOX'] }, 'me', this.getId());
|
|
330
|
+
return this.refresh();
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
moveToSpam() {
|
|
334
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'moveToSpam');
|
|
335
|
+
Gmail.Users.Threads.modify({ addLabelIds: ['SPAM'] }, 'me', this.getId());
|
|
336
|
+
return this.refresh();
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
moveToTrash() {
|
|
340
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'moveToTrash');
|
|
341
|
+
Gmail.Users.Threads.trash('me', this.getId());
|
|
342
|
+
return this.refresh();
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
createDraftReply(body, options) {
|
|
346
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'createDraftReply');
|
|
347
|
+
const msgs = this.getMessages();
|
|
348
|
+
return msgs.length > 0 ? msgs[msgs.length - 1].createDraftReply(body, options) : null;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
createDraftReplyAll(body, options) {
|
|
352
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'createDraftReplyAll');
|
|
353
|
+
const msgs = this.getMessages();
|
|
354
|
+
return msgs.length > 0 ? msgs[msgs.length - 1].createDraftReplyAll(body, options) : null;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
reply(body, options) {
|
|
358
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'reply');
|
|
359
|
+
const msgs = this.getMessages();
|
|
360
|
+
if (msgs.length > 0) msgs[msgs.length - 1].reply(body, options);
|
|
361
|
+
return this;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
replyAll(body, options) {
|
|
365
|
+
ScriptApp.__behavior.checkMethod('GmailThread', 'replyAll');
|
|
366
|
+
const msgs = this.getMessages();
|
|
367
|
+
if (msgs.length > 0) msgs[msgs.length - 1].replyAll(body, options);
|
|
218
368
|
return this;
|
|
219
369
|
}
|
|
220
370
|
|
|
@@ -81,9 +81,9 @@ export class FakeColorScheme {
|
|
|
81
81
|
* @param {FakeColor} color
|
|
82
82
|
* @returns {FakeColorScheme} self
|
|
83
83
|
*/
|
|
84
|
-
setConcreteColor(themeColorType,
|
|
84
|
+
setConcreteColor(themeColorType, ...colorArgs) {
|
|
85
85
|
const { nargs, matchThrow } = signatureArgs(arguments, "ColorScheme.setConcreteColor");
|
|
86
|
-
if (nargs
|
|
86
|
+
if (nargs < 2 || nargs > 4) matchThrow();
|
|
87
87
|
|
|
88
88
|
const master = this.__masterPage;
|
|
89
89
|
if (!master) throw new Error('Could not find master page for color scheme');
|
|
@@ -96,15 +96,34 @@ export class FakeColorScheme {
|
|
|
96
96
|
const currentResource = this.__resource;
|
|
97
97
|
const colors = [...(currentResource.colors || [])];
|
|
98
98
|
|
|
99
|
-
// Convert the new Color to API format
|
|
100
99
|
const apiColor = {};
|
|
101
|
-
if (
|
|
102
|
-
|
|
103
|
-
apiColor.red =
|
|
104
|
-
apiColor.green =
|
|
105
|
-
apiColor.blue =
|
|
106
|
-
} else if (
|
|
107
|
-
|
|
100
|
+
if (colorArgs.length === 3) {
|
|
101
|
+
// (ThemeColorType, r, g, b)
|
|
102
|
+
apiColor.red = colorArgs[0] / 255;
|
|
103
|
+
apiColor.green = colorArgs[1] / 255;
|
|
104
|
+
apiColor.blue = colorArgs[2] / 255;
|
|
105
|
+
} else if (typeof colorArgs[0] === 'string') {
|
|
106
|
+
// (ThemeColorType, hexString)
|
|
107
|
+
const hex = colorArgs[0];
|
|
108
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
109
|
+
if (result) {
|
|
110
|
+
apiColor.red = parseInt(result[1], 16) / 255;
|
|
111
|
+
apiColor.green = parseInt(result[2], 16) / 255;
|
|
112
|
+
apiColor.blue = parseInt(result[3], 16) / 255;
|
|
113
|
+
} else {
|
|
114
|
+
throw new Error("Invalid hex color string");
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
// (ThemeColorType, Color)
|
|
118
|
+
const color = colorArgs[0];
|
|
119
|
+
if (color.getColorType().toString() === 'RGB') {
|
|
120
|
+
const rgb = color.asRgbColor();
|
|
121
|
+
apiColor.red = rgb.getRed() / 255;
|
|
122
|
+
apiColor.green = rgb.getGreen() / 255;
|
|
123
|
+
apiColor.blue = rgb.getBlue() / 255;
|
|
124
|
+
} else if (color.getColorType().toString() === 'THEME') {
|
|
125
|
+
apiColor.themeColor = color.asThemeColor().getThemeColorType().toString();
|
|
126
|
+
}
|
|
108
127
|
}
|
|
109
128
|
|
|
110
129
|
// Find and update or add the color pair
|
|
@@ -52,14 +52,6 @@ export class FakePresentation {
|
|
|
52
52
|
return `https://docs.google.com/presentation/d/${this.getId()}/edit`;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
/**
|
|
56
|
-
* Gets the color scheme of the presentation.
|
|
57
|
-
* @returns {FakeColorScheme} The color scheme.
|
|
58
|
-
*/
|
|
59
|
-
getColorScheme() {
|
|
60
|
-
return newFakeColorScheme(this);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
55
|
/**
|
|
64
56
|
* Gets the masters in the presentation.
|
|
65
57
|
* @returns {FakeMaster[]} The masters.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Proxies } from "../../support/proxies.js";
|
|
2
|
-
import { signatureArgs } from "../../support/helpers.js";
|
|
2
|
+
import { signatureArgs, notYetImplemented } from "../../support/helpers.js";
|
|
3
3
|
import { Utils } from "../../support/utils.js";
|
|
4
4
|
import { makeSheetsGridRange } from "./sheetrangehelpers.js";
|
|
5
5
|
import { newFakeEmbeddedChart } from "./fakeembeddedchart.js";
|
|
@@ -155,6 +155,25 @@ export class FakeEmbeddedChartBuilder {
|
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
+
// Apply colors to series
|
|
159
|
+
if (this.__colors && basic && basic.series) {
|
|
160
|
+
basic.series.forEach((s, i) => {
|
|
161
|
+
if (this.__colors[i]) {
|
|
162
|
+
const hex = this.__colors[i];
|
|
163
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
164
|
+
if (result) {
|
|
165
|
+
s.colorStyle = {
|
|
166
|
+
rgbColor: {
|
|
167
|
+
red: parseInt(result[1], 16) / 255,
|
|
168
|
+
green: parseInt(result[2], 16) / 255,
|
|
169
|
+
blue: parseInt(result[3], 16) / 255
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
158
177
|
// 2. Handle Specialized Spec Blocks
|
|
159
178
|
if (basic && basic.chartType === "PIE") {
|
|
160
179
|
spec.pieChart = {
|
|
@@ -233,43 +252,109 @@ export class FakeEmbeddedChartBuilder {
|
|
|
233
252
|
setTransposeRowsAndColumns(transpose) { return this; }
|
|
234
253
|
|
|
235
254
|
// --- Chart Specific Builder Methods ---
|
|
236
|
-
|
|
255
|
+
__getAxis(position) {
|
|
256
|
+
if (!this.__apiChart.spec.basicChart) {
|
|
257
|
+
this.__apiChart.spec.basicChart = { axis: [], domains: [], series: [] };
|
|
258
|
+
}
|
|
259
|
+
if (!this.__apiChart.spec.basicChart.axis) {
|
|
260
|
+
this.__apiChart.spec.basicChart.axis = [];
|
|
261
|
+
}
|
|
262
|
+
let axis = this.__apiChart.spec.basicChart.axis.find(a => a.position === position);
|
|
263
|
+
if (!axis) {
|
|
264
|
+
axis = { position };
|
|
265
|
+
this.__apiChart.spec.basicChart.axis.push(axis);
|
|
266
|
+
}
|
|
267
|
+
return axis;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
reverseCategories() { notYetImplemented('reverseCategories'); return this; }
|
|
237
271
|
setBackgroundColor(color) { return this.setOption("backgroundColor", color); }
|
|
238
|
-
|
|
272
|
+
|
|
273
|
+
setColors(colors) {
|
|
274
|
+
ScriptApp.__behavior.checkMethod("EmbeddedChartBuilder", "setColors");
|
|
275
|
+
this.__colors = Array.isArray(colors) ? colors : [colors];
|
|
276
|
+
return this;
|
|
277
|
+
}
|
|
278
|
+
|
|
239
279
|
setLegendPosition(position) {
|
|
240
280
|
this.__apiChart.spec.basicChart.legendPosition = position ? position.toString() : "RIGHT_LEGEND";
|
|
241
281
|
return this;
|
|
242
282
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
283
|
+
|
|
284
|
+
setLegendTextStyle(textStyle) { notYetImplemented('setLegendTextStyle'); return this; }
|
|
285
|
+
setPointStyle(pointStyle) { notYetImplemented('setPointStyle'); return this; }
|
|
286
|
+
|
|
287
|
+
setRange(min, max) {
|
|
288
|
+
ScriptApp.__behavior.checkMethod("EmbeddedChartBuilder", "setRange");
|
|
289
|
+
const chartType = this.__apiChart.spec.basicChart ? this.__apiChart.spec.basicChart.chartType : null;
|
|
290
|
+
if (chartType === "BAR") {
|
|
291
|
+
return this.setXAxisRange(min, max);
|
|
292
|
+
}
|
|
293
|
+
return this.setYAxisRange(min, max);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
setStacked() {
|
|
297
|
+
ScriptApp.__behavior.checkMethod("EmbeddedChartBuilder", "setStacked");
|
|
298
|
+
if (this.__apiChart.spec.basicChart) {
|
|
299
|
+
this.__apiChart.spec.basicChart.stackedType = "STACKED";
|
|
300
|
+
}
|
|
301
|
+
return this;
|
|
302
|
+
}
|
|
303
|
+
|
|
247
304
|
setTitle(title) {
|
|
305
|
+
ScriptApp.__behavior.checkMethod("EmbeddedChartBuilder", "setTitle");
|
|
248
306
|
this.__apiChart.spec.title = title;
|
|
249
307
|
return this;
|
|
250
308
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
309
|
+
|
|
310
|
+
setTitleTextStyle(textStyle) { notYetImplemented('setTitleTextStyle'); return this; }
|
|
311
|
+
setXAxisTextStyle(textStyle) { notYetImplemented('setXAxisTextStyle'); return this; }
|
|
312
|
+
|
|
313
|
+
setXAxisTitle(title) {
|
|
314
|
+
ScriptApp.__behavior.checkMethod("EmbeddedChartBuilder", "setXAxisTitle");
|
|
315
|
+
this.__getAxis("BOTTOM_AXIS").title = title;
|
|
316
|
+
return this;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
setXAxisTitleTextStyle(textStyle) { notYetImplemented('setXAxisTitleTextStyle'); return this; }
|
|
320
|
+
setYAxisTextStyle(textStyle) { notYetImplemented('setYAxisTextStyle'); return this; }
|
|
321
|
+
|
|
322
|
+
setYAxisTitle(title) {
|
|
323
|
+
ScriptApp.__behavior.checkMethod("EmbeddedChartBuilder", "setYAxisTitle");
|
|
324
|
+
this.__getAxis("LEFT_AXIS").title = title;
|
|
325
|
+
return this;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
setYAxisTitleTextStyle(textStyle) { notYetImplemented('setYAxisTitleTextStyle'); return this; }
|
|
329
|
+
useLogScale() { notYetImplemented('useLogScale'); return this; }
|
|
259
330
|
set3D() { return this.setOption("is3D", true); }
|
|
260
|
-
enablePaging(enable, pageSize) { return this; }
|
|
261
|
-
enableRtlTable(enable) { return this; }
|
|
262
|
-
enableSorting(enable) { return this; }
|
|
263
|
-
setFirstRowNumber(number) { return this; }
|
|
264
|
-
setInitialSortingAscending(column) { return this; }
|
|
265
|
-
setInitialSortingDescending(column) { return this; }
|
|
266
|
-
showRowNumberColumn(show) { return this; }
|
|
267
|
-
useAlternatingRowStyle(use) { return this; }
|
|
268
|
-
setXAxisLogScale() { return this; }
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
331
|
+
enablePaging(enable, pageSize) { notYetImplemented('enablePaging'); return this; }
|
|
332
|
+
enableRtlTable(enable) { notYetImplemented('enableRtlTable'); return this; }
|
|
333
|
+
enableSorting(enable) { notYetImplemented('enableSorting'); return this; }
|
|
334
|
+
setFirstRowNumber(number) { notYetImplemented('setFirstRowNumber'); return this; }
|
|
335
|
+
setInitialSortingAscending(column) { notYetImplemented('setInitialSortingAscending'); return this; }
|
|
336
|
+
setInitialSortingDescending(column) { notYetImplemented('setInitialSortingDescending'); return this; }
|
|
337
|
+
showRowNumberColumn(show) { notYetImplemented('showRowNumberColumn'); return this; }
|
|
338
|
+
useAlternatingRowStyle(use) { notYetImplemented('useAlternatingRowStyle'); return this; }
|
|
339
|
+
setXAxisLogScale() { notYetImplemented('setXAxisLogScale'); return this; }
|
|
340
|
+
|
|
341
|
+
setXAxisRange(min, max) {
|
|
342
|
+
ScriptApp.__behavior.checkMethod("EmbeddedChartBuilder", "setXAxisRange");
|
|
343
|
+
const axis = this.__getAxis("BOTTOM_AXIS");
|
|
344
|
+
axis.viewWindowOptions = { viewWindowMin: min, viewWindowMax: max };
|
|
345
|
+
return this;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
setYAxisLogScale() { notYetImplemented('setYAxisLogScale'); return this; }
|
|
349
|
+
|
|
350
|
+
setYAxisRange(min, max) {
|
|
351
|
+
ScriptApp.__behavior.checkMethod("EmbeddedChartBuilder", "setYAxisRange");
|
|
352
|
+
const axis = this.__getAxis("LEFT_AXIS");
|
|
353
|
+
axis.viewWindowOptions = { viewWindowMin: min, viewWindowMax: max };
|
|
354
|
+
return this;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
reverseDirection() { notYetImplemented('reverseDirection'); return this; }
|
|
273
358
|
|
|
274
359
|
toString() {
|
|
275
360
|
const type = this.__apiChart.spec.basicChart?.chartType;
|
|
@@ -91,7 +91,6 @@ export class FakeSpreadsheetApp {
|
|
|
91
91
|
"setActiveRange",
|
|
92
92
|
"setActiveRangeList",
|
|
93
93
|
"getUi",
|
|
94
|
-
"open",
|
|
95
94
|
|
|
96
95
|
"ChartAggregationType",
|
|
97
96
|
"ChartTransformationType",
|
|
@@ -106,6 +105,21 @@ export class FakeSpreadsheetApp {
|
|
|
106
105
|
toString() {
|
|
107
106
|
return "SpreadsheetApp";
|
|
108
107
|
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Opens the spreadsheet that corresponds to the given File object.
|
|
111
|
+
* @param {File} file A Drive file object representing a spreadsheet.
|
|
112
|
+
* @returns {FakeSpreadsheet} the spreadsheet
|
|
113
|
+
*/
|
|
114
|
+
open(file) {
|
|
115
|
+
const { nargs, matchThrow } = signatureArgs(arguments, "SpreadsheetApp.open");
|
|
116
|
+
if (nargs !== 1) matchThrow();
|
|
117
|
+
if (!file || typeof file.getId !== 'function') {
|
|
118
|
+
throw new Error('Invalid file object');
|
|
119
|
+
}
|
|
120
|
+
return this.openById(file.getId());
|
|
121
|
+
}
|
|
122
|
+
|
|
109
123
|
getActiveSpreadsheet() {
|
|
110
124
|
if (this.__activeSpreadsheet) return this.__activeSpreadsheet;
|
|
111
125
|
// because this is a faked container bound app, we need to get the documentId from the config file
|
package/src/support/sxgmail.js
CHANGED
|
@@ -16,8 +16,28 @@ export const sxGmail = async (Auth, { subProp, prop, method, params, options })
|
|
|
16
16
|
const tag = `sxGmail for ${methodName}`;
|
|
17
17
|
|
|
18
18
|
return sxRetry(Auth, tag, async () => {
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
let context = subProp ? apiClient[prop][subProp] : apiClient[prop];
|
|
20
|
+
let methodFunc = context[method];
|
|
21
|
+
|
|
22
|
+
if (!methodFunc && method.includes('.')) {
|
|
23
|
+
const parts = method.split('.');
|
|
24
|
+
for (const part of parts) {
|
|
25
|
+
if (!context[part]) {
|
|
26
|
+
methodFunc = undefined;
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
methodFunc = context[part];
|
|
30
|
+
if (part !== parts[parts.length - 1]) {
|
|
31
|
+
context = methodFunc;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (typeof methodFunc !== 'function') {
|
|
37
|
+
throw new Error(`Method ${methodName} not found on Gmail API client`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return methodFunc.call(context, params, options);
|
|
21
41
|
}, {
|
|
22
42
|
skipLog: (error, response) => {
|
|
23
43
|
// Don't log 404, 409, or 400 as an error.
|
package/src/support/sxjdbc.js
CHANGED
|
@@ -50,11 +50,24 @@ export const sxJdbcConnect = async (Auth, { url, user, password }) => {
|
|
|
50
50
|
ssl: disableSsl ? false : { rejectUnauthorized: false }
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
let finalUser = user;
|
|
54
|
+
let finalPassword = password;
|
|
55
|
+
|
|
56
|
+
if ((user === null || typeof user === 'undefined') && (password === null || typeof password === 'undefined')) {
|
|
57
|
+
try {
|
|
58
|
+
const parsedUrl = new URL(pgConnectionString);
|
|
59
|
+
if (parsedUrl.username) finalUser = decodeURIComponent(parsedUrl.username);
|
|
60
|
+
if (parsedUrl.password) finalPassword = decodeURIComponent(parsedUrl.password);
|
|
61
|
+
} catch (e) {
|
|
62
|
+
// ignore parsing errors
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (finalUser !== null && typeof finalUser !== 'undefined' && finalPassword !== null && typeof finalPassword !== 'undefined') {
|
|
54
67
|
client = new pg.Client({
|
|
55
68
|
...clientConfig,
|
|
56
|
-
user: String(
|
|
57
|
-
password: String(
|
|
69
|
+
user: String(finalUser),
|
|
70
|
+
password: String(finalPassword)
|
|
58
71
|
});
|
|
59
72
|
} else {
|
|
60
73
|
client = new pg.Client(clientConfig);
|
package/src/support/utils.js
CHANGED
|
@@ -363,11 +363,11 @@ const normalizeColorStringToHex = (color) => {
|
|
|
363
363
|
if (!is.string(color)) return null;
|
|
364
364
|
const lowerColor = color.toLowerCase().replace(/\s/g, '');
|
|
365
365
|
if (colorNameToHex[lowerColor]) {
|
|
366
|
-
return colorNameToHex[lowerColor];
|
|
366
|
+
return colorNameToHex[lowerColor].toUpperCase();
|
|
367
367
|
}
|
|
368
368
|
// Check if it's a valid hex string
|
|
369
369
|
if (/^#[0-9a-f]{6}$/i.test(lowerColor)) {
|
|
370
|
-
return lowerColor;
|
|
370
|
+
return lowerColor.toUpperCase();
|
|
371
371
|
}
|
|
372
372
|
return null; // Invalid color string
|
|
373
373
|
};
|