Skip to content

Commit de23e66

Browse files
authored
Updating README and build:watch (#11)
1 parent 8a64cec commit de23e66

2 files changed

Lines changed: 50 additions & 9 deletions

File tree

README.md

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@ gas-project/
1717
│ └── shared/
1818
│ └── types.ts # TypeScript interfaces
1919
├── __tests__/
20-
│ ├── utils.test.ts # Tests for pure functions (no mocking)
21-
│ └── api.test.ts # Tests for Gemini API with mocked globals
20+
│ ├── utils.test.ts # Tests for pure helpers
21+
│ ├── api.test.ts # Tests for Gemini API with mocked globals
22+
│ ├── drive.test.ts # Tests for Drive text extraction
23+
│ └── menu.test.ts # Tests for onOpen / menu registration
2224
├── dist/ # Build output (clasp pushes from here)
2325
├── appsscript.json # Manifest: scopes, Drive Advanced Service
2426
├── .clasp.dev.json # Dev script ID
2527
├── .clasp.prod.json # Prod script ID
2628
├── rollup.config.js # Bundler config
2729
├── tsconfig.json # TypeScript config (ES2019/V8 target)
28-
├── jest.config.js # Test runner
30+
├── jest.config.cjs # Test runner
2931
├── .eslintrc.json # Linting
3032
└── .prettierrc # Formatting
3133
```
@@ -39,7 +41,7 @@ gas-project/
3941
| `drive.ts` | `extractTextUniversal()`, OCR via Doc conversion | `DriveApp`, `Drive` (Advanced), `DocumentApp` |
4042
| `dialog.ts` | HTML string for the modal dialog | None |
4143
| `utils.ts` | ID extraction, link validation, seeded RNG, recursive file listing | `DriveApp` (only `getAllFilesRecursive`) |
42-
| `index.ts` | Menu creation, 4 tools, `global.*` assignments | `SpreadsheetApp`, `HtmlService`, `PropertiesService` |
44+
| `index.ts` | Menu creation, 4 tools, exports wired to footer stubs | `SpreadsheetApp`, `HtmlService`, `PropertiesService` |
4345

4446
## Prerequisites
4547

@@ -70,30 +72,69 @@ npm run deploy:dev
7072
## Development
7173

7274
```bash
73-
npm run build # Build once to dist/
75+
npm run build # Clean build to dist/
76+
npm run build:watch # Continuous rebuild on file changes
7477
npm run deploy:dev # Build + push to dev script
7578
npm run deploy:prod # Build + push to prod script
76-
npm run deploy:watch # Rebuild + push on every save
79+
npm run deploy:watch:dev # Continuous build + push watch (dev)
80+
npm run deploy:watch:prod # Continuous build + push watch (prod)
7781

7882
npm test # Run tests
7983
npm run test:watch # Run tests in watch mode
84+
npm run test:coverage # Run tests with coverage + enforce per-file thresholds
85+
8086
npm run lint # Lint TypeScript
87+
npm run lint:fix # Lint with auto-fix
8188
npm run format # Format with Prettier
89+
npm run format:check # Check formatting without modifying files
90+
npm run typecheck # Type-check without building
91+
92+
npm run clasp:open # Open the Apps Script editor in browser
93+
npm run clasp:logs # Tail execution logs from Apps Script
8294
```
8395

96+
Run a single test file: `npx jest __tests__/utils.test.ts`
97+
Run a single test by name: `npx jest -t "extractId"`
98+
8499
## How the Build Works
85100

86101
```
87102
src/**/*.ts → Rollup (TS + node-resolve) → dist/index.js → clasp push → Apps Script
88103
```
89104

90-
Rollup bundles everything into a single IIFE. Functions are exposed to Apps Script via `global.functionName = functionName` at the bottom of `index.ts`. If you add a new function that needs to be callable from the Sheets menu or a trigger, add it there.
105+
Rollup bundles everything into a single IIFE assigned to `_GASEntry`. Apps Script has no module system and can only discover top-level functions in the global scope. The `footer` field in `rollup.config.js` bridges this gap by appending plain global stubs that delegate into the IIFE:
106+
107+
```js
108+
function onOpen(e) { _GASEntry.onOpen(e); }
109+
function showSourceDialog() { _GASEntry.showSourceDialog(); }
110+
// ... one stub per public entry point
111+
```
112+
113+
**To expose a new function to Apps Script, you must do both:**
114+
1. `export` it from `src/server/index.ts`
115+
2. Add a matching global stub in the `footer` of `rollup.config.js`
116+
117+
If you skip step 2, the function will exist in the bundle but Apps Script won't be able to discover or call it.
118+
119+
## Tool 4 — Run AI: Required Columns
120+
121+
`runBatchAI` maps columns by header name. The active sheet must contain these exact headers (case-sensitive):
122+
123+
| Column header | Purpose |
124+
|---|---|
125+
| `source_drive` | Drive file link (multimodal mode) |
126+
| `source_text` | Plain text input (text mode) |
127+
| `system_prompt` | System prompt for each row |
128+
| `user_prompt` | User prompt for each row |
129+
| `ai_inference` | Output column (written by the tool) |
130+
131+
The Gemini API key must be stored as a Script Property (`GEMINI_API_KEY`) in Apps Script > Project Settings > Script Properties before Tool 4 will run.
91132

92133
## Key Notes
93134

94135
**Drive Advanced Service:** The `extractTextUniversal` function uses `Drive.Files.create()` and `Drive.Files.remove()` (v3 API) for PDF/image OCR. This is the Drive *Advanced Service*, not `DriveApp`. It must be enabled separately in the Apps Script editor AND is declared in `appsscript.json` under `enabledAdvancedServices`.
95136

96-
**appsscript.json must be in dist/:** Clasp needs the manifest alongside the bundled JS. Either copy it manually (`cp appsscript.json dist/`) or add a Rollup copy plugin. The build script uses `rimraf dist` so you'll need to copy it after each build.
137+
**appsscript.json must be in dist/:** Clasp needs the manifest alongside the bundled JS. The build script handles this automatically — it runs `rimraf dist`, Rollup, then copies `appsscript.json` into `dist/`. No manual copy needed.
97138

98139
**Custom functions have limited permissions:** The `GEMINI()` custom function (if you add one) cannot access `PropertiesService`, so passing an API key to it requires a different pattern (hardcoded config, cache, or trigger-based pre-fetch).
99140

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"type": "module",
77
"scripts": {
88
"build": "rimraf dist && rollup -c && cp appsscript.json dist/",
9-
"build:watch": "rollup -c --watch",
9+
"build:watch": "mkdir -p dist && cp appsscript.json dist/ && rollup -c --watch",
1010
"deploy:dev": "npm run build && cp .clasp.dev.json .clasp.json && clasp push",
1111
"deploy:prod": "npm run build && cp .clasp.prod.json .clasp.json && clasp push",
1212
"deploy:watch:dev": "cp .clasp.dev.json .clasp.json && npm-run-all --parallel build:watch push:watch",

0 commit comments

Comments
 (0)