@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 +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.CS6ipBfD.mjs → gasnuki.C96Q3amR.mjs} +56 -3
- package/dist/shared/{gasnuki.BziruiRW.cjs → gasnuki.kBd1L15Q.cjs} +56 -3
- 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.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.
|
|
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
|
|
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.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.
|
|
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
|
|
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.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.
|
|
5
|
-
export { d as defineConfig } from './shared/gasnuki.
|
|
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
|
|
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
|
|
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
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.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.
|
|
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": "^
|
|
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.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.
|
|
71
|
-
"vitest": "
|
|
70
|
+
"vite": "^7.3.0",
|
|
71
|
+
"vitest": "4.0.16"
|
|
72
72
|
},
|
|
73
73
|
"peerDependencies": {
|
|
74
74
|
"vite": "^7"
|
package/.vscode/settings.json
DELETED