@ciderjs/gasnuki 0.3.2 → 0.3.4

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 CHANGED
@@ -1,7 +1,8 @@
1
- # gasnuki
1
+ # @ciderjs/gasnuki
2
2
 
3
- [![Test Coverage](https://img.shields.io/badge/test%20coverage-95.1%25-brightgreen)](https://github.com/luthpg/gasnuki)
4
- [![License](https://img.shields.io/badge/license-ISC-blue.svg)](LICENSE)
3
+ [![README-en](https://img.shields.io/badge/English-blue?logo=ReadMe)](./README.md)
4
+ [![Test Coverage](https://img.shields.io/badge/test%20coverage-94.32%25-brightgreen)](https://github.com/luthpg/gasnuki)
5
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5
6
  [![npm version](https://img.shields.io/npm/v/@ciderjs/gasnuki.svg)](https://www.npmjs.com/package/@ciderjs/gasnuki)
6
7
  [![GitHub issues](https://img.shields.io/github/issues/luthpg/gasnuki.svg)](https://github.com/luthpg/gasnuki/issues)
7
8
 
@@ -9,8 +10,16 @@ Google Apps Script クライアントサイドAPIの型定義・ユーティリ
9
10
 
10
11
  ## 概要
11
12
 
12
- `gasnuki`は、Google Apps Script のクライアントサイドAPIをTypeScriptで安全に扱うための型定義とユーティリティを提供します。
13
- Apps Scriptとフロントエンド間の型安全な通信をサポートします。
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
- - Google Apps Script クライアントAPIの型定義
107
- - サーバーサイド関数の戻り値型をvoidに変換するユーティリティ型
119
+ `gasnuki`コマンドを実行すると、指定されたApps Scriptプロジェクト内の `.ts` ファイルを解析し、公開されているすべてのサーバーサイド関数のシグネチャを抽出します。そして、クライアントサイドの`google.script.run`から安全に呼び出せる型定義ファイルを生成します。
108
120
 
109
- ### Promiseベースのラッパー
121
+ ### PromiseベースのモダンなAPIラッパー
110
122
 
111
- `@ciderjs/gasnuki/promise` を利用すると、`google.script.run` をPromiseを返す型安全なラッパーとして使用できます。これにより、`async/await` を使ったモダンな非同期処理を記述できます。
123
+ `@ciderjs/gasnuki/promise`は、従来のコールバックベースのAPIを、`async/await`で利用可能なPromiseベースの型安全なラッパーに変換します。
112
124
 
113
- 1. まず、`gasnuki` で生成した型定義 (`ServerScripts`) と、`getPromisedServerScripts` 関数をインポートします。
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. 作成した `gas` オブジェクトを使って、サーバーサイド関数を `async/await` で呼び出します。
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` にモック関数を渡すことで、`clasp push` をせずともフロントエンド開発を進めることができます。
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
- [![Test Coverage](https://img.shields.io/badge/test%20coverage-95.1%25-brightgreen)](https://github.com/luthpg/gasnuki)
4
- [![License](https://img.shields.io/badge/license-ISC-blue.svg)](LICENSE)
3
+ [![README-ja](https://img.shields.io/badge/日本語-blue?logo=ReadMe)](./README.ja.md)
4
+ [![Test Coverage](https://img.shields.io/badge/test%20coverage-94.32%25-brightgreen)](https://github.com/luthpg/gasnuki)
5
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5
6
  [![npm version](https://img.shields.io/npm/v/@ciderjs/gasnuki.svg)](https://www.npmjs.com/package/@ciderjs/gasnuki)
6
7
  [![GitHub issues](https://img.shields.io/github/issues/luthpg/gasnuki.svg)](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` provides TypeScript type definitions and utilities for safely using the Google Apps Script client-side API. It helps ensure type-safe communication between Apps Script and your frontend.
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
- - Type definitions for Google Apps Script client-side API
106
- - Utility type to convert server-side function return types to void
117
+ ### Automatic Type Generation for Server Functions
107
118
 
108
- ### Promise-based Wrapper
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
- For a more modern asynchronous approach, you can use the type-safe Promise-based wrapper for `google.script.run`. This allows you to write clean code with `async/await`.
121
+ ### Modern, Promise-Based API Wrapper
111
122
 
112
- 1. First, import the type definitions (`ServerScripts`) generated by `gasnuki` and the `getPromisedServerScripts` function.
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
- #### Development with Mockups
151
+ ### Mocking for Accelerated Frontend Development
139
152
 
140
- By passing mockup functions to `getPromisedServerScripts`, you can proceed with frontend development without needing to `clasp push` every time.
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.BziruiRW.cjs');
7
+ const config = require('./shared/gasnuki.kBd1L15Q.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.2";
28
+ const version = "0.3.4";
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 cli = async () => {
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
- cli();
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
@@ -2,6 +2,6 @@
2
2
  import { Command } from 'commander';
3
3
 
4
4
  declare const parseArgs: (command: Command) => Promise<void>;
5
- declare const cli: () => Promise<void>;
5
+ declare const runCli: () => Promise<void>;
6
6
 
7
- export { cli, parseArgs };
7
+ export { parseArgs, runCli };
package/dist/cli.d.mts CHANGED
@@ -2,6 +2,6 @@
2
2
  import { Command } from 'commander';
3
3
 
4
4
  declare const parseArgs: (command: Command) => Promise<void>;
5
- declare const cli: () => Promise<void>;
5
+ declare const runCli: () => Promise<void>;
6
6
 
7
- export { cli, parseArgs };
7
+ export { parseArgs, runCli };
package/dist/cli.d.ts CHANGED
@@ -2,6 +2,6 @@
2
2
  import { Command } from 'commander';
3
3
 
4
4
  declare const parseArgs: (command: Command) => Promise<void>;
5
- declare const cli: () => Promise<void>;
5
+ declare const runCli: () => Promise<void>;
6
6
 
7
- export { cli, parseArgs };
7
+ export { parseArgs, runCli };
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.CS6ipBfD.mjs';
5
+ import { l as loadConfig } from './shared/gasnuki.C96Q3amR.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.2";
12
+ const version = "0.3.4";
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 cli = async () => {
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
- cli();
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 { cli, parseArgs };
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.BziruiRW.cjs');
6
+ const config = require('./shared/gasnuki.kBd1L15Q.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.CS6ipBfD.mjs';
5
- export { d as defineConfig } from './shared/gasnuki.CS6ipBfD.mjs';
4
+ import { g as generateAppsScriptTypes } from './shared/gasnuki.C96Q3amR.mjs';
5
+ export { d as defineConfig } from './shared/gasnuki.C96Q3amR.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
  });
@@ -116,7 +139,18 @@ const generateAppsScriptTypes = async ({
116
139
  }
117
140
  }
118
141
  const collectSymbolsFromType = (type, foundSymbols) => {
119
- const symbol = type.getAliasSymbol() ?? type.getSymbol();
142
+ const aliasSymbol = type.getAliasSymbol();
143
+ if (aliasSymbol) {
144
+ if (foundSymbols.has(aliasSymbol)) {
145
+ return;
146
+ }
147
+ foundSymbols.add(aliasSymbol);
148
+ for (const typeArg of type.getAliasTypeArguments()) {
149
+ collectSymbolsFromType(typeArg, foundSymbols);
150
+ }
151
+ return;
152
+ }
153
+ const symbol = type.getSymbol();
120
154
  if (symbol && !foundSymbols.has(symbol)) {
121
155
  foundSymbols.add(symbol);
122
156
  if (type.isObject()) {
@@ -142,15 +176,18 @@ const generateAppsScriptTypes = async ({
142
176
  }
143
177
  }
144
178
  };
179
+ const functionSignatureSymbols = /* @__PURE__ */ new Set();
145
180
  const symbolsToProcess = /* @__PURE__ */ new Set();
146
181
  for (const decl of exportedDeclarations) {
147
182
  if (decl.getKind() === SyntaxKind.FunctionDeclaration || decl.getKind() === SyntaxKind.VariableDeclaration && (decl.getInitializer()?.getKind() === SyntaxKind.ArrowFunction || decl.getInitializer()?.getKind() === SyntaxKind.FunctionExpression)) {
148
183
  const func = decl.getKind() === SyntaxKind.FunctionDeclaration ? decl : decl.getInitializer();
149
184
  const parameters = func.getParameters();
150
185
  for (const param of parameters) {
186
+ collectSymbolsFromType(param.getType(), functionSignatureSymbols);
151
187
  collectSymbolsFromType(param.getType(), symbolsToProcess);
152
188
  }
153
189
  const returnType = func.getReturnType();
190
+ collectSymbolsFromType(returnType, functionSignatureSymbols);
154
191
  collectSymbolsFromType(returnType, symbolsToProcess);
155
192
  } else if (decl.getKind() === SyntaxKind.InterfaceDeclaration || decl.getKind() === SyntaxKind.TypeAliasDeclaration) {
156
193
  collectSymbolsFromType(decl.getType(), symbolsToProcess);
@@ -175,9 +212,25 @@ const generateAppsScriptTypes = async ({
175
212
  if (!declaration) {
176
213
  continue;
177
214
  }
215
+ if (declaration.getKind() === SyntaxKind.MethodSignature || declaration.getKind() === SyntaxKind.PropertySignature || declaration.getKind() === SyntaxKind.MethodDeclaration || declaration.getKind() === SyntaxKind.PropertyDeclaration) {
216
+ continue;
217
+ }
178
218
  const sourceFile = declaration.getSourceFile();
179
219
  const sourceFilePath = sourceFile.getFilePath();
220
+ if (/[/\\]typescript[/\\]lib[/\\]/.test(sourceFilePath)) {
221
+ continue;
222
+ }
180
223
  if (sourceFilePath.includes("node_modules")) {
224
+ if (functionSignatureSymbols.has(symbol)) {
225
+ const packageName = getPackageNameFromNodeModulesPath_(sourceFilePath);
226
+ if (packageName) {
227
+ processedSymbols.add(symbolName);
228
+ if (!importsMap.has(packageName)) {
229
+ importsMap.set(packageName, /* @__PURE__ */ new Set());
230
+ }
231
+ importsMap.get(packageName)?.add(symbolName);
232
+ }
233
+ }
181
234
  continue;
182
235
  }
183
236
  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
  });
@@ -133,7 +156,18 @@ const generateAppsScriptTypes = async ({
133
156
  }
134
157
  }
135
158
  const collectSymbolsFromType = (type, foundSymbols) => {
136
- const symbol = type.getAliasSymbol() ?? type.getSymbol();
159
+ const aliasSymbol = type.getAliasSymbol();
160
+ if (aliasSymbol) {
161
+ if (foundSymbols.has(aliasSymbol)) {
162
+ return;
163
+ }
164
+ foundSymbols.add(aliasSymbol);
165
+ for (const typeArg of type.getAliasTypeArguments()) {
166
+ collectSymbolsFromType(typeArg, foundSymbols);
167
+ }
168
+ return;
169
+ }
170
+ const symbol = type.getSymbol();
137
171
  if (symbol && !foundSymbols.has(symbol)) {
138
172
  foundSymbols.add(symbol);
139
173
  if (type.isObject()) {
@@ -159,15 +193,18 @@ const generateAppsScriptTypes = async ({
159
193
  }
160
194
  }
161
195
  };
196
+ const functionSignatureSymbols = /* @__PURE__ */ new Set();
162
197
  const symbolsToProcess = /* @__PURE__ */ new Set();
163
198
  for (const decl of exportedDeclarations) {
164
199
  if (decl.getKind() === tsMorph.SyntaxKind.FunctionDeclaration || decl.getKind() === tsMorph.SyntaxKind.VariableDeclaration && (decl.getInitializer()?.getKind() === tsMorph.SyntaxKind.ArrowFunction || decl.getInitializer()?.getKind() === tsMorph.SyntaxKind.FunctionExpression)) {
165
200
  const func = decl.getKind() === tsMorph.SyntaxKind.FunctionDeclaration ? decl : decl.getInitializer();
166
201
  const parameters = func.getParameters();
167
202
  for (const param of parameters) {
203
+ collectSymbolsFromType(param.getType(), functionSignatureSymbols);
168
204
  collectSymbolsFromType(param.getType(), symbolsToProcess);
169
205
  }
170
206
  const returnType = func.getReturnType();
207
+ collectSymbolsFromType(returnType, functionSignatureSymbols);
171
208
  collectSymbolsFromType(returnType, symbolsToProcess);
172
209
  } else if (decl.getKind() === tsMorph.SyntaxKind.InterfaceDeclaration || decl.getKind() === tsMorph.SyntaxKind.TypeAliasDeclaration) {
173
210
  collectSymbolsFromType(decl.getType(), symbolsToProcess);
@@ -192,9 +229,25 @@ const generateAppsScriptTypes = async ({
192
229
  if (!declaration) {
193
230
  continue;
194
231
  }
232
+ if (declaration.getKind() === tsMorph.SyntaxKind.MethodSignature || declaration.getKind() === tsMorph.SyntaxKind.PropertySignature || declaration.getKind() === tsMorph.SyntaxKind.MethodDeclaration || declaration.getKind() === tsMorph.SyntaxKind.PropertyDeclaration) {
233
+ continue;
234
+ }
195
235
  const sourceFile = declaration.getSourceFile();
196
236
  const sourceFilePath = sourceFile.getFilePath();
237
+ if (/[/\\]typescript[/\\]lib[/\\]/.test(sourceFilePath)) {
238
+ continue;
239
+ }
197
240
  if (sourceFilePath.includes("node_modules")) {
241
+ if (functionSignatureSymbols.has(symbol)) {
242
+ const packageName = getPackageNameFromNodeModulesPath_(sourceFilePath);
243
+ if (packageName) {
244
+ processedSymbols.add(symbolName);
245
+ if (!importsMap.has(packageName)) {
246
+ importsMap.set(packageName, /* @__PURE__ */ new Set());
247
+ }
248
+ importsMap.get(packageName)?.add(symbolName);
249
+ }
250
+ }
198
251
  continue;
199
252
  }
200
253
  processedSymbols.add(symbolName);
package/dist/vite.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  const path = require('node:path');
4
4
  const consola = require('consola');
5
- const config = require('./shared/gasnuki.BziruiRW.cjs');
5
+ const config = require('./shared/gasnuki.kBd1L15Q.cjs');
6
6
  require('node:fs');
7
7
  require('ts-morph');
8
8
  require('jiti');
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.CS6ipBfD.mjs';
3
+ import { l as loadConfig, g as generateAppsScriptTypes } from './shared/gasnuki.C96Q3amR.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.2",
3
+ "version": "0.3.4",
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": "^4.0.3",
59
- "commander": "^14.0.1",
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.2.6",
66
- "@types/node": "^24.8.1",
67
- "@vitest/coverage-v8": "3.2.4",
65
+ "@biomejs/biome": "^2.3.10",
66
+ "@types/node": "^25.0.3",
67
+ "@vitest/coverage-v8": "4.0.16",
68
68
  "typescript": "^5.9.3",
69
69
  "unbuild": "^3.6.1",
70
- "vite": "^7.1.10",
71
- "vitest": "3.2.4"
70
+ "vite": "^7.3.0",
71
+ "vitest": "4.0.16"
72
72
  },
73
73
  "peerDependencies": {
74
74
  "vite": "^7"
@@ -1,3 +0,0 @@
1
- {
2
- "cSpell.words": ["gasnuki"]
3
- }