From 470f760b9b88d42c53f96cb2c03406433ddab8e0 Mon Sep 17 00:00:00 2001 From: "Peter.Morton" Date: Sat, 7 Mar 2026 11:46:06 -0600 Subject: [PATCH] Rename helpers.js to googleDriveAdapterHelper.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rationale: - More descriptive name indicates purpose (Google Drive adapter utilities) - Distinguishes from generic 'helpers' (could apply to anything) - Clearer intent when reading code and logs - Follows convention of naming modules by their domain Changes: 1. File renamed: - src/globalVariables/helpers.js → src/globalVariables/googleDriveAdapterHelper.js 2. Updated all references in proxy.js (6 occurrences): - helpers.generateRequestId() → googleDriveAdapterHelper.generateRequestId() - helpers.parseRoute() → googleDriveAdapterHelper.parseRoute() - helpers.DocumentCountExceededError → googleDriveAdapterHelper.DocumentCountExceededError() - helpers.generateSitemap() → googleDriveAdapterHelper.generateSitemap() - helpers.mapDriveErrorToHttp() → googleDriveAdapterHelper.mapDriveErrorToHttp() - Header comment updated 3. Updated constitution.md documentation: - All references to helpers.js → googleDriveAdapterHelper.js - globalVariableContext.helpers → globalVariableContext.googleDriveAdapterHelper - Function call examples updated throughout Benefits: ✅ Self-documenting name (clear it's for Google Drive adapter) ✅ Better intellisense/autocomplete (shows domain) ✅ Clearer logs (googleDriveAdapterHelper vs generic helpers) ✅ Future-proof (can add other helper modules without confusion) Generic Loading Pattern: - server.js automatically loads all .js files from globalVariables/ - Filename determines key: googleDriveAdapterHelper.js → globalVariableContext.googleDriveAdapterHelper - No server.js changes needed (generic loader handles it) Testing: ✓ Syntax validated ✓ Server starts successfully ✓ Module loads: 'Loaded global functions: googleDriveAdapterHelper' ✓ All function calls work correctly Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .specify/memory/constitution.md | 80 +++++++++---------- ...helpers.js => googleDriveAdapterHelper.js} | 0 src/proxyScripts/proxy.js | 12 +-- 3 files changed, 46 insertions(+), 46 deletions(-) rename src/globalVariables/{helpers.js => googleDriveAdapterHelper.js} (100%) diff --git a/.specify/memory/constitution.md b/.specify/memory/constitution.md index a331b49..975bcb6 100644 --- a/.specify/memory/constitution.md +++ b/.specify/memory/constitution.md @@ -3,7 +3,7 @@ Sync Impact Report: Version: 1.18.0 → 1.19.0 (MINOR: Code simplification and optimization) Modified Principles: - Section I.V: Updated to document unified loadGlobalVariables() function - - Section I.II: Updated helpers.js pattern to reflect simplified approach + - Section I.II: Updated googleDriveAdapterHelper.js pattern to reflect simplified approach - Overall: Documented 47% reduction in codebase size through systematic simplification Architecture Changes: - server.js: Unified loadGlobalObjects() + loadGlobalVariables() → loadGlobalVariables() @@ -28,7 +28,7 @@ Code Changes: - Combined savings: 596 lines removed (47% overall reduction) Modified Sections: - Section I.V: Updated loadGlobalVariables() pattern (unified loader) - - Section I.II: Updated helpers.js documentation for simplified approach + - Section I.II: Updated googleDriveAdapterHelper.js documentation for simplified approach - Throughout: Removed references to separate loadGlobalObjects/loadGlobalVariableFunctions Rationale: - Unified loader is simpler API (one function instead of two) @@ -51,11 +51,11 @@ Modified Principles: - Section I.V: Updated VM context injection pattern to reflect loadGlobalVariableFunctions - Section I.V: Documented generic .js file loading from globalVariables/ - Section I.V: Updated tempContext to use full globalVMContext + globalVariableContext - - Section I.II: Updated helpers.js documentation to reflect generic pattern + - Section I.II: Updated googleDriveAdapterHelper.js documentation to reflect generic pattern Architecture Changes: - Renamed loadHelpers() → loadGlobalVariables() - - Generic pattern: loads ALL .js files from globalVariables/ (not just helpers.js) - - Filename determines key: helpers.js → globalVariableContext.helpers + - Generic pattern: loads ALL .js files from globalVariables/ (not just googleDriveAdapterHelper.js) + - Filename determines key: googleDriveAdapterHelper.js → globalVariableContext.googleDriveAdapterHelper - tempContext now includes full VM globals and previously loaded data - Function modules can access all dependencies (axios, jwt, etc.) Code Changes: @@ -63,7 +63,7 @@ Code Changes: - server.js: tempContext uses {...globalVMContext, ...globalVariableContext} - Pattern matches loadGlobalObjects() structure for consistency Modified Sections: - - Section I.II: Updated file structure and helpers.js pattern documentation + - Section I.II: Updated file structure and googleDriveAdapterHelper.js pattern documentation - Section I.V: Complete rewrite of function module loading documentation - Section I.V: Updated context injection pattern code example Rationale: @@ -76,18 +76,18 @@ Templates Status: Previous Version: Version: 1.16.0 → 1.17.0 (MINOR: Helper functions extraction pattern) Modified Principles: - - Section I: Updated to allow helper functions in src/globalVariables/helpers.js - - Section I.II: Added helpers.js to allowed files list + - Section I: Updated to allow helper functions in src/globalVariables/googleDriveAdapterHelper.js + - Section I.II: Added googleDriveAdapterHelper.js to allowed files list - Section I.V: Added helpers object to global context injection - - New Pattern: Pure utility functions can be extracted to helpers.js and loaded via vm.Script + - New Pattern: Pure utility functions can be extracted to googleDriveAdapterHelper.js and loaded via vm.Script Architecture Changes: - - Created src/globalVariables/helpers.js (315 lines) + - Created src/globalVariables/googleDriveAdapterHelper.js (315 lines) - Extracted 11 helper functions from proxy.js - Reduced proxy.js from 752 to 493 lines (35% reduction) - Helper functions loaded via vm.Script and injected as 'helpers' global object - proxy.js now uses helpers.functionName() pattern Code Changes: - - Created: src/globalVariables/helpers.js with IIFE returning helpers object + - Created: src/globalVariables/googleDriveAdapterHelper.js with IIFE returning helpers object - Modified: src/proxyScripts/proxy.js to use helpers object - Extracted: generateRequestId, validateDocumentId, validateDocumentCount, escapeXml, mapDriveErrorToHttp, toSitemapEntry, transformDocumentsToSitemapEntries, @@ -95,7 +95,7 @@ Code Changes: Modified Sections: - Section I: Core monolithic architecture principle (added helpers exception) - Section I.I: What must be in proxy.js (clarified helpers can be external) - - Section I.II: What can be separate files (added helpers.js) + - Section I.II: What can be separate files (added googleDriveAdapterHelper.js) - Section I.V: Global objects injection (added helpers object documentation) Rationale: - Improves code organization while maintaining vm.Script isolation @@ -105,7 +105,7 @@ Rationale: Templates Status: ✅ All templates - No changes needed (helper pattern is optional optimization) Follow-up TODOs: - - Update server.js to load helpers.js via vm.Script + - Update server.js to load googleDriveAdapterHelper.js via vm.Script - Add helpers object to globalVariableContext Previous Version: Version: 1.15.0 → 1.16.0 (PATCH: Directory relocation and documentation update) @@ -185,12 +185,12 @@ Follow-up TODOs: ### I. Monolithic Architecture (NON-NEGOTIABLE) -**ALL business logic, data processing, authentication, and request handling MUST exist within the `src/proxyScripts/proxy.js` file.** Pure utility/helper functions MAY be extracted to `src/globalVariables/helpers.js` if they improve code organization. The `server.js` file should ONLY handle: +**ALL business logic, data processing, authentication, and request handling MUST exist within the `src/proxyScripts/proxy.js` file.** Pure utility/helper functions MAY be extracted to `src/globalVariables/googleDriveAdapterHelper.js` if they improve code organization. The `server.js` file should ONLY handle: - HTTP server setup - Configuration loading - Global object injection into isolated context - Loading src/proxyScripts/proxy.js via `vm.Script` and `vm.createContext` -- Loading src/globalVariables/helpers.js via `vm.Script` (optional) +- Loading src/globalVariables/googleDriveAdapterHelper.js via `vm.Script` (optional) - Per-request context creation with all necessary globals **Implementation via vm.Script**: @@ -202,7 +202,7 @@ Follow-up TODOs: **Rationale**: Monolithic architecture enables simple packaging as a single IVA Studio proxy script and prevents fragmentation of business logic across multiple files. Using `vm.Script` enforces architectural boundaries at runtime, making it impossible for `src/proxyScripts/proxy.js` to access Node.js module system or file system, ensuring ALL functionality exists in one isolated, dependency-injected file. -**Helper Functions Pattern**: Pure utility functions (XML escaping, validation, formatting, routing) MAY be extracted to `src/globalVariables/helpers.js` to improve readability and maintainability. The helpers module: +**Helper Functions Pattern**: Pure utility functions (XML escaping, validation, formatting, routing) MAY be extracted to `src/globalVariables/googleDriveAdapterHelper.js` to improve readability and maintainability. The helpers module: - MUST be loaded via `vm.Script` (same isolation as proxy.js) - MUST return a single object with all helper functions - MUST have ZERO imports/exports @@ -245,15 +245,15 @@ Follow-up TODOs: #### I.I What MUST Be in src/proxyScripts/proxy.js -The following MUST be implemented in `src/proxyScripts/proxy.js` (or extracted to helpers.js if pure utilities): +The following MUST be implemented in `src/proxyScripts/proxy.js` (or extracted to googleDriveAdapterHelper.js if pure utilities): 1. **Authentication**: Service Account JWT, OAuth flows, token management (MUST be in proxy.js) 2. **Business Logic**: All request handling, routing, and processing (MUST be in proxy.js) -3. **Data Transformation**: Document parsing, XML generation, data mapping (MUST be in proxy.js or helpers.js) +3. **Data Transformation**: Document parsing, XML generation, data mapping (MUST be in proxy.js or googleDriveAdapterHelper.js) 4. **API Integration**: Drive API queries, error mapping, response handling (MUST be in proxy.js) 5. **Request Queue**: FIFO queue for sequential processing (MUST be in proxy.js) -6. **Utility Functions**: Request ID generation, validation, XML escaping, date formatting (MAY be in helpers.js) -7. **Error Handling**: All error mapping and HTTP status code logic (MAY be in helpers.js) +6. **Utility Functions**: Request ID generation, validation, XML escaping, date formatting (MAY be in googleDriveAdapterHelper.js) +7. **Error Handling**: All error mapping and HTTP status code logic (MAY be in googleDriveAdapterHelper.js) **Helper Extraction Guidelines**: - ✅ **CAN extract**: Pure functions, validators, formatters, XML utilities, error mappers, route parsers @@ -268,9 +268,9 @@ ONLY the following infrastructure modules may exist outside `src/proxyScripts/pr 1. **src/logger.js**: Structured logging with console replacement (ONLY logging, no business logic) 2. **src/server.js**: HTTP server bootstrap and configuration (ONLY server setup, no business logic) 3. **config/**: JSON configuration files (data files, not code) -4. **src/globalVariables/**: JSON data files AND helpers.js module +4. **src/globalVariables/**: JSON data files AND googleDriveAdapterHelper.js module - `*.json`: Runtime data loaded at startup (credentials, settings) - - `helpers.js`: Pure utility functions loaded via vm.Script (OPTIONAL) + - `googleDriveAdapterHelper.js`: Pure utility functions loaded via vm.Script (OPTIONAL) 5. **src/proxyScripts/**: Directory containing the main proxy script (proxy.js) **Test files are exempt** - Test utilities may exist solely for test compatibility if needed, but MUST NOT be imported by production code. @@ -282,19 +282,19 @@ src/ │ └── proxy.js # Main business logic (authentication, API, queue) ├── globalVariables/ │ ├── *.json # Data files for VM context -│ └── helpers.js # Pure utility functions (OPTIONAL) +│ └── googleDriveAdapterHelper.js # Pure utility functions (OPTIONAL) ├── logger.js # Structured logging └── server.js # HTTP server bootstrap config/ └── default.json # Infrastructure settings ``` -**helpers.js Pattern**: +**googleDriveAdapterHelper.js Pattern**: - MUST be loaded using `vm.Script` (same isolation as proxy.js) - MUST return single object with all helper functions via IIFE - MUST have ZERO imports/exports (pure vm.Script execution) - Loaded by `loadGlobalVariables()` which scans for both JSON and JS files -- Filename determines global key: `helpers.js` → `globalVariableContext.helpers` +- Filename determines global key: `googleDriveAdapterHelper.js` → `globalVariableContext.helpers` - Injected as `helpers` global object into VM context - Contains ONLY pure utilities: validators, formatters, XML, error mappers - MUST NOT contain: authentication, API calls, state, business decisions @@ -304,10 +304,10 @@ config/ During code review and planning: - ANY file in `src/proxyScripts/` besides `proxy.js` MUST be challenged -- ANY file in `src/globalVariables/` besides `helpers.js` and `*.json` MUST be challenged +- ANY file in `src/globalVariables/` besides `googleDriveAdapterHelper.js` and `*.json` MUST be challenged - ANY file in `src/` besides `proxyScripts/`, `globalVariables/`, `logger.js`, `server.js` MUST be challenged -- Authentication, even if complex, MUST be in `src/proxyScripts/proxy.js` (never in helpers.js) -- Business logic MUST be in `src/proxyScripts/proxy.js` (never in helpers.js) +- Authentication, even if complex, MUST be in `src/proxyScripts/proxy.js` (never in googleDriveAdapterHelper.js) +- Business logic MUST be in `src/proxyScripts/proxy.js` (never in googleDriveAdapterHelper.js) - Exceptions require explicit constitutional justification with measurable trade-offs - When in doubt about helpers extraction, keep it in `src/proxyScripts/proxy.js` @@ -357,7 +357,7 @@ loadGlobalVariables(); // 3. Load JSON files first (data) → globalVariableContext[filename] // 4. Load JS files second (functions) → globalVariableContext[filename] // 5. JS files execute in context with {...globalVMContext, ...globalVariableContext} -// Example: helpers.js returns object → globalVariableContext.helpers = object +// Example: googleDriveAdapterHelper.js returns object → globalVariableContext.helpers = object // Example: google_drive_settings.json → globalVariableContext.google_drive_settings = data // Per-request: Create fresh context with all dependencies @@ -438,29 +438,29 @@ script.runInContext(context); **Helper Functions Module:** -10. **helpers** - Pure utility functions object (OPTIONAL) +10. **googleDriveAdapterHelper** - Pure utility functions object (OPTIONAL) - Purpose: Extracted helper functions for code organization - - Source: `src/globalVariables/helpers.js` loaded via `vm.Script` + - Source: `src/globalVariables/googleDriveAdapterHelper.js` loaded via `vm.Script` - Pattern: IIFE returning object with all helper functions - Loading: server.js loads via `loadGlobalVariables()` at startup - Generic Loading Pattern: - All .js files in globalVariables/ are loaded automatically - - Filename determines key: `helpers.js` → `globalVariableContext.helpers` + - Filename determines key: `googleDriveAdapterHelper.js` → `globalVariableContext.helpers` - Executed in tempContext with `{...globalVMContext, ...globalVariableContext}` - Can access all VM globals: axios, jwt, crypto, console, etc. - Can access previously loaded JSON data and function modules - Injection: Spread into VM context via `...globalVariableContext` - - Usage in src/proxyScripts/proxy.js: `helpers.functionName()` (e.g., `helpers.generateRequestId()`) + - Usage in src/proxyScripts/proxy.js: `googleDriveAdapterHelper.functionName()` (e.g., `googleDriveAdapterHelper.generateRequestId()`) - Contains: Pure utilities only (validators, formatters, XML, error mappers, route parsers) - MUST NOT contain: Authentication, API calls, state, business logic - Example functions: - - `helpers.generateRequestId()` - UUID generation - - `helpers.validateDocumentId(id)` - Document ID validation - - `helpers.escapeXml(str)` - XML character escaping - - `helpers.generateSitemap(docs, baseUrl)` - Sitemap generation - - `helpers.mapDriveErrorToHttp(error)` - Error mapping - - `helpers.parseRoute(method, url)` - Route parsing - - `helpers.DocumentCountExceededError` - Custom error class + - `googleDriveAdapterHelper.generateRequestId()` - UUID generation + - `googleDriveAdapterHelper.validateDocumentId(id)` - Document ID validation + - `googleDriveAdapterHelper.escapeXml(str)` - XML character escaping + - `googleDriveAdapterHelper.generateSitemap(docs, baseUrl)` - Sitemap generation + - `googleDriveAdapterHelper.mapDriveErrorToHttp(error)` - Error mapping + - `googleDriveAdapterHelper.parseRoute(method, url)` - Route parsing + - `googleDriveAdapterHelper.DocumentCountExceededError` - Custom error class - Generic Pattern Note: You can add more .js files (e.g., `utils.js`, `validators.js`) and they will be automatically loaded as `globalVariableContext.utils`, etc. diff --git a/src/globalVariables/helpers.js b/src/globalVariables/googleDriveAdapterHelper.js similarity index 100% rename from src/globalVariables/helpers.js rename to src/globalVariables/googleDriveAdapterHelper.js diff --git a/src/proxyScripts/proxy.js b/src/proxyScripts/proxy.js index c4a21ba..805d385 100644 --- a/src/proxyScripts/proxy.js +++ b/src/proxyScripts/proxy.js @@ -16,7 +16,7 @@ * - uuidv4: UUID generator * - jwt: JSON Web Token library * - xmlBuilder: XML document builder - * - helpers: Helper functions module (loaded from globalVariables/helpers.js) + * - googleDriveAdapterHelper: Helper functions module (loaded from globalVariables/googleDriveAdapterHelper.js) * - google_drive_settings: Consolidated settings (from global/google_drive_settings.json) * - serviceAccount: Service account credentials * - scopes: OAuth2 scopes array @@ -147,7 +147,7 @@ async function queryDocuments(options = {}) { // Check if we've exceeded the limit BEFORE fetching more if (allFiles.length > maxDocuments) { - throw new helpers.DocumentCountExceededError(allFiles.length, maxDocuments); + throw new googleDriveAdapterHelper.DocumentCountExceededError(allFiles.length, maxDocuments); } pageToken = response.data.nextPageToken; @@ -175,7 +175,7 @@ async function handleSitemapRequest(res, requestId) { const query = settings.driveQuery || "trashed = false"; const documents = await queryDocuments({ query, maxDocuments: maxUrls }); - const xml = helpers.generateSitemap(documents, settings.proxyScriptEndPoint); + const xml = googleDriveAdapterHelper.generateSitemap(documents, settings.proxyScriptEndPoint); res.statusCode = 200; res.setHeader("Content-Type", "application/xml; charset=utf-8"); @@ -185,7 +185,7 @@ async function handleSitemapRequest(res, requestId) { console.info("Sitemap generated", { requestId, documentCount: documents.length }); } catch (error) { - const errorResponse = helpers.mapDriveErrorToHttp(error); + const errorResponse = googleDriveAdapterHelper.mapDriveErrorToHttp(error); res.statusCode = errorResponse.statusCode; if (errorResponse.retryAfter) { res.setHeader("Retry-After", errorResponse.retryAfter.toString()); @@ -204,7 +204,7 @@ async function handleSitemapRequest(res, requestId) { * Main HTTP request handler */ (async () => { - const requestId = helpers.generateRequestId(); + const requestId = googleDriveAdapterHelper.generateRequestId(); const startTime = Date.now(); console.info("Request received", { @@ -214,7 +214,7 @@ async function handleSitemapRequest(res, requestId) { }); try { - const routeResult = helpers.parseRoute(req.method, req.url); + const routeResult = googleDriveAdapterHelper.parseRoute(req.method, req.url); if (!routeResult.route) { res.statusCode = routeResult.statusCode;