@ciderjs/gasnuki 0.3.1 → 0.3.3
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.ja.md +26 -14
- package/README.md +24 -13
- package/dist/cli.cjs +8 -5
- package/dist/cli.d.cts +2 -2
- package/dist/cli.d.mts +2 -2
- package/dist/cli.d.ts +2 -2
- package/dist/cli.mjs +8 -5
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +2 -2
- package/dist/shared/{gasnuki.Bcijv2Ub.mjs → gasnuki.D1fp3Uiw.mjs} +48 -29
- package/dist/shared/{gasnuki.Cbwq1CES.cjs → gasnuki.D8w16Lbm.cjs} +48 -29
- package/dist/vite.cjs +1 -1
- package/dist/vite.mjs +1 -1
- package/package.json +10 -10
- package/.vscode/settings.json +0 -3
package/README.ja.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
# gasnuki
|
|
1
|
+
# @ciderjs/gasnuki
|
|
2
2
|
|
|
3
|
-
[](./README.md)
|
|
4
|
+
[](https://github.com/luthpg/gasnuki)
|
|
5
|
+
[](LICENSE)
|
|
5
6
|
[](https://www.npmjs.com/package/@ciderjs/gasnuki)
|
|
6
7
|
[](https://github.com/luthpg/gasnuki/issues)
|
|
7
8
|
|
|
@@ -9,8 +10,16 @@ Google Apps Script クライアントサイドAPIの型定義・ユーティリ
|
|
|
9
10
|
|
|
10
11
|
## 概要
|
|
11
12
|
|
|
12
|
-
`gasnuki
|
|
13
|
-
|
|
13
|
+
`gasnuki`は、サーバーサイドのGoogle Apps Script関数から型定義を自動で抽出し、クライアントサイドで利用する`google.script.run` APIに完全な型付けを提供します。これにより、Apps Scriptバックエンドとモダンなフロントエンド開発との間のギャップを埋め、自動補完と堅牢な型チェックを実現します。
|
|
14
|
+
|
|
15
|
+
## `gasnuki`が実現する開発体験
|
|
16
|
+
|
|
17
|
+
`gasnuki`は、Google Apps Scriptを用いたWebアプリケーション開発における、もどかしい開発体験を劇的に改善します。
|
|
18
|
+
|
|
19
|
+
- **完全な型安全性**: `google.script.run`の引数や戻り値に型が付き、エディタの自動補完が効くため、推測に頼るコーディングは不要になります。
|
|
20
|
+
- **モダンな非同期処理**: `async/await`構文を利用して、コールバック地獄に陥ることなく、サーバーサイド関数をシンプルかつ直感的に呼び出せます。
|
|
21
|
+
- **高速な開発サイクル**: フロントエンドの変更を試すたびに`clasp push`する必要はありません。モック機能を使えば、オフラインで迅速なUI開発が可能です。
|
|
22
|
+
- **シームレスな統合**: Vite開発サーバーと連携し、サーバーサイドのコードを変更・保存するだけで、クライアントサイドの型定義が自動的に更新されます。
|
|
14
23
|
|
|
15
24
|
## インストール
|
|
16
25
|
|
|
@@ -101,16 +110,19 @@ google.script.run
|
|
|
101
110
|
.getContent('Sheet1');
|
|
102
111
|
```
|
|
103
112
|
|
|
104
|
-
##
|
|
113
|
+
## 主な機能
|
|
114
|
+
|
|
115
|
+
`gasnuki`は、優れた開発体験を実現するために、以下の機能を提供します。
|
|
116
|
+
|
|
117
|
+
### サーバーサイド関数の型定義を自動生成
|
|
105
118
|
|
|
106
|
-
|
|
107
|
-
- サーバーサイド関数の戻り値型をvoidに変換するユーティリティ型
|
|
119
|
+
`gasnuki`コマンドを実行すると、指定されたApps Scriptプロジェクト内の `.ts` ファイルを解析し、公開されているすべてのサーバーサイド関数のシグネチャを抽出します。そして、クライアントサイドの`google.script.run`から安全に呼び出せる型定義ファイルを生成します。
|
|
108
120
|
|
|
109
|
-
### Promise
|
|
121
|
+
### PromiseベースのモダンなAPIラッパー
|
|
110
122
|
|
|
111
|
-
`@ciderjs/gasnuki/promise
|
|
123
|
+
`@ciderjs/gasnuki/promise`は、従来のコールバックベースのAPIを、`async/await`で利用可能なPromiseベースの型安全なラッパーに変換します。
|
|
112
124
|
|
|
113
|
-
1.
|
|
125
|
+
1. `getPromisedServerScripts`関数をインポートし、`gasnuki`が生成した型`ServerScripts`を渡します。
|
|
114
126
|
|
|
115
127
|
```ts:lib/gas.ts
|
|
116
128
|
import { getPromisedServerScripts } from '@ciderjs/gasnuki/promise';
|
|
@@ -120,7 +132,7 @@ google.script.run
|
|
|
120
132
|
export const gas = getPromisedServerScripts<ServerScripts>();
|
|
121
133
|
```
|
|
122
134
|
|
|
123
|
-
2.
|
|
135
|
+
2. これで、サーバーサイド関数を `async/await` で呼び出せます。
|
|
124
136
|
|
|
125
137
|
```ts:components/MyComponent.tsx
|
|
126
138
|
import { gas } from '../lib/gas';
|
|
@@ -136,9 +148,9 @@ google.script.run
|
|
|
136
148
|
}
|
|
137
149
|
```
|
|
138
150
|
|
|
139
|
-
|
|
151
|
+
### フロントエンド開発を加速するモック機能
|
|
140
152
|
|
|
141
|
-
`getPromisedServerScripts
|
|
153
|
+
`getPromisedServerScripts`にモック用のオブジェクトを渡すことで、`clasp push`をせずともフロントエンド開発を進めることができます。これにより、バックエンドのロジックに依存せず、UIの挙動確認やデバッグを迅速に行えます。
|
|
142
154
|
|
|
143
155
|
```ts:lib/gas.ts
|
|
144
156
|
import {
|
package/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# @ciderjs/gasnuki
|
|
2
2
|
|
|
3
|
-
[](./README.ja.md)
|
|
4
|
+
[](https://github.com/luthpg/gasnuki)
|
|
5
|
+
[](LICENSE)
|
|
5
6
|
[](https://www.npmjs.com/package/@ciderjs/gasnuki)
|
|
6
7
|
[](https://github.com/luthpg/gasnuki/issues)
|
|
7
8
|
|
|
@@ -9,7 +10,16 @@ Type definitions and utilities for Google Apps Script client-side API
|
|
|
9
10
|
|
|
10
11
|
## Overview
|
|
11
12
|
|
|
12
|
-
`gasnuki`
|
|
13
|
+
`gasnuki` automatically extracts type definitions from your server-side Google Apps Script functions, providing a fully type-safe `google.script.run` API for your client-side code. This bridges the gap between your Apps Script backend and modern frontend development with autocompletion and robust type-checking.
|
|
14
|
+
|
|
15
|
+
## The developer experience gasnuki Delivers
|
|
16
|
+
|
|
17
|
+
`gasnuki` dramatically improves the often-frustrating developer experience of building web applications with Google Apps Script.
|
|
18
|
+
|
|
19
|
+
- **Full Type Safety**: Say goodbye to guesswork. With typed arguments and return values for `google.script.run`, you get full autocompletion and compile-time checks in your editor.
|
|
20
|
+
- **Modern Async Syntax**: Write clean, intuitive code using `async/await` for your server-side calls, freeing you from callback hell.
|
|
21
|
+
- **Rapid Development Cycles**: No more waiting for `clasp push` every time you want to test a frontend change. The mocking feature allows you to develop your UI swiftly and offline.
|
|
22
|
+
- **Seamless Integration**: With the Vite plugin, your client-side types are automatically regenerated whenever you save a change in your server-side code, creating a truly seamless workflow.
|
|
13
23
|
|
|
14
24
|
## Installation
|
|
15
25
|
|
|
@@ -100,16 +110,19 @@ google.script.run
|
|
|
100
110
|
.getContent('Sheet1');
|
|
101
111
|
```
|
|
102
112
|
|
|
103
|
-
## Features
|
|
113
|
+
## Core Features
|
|
114
|
+
|
|
115
|
+
`gasnuki` provides the following features to deliver a superior developer experience.
|
|
104
116
|
|
|
105
|
-
|
|
106
|
-
- Utility type to convert server-side function return types to void
|
|
117
|
+
### Automatic Type Generation for Server Functions
|
|
107
118
|
|
|
108
|
-
|
|
119
|
+
Running the `gasnuki` command parses the `.ts` files in your Apps Script project, extracts the signatures of all your published server-side functions, and generates a type definition file. This file makes your functions safely callable from the client-side `google.script.run`.
|
|
109
120
|
|
|
110
|
-
|
|
121
|
+
### Modern, Promise-Based API Wrapper
|
|
111
122
|
|
|
112
|
-
|
|
123
|
+
`@ciderjs/gasnuki/promise` transforms the traditional callback-based API into a type-safe, Promise-based wrapper that supports `async/await`.
|
|
124
|
+
|
|
125
|
+
1. Import the `getPromisedServerScripts` function and pass it the `ServerScripts` type generated by `gasnuki`.
|
|
113
126
|
|
|
114
127
|
```ts:lib/gas.ts
|
|
115
128
|
import { getPromisedServerScripts } from '@ciderjs/gasnuki/promise';
|
|
@@ -135,9 +148,9 @@ For a more modern asynchronous approach, you can use the type-safe Promise-based
|
|
|
135
148
|
}
|
|
136
149
|
```
|
|
137
150
|
|
|
138
|
-
|
|
151
|
+
### Mocking for Accelerated Frontend Development
|
|
139
152
|
|
|
140
|
-
By passing
|
|
153
|
+
By passing a mock object to `getPromisedServerScripts`, you can develop your frontend without needing to `clasp push`. This allows for rapid testing and debugging of your UI without any dependency on the live backend logic.
|
|
141
154
|
|
|
142
155
|
```ts:lib/gas.ts
|
|
143
156
|
import {
|
|
@@ -159,8 +172,6 @@ const mockup: PartialScriptType<ServerScripts> = {
|
|
|
159
172
|
export const gas = getPromisedServerScripts<ServerScripts>(mockup);
|
|
160
173
|
```
|
|
161
174
|
|
|
162
|
-
---
|
|
163
|
-
|
|
164
175
|
## Contributing
|
|
165
176
|
|
|
166
177
|
Bug reports and pull requests are welcome. Please use the `issues` or `pull requests` section.
|
package/dist/cli.cjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
const path = require('node:path');
|
|
5
5
|
const commander = require('commander');
|
|
6
6
|
const index = require('./index.cjs');
|
|
7
|
-
const config = require('./shared/gasnuki.
|
|
7
|
+
const config = require('./shared/gasnuki.D8w16Lbm.cjs');
|
|
8
8
|
require('chokidar');
|
|
9
9
|
require('consola');
|
|
10
10
|
require('node:fs');
|
|
@@ -25,7 +25,7 @@ function _interopNamespaceCompat(e) {
|
|
|
25
25
|
|
|
26
26
|
const path__namespace = /*#__PURE__*/_interopNamespaceCompat(path);
|
|
27
27
|
|
|
28
|
-
const version = "0.3.
|
|
28
|
+
const version = "0.3.3";
|
|
29
29
|
|
|
30
30
|
const parseArgs = async (command) => {
|
|
31
31
|
const cliOpts = command.opts();
|
|
@@ -51,7 +51,7 @@ const parseArgs = async (command) => {
|
|
|
51
51
|
};
|
|
52
52
|
await index.generateTypes(finalOptions);
|
|
53
53
|
};
|
|
54
|
-
const
|
|
54
|
+
const runCli = async () => {
|
|
55
55
|
const program = new commander.Command();
|
|
56
56
|
program.name("gasnuki").description(
|
|
57
57
|
"Generate type definitions and utilities for Google Apps Script client-side API"
|
|
@@ -72,7 +72,10 @@ const cli = async () => {
|
|
|
72
72
|
).option("-f, --outputFile <file>", "Output file name", "appsscript.ts").option("-w, --watch", "Watch for changes and re-generate types", false);
|
|
73
73
|
await program.parseAsync(process.argv);
|
|
74
74
|
};
|
|
75
|
-
|
|
75
|
+
const isMainModule = typeof require !== "undefined" && require.main === module;
|
|
76
|
+
if (isMainModule || process.argv[1] === undefined) {
|
|
77
|
+
runCli();
|
|
78
|
+
}
|
|
76
79
|
|
|
77
|
-
exports.cli = cli;
|
|
78
80
|
exports.parseArgs = parseArgs;
|
|
81
|
+
exports.runCli = runCli;
|
package/dist/cli.d.cts
CHANGED
package/dist/cli.d.mts
CHANGED
package/dist/cli.d.ts
CHANGED
package/dist/cli.mjs
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import { generateTypes } from './index.mjs';
|
|
5
|
-
import { l as loadConfig } from './shared/gasnuki.
|
|
5
|
+
import { l as loadConfig } from './shared/gasnuki.D1fp3Uiw.mjs';
|
|
6
6
|
import 'chokidar';
|
|
7
7
|
import 'consola';
|
|
8
8
|
import 'node:fs';
|
|
9
9
|
import 'ts-morph';
|
|
10
10
|
import 'jiti';
|
|
11
11
|
|
|
12
|
-
const version = "0.3.
|
|
12
|
+
const version = "0.3.3";
|
|
13
13
|
|
|
14
14
|
const parseArgs = async (command) => {
|
|
15
15
|
const cliOpts = command.opts();
|
|
@@ -35,7 +35,7 @@ const parseArgs = async (command) => {
|
|
|
35
35
|
};
|
|
36
36
|
await generateTypes(finalOptions);
|
|
37
37
|
};
|
|
38
|
-
const
|
|
38
|
+
const runCli = async () => {
|
|
39
39
|
const program = new Command();
|
|
40
40
|
program.name("gasnuki").description(
|
|
41
41
|
"Generate type definitions and utilities for Google Apps Script client-side API"
|
|
@@ -56,6 +56,9 @@ const cli = async () => {
|
|
|
56
56
|
).option("-f, --outputFile <file>", "Output file name", "appsscript.ts").option("-w, --watch", "Watch for changes and re-generate types", false);
|
|
57
57
|
await program.parseAsync(process.argv);
|
|
58
58
|
};
|
|
59
|
-
|
|
59
|
+
const isMainModule = typeof require !== "undefined" && require.main === module;
|
|
60
|
+
if (isMainModule || process.argv[1] === import.meta.filename) {
|
|
61
|
+
runCli();
|
|
62
|
+
}
|
|
60
63
|
|
|
61
|
-
export {
|
|
64
|
+
export { parseArgs, runCli };
|
package/dist/index.cjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const path = require('node:path');
|
|
4
4
|
const chokidar = require('chokidar');
|
|
5
5
|
const consola = require('consola');
|
|
6
|
-
const config = require('./shared/gasnuki.
|
|
6
|
+
const config = require('./shared/gasnuki.D8w16Lbm.cjs');
|
|
7
7
|
require('node:fs');
|
|
8
8
|
require('ts-morph');
|
|
9
9
|
require('jiti');
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as path from 'node:path';
|
|
2
2
|
import * as chokidar from 'chokidar';
|
|
3
3
|
import { consola } from 'consola';
|
|
4
|
-
import { g as generateAppsScriptTypes } from './shared/gasnuki.
|
|
5
|
-
export { d as defineConfig } from './shared/gasnuki.
|
|
4
|
+
import { g as generateAppsScriptTypes } from './shared/gasnuki.D1fp3Uiw.mjs';
|
|
5
|
+
export { d as defineConfig } from './shared/gasnuki.D1fp3Uiw.mjs';
|
|
6
6
|
import 'node:fs';
|
|
7
7
|
import 'ts-morph';
|
|
8
8
|
import 'jiti';
|
|
@@ -51,11 +51,34 @@ const SIMPLE_TRIGGER_FUNCTION_NAMES = [
|
|
|
51
51
|
"doGet",
|
|
52
52
|
"doPost"
|
|
53
53
|
];
|
|
54
|
+
const getPackageNameFromNodeModulesPath_ = (filePath) => {
|
|
55
|
+
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
56
|
+
const nodeModulesIndex = normalizedPath.lastIndexOf("node_modules/");
|
|
57
|
+
if (nodeModulesIndex === -1) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
const afterNodeModules = normalizedPath.slice(
|
|
61
|
+
nodeModulesIndex + "node_modules/".length
|
|
62
|
+
);
|
|
63
|
+
const parts = afterNodeModules.split("/");
|
|
64
|
+
if (parts.length === 0) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
if (parts[0].startsWith("@") && parts.length >= 2) {
|
|
68
|
+
const scopedName = `${parts[0]}/${parts[1]}`;
|
|
69
|
+
if (parts[0] === "@types") {
|
|
70
|
+
return parts[1];
|
|
71
|
+
}
|
|
72
|
+
return scopedName;
|
|
73
|
+
}
|
|
74
|
+
return parts[0];
|
|
75
|
+
};
|
|
54
76
|
const generateAppsScriptTypes = async ({
|
|
55
77
|
project: projectPath,
|
|
56
78
|
srcDir,
|
|
57
79
|
outDir,
|
|
58
|
-
outputFile
|
|
80
|
+
outputFile,
|
|
81
|
+
projectInstance
|
|
59
82
|
}) => {
|
|
60
83
|
const absoluteSrcDir = path.resolve(projectPath, srcDir);
|
|
61
84
|
const absoluteOutDir = path.resolve(projectPath, outDir);
|
|
@@ -63,7 +86,7 @@ const generateAppsScriptTypes = async ({
|
|
|
63
86
|
consola.info("Starting AppsScript type generation with gasnuki...");
|
|
64
87
|
consola.info(` AppsScript Source Directory: ${absoluteSrcDir}`);
|
|
65
88
|
consola.info(` Output File: ${absoluteOutputFile}`);
|
|
66
|
-
const project = new Project({
|
|
89
|
+
const project = projectInstance ?? new Project({
|
|
67
90
|
tsConfigFilePath: path.resolve(projectPath, "tsconfig.json"),
|
|
68
91
|
skipAddingFilesFromTsConfig: true
|
|
69
92
|
});
|
|
@@ -75,7 +98,6 @@ const generateAppsScriptTypes = async ({
|
|
|
75
98
|
const methodDefinitions = [];
|
|
76
99
|
const exportedDeclarations = [];
|
|
77
100
|
const exportedDeclarationNames = /* @__PURE__ */ new Set();
|
|
78
|
-
const exportedFunctions = [];
|
|
79
101
|
for (const sourceFile of sourceFiles) {
|
|
80
102
|
const filePath = sourceFile.getFilePath().replace(/\\/g, "/");
|
|
81
103
|
const srcPath = absoluteSrcDir.replace(/\\/g, "/");
|
|
@@ -101,7 +123,6 @@ const generateAppsScriptTypes = async ({
|
|
|
101
123
|
exportedDeclarations.push(func);
|
|
102
124
|
exportedDeclarationNames.add(name);
|
|
103
125
|
methodDefinitions.push(getInterfaceMethodDefinition_(name, func));
|
|
104
|
-
exportedFunctions.push(func);
|
|
105
126
|
}
|
|
106
127
|
}
|
|
107
128
|
for (const varStmt of sourceFile.getVariableStatements()) {
|
|
@@ -113,7 +134,6 @@ const generateAppsScriptTypes = async ({
|
|
|
113
134
|
exportedDeclarations.push(varDecl);
|
|
114
135
|
exportedDeclarationNames.add(name);
|
|
115
136
|
methodDefinitions.push(getInterfaceMethodDefinition_(name, funcExpr));
|
|
116
|
-
exportedFunctions.push(funcExpr);
|
|
117
137
|
}
|
|
118
138
|
}
|
|
119
139
|
}
|
|
@@ -145,38 +165,21 @@ const generateAppsScriptTypes = async ({
|
|
|
145
165
|
}
|
|
146
166
|
}
|
|
147
167
|
};
|
|
148
|
-
const
|
|
149
|
-
for (const func of exportedFunctions) {
|
|
150
|
-
collectSymbolsFromType(func.getReturnType(), returnValueSymbols);
|
|
151
|
-
}
|
|
168
|
+
const functionSignatureSymbols = /* @__PURE__ */ new Set();
|
|
152
169
|
const symbolsToProcess = /* @__PURE__ */ new Set();
|
|
153
170
|
for (const decl of exportedDeclarations) {
|
|
154
171
|
if (decl.getKind() === SyntaxKind.FunctionDeclaration || decl.getKind() === SyntaxKind.VariableDeclaration && (decl.getInitializer()?.getKind() === SyntaxKind.ArrowFunction || decl.getInitializer()?.getKind() === SyntaxKind.FunctionExpression)) {
|
|
155
172
|
const func = decl.getKind() === SyntaxKind.FunctionDeclaration ? decl : decl.getInitializer();
|
|
156
173
|
const parameters = func.getParameters();
|
|
157
174
|
for (const param of parameters) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const symbol = typeRef.getType().getAliasSymbol() ?? typeRef.getType().getSymbol();
|
|
161
|
-
if (symbol) symbolsToProcess.add(symbol);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
const returnTypeNode = func.getReturnTypeNode();
|
|
165
|
-
if (returnTypeNode) {
|
|
166
|
-
const typeRefs = returnTypeNode.getDescendantsOfKind(
|
|
167
|
-
SyntaxKind.TypeReference
|
|
168
|
-
);
|
|
169
|
-
for (const typeRef of typeRefs) {
|
|
170
|
-
const symbol = typeRef.getType().getAliasSymbol() ?? typeRef.getType().getSymbol();
|
|
171
|
-
if (symbol) symbolsToProcess.add(symbol);
|
|
172
|
-
}
|
|
175
|
+
collectSymbolsFromType(param.getType(), functionSignatureSymbols);
|
|
176
|
+
collectSymbolsFromType(param.getType(), symbolsToProcess);
|
|
173
177
|
}
|
|
178
|
+
const returnType = func.getReturnType();
|
|
179
|
+
collectSymbolsFromType(returnType, functionSignatureSymbols);
|
|
180
|
+
collectSymbolsFromType(returnType, symbolsToProcess);
|
|
174
181
|
} else if (decl.getKind() === SyntaxKind.InterfaceDeclaration || decl.getKind() === SyntaxKind.TypeAliasDeclaration) {
|
|
175
|
-
|
|
176
|
-
for (const typeRef of typeRefs) {
|
|
177
|
-
const symbol = typeRef.getType().getAliasSymbol() ?? typeRef.getType().getSymbol();
|
|
178
|
-
if (symbol) symbolsToProcess.add(symbol);
|
|
179
|
-
}
|
|
182
|
+
collectSymbolsFromType(decl.getType(), symbolsToProcess);
|
|
180
183
|
}
|
|
181
184
|
}
|
|
182
185
|
const importsMap = /* @__PURE__ */ new Map();
|
|
@@ -198,9 +201,25 @@ const generateAppsScriptTypes = async ({
|
|
|
198
201
|
if (!declaration) {
|
|
199
202
|
continue;
|
|
200
203
|
}
|
|
204
|
+
if (declaration.getKind() === SyntaxKind.MethodSignature || declaration.getKind() === SyntaxKind.PropertySignature || declaration.getKind() === SyntaxKind.MethodDeclaration || declaration.getKind() === SyntaxKind.PropertyDeclaration) {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
201
207
|
const sourceFile = declaration.getSourceFile();
|
|
202
208
|
const sourceFilePath = sourceFile.getFilePath();
|
|
209
|
+
if (/[/\\]typescript[/\\]lib[/\\]/.test(sourceFilePath)) {
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
203
212
|
if (sourceFilePath.includes("node_modules")) {
|
|
213
|
+
if (functionSignatureSymbols.has(symbol)) {
|
|
214
|
+
const packageName = getPackageNameFromNodeModulesPath_(sourceFilePath);
|
|
215
|
+
if (packageName) {
|
|
216
|
+
processedSymbols.add(symbolName);
|
|
217
|
+
if (!importsMap.has(packageName)) {
|
|
218
|
+
importsMap.set(packageName, /* @__PURE__ */ new Set());
|
|
219
|
+
}
|
|
220
|
+
importsMap.get(packageName)?.add(symbolName);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
204
223
|
continue;
|
|
205
224
|
}
|
|
206
225
|
processedSymbols.add(symbolName);
|
|
@@ -68,11 +68,34 @@ const SIMPLE_TRIGGER_FUNCTION_NAMES = [
|
|
|
68
68
|
"doGet",
|
|
69
69
|
"doPost"
|
|
70
70
|
];
|
|
71
|
+
const getPackageNameFromNodeModulesPath_ = (filePath) => {
|
|
72
|
+
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
73
|
+
const nodeModulesIndex = normalizedPath.lastIndexOf("node_modules/");
|
|
74
|
+
if (nodeModulesIndex === -1) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const afterNodeModules = normalizedPath.slice(
|
|
78
|
+
nodeModulesIndex + "node_modules/".length
|
|
79
|
+
);
|
|
80
|
+
const parts = afterNodeModules.split("/");
|
|
81
|
+
if (parts.length === 0) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
if (parts[0].startsWith("@") && parts.length >= 2) {
|
|
85
|
+
const scopedName = `${parts[0]}/${parts[1]}`;
|
|
86
|
+
if (parts[0] === "@types") {
|
|
87
|
+
return parts[1];
|
|
88
|
+
}
|
|
89
|
+
return scopedName;
|
|
90
|
+
}
|
|
91
|
+
return parts[0];
|
|
92
|
+
};
|
|
71
93
|
const generateAppsScriptTypes = async ({
|
|
72
94
|
project: projectPath,
|
|
73
95
|
srcDir,
|
|
74
96
|
outDir,
|
|
75
|
-
outputFile
|
|
97
|
+
outputFile,
|
|
98
|
+
projectInstance
|
|
76
99
|
}) => {
|
|
77
100
|
const absoluteSrcDir = path__namespace.resolve(projectPath, srcDir);
|
|
78
101
|
const absoluteOutDir = path__namespace.resolve(projectPath, outDir);
|
|
@@ -80,7 +103,7 @@ const generateAppsScriptTypes = async ({
|
|
|
80
103
|
consola.consola.info("Starting AppsScript type generation with gasnuki...");
|
|
81
104
|
consola.consola.info(` AppsScript Source Directory: ${absoluteSrcDir}`);
|
|
82
105
|
consola.consola.info(` Output File: ${absoluteOutputFile}`);
|
|
83
|
-
const project = new tsMorph.Project({
|
|
106
|
+
const project = projectInstance ?? new tsMorph.Project({
|
|
84
107
|
tsConfigFilePath: path__namespace.resolve(projectPath, "tsconfig.json"),
|
|
85
108
|
skipAddingFilesFromTsConfig: true
|
|
86
109
|
});
|
|
@@ -92,7 +115,6 @@ const generateAppsScriptTypes = async ({
|
|
|
92
115
|
const methodDefinitions = [];
|
|
93
116
|
const exportedDeclarations = [];
|
|
94
117
|
const exportedDeclarationNames = /* @__PURE__ */ new Set();
|
|
95
|
-
const exportedFunctions = [];
|
|
96
118
|
for (const sourceFile of sourceFiles) {
|
|
97
119
|
const filePath = sourceFile.getFilePath().replace(/\\/g, "/");
|
|
98
120
|
const srcPath = absoluteSrcDir.replace(/\\/g, "/");
|
|
@@ -118,7 +140,6 @@ const generateAppsScriptTypes = async ({
|
|
|
118
140
|
exportedDeclarations.push(func);
|
|
119
141
|
exportedDeclarationNames.add(name);
|
|
120
142
|
methodDefinitions.push(getInterfaceMethodDefinition_(name, func));
|
|
121
|
-
exportedFunctions.push(func);
|
|
122
143
|
}
|
|
123
144
|
}
|
|
124
145
|
for (const varStmt of sourceFile.getVariableStatements()) {
|
|
@@ -130,7 +151,6 @@ const generateAppsScriptTypes = async ({
|
|
|
130
151
|
exportedDeclarations.push(varDecl);
|
|
131
152
|
exportedDeclarationNames.add(name);
|
|
132
153
|
methodDefinitions.push(getInterfaceMethodDefinition_(name, funcExpr));
|
|
133
|
-
exportedFunctions.push(funcExpr);
|
|
134
154
|
}
|
|
135
155
|
}
|
|
136
156
|
}
|
|
@@ -162,38 +182,21 @@ const generateAppsScriptTypes = async ({
|
|
|
162
182
|
}
|
|
163
183
|
}
|
|
164
184
|
};
|
|
165
|
-
const
|
|
166
|
-
for (const func of exportedFunctions) {
|
|
167
|
-
collectSymbolsFromType(func.getReturnType(), returnValueSymbols);
|
|
168
|
-
}
|
|
185
|
+
const functionSignatureSymbols = /* @__PURE__ */ new Set();
|
|
169
186
|
const symbolsToProcess = /* @__PURE__ */ new Set();
|
|
170
187
|
for (const decl of exportedDeclarations) {
|
|
171
188
|
if (decl.getKind() === tsMorph.SyntaxKind.FunctionDeclaration || decl.getKind() === tsMorph.SyntaxKind.VariableDeclaration && (decl.getInitializer()?.getKind() === tsMorph.SyntaxKind.ArrowFunction || decl.getInitializer()?.getKind() === tsMorph.SyntaxKind.FunctionExpression)) {
|
|
172
189
|
const func = decl.getKind() === tsMorph.SyntaxKind.FunctionDeclaration ? decl : decl.getInitializer();
|
|
173
190
|
const parameters = func.getParameters();
|
|
174
191
|
for (const param of parameters) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
const symbol = typeRef.getType().getAliasSymbol() ?? typeRef.getType().getSymbol();
|
|
178
|
-
if (symbol) symbolsToProcess.add(symbol);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
const returnTypeNode = func.getReturnTypeNode();
|
|
182
|
-
if (returnTypeNode) {
|
|
183
|
-
const typeRefs = returnTypeNode.getDescendantsOfKind(
|
|
184
|
-
tsMorph.SyntaxKind.TypeReference
|
|
185
|
-
);
|
|
186
|
-
for (const typeRef of typeRefs) {
|
|
187
|
-
const symbol = typeRef.getType().getAliasSymbol() ?? typeRef.getType().getSymbol();
|
|
188
|
-
if (symbol) symbolsToProcess.add(symbol);
|
|
189
|
-
}
|
|
192
|
+
collectSymbolsFromType(param.getType(), functionSignatureSymbols);
|
|
193
|
+
collectSymbolsFromType(param.getType(), symbolsToProcess);
|
|
190
194
|
}
|
|
195
|
+
const returnType = func.getReturnType();
|
|
196
|
+
collectSymbolsFromType(returnType, functionSignatureSymbols);
|
|
197
|
+
collectSymbolsFromType(returnType, symbolsToProcess);
|
|
191
198
|
} else if (decl.getKind() === tsMorph.SyntaxKind.InterfaceDeclaration || decl.getKind() === tsMorph.SyntaxKind.TypeAliasDeclaration) {
|
|
192
|
-
|
|
193
|
-
for (const typeRef of typeRefs) {
|
|
194
|
-
const symbol = typeRef.getType().getAliasSymbol() ?? typeRef.getType().getSymbol();
|
|
195
|
-
if (symbol) symbolsToProcess.add(symbol);
|
|
196
|
-
}
|
|
199
|
+
collectSymbolsFromType(decl.getType(), symbolsToProcess);
|
|
197
200
|
}
|
|
198
201
|
}
|
|
199
202
|
const importsMap = /* @__PURE__ */ new Map();
|
|
@@ -215,9 +218,25 @@ const generateAppsScriptTypes = async ({
|
|
|
215
218
|
if (!declaration) {
|
|
216
219
|
continue;
|
|
217
220
|
}
|
|
221
|
+
if (declaration.getKind() === tsMorph.SyntaxKind.MethodSignature || declaration.getKind() === tsMorph.SyntaxKind.PropertySignature || declaration.getKind() === tsMorph.SyntaxKind.MethodDeclaration || declaration.getKind() === tsMorph.SyntaxKind.PropertyDeclaration) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
218
224
|
const sourceFile = declaration.getSourceFile();
|
|
219
225
|
const sourceFilePath = sourceFile.getFilePath();
|
|
226
|
+
if (/[/\\]typescript[/\\]lib[/\\]/.test(sourceFilePath)) {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
220
229
|
if (sourceFilePath.includes("node_modules")) {
|
|
230
|
+
if (functionSignatureSymbols.has(symbol)) {
|
|
231
|
+
const packageName = getPackageNameFromNodeModulesPath_(sourceFilePath);
|
|
232
|
+
if (packageName) {
|
|
233
|
+
processedSymbols.add(symbolName);
|
|
234
|
+
if (!importsMap.has(packageName)) {
|
|
235
|
+
importsMap.set(packageName, /* @__PURE__ */ new Set());
|
|
236
|
+
}
|
|
237
|
+
importsMap.get(packageName)?.add(symbolName);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
221
240
|
continue;
|
|
222
241
|
}
|
|
223
242
|
processedSymbols.add(symbolName);
|
package/dist/vite.cjs
CHANGED
package/dist/vite.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as path from 'node:path';
|
|
2
2
|
import { consola } from 'consola';
|
|
3
|
-
import { l as loadConfig, g as generateAppsScriptTypes } from './shared/gasnuki.
|
|
3
|
+
import { l as loadConfig, g as generateAppsScriptTypes } from './shared/gasnuki.D1fp3Uiw.mjs';
|
|
4
4
|
import 'node:fs';
|
|
5
5
|
import 'ts-morph';
|
|
6
6
|
import 'jiti';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ciderjs/gasnuki",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Type definitions and utilities for Google Apps Script client-side API",
|
|
5
5
|
"main": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"start": "node dist/cli.mjs -p playground/react -s src/server",
|
|
31
31
|
"check": "biome check --write",
|
|
32
32
|
"build": "unbuild",
|
|
33
|
-
"test": "vitest run",
|
|
34
|
-
"test:coverage": "vitest run --coverage",
|
|
33
|
+
"test": "vitest run --silent",
|
|
34
|
+
"test:coverage": "vitest run --coverage --silent",
|
|
35
35
|
"update-coverage-badge": "jiti scripts/update-coverage-badge.ts README.md README.ja.md",
|
|
36
36
|
"test:coverage:update": "pnpm test:coverage && pnpm update-coverage-badge",
|
|
37
37
|
"prepublish": "pnpm run generate && pnpm run check && pnpm run test:coverage:update && pnpm run build",
|
|
@@ -55,20 +55,20 @@
|
|
|
55
55
|
},
|
|
56
56
|
"packageManager": "pnpm@10.18.3",
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"chokidar": "^
|
|
59
|
-
"commander": "^14.0.
|
|
58
|
+
"chokidar": "^5.0.0",
|
|
59
|
+
"commander": "^14.0.2",
|
|
60
60
|
"consola": "^3.4.2",
|
|
61
61
|
"jiti": "^2.6.1",
|
|
62
62
|
"ts-morph": "^27.0.2"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@biomejs/biome": "^2.
|
|
66
|
-
"@types/node": "^
|
|
67
|
-
"@vitest/coverage-v8": "
|
|
65
|
+
"@biomejs/biome": "^2.3.8",
|
|
66
|
+
"@types/node": "^25.0.1",
|
|
67
|
+
"@vitest/coverage-v8": "4.0.15",
|
|
68
68
|
"typescript": "^5.9.3",
|
|
69
69
|
"unbuild": "^3.6.1",
|
|
70
|
-
"vite": "^7.
|
|
71
|
-
"vitest": "
|
|
70
|
+
"vite": "^7.2.7",
|
|
71
|
+
"vitest": "4.0.15"
|
|
72
72
|
},
|
|
73
73
|
"peerDependencies": {
|
|
74
74
|
"vite": "^7"
|
package/.vscode/settings.json
DELETED