@mcpher/gas-fakes 1.0.19 → 1.0.21

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.
Files changed (72) hide show
  1. package/README.md +63 -30
  2. package/gasmess/bruce/pbx.js +53 -2
  3. package/gprompts/gas-inventory.js +92 -0
  4. package/gprompts/gas-inventory.json +176 -0
  5. package/gprompts/inventory-list.json +1 -0
  6. package/gprompts/model.json +34 -0
  7. package/gprompts/package-lock.json +1103 -0
  8. package/gprompts/package.json +18 -0
  9. package/gprompts/temp_fetch.mjs +9 -0
  10. package/gprompts/update-progress.js +142 -0
  11. package/package.json +6 -2
  12. package/setup.sh +147 -0
  13. package/src/index.js +9 -2
  14. package/src/services/advdocs/app.js +4 -23
  15. package/src/services/advdrive/app.js +6 -28
  16. package/src/services/advforms/app.js +6 -25
  17. package/src/services/advgmail/app.js +11 -0
  18. package/src/services/advgmail/fakeadvgmail.js +39 -0
  19. package/src/services/advgmail/fakeadvgmaillabels.js +119 -0
  20. package/src/services/advgmail/fakeadvgmailusers.js +23 -0
  21. package/src/services/advgmail/gmailapis.js +15 -0
  22. package/src/services/advsheets/app.js +6 -26
  23. package/src/services/advslides/app.js +6 -28
  24. package/src/services/common/lazyloader.js +22 -0
  25. package/src/services/documentapp/app.js +8 -42
  26. package/src/services/documentapp/appenderhelpers.js +21 -23
  27. package/src/services/documentapp/elementhelpers.js +0 -1
  28. package/src/services/documentapp/elementoptions.js +22 -32
  29. package/src/services/documentapp/fakeelement.js +20 -3
  30. package/src/services/documentapp/fakelistitem.js +177 -28
  31. package/src/services/documentapp/fakeparagraph.js +194 -7
  32. package/src/services/documentapp/faketable.js +16 -0
  33. package/src/services/documentapp/faketablerow.js +15 -0
  34. package/src/services/documentapp/nrhelpers.js +1 -0
  35. package/src/services/documentapp/shadowdocument.js +10 -0
  36. package/src/services/driveapp/app.js +6 -28
  37. package/src/services/enums/gmailenums.js +8 -0
  38. package/src/services/formapp/app.js +5 -40
  39. package/src/services/gmailapp/app.js +11 -0
  40. package/src/services/gmailapp/fakegmailapp.js +35 -0
  41. package/src/services/gmailapp/fakegmaillabel.js +44 -0
  42. package/src/services/logger/app.js +8 -0
  43. package/src/services/logger/fakelogger.js +162 -0
  44. package/src/services/scriptapp/app.js +7 -1
  45. package/src/services/scriptapp/behavior.js +1 -1
  46. package/src/services/session/app.js +10 -0
  47. package/src/services/slidesapp/app.js +5 -40
  48. package/src/services/spreadsheetapp/app.js +6 -50
  49. package/src/services/spreadsheetapp/fakeprotection.js +6 -7
  50. package/src/services/spreadsheetapp/fakesheet.js +3 -4
  51. package/src/services/stores/app.js +0 -1
  52. package/src/services/urlfetchapp/app.js +0 -1
  53. package/src/services/utilities/app.js +6 -20
  54. package/src/support/gmailcacher.js +7 -0
  55. package/src/support/helpers.js +2 -2
  56. package/src/support/proxies.js +20 -1
  57. package/src/support/sxgmail.js +55 -0
  58. package/src/support/syncit.js +5 -2
  59. package/src/support/utils.js +46 -15
  60. package/src/support/workersync/sxfunctions.js +5 -10
  61. package/togas.bash +18 -5
  62. package/ghissues/image-size-inconsistency-issue.sh +0 -46
  63. package/ghissues/issue-formapp-create-title-inconsistency.sh +0 -51
  64. package/ghissues/issue-positioned-image.sh +0 -25
  65. package/ghissues/post-issue.sh +0 -53
  66. package/ghissues/protection-editors-issue.sh +0 -33
  67. package/ghissues/review-sandbox-listing-issue.sh +0 -45
  68. package/ghissues/sandbox-issue.sh +0 -31
  69. package/ghissues/setup-under-construction.sh +0 -107
  70. package/src/services/base/app.js +0 -33
  71. /package/{regenerate-progress-reports.sh → gprompts/regenerate-progress-reports.sh} +0 -0
  72. /package/src/services/{base → session}/fakesession.js +0 -0
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "gas-inventory",
3
+ "version": "1.0.0",
4
+ "description": "Scrapes Google Apps Script documentation",
5
+ "main": "gas-inventory.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "start": "node gas-inventory.js"
9
+ },
10
+ "keywords": [],
11
+ "author": "",
12
+ "license": "ISC",
13
+ "dependencies": {
14
+ "cheerio": "^1.1.2",
15
+ "jsdom": "^24.0.0",
16
+ "node-fetch": "^3.3.2"
17
+ }
18
+ }
@@ -0,0 +1,9 @@
1
+ import got from 'got';
2
+
3
+ const url = 'https://developers.google.com/apps-script/reference/document';
4
+
5
+ got(url).then(response => {
6
+ console.log(response.body);
7
+ }).catch(err => {
8
+ console.error(err);
9
+ });
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { promises as fs } from 'fs';
4
+ import path from 'path';
5
+ import { fileURLToPath } from 'url';
6
+
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = path.dirname(__filename);
10
+ const progressDir = path.join(__dirname, '..', 'progress');
11
+ const overallMdPath = path.join(progressDir, 'overall.md');
12
+
13
+ /**
14
+ * Calculates a percentage and formats it as a string.
15
+ * @param {number} completed - The number of completed items.
16
+ * @param {number} total - The total number of items.
17
+ * @returns {string} The formatted percentage string.
18
+ */
19
+ const formatPercent = (completed, total) => {
20
+ if (total === 0) {
21
+ return '0%';
22
+ }
23
+ return `${Math.round((completed / total) * 100)}%`;
24
+ };
25
+
26
+ /**
27
+ * Parses a single markdown progress file to count classes and methods.
28
+ * @param {string} filePath - The path to the markdown file.
29
+ * @returns {Promise<{totalClasses: number, completedClasses: number, totalMethods: number, completedMethods: number}>}
30
+ */
31
+ async function parseProgressFile(filePath) {
32
+ const content = await fs.readFile(filePath, 'utf-8');
33
+ // Split the file into sections based on '## ' headings.
34
+ // The first element will be anything before the first class, which we ignore.
35
+ const classSections = content.split('\n## ').slice(1);
36
+
37
+ if (classSections.length === 0) {
38
+ return { totalClasses: 0, completedClasses: 0, totalMethods: 0, completedMethods: 0 };
39
+ }
40
+
41
+ let totalClasses = 0;
42
+ let completedClasses = 0;
43
+ let totalMethods = 0;
44
+ let completedMethods = 0;
45
+ for (const classContent of classSections) {
46
+ totalClasses++;
47
+ const classLines = classContent.split('\n');
48
+ let statusColumnIndex = -1;
49
+ let classTotalMethods = 0;
50
+ let classCompletedMethods = 0;
51
+ let isTableBody = false;
52
+
53
+ for (const line of classLines) {
54
+ const trimmedLine = line.trim();
55
+
56
+ if (!trimmedLine.startsWith('|')) {
57
+ continue;
58
+ }
59
+
60
+ // Find the header row to locate the 'status' column.
61
+ if (statusColumnIndex === -1 && trimmedLine.toLowerCase().includes('status') && !trimmedLine.includes('---')) {
62
+ const headers = trimmedLine.split('|').map(h => h.trim().toLowerCase());
63
+ statusColumnIndex = headers.indexOf('status');
64
+ continue;
65
+ }
66
+
67
+ // The separator row marks the beginning of the table body.
68
+ if (trimmedLine.includes('---')) {
69
+ isTableBody = true;
70
+ continue;
71
+ }
72
+
73
+ // If we are in the table body and have a valid status column, count the method.
74
+ if (isTableBody && statusColumnIndex > -1) {
75
+ const columns = trimmedLine.split('|');
76
+ if (columns.length > statusColumnIndex) {
77
+ classTotalMethods++;
78
+ const statusCell = columns[statusColumnIndex].trim();
79
+ if (statusCell.toLowerCase().includes('completed')) {
80
+ classCompletedMethods++;
81
+ }
82
+ }
83
+ }
84
+ }
85
+ totalMethods += classTotalMethods;
86
+ completedMethods += classCompletedMethods;
87
+ if (classTotalMethods > 0 && classTotalMethods === classCompletedMethods) {
88
+ completedClasses++;
89
+ }
90
+ }
91
+
92
+ return { totalClasses, completedClasses, totalMethods, completedMethods };
93
+ }
94
+
95
+ /**
96
+ * Main function to generate the overall progress summary.
97
+ */
98
+ async function generateSummary() {
99
+ try {
100
+ const files = await fs.readdir(progressDir);
101
+ // Filter for .md files, excluding overall.md and other non-service files, case-insensitively
102
+ const mdFiles = files.filter(file =>
103
+ file.toLowerCase().endsWith('.md') &&
104
+ !['overall.md'].includes(file.toLowerCase())
105
+ );
106
+
107
+ const allStats = [];
108
+ const grandTotal = { classes: 0, classesCompleted: 0, methods: 0, methodsCompleted: 0 };
109
+
110
+ for (const file of mdFiles) {
111
+ const serviceName = path.basename(file, path.extname(file));
112
+ const filePath = path.join(progressDir, file);
113
+ const stats = await parseProgressFile(filePath);
114
+ allStats.push({ name: serviceName, file, ...stats });
115
+ grandTotal.classes += stats.totalClasses;
116
+ grandTotal.classesCompleted += stats.completedClasses;
117
+ grandTotal.methods += stats.totalMethods;
118
+ grandTotal.methodsCompleted += stats.completedMethods;
119
+ }
120
+
121
+ allStats.sort((a, b) => a.name.localeCompare(b.name));
122
+
123
+ let table = '# Overall Progress\n\n';
124
+ table += '| service | classes | methods | methods completed | %age |\n';
125
+ table += '| :--- | :---: | :---: | :---: | :---: |\n';
126
+
127
+ for (const stat of allStats) {
128
+ const methodPercent = formatPercent(stat.completedMethods, stat.totalMethods);
129
+ table += `| [${stat.name}](${stat.file}) | ${stat.totalClasses} | ${stat.totalMethods} | ${stat.completedMethods} | ${methodPercent} |\n`;
130
+ }
131
+
132
+ const totalMethodPercent = formatPercent(grandTotal.methodsCompleted, grandTotal.methods);
133
+ table += `| **Total** | **${grandTotal.classes}** | **${grandTotal.methods}** | **${grandTotal.methodsCompleted}** | **${totalMethodPercent}** |\n`;
134
+
135
+ await fs.writeFile(overallMdPath, table);
136
+ console.log(`Successfully updated ${overallMdPath}`);
137
+ } catch (error) {
138
+ console.error('Failed to generate progress summary:', error);
139
+ }
140
+ }
141
+
142
+ generateSummary();
package/package.json CHANGED
@@ -3,10 +3,12 @@
3
3
  "node": ">=20.11.0"
4
4
  },
5
5
  "dependencies": {
6
+ "@google-cloud/logging": "^11.2.1",
6
7
  "@mcpher/fake-gasenum": "^1.0.2",
7
8
  "@mcpher/unit": "^1.1.11",
8
9
  "@sindresorhus/is": "^7.0.1",
9
10
  "archiver": "^7.0.1",
11
+ "fast-json-stable-stringify": "^2.1.0",
10
12
  "get-stream": "^9.0.1",
11
13
  "googleapis": "^157.0.0",
12
14
  "got": "^14.4.7",
@@ -57,13 +59,15 @@
57
59
  "testdocsimages": "cp mainlocal.js main.js && node --env-file=.env ./test/testdocsimages.js execute",
58
60
  "testdocsstyles": "cp mainlocal.js main.js && node --env-file=.env ./test/testdocsstyles.js execute",
59
61
  "testsandbox": "cp mainlocal.js main.js && node --env-file=.env ./test/testsandbox.js execute",
62
+ "testgmail": "cp mainlocal.js main.js && node --env-file=.env ./test/testgmail.js execute",
63
+ "testlogger": "cp mainlocal.js main.js && node --env-file=.env ./test/testlogger.js execute",
60
64
  "pub": "cp mainlocal.js main.js && npm publish --access public"
61
65
  },
62
66
  "name": "@mcpher/gas-fakes",
63
- "version": "1.0.19",
67
+ "version": "1.0.21",
64
68
  "license": "MIT",
65
69
  "main": "main.js",
66
70
  "description": "A proof of concept implementation of Apps Script Environment on Node",
67
71
  "repository": "github:brucemcpherson/gas-fakes",
68
72
  "homepage": "https://ramblings.mcpher.com/a-proof-of-concept-implementation-of-apps-script-environment-on-node/"
69
- }
73
+ }
package/setup.sh ADDED
@@ -0,0 +1,147 @@
1
+ #!/bin/bash
2
+
3
+ # --- 1. Collect Phase ---
4
+ echo "Welcome to the gas-fakes project setup."
5
+ echo "This script will guide you through creating your .env file for testing."
6
+ echo "Please provide the following configuration values."
7
+ echo "Some values are required for the test suite to run correctly."
8
+ echo
9
+
10
+ # --- Required values ---
11
+ read -p "Enter your GCP Project ID: " gcp_project_id
12
+ if [ -z "$gcp_project_id" ]; then
13
+ echo "Error: GCP Project ID is required." >&2
14
+ exit 1
15
+ fi
16
+
17
+ read -p "Enter a Drive File ID you have read access to (for testing ADC): " drive_test_file_id
18
+ if [ -z "$drive_test_file_id" ]; then
19
+ echo "Error: Drive File ID is required." >&2
20
+ exit 1
21
+ fi
22
+
23
+ read -p "Enter a test Drive Folder Name you have write access to: " test_folder_name
24
+ if [ -z "$test_folder_name" ]; then
25
+ echo "Error: Test Folder Name is required." >&2
26
+ exit 1
27
+ fi
28
+
29
+ read -p "Enter the ID of that test Drive Folder: " test_folder_id
30
+ if [ -z "$test_folder_id" ]; then
31
+ echo "Error: Test Folder ID is required." >&2
32
+ exit 1
33
+ fi
34
+
35
+ # --- Optional values with defaults ---
36
+ read -p "Enter the number of files in that folder [0]: " test_folder_files
37
+ test_folder_files=${test_folder_files:-0}
38
+
39
+ read -p "Enter a viewer email for permission tests [viewer@mcpher.com]: " scratch_viewer
40
+ scratch_viewer=${scratch_viewer:-"viewer@mcpher.com"}
41
+
42
+ read -p "Enter an editor email for permission tests [editor@mcpher.com]: " scratch_editor
43
+ scratch_editor=${scratch_editor:-"editor@mcpher.com"}
44
+
45
+ read -p "Enter a second viewer email [viewer2@mcpher.com]: " scratch_b_viewer
46
+ scratch_b_viewer=${scratch_b_viewer:-"viewer2@mcpher.com"}
47
+
48
+ read -p "Enter a second editor email [editor2@mcpher.com]: " scratch_b_editor
49
+ scratch_b_editor=${scratch_b_editor:-"editor2@mcpher.com"}
50
+
51
+ read -p "Enter min PDFs in root for tests [20]: " min_root_pdfs
52
+ min_root_pdfs=${min_root_pdfs:-20}
53
+
54
+ read -p "Enter min PDFs total for tests [400]: " min_pdfs
55
+ min_pdfs=${min_pdfs:-400}
56
+
57
+ read -p "Enter min folders in root for tests [5]: " min_folders_root
58
+ min_folders_root=${min_folders_root:-5}
59
+
60
+
61
+ # --- 2. Confirm Phase ---
62
+ echo
63
+ echo "The following configuration will be written to .env:"
64
+ echo "================================================="
65
+ echo "# User-specific values"
66
+ echo "GCP_PROJECT_ID=${gcp_project_id}"
67
+ echo "DRIVE_TEST_FILE_ID=${drive_test_file_id}"
68
+ echo "TEST_FOLDER_NAME=\"${test_folder_name}\""
69
+ echo "TEST_FOLDER_ID=${test_folder_id}"
70
+ echo "TEST_FOLDER_FILES=${test_folder_files}"
71
+ echo "SCRATCH_VIEWER=${scratch_viewer}"
72
+ echo "SCRATCH_EDITOR=${scratch_editor}"
73
+ echo "SCRATCH_B_VIEWER=${scratch_b_viewer}"
74
+ echo "SCRATCH_B_EDITOR=${scratch_b_editor}"
75
+ echo "MIN_ROOT_PDFS=${min_root_pdfs}"
76
+ echo "MIN_PDFS=${min_pdfs}"
77
+ echo "MIN_FOLDERS_ROOT=${min_folders_root}"
78
+ echo
79
+ echo "# Shared and static values will also be included."
80
+ echo "================================================="
81
+ echo
82
+
83
+ read -p "Proceed with creating the .env file? (y/N) " confirm
84
+ if [[ ! "$confirm" =~ ^[yY](es)?$ ]]; then
85
+ echo "Setup aborted. No file was written."
86
+ exit 0
87
+ fi
88
+
89
+
90
+ # --- 3. Commit Phase ---
91
+ ENV_FILE=".env"
92
+ TEMP_ENV_FILE="${ENV_FILE}.tmp"
93
+
94
+ # Using a heredoc to write the complete file content.
95
+ cat > "$TEMP_ENV_FILE" << EOL
96
+ # Auto-generated by setup.sh on $(date)
97
+
98
+ # --- User-specific values ---
99
+ # Required for authentication and core tests
100
+ GCP_PROJECT_ID="${gcp_project_id}"
101
+ DRIVE_TEST_FILE_ID="${drive_test_file_id}"
102
+
103
+ # Required for file/folder manipulation tests
104
+ TEST_FOLDER_NAME="${test_folder_name}"
105
+ TEST_FOLDER_ID="${test_folder_id}"
106
+ TEST_FOLDER_FILES=${test_folder_files}
107
+
108
+ # For permission tests
109
+ SCRATCH_VIEWER="${scratch_viewer}"
110
+ SCRATCH_EDITOR="${scratch_editor}"
111
+ SCRATCH_B_VIEWER="${scratch_b_viewer}"
112
+ SCRATCH_B_EDITOR="${scratch_b_editor}"
113
+
114
+ # For iterator/search tests (adjust to your Drive content)
115
+ MIN_ROOT_PDFS=${min_root_pdfs}
116
+ MIN_PDFS=${min_pdfs}
117
+ MIN_FOLDERS_ROOT=${min_folders_root}
118
+
119
+ # --- Static auth config ---
120
+ # we'll use the default config for application default credentials
121
+ # probably dont need to change these
122
+ AC=default
123
+ DEFAULT_SCOPES="https://www.googleapis.com/auth/userinfo.email,openid,https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/sqlservice.login"
124
+ EXTRA_SCOPES=",https://www.googleapis.com/auth/drive,https://www.googleapis.com/auth/spreadsheets"
125
+
126
+ # --- Shared test file fixtures (read-only) ---
127
+ TEST_BORDERS_ID=1hRGdrYHEPixXTuQLeL3Z0qGRZVs_8ojMIm6D4KrCh1o
128
+ TEST_AIRPORTS_ID=1h9IGIShgVBVUrUjjawk5MaCEQte_7t32XeEP1Z5jXKQ
129
+ TEXT_FILE_NAME="fake.txt"
130
+ TEXT_FILE_ID=1142Vn7W-pGl5nWLpUSkpOB82JDiz9R6p
131
+ TEXT_FILE_TYPE="text/plain"
132
+ TEXT_FILE_CONTENT="foo is not bar"
133
+ TEST_SHEET_ID=1DlKpVVYCrCPNfRbGsz6N_K3oPTgdC9gQIKi0aNb42uI
134
+ TEST_SHEET_NAME="sharedlibraries"
135
+ PDF_ID=17t4ep9Jt6jRyDx0KlxMhHQNGZ3whg6GS
136
+
137
+ # --- Test behavior ---
138
+ # Set to 0 to preserve test files for debugging
139
+ CLEAN=1
140
+ EOL
141
+
142
+ # Atomically rename the temp file to the final .env file.
143
+ mv "$TEMP_ENV_FILE" "$ENV_FILE"
144
+
145
+ echo
146
+ echo "✅ The .env file has been created successfully."
147
+ echo "You can now run 'npm install && npm test' to run the test suite."
package/src/index.js CHANGED
@@ -1,15 +1,22 @@
1
1
  import './services/scriptapp/app.js'
2
2
  import './services/driveapp/app.js'
3
+ import './services/logger/app.js'
3
4
  import './services/urlfetchapp/app.js'
4
5
  import './services/utilities/app.js'
5
6
  import './services/spreadsheetapp/app.js'
6
7
  import './services/stores/app.js'
7
- import './services/base/app.js'
8
+ import './services/gmailapp/app.js'
9
+ import './services/session/app.js'
8
10
  import './services/advdrive/app.js'
9
11
  import './services/advsheets/app.js'
10
12
  import './services/advdocs/app.js'
13
+ import './services/advgmail/app.js'
11
14
  import './services/advslides/app.js'
12
15
  import './services/documentapp/app.js'
13
16
  import './services/advforms/app.js'
14
17
  import './services/formapp/app.js'
15
- import './services/slidesapp/app.js'
18
+ import './services/slidesapp/app.js'
19
+
20
+ // force initilialization of scriptApp - which is always needed
21
+ // scriptapp will always be fake here
22
+ ScriptApp.isFake
@@ -5,28 +5,9 @@
5
5
  * We do this by using a proxy, intercepting calls to the
6
6
  * initial sigleton and diverting them to a completed one
7
7
  */
8
- import { newFakeAdvDocs } from './fakeadvdocs.js'
9
- import { Proxies } from '../../support/proxies.js'
8
+ import { newFakeAdvDocs as maker } from './fakeadvdocs.js'
9
+ import { lazyLoaderApp } from '../common/lazyloader.js'
10
10
 
11
- // This will eventually hold a proxy for DriveApp
12
- let _app = null
11
+ let _app = null;
12
+ _app = lazyLoaderApp(_app, 'Docs', maker)
13
13
 
14
- /**
15
- * adds to global space to mimic Apps Script behavior
16
- */
17
- const name = "Docs"
18
- if (typeof globalThis[name] === typeof undefined) {
19
-
20
- const getApp = () => {
21
- // if it hasne been intialized yet then do that
22
- if (!_app) {
23
- console.log('...activating proxy for', name)
24
- _app = newFakeAdvDocs()
25
- }
26
- // this is the actual driveApp we'll return from the proxy
27
- return _app
28
- }
29
-
30
- Proxies.registerProxy(name, getApp)
31
-
32
- }
@@ -1,32 +1,10 @@
1
- // fake Apps Script DriveApp
2
- /**
3
- * the idea here is to create a global entry for the singleton
4
- * before we actually have everything we need to create it.
5
- * We do this by using a proxy, intercepting calls to the
6
- * initial sigleton and diverting them to a completed one
7
- */
8
- import { newFakeAdvDrive} from './fakeadvdrive.js'
9
- import { Proxies } from '../../support/proxies.js'
10
-
11
-
12
- let _app = null
13
1
 
14
2
  /**
15
- * adds to global space to mimic Apps Script behavior
3
+ * the idea here is to create an empty global entry for the singleton
4
+ * but only load it when it is actually used.
16
5
  */
17
- const name = "Drive"
18
- if (typeof globalThis[name] === typeof undefined) {
19
-
20
- const getApp = () => {
21
- // if it hasne been intialized yet then do that
22
- if (!_app) {
23
- console.log ('...activating proxy for', name)
24
- _app = newFakeAdvDrive()
25
- }
26
- // this is the actual driveApp we'll return from the proxy
27
- return _app
28
- }
29
-
30
- Proxies.registerProxy (name, getApp)
6
+ import { newFakeAdvDrive as maker} from './fakeadvdrive.js'
7
+ import { lazyLoaderApp } from '../common/lazyloader.js'
31
8
 
32
- }
9
+ let _app = null;
10
+ _app = lazyLoaderApp(_app, 'Drive', maker)
@@ -1,31 +1,12 @@
1
1
 
2
- /**
3
- * NOTE - Although Apps Script doesnt yet have a Forms advanced service
4
- * we're going to funnel everything through here as if there was one.
5
- *
6
- */
7
- import { newFakeAdvForms } from './fakeadvforms.js'
8
- import { Proxies } from '../../support/proxies.js'
9
-
10
- // This will eventually hold a proxy for Formsapp
11
- let _app = null
12
2
 
13
3
  /**
14
- * adds to global space to mimic Apps Script behavior
4
+ * the idea here is to create an empty global entry for the singleton
5
+ * but only load it when it is actually used.
15
6
  */
16
- const name = "Forms"
17
- if (typeof globalThis[name] === typeof undefined) {
18
-
19
- const getApp = () => {
20
- // if it hasne been intialized yet then do that
21
- if (!_app) {
22
- console.log('...activating proxy for', name)
23
- _app = newFakeAdvForms()
24
- }
25
- // this is the actual formsapp we'll return from the proxy
26
- return _app
27
- }
28
7
 
29
- Proxies.registerProxy(name, getApp)
8
+ import { newFakeAdvForms as maker} from './fakeadvforms.js'
9
+ import { lazyLoaderApp } from '../common/lazyloader.js'
30
10
 
31
- }
11
+ let _app = null;
12
+ _app = lazyLoaderApp(_app, 'Forms', maker)
@@ -0,0 +1,11 @@
1
+
2
+
3
+ /**
4
+ * the idea here is to create an empty global entry for the singleton
5
+ * but only load it when it is actually used.
6
+ */
7
+ import { newFakeAdvGmail as maker} from './fakeadvgmail.js'
8
+ import { lazyLoaderApp } from '../common/lazyloader.js'
9
+
10
+ let _app = null;
11
+ _app = lazyLoaderApp(_app, 'Gmail', maker)
@@ -0,0 +1,39 @@
1
+
2
+ /**
3
+ * Advanced gmail service
4
+ */
5
+ import { Proxies } from '../../support/proxies.js';
6
+ import { newFakeAdvGmailUsers } from './fakeadvgmailusers.js';
7
+ import { advClassMaker } from '../../support/helpers.js';
8
+ import { gmailCacher } from '../../support/gmailcacher.js';
9
+
10
+ const propsList = { "newModifyMessageRequest": ["addLabelIds", "removeLabelIds"], "newObliterateCseKeyPairRequest": [], "newFilter": ["action", "criteria", "id"], "newHardwareKeyMetadata": ["description"], "newImapSettings": ["autoExpunge", "enabled", "expungeBehavior", "maxFolderSize"], "newDisableCseKeyPairRequest": [], "newFilterAction": ["addLabelIds", "forward", "removeLabelIds"], "newMessagePartHeader": ["name", "value"], "newVacationSettings": ["enableAutoReply", "endTime", "responseBodyHtml", "responseBodyPlainText", "responseSubject", "restrictToContacts", "restrictToDomain", "startTime"], "newFilterCriteria": ["excludeChats", "from", "hasAttachment", "negatedQuery", "query", "size", "sizeComparison", "subject", "to"], "newModifyThreadRequest": ["addLabelIds", "removeLabelIds"], "newSmimeInfo": ["encryptedKeyPassword", "expiration", "id", "isDefault", "issuerCn", "pem", "pkcs12"], "newMessage": ["historyId", "id", "internalDate", "labelIds", "payload", "raw", "sizeEstimate", "snippet", "threadId"], "newMessagePartBody": ["attachmentId", "data", "size"], "newBatchDeleteMessagesRequest": ["ids"], "newCsePrivateKeyMetadata": ["hardwareKeyMetadata", "kaclsKeyMetadata", "privateKeyMetadataId"], "newAutoForwarding": ["disposition", "emailAddress", "enabled"], "newLabelColor": ["backgroundColor", "textColor"], "newLanguageSettings": ["displayLanguage"], "newBatchModifyMessagesRequest": ["addLabelIds", "ids", "removeLabelIds"], "newForwardingAddress": ["forwardingEmail", "verificationStatus"], "newSignAndEncryptKeyPairs": ["encryptionKeyPairId", "signingKeyPairId"], "newSendAs": ["displayName", "isDefault", "isPrimary", "replyToAddress", "sendAsEmail", "signature", "smtpMsa", "treatAsAlias", "verificationStatus"], "newSmtpMsa": ["host", "password", "port", "securityMode", "username"], "newMessagePart": ["body", "filename", "headers", "mimeType", "partId", "parts"], "newLabel": ["color", "id", "labelListVisibility", "messageListVisibility", "messagesTotal", "messagesUnread", "name", "threadsTotal", "threadsUnread", "type"], "newWatchRequest": ["labelFilterAction", "labelFilterBehavior", "labelIds", "topicName"], "newKaclsKeyMetadata": ["kaclsData", "kaclsUri"], "newEnableCseKeyPairRequest": [], "newDraft": ["id", "message"], "newPopSettings": ["accessWindow", "disposition"], "newDelegate": ["delegateEmail", "verificationStatus"], "newCseIdentity": ["emailAddress", "primaryKeyPairId", "signAndEncryptKeyPairs"], "newCseKeyPair": ["disableTime", "enablementState", "keyPairId", "pem", "pkcs7", "privateKeyMetadata", "subjectEmailAddresses"] }
11
+
12
+
13
+ class FakeAdvGmail {
14
+ constructor() {
15
+ this.__fakeObjectType = "Gmail"
16
+
17
+ Reflect.ownKeys(propsList).forEach(p => {
18
+ this[p] = () => advClassMaker(propsList[p])
19
+ })
20
+
21
+ }
22
+ toString() {
23
+ return 'AdvancedServiceIdentifier{name=gmail, version=v1}'
24
+ }
25
+
26
+ getVersion() {
27
+ return 'v1'
28
+ }
29
+
30
+ get Users() {
31
+ return newFakeAdvGmailUsers(this)
32
+ }
33
+
34
+ __getGmailPerformance() {
35
+ return gmailCacher.getPerformance()
36
+ }
37
+ }
38
+
39
+ export const newFakeAdvGmail = (...args) => Proxies.guard(new FakeAdvGmail(...args))
@@ -0,0 +1,119 @@
1
+ import { FakeAdvResource } from '../common/fakeadvresource.js';
2
+ import { Proxies } from '../../support/proxies.js';
3
+ import { gError, normalizeSerialization } from '../../support/helpers.js';
4
+ import { Syncit } from '../../support/syncit.js';
5
+
6
+ export const newFakeAdvGmailLabels = (...args) => Proxies.guard(new FakeAdvGmailLabels(...args));
7
+
8
+ class FakeAdvGmailLabels extends FakeAdvResource {
9
+ constructor(mainService) {
10
+ super(mainService, 'users', Syncit.fxGmail);
11
+ this.gmail = mainService;
12
+ this.__fakeObjectType = 'Gmail.Users.Labels';
13
+ }
14
+
15
+ /**
16
+ * Creates a new label.
17
+ * @param {object} resource - The label resource to create.
18
+ * @param {string} userId - The user's email address. The special value me can be used to indicate the authenticated user.
19
+ * @returns {object} The created label resource.
20
+ */
21
+ create(resource, userId) {
22
+ const { data, response } = this._call(
23
+ 'create',
24
+ { userId, requestBody: normalizeSerialization(resource) },
25
+ null,
26
+ 'labels'
27
+ );
28
+ gError(response, 'gmail', 'users.labels.create');
29
+ return data;
30
+ }
31
+
32
+ /**
33
+ * Deletes the specified label.
34
+ * @param {string} userId - The user's email address. The special value me can be used to indicate the authenticated user.
35
+ * @param {string} id - The ID of the label to delete.
36
+ */
37
+ remove(userId, id) {
38
+ const { data, response } = this._call(
39
+ 'delete',
40
+ { userId, id },
41
+ null,
42
+ 'labels'
43
+ );
44
+ gError(response, 'gmail', 'users.labels.delete');
45
+ return data;
46
+ }
47
+
48
+ /**
49
+ * Gets the specified label.
50
+ * @param {string} userId - The user's email address. The special value me can be used to indicate the authenticated user.
51
+ * @param {string} id - The ID of the label to retrieve.
52
+ * @returns {object} The label resource.
53
+ */
54
+ get(userId, id) {
55
+ const { data, response } = this._call(
56
+ 'get',
57
+ { userId, id },
58
+ null,
59
+ 'labels'
60
+ );
61
+ gError(response, 'gmail', 'users.labels.get', true);
62
+ return data;
63
+ }
64
+
65
+ /**
66
+ * Lists all labels in the user's mailbox.
67
+ * @param {string} userId - The user's email address. The special value me can be used to indicate the authenticated user.
68
+ * @param {object} params - The parameters for the request.
69
+ * @returns {object} A list of labels.
70
+ */
71
+ list(userId, params = {}) {
72
+ const { data, response } = this._call(
73
+ 'list',
74
+ { ...params, userId },
75
+ null,
76
+ 'labels'
77
+ );
78
+ gError(response, 'gmail', 'users.labels.list');
79
+ return data;
80
+ }
81
+
82
+ /**
83
+ * Updates the specified label. This method supports patch semantics.
84
+ * @param {string} userId - The user's email address. The special value me can be used to indicate the authenticated user.
85
+ * @param {object} resource - The label resource to update.
86
+ * @param {object} [params={}] - The parameters for the request.
87
+ * @param {string} params.id - The ID of the label to update.
88
+ * @returns {object} The updated label resource.
89
+ */
90
+ patch(userId, resource, params = {}) {
91
+ const { data, response } = this._call(
92
+ 'patch',
93
+ { ...params, userId, requestBody: normalizeSerialization(resource) },
94
+ null,
95
+ 'labels'
96
+ );
97
+ gError(response, 'gmail', 'users.labels.patch');
98
+ return data;
99
+ }
100
+
101
+ /**
102
+ * Updates the specified label.
103
+ * @param {string} userId - The user's email address. The special value me can be used to indicate the authenticated user.
104
+ * @param {object} resource - The label resource to update.
105
+ * @param {object} [params={}] - The parameters for the request.
106
+ * @param {string} params.id - The ID of the label to update.
107
+ * @returns {object} The updated label resource.
108
+ */
109
+ update(userId, resource, params = {}) {
110
+ const { data, response } = this._call(
111
+ 'update',
112
+ { ...params, userId, requestBody: normalizeSerialization(resource) },
113
+ null,
114
+ 'labels'
115
+ );
116
+ gError(response, 'gmail', 'users.labels.update');
117
+ return data;
118
+ }
119
+ }