@ciderjs/gasnuki 0.2.4 → 0.2.6
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 +1 -1
- package/README.md +1 -1
- package/dist/cli.cjs +2 -2
- package/dist/cli.mjs +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/shared/{gasnuki.CYh0jbl5.cjs → gasnuki.DH8w-v3n.cjs} +160 -78
- package/dist/shared/{gasnuki.DvpVGJ1U.mjs → gasnuki.DgQBiLxg.mjs} +161 -79
- package/package.json +2 -2
package/README.ja.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# gasnuki
|
|
2
2
|
|
|
3
|
-
[](https://github.com/luthpg/gasnuki)
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://www.npmjs.com/package/@ciderjs/gasnuki)
|
|
6
6
|
[](https://github.com/luthpg/gasnuki/issues)
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @ciderjs/gasnuki
|
|
2
2
|
|
|
3
|
-
[](https://github.com/luthpg/gasnuki)
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://www.npmjs.com/package/@ciderjs/gasnuki)
|
|
6
6
|
[](https://github.com/luthpg/gasnuki/issues)
|
package/dist/cli.cjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
const path = require('node:path');
|
|
5
5
|
const commander = require('commander');
|
|
6
|
-
const index = require('./shared/gasnuki.
|
|
6
|
+
const index = require('./shared/gasnuki.DH8w-v3n.cjs');
|
|
7
7
|
require('chokidar');
|
|
8
8
|
require('consola');
|
|
9
9
|
require('node:fs');
|
|
@@ -24,7 +24,7 @@ function _interopNamespaceCompat(e) {
|
|
|
24
24
|
|
|
25
25
|
const path__namespace = /*#__PURE__*/_interopNamespaceCompat(path);
|
|
26
26
|
|
|
27
|
-
const version = "0.2.
|
|
27
|
+
const version = "0.2.6";
|
|
28
28
|
|
|
29
29
|
const parseArgs = async (command) => {
|
|
30
30
|
const cliOpts = command.opts();
|
package/dist/cli.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import { Command } from 'commander';
|
|
4
|
-
import { l as loadConfig, g as generateTypes } from './shared/gasnuki.
|
|
4
|
+
import { l as loadConfig, g as generateTypes } from './shared/gasnuki.DgQBiLxg.mjs';
|
|
5
5
|
import 'chokidar';
|
|
6
6
|
import 'consola';
|
|
7
7
|
import 'node:fs';
|
|
8
8
|
import 'ts-morph';
|
|
9
9
|
import 'jiti';
|
|
10
10
|
|
|
11
|
-
const version = "0.2.
|
|
11
|
+
const version = "0.2.6";
|
|
12
12
|
|
|
13
13
|
const parseArgs = async (command) => {
|
|
14
14
|
const cliOpts = command.opts();
|
package/dist/index.cjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import 'node:path';
|
|
2
2
|
import 'chokidar';
|
|
3
3
|
import 'consola';
|
|
4
|
-
export { d as defineConfig, g as generateTypes } from './shared/gasnuki.
|
|
4
|
+
export { d as defineConfig, g as generateTypes } from './shared/gasnuki.DgQBiLxg.mjs';
|
|
5
5
|
import 'node:fs';
|
|
6
6
|
import 'ts-morph';
|
|
7
7
|
import 'jiti';
|
|
@@ -47,29 +47,17 @@ const getInterfaceMethodDefinition_ = (name, node) => {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
let jsDocString = "";
|
|
50
|
-
const jsDocOwner = "getJsDocs" in node ? node : "
|
|
50
|
+
const jsDocOwner = "getJsDocs" in node ? node : "getParentOrThrow" in node && // @ts-expect-error variable declaration
|
|
51
51
|
node.getParentOrThrow().getKind() === tsMorph.SyntaxKind.VariableDeclaration ? (
|
|
52
52
|
// @ts-expect-error variable declaration
|
|
53
53
|
node.getParentOrThrow()
|
|
54
54
|
) : null;
|
|
55
55
|
if (jsDocOwner != null) {
|
|
56
|
-
const jsDocs = "getJsDocs" in jsDocOwner ? jsDocOwner.getJsDocs() :
|
|
57
|
-
if (jsDocs
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
const deprecatedDoc = jsDocs.find(
|
|
61
|
-
(doc) => doc.getFullText().includes("@deprecated")
|
|
62
|
-
);
|
|
63
|
-
jsDocString = `${deprecatedDoc != null ? deprecatedDoc.getFullText().trim() : "/**\n * @deprecated\n */"}
|
|
64
|
-
`;
|
|
65
|
-
} else {
|
|
66
|
-
const firstDoc = jsDocs[0];
|
|
67
|
-
const description = firstDoc.getDescription().trim();
|
|
68
|
-
if (description != null || firstDoc.getTags().length > 0) {
|
|
69
|
-
jsDocString = `${firstDoc.getFullText().trim()}
|
|
56
|
+
const jsDocs = "getJsDocs" in jsDocOwner ? jsDocOwner.getJsDocs() : [];
|
|
57
|
+
if (jsDocs.length > 0) {
|
|
58
|
+
const firstDoc = jsDocs[0];
|
|
59
|
+
jsDocString = `${firstDoc.getFullText().trim()}
|
|
70
60
|
`;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
61
|
}
|
|
74
62
|
}
|
|
75
63
|
return `${jsDocString}${name}${typeParamsString}(${parameters}): ${returnType};`;
|
|
@@ -98,80 +86,154 @@ const generateAppsScriptTypes = async ({
|
|
|
98
86
|
tsConfigFilePath: path__namespace.resolve(projectPath, "tsconfig.json"),
|
|
99
87
|
skipAddingFilesFromTsConfig: true
|
|
100
88
|
});
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
);
|
|
104
|
-
const methodDefinitions = [];
|
|
105
|
-
const globalTypeDefinitions = [];
|
|
106
|
-
const importStatements = /* @__PURE__ */ new Set();
|
|
89
|
+
const sourceFilesPattern = path__namespace.join(absoluteSrcDir, "**/*.ts").replace(/\\/g, "/");
|
|
90
|
+
const testFilesPattern = `!${path__namespace.join(absoluteSrcDir, "**/*.{test,spec}.ts").replace(/\\/g, "/")}`;
|
|
91
|
+
project.addSourceFilesAtPaths([sourceFilesPattern, testFilesPattern]);
|
|
107
92
|
const sourceFiles = project.getSourceFiles();
|
|
108
93
|
consola.consola.info(`Found ${sourceFiles.length} source file(s).`);
|
|
94
|
+
const methodDefinitions = [];
|
|
95
|
+
const exportedDeclarations = [];
|
|
96
|
+
const exportedDeclarationNames = /* @__PURE__ */ new Set();
|
|
97
|
+
const exportedFunctions = [];
|
|
109
98
|
for (const sourceFile of sourceFiles) {
|
|
110
|
-
const importDeclarations = sourceFile.getImportDeclarations?.();
|
|
111
|
-
if (importDeclarations != null && importDeclarations.length > 0) {
|
|
112
|
-
for (const importDeclaration of importDeclarations) {
|
|
113
|
-
const moduleSpecifier = importDeclaration.getModuleSpecifierSourceFile();
|
|
114
|
-
if (moduleSpecifier) {
|
|
115
|
-
const importedFilePath = moduleSpecifier.getFilePath();
|
|
116
|
-
let relativePath = path__namespace.relative(path__namespace.dirname(absoluteOutputFile), importedFilePath).replace(/\\/g, "/");
|
|
117
|
-
relativePath = relativePath.replace(/\.(ts|tsx|d\.ts)$/, "");
|
|
118
|
-
if (!relativePath.startsWith(".") && !relativePath.startsWith("..")) {
|
|
119
|
-
relativePath = `./${relativePath}`;
|
|
120
|
-
}
|
|
121
|
-
const originalText = importDeclaration.getText();
|
|
122
|
-
const newImportText = originalText.replace(
|
|
123
|
-
importDeclaration.getModuleSpecifierValue(),
|
|
124
|
-
relativePath
|
|
125
|
-
);
|
|
126
|
-
importStatements.add(newImportText);
|
|
127
|
-
} else {
|
|
128
|
-
importStatements.add(importDeclaration.getText());
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
99
|
for (const iface of sourceFile.getInterfaces()) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
100
|
+
if (iface.isExported() && !iface.getName()?.endsWith("_")) {
|
|
101
|
+
exportedDeclarations.push(iface);
|
|
102
|
+
exportedDeclarationNames.add(iface.getName());
|
|
136
103
|
}
|
|
137
|
-
globalTypeDefinitions.push(iface.getText());
|
|
138
104
|
}
|
|
139
105
|
for (const typeAlias of sourceFile.getTypeAliases()) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
106
|
+
if (typeAlias.isExported() && !typeAlias.getName().endsWith("_")) {
|
|
107
|
+
exportedDeclarations.push(typeAlias);
|
|
108
|
+
exportedDeclarationNames.add(typeAlias.getName());
|
|
143
109
|
}
|
|
144
|
-
globalTypeDefinitions.push(typeAlias.getText());
|
|
145
110
|
}
|
|
146
|
-
for (const
|
|
147
|
-
|
|
148
|
-
|
|
111
|
+
for (const func of sourceFile.getFunctions()) {
|
|
112
|
+
const name = func.getName();
|
|
113
|
+
if (func.isExported() && name && !name.endsWith("_") && !SIMPLE_TRIGGER_FUNCTION_NAMES.includes(name)) {
|
|
114
|
+
exportedDeclarations.push(func);
|
|
115
|
+
exportedDeclarationNames.add(name);
|
|
116
|
+
methodDefinitions.push(getInterfaceMethodDefinition_(name, func));
|
|
117
|
+
exportedFunctions.push(func);
|
|
149
118
|
}
|
|
150
119
|
}
|
|
151
|
-
for (const
|
|
152
|
-
if (!
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
120
|
+
for (const varStmt of sourceFile.getVariableStatements()) {
|
|
121
|
+
if (!varStmt.isExported()) continue;
|
|
122
|
+
for (const varDecl of varStmt.getDeclarations()) {
|
|
123
|
+
const name = varDecl.getName();
|
|
124
|
+
const initializer = varDecl.getInitializer();
|
|
125
|
+
if (!name.endsWith("_") && !SIMPLE_TRIGGER_FUNCTION_NAMES.includes(name) && initializer && (initializer.getKind() === tsMorph.SyntaxKind.ArrowFunction || initializer.getKind() === tsMorph.SyntaxKind.FunctionExpression)) {
|
|
126
|
+
const funcExpr = initializer;
|
|
127
|
+
exportedDeclarations.push(varDecl);
|
|
128
|
+
exportedDeclarationNames.add(name);
|
|
129
|
+
methodDefinitions.push(getInterfaceMethodDefinition_(name, funcExpr));
|
|
130
|
+
exportedFunctions.push(funcExpr);
|
|
156
131
|
}
|
|
157
132
|
}
|
|
158
133
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
)
|
|
170
|
-
);
|
|
134
|
+
}
|
|
135
|
+
const collectSymbolsFromType = (type, foundSymbols) => {
|
|
136
|
+
const symbol = type.getAliasSymbol() ?? type.getSymbol();
|
|
137
|
+
if (symbol && !foundSymbols.has(symbol)) {
|
|
138
|
+
foundSymbols.add(symbol);
|
|
139
|
+
if (type.isObject()) {
|
|
140
|
+
for (const prop of type.getProperties()) {
|
|
141
|
+
const propDecl = prop.getDeclarations()[0];
|
|
142
|
+
if (propDecl) {
|
|
143
|
+
collectSymbolsFromType(propDecl.getType(), foundSymbols);
|
|
171
144
|
}
|
|
172
145
|
}
|
|
173
146
|
}
|
|
174
147
|
}
|
|
148
|
+
for (const typeArg of type.getTypeArguments()) {
|
|
149
|
+
collectSymbolsFromType(typeArg, foundSymbols);
|
|
150
|
+
}
|
|
151
|
+
if (type.isUnion()) {
|
|
152
|
+
for (const unionType of type.getUnionTypes()) {
|
|
153
|
+
collectSymbolsFromType(unionType, foundSymbols);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (type.isIntersection()) {
|
|
157
|
+
for (const intersectionType of type.getIntersectionTypes()) {
|
|
158
|
+
collectSymbolsFromType(intersectionType, foundSymbols);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const returnValueSymbols = /* @__PURE__ */ new Set();
|
|
163
|
+
for (const func of exportedFunctions) {
|
|
164
|
+
collectSymbolsFromType(func.getReturnType(), returnValueSymbols);
|
|
165
|
+
}
|
|
166
|
+
const importsMap = /* @__PURE__ */ new Map();
|
|
167
|
+
const inlineDefinitions = /* @__PURE__ */ new Map();
|
|
168
|
+
const symbolsToProcess = /* @__PURE__ */ new Set();
|
|
169
|
+
const processedSymbols = /* @__PURE__ */ new Set();
|
|
170
|
+
for (const decl of exportedDeclarations) {
|
|
171
|
+
for (const descendant of decl.getDescendantsOfKind(
|
|
172
|
+
tsMorph.SyntaxKind.TypeReference
|
|
173
|
+
)) {
|
|
174
|
+
const symbol = descendant.getType().getAliasSymbol() ?? descendant.getType().getSymbol();
|
|
175
|
+
if (symbol) {
|
|
176
|
+
symbolsToProcess.add(symbol);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
while (symbolsToProcess.size > 0) {
|
|
181
|
+
const symbol = symbolsToProcess.values().next().value;
|
|
182
|
+
if (!symbol) continue;
|
|
183
|
+
symbolsToProcess.delete(symbol);
|
|
184
|
+
const symbolName = symbol.getName();
|
|
185
|
+
if (processedSymbols.has(symbolName) || exportedDeclarationNames.has(symbolName) || symbolName === "__type") {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const symbolFlags = symbol.getFlags();
|
|
189
|
+
if (symbolFlags & tsMorph.SymbolFlags.TypeParameter) {
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
const declaration = symbol.getDeclarations()[0];
|
|
193
|
+
if (!declaration) {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
const sourceFile = declaration.getSourceFile();
|
|
197
|
+
if (sourceFile.getFilePath().includes("node_modules")) {
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
processedSymbols.add(symbolName);
|
|
201
|
+
const isLocalDefinition = declaration.getParent()?.getKind() !== tsMorph.SyntaxKind.SourceFile;
|
|
202
|
+
if (isLocalDefinition) {
|
|
203
|
+
if (returnValueSymbols.has(symbol)) {
|
|
204
|
+
const declText = declaration.getText();
|
|
205
|
+
inlineDefinitions.set(symbolName, declText);
|
|
206
|
+
const tempSourceFile = project.createSourceFile(
|
|
207
|
+
`__temp_${symbolName}.ts`,
|
|
208
|
+
declText
|
|
209
|
+
);
|
|
210
|
+
for (const descendant of tempSourceFile.getDescendantsOfKind(
|
|
211
|
+
tsMorph.SyntaxKind.TypeReference
|
|
212
|
+
)) {
|
|
213
|
+
const newSymbol = descendant.getType().getAliasSymbol() ?? descendant.getType().getSymbol();
|
|
214
|
+
if (newSymbol) {
|
|
215
|
+
symbolsToProcess.add(newSymbol);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
tempSourceFile.delete();
|
|
219
|
+
}
|
|
220
|
+
} else {
|
|
221
|
+
let modulePath = path__namespace.relative(absoluteOutDir, sourceFile.getFilePath()).replace(/\\/g, "/");
|
|
222
|
+
modulePath = modulePath.replace(/\.(d\.)?ts$/, "");
|
|
223
|
+
if (modulePath.endsWith("/index")) {
|
|
224
|
+
modulePath = modulePath.slice(0, -6);
|
|
225
|
+
}
|
|
226
|
+
if (modulePath === "index" || modulePath === "") {
|
|
227
|
+
modulePath = ".";
|
|
228
|
+
}
|
|
229
|
+
if (!modulePath.startsWith(".")) {
|
|
230
|
+
modulePath = `./${modulePath}`;
|
|
231
|
+
}
|
|
232
|
+
if (!importsMap.has(modulePath)) {
|
|
233
|
+
importsMap.set(modulePath, /* @__PURE__ */ new Set());
|
|
234
|
+
}
|
|
235
|
+
importsMap.get(modulePath)?.add(symbolName);
|
|
236
|
+
}
|
|
175
237
|
}
|
|
176
238
|
if (!fs__namespace.existsSync(absoluteOutDir)) {
|
|
177
239
|
fs__namespace.mkdirSync(absoluteOutDir, { recursive: true });
|
|
@@ -180,14 +242,34 @@ const generateAppsScriptTypes = async ({
|
|
|
180
242
|
const generatorName = "gasnuki";
|
|
181
243
|
let outputContent = `// Auto-generated by ${generatorName}
|
|
182
244
|
// Do NOT edit this file manually.
|
|
245
|
+
|
|
183
246
|
`;
|
|
184
|
-
|
|
185
|
-
|
|
247
|
+
const sortedModulePaths = [...importsMap.keys()].sort((a, b) => {
|
|
248
|
+
const aIsRelative = a.startsWith(".");
|
|
249
|
+
const bIsRelative = b.startsWith(".");
|
|
250
|
+
if (aIsRelative !== bIsRelative) return aIsRelative ? 1 : -1;
|
|
251
|
+
return a.localeCompare(b);
|
|
252
|
+
});
|
|
253
|
+
if (sortedModulePaths.length > 0) {
|
|
254
|
+
const importStatements = sortedModulePaths.map((modulePath) => {
|
|
255
|
+
const imports = [...importsMap.get(modulePath) ?? []].sort();
|
|
256
|
+
const finalModulePath = modulePath === "." ? "./index" : modulePath;
|
|
257
|
+
return `import type { ${imports.join(", ")} } from '${finalModulePath}';`;
|
|
258
|
+
});
|
|
259
|
+
outputContent += `${importStatements.join("\n")}
|
|
260
|
+
|
|
261
|
+
`;
|
|
262
|
+
}
|
|
263
|
+
if (inlineDefinitions.size > 0) {
|
|
264
|
+
outputContent += `${[...inlineDefinitions.values()].join("\n\n")}
|
|
186
265
|
|
|
187
266
|
`;
|
|
188
267
|
}
|
|
189
|
-
|
|
190
|
-
|
|
268
|
+
const exportedTypeDefinitions = exportedDeclarations.filter(
|
|
269
|
+
(d) => d.getKind() === tsMorph.SyntaxKind.InterfaceDeclaration || d.getKind() === tsMorph.SyntaxKind.TypeAliasDeclaration
|
|
270
|
+
).map((decl) => decl.getText());
|
|
271
|
+
if (exportedTypeDefinitions.length > 0) {
|
|
272
|
+
outputContent += `${exportedTypeDefinitions.join("\n\n")}
|
|
191
273
|
|
|
192
274
|
`;
|
|
193
275
|
}
|
|
@@ -200,7 +282,7 @@ ${formattedMethods}
|
|
|
200
282
|
}
|
|
201
283
|
`;
|
|
202
284
|
consola.consola.info(
|
|
203
|
-
`Interface 'ServerScript' type definitions written to ${absoluteOutputFile} (${methodDefinitions.length} function(s), ${
|
|
285
|
+
`Interface 'ServerScript' type definitions written to ${absoluteOutputFile} (${methodDefinitions.length} function(s), ${exportedTypeDefinitions.length + inlineDefinitions.size} type(s)).`
|
|
204
286
|
);
|
|
205
287
|
} else {
|
|
206
288
|
outputContent += "export type ServerScripts = {}\n";
|
|
@@ -2,7 +2,7 @@ import * as path from 'node:path';
|
|
|
2
2
|
import * as chokidar from 'chokidar';
|
|
3
3
|
import { consola } from 'consola';
|
|
4
4
|
import * as fs from 'node:fs';
|
|
5
|
-
import { Project, SyntaxKind } from 'ts-morph';
|
|
5
|
+
import { Project, SyntaxKind, SymbolFlags } from 'ts-morph';
|
|
6
6
|
import { createJiti } from 'jiti';
|
|
7
7
|
|
|
8
8
|
const text = "export type RemoveReturnType<T> = {\n [P in keyof T]: T[P] extends (...args: infer A) => any\n ? (...args: A) => void\n : T[P];\n};\n\ntype _AppsScriptRun = RemoveReturnType<ServerScripts> & {\n [key: string]: (...args: any[]) => any;\n withSuccessHandler: <T = string | number | boolean | undefined, U = any>(\n callback: (returnValues: T, userObject?: U) => void,\n ) => _AppsScriptRun;\n withFailureHandler: <U = any>(\n callback: (error: Error, userObject?: U) => void,\n ) => _AppsScriptRun;\n withUserObject: <U = any>(userObject: U) => _AppsScriptRun;\n};\n\ntype _AppsScriptHistoryFunction = (\n stateObject: object,\n params: object,\n hash: string,\n) => void;\n\ninterface _WebAppLovacationType {\n hash: string;\n parameter: Record<string, string>;\n parameters: Record<string, string[]>;\n}\n\nexport declare interface GoogleClientSideApi {\n script: {\n run: _AppsScriptRun;\n url: {\n getLocation: (\n callback: (location: _WebAppLovacationType) => void,\n ) => void;\n };\n history: {\n push: _AppsScriptHistoryFunction;\n replace: _AppsScriptHistoryFunction;\n setChangeHandler: (\n callback: (e: {\n state: object;\n location: _WebAppLovacationType;\n }) => void,\n ) => void;\n };\n };\n}\n\ndeclare global {\n const google: GoogleClientSideApi;\n}\n";
|
|
@@ -29,29 +29,17 @@ const getInterfaceMethodDefinition_ = (name, node) => {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
let jsDocString = "";
|
|
32
|
-
const jsDocOwner = "getJsDocs" in node ? node : "
|
|
32
|
+
const jsDocOwner = "getJsDocs" in node ? node : "getParentOrThrow" in node && // @ts-expect-error variable declaration
|
|
33
33
|
node.getParentOrThrow().getKind() === SyntaxKind.VariableDeclaration ? (
|
|
34
34
|
// @ts-expect-error variable declaration
|
|
35
35
|
node.getParentOrThrow()
|
|
36
36
|
) : null;
|
|
37
37
|
if (jsDocOwner != null) {
|
|
38
|
-
const jsDocs = "getJsDocs" in jsDocOwner ? jsDocOwner.getJsDocs() :
|
|
39
|
-
if (jsDocs
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
const deprecatedDoc = jsDocs.find(
|
|
43
|
-
(doc) => doc.getFullText().includes("@deprecated")
|
|
44
|
-
);
|
|
45
|
-
jsDocString = `${deprecatedDoc != null ? deprecatedDoc.getFullText().trim() : "/**\n * @deprecated\n */"}
|
|
46
|
-
`;
|
|
47
|
-
} else {
|
|
48
|
-
const firstDoc = jsDocs[0];
|
|
49
|
-
const description = firstDoc.getDescription().trim();
|
|
50
|
-
if (description != null || firstDoc.getTags().length > 0) {
|
|
51
|
-
jsDocString = `${firstDoc.getFullText().trim()}
|
|
38
|
+
const jsDocs = "getJsDocs" in jsDocOwner ? jsDocOwner.getJsDocs() : [];
|
|
39
|
+
if (jsDocs.length > 0) {
|
|
40
|
+
const firstDoc = jsDocs[0];
|
|
41
|
+
jsDocString = `${firstDoc.getFullText().trim()}
|
|
52
42
|
`;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
43
|
}
|
|
56
44
|
}
|
|
57
45
|
return `${jsDocString}${name}${typeParamsString}(${parameters}): ${returnType};`;
|
|
@@ -80,80 +68,154 @@ const generateAppsScriptTypes = async ({
|
|
|
80
68
|
tsConfigFilePath: path.resolve(projectPath, "tsconfig.json"),
|
|
81
69
|
skipAddingFilesFromTsConfig: true
|
|
82
70
|
});
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
);
|
|
86
|
-
const methodDefinitions = [];
|
|
87
|
-
const globalTypeDefinitions = [];
|
|
88
|
-
const importStatements = /* @__PURE__ */ new Set();
|
|
71
|
+
const sourceFilesPattern = path.join(absoluteSrcDir, "**/*.ts").replace(/\\/g, "/");
|
|
72
|
+
const testFilesPattern = `!${path.join(absoluteSrcDir, "**/*.{test,spec}.ts").replace(/\\/g, "/")}`;
|
|
73
|
+
project.addSourceFilesAtPaths([sourceFilesPattern, testFilesPattern]);
|
|
89
74
|
const sourceFiles = project.getSourceFiles();
|
|
90
75
|
consola.info(`Found ${sourceFiles.length} source file(s).`);
|
|
76
|
+
const methodDefinitions = [];
|
|
77
|
+
const exportedDeclarations = [];
|
|
78
|
+
const exportedDeclarationNames = /* @__PURE__ */ new Set();
|
|
79
|
+
const exportedFunctions = [];
|
|
91
80
|
for (const sourceFile of sourceFiles) {
|
|
92
|
-
const importDeclarations = sourceFile.getImportDeclarations?.();
|
|
93
|
-
if (importDeclarations != null && importDeclarations.length > 0) {
|
|
94
|
-
for (const importDeclaration of importDeclarations) {
|
|
95
|
-
const moduleSpecifier = importDeclaration.getModuleSpecifierSourceFile();
|
|
96
|
-
if (moduleSpecifier) {
|
|
97
|
-
const importedFilePath = moduleSpecifier.getFilePath();
|
|
98
|
-
let relativePath = path.relative(path.dirname(absoluteOutputFile), importedFilePath).replace(/\\/g, "/");
|
|
99
|
-
relativePath = relativePath.replace(/\.(ts|tsx|d\.ts)$/, "");
|
|
100
|
-
if (!relativePath.startsWith(".") && !relativePath.startsWith("..")) {
|
|
101
|
-
relativePath = `./${relativePath}`;
|
|
102
|
-
}
|
|
103
|
-
const originalText = importDeclaration.getText();
|
|
104
|
-
const newImportText = originalText.replace(
|
|
105
|
-
importDeclaration.getModuleSpecifierValue(),
|
|
106
|
-
relativePath
|
|
107
|
-
);
|
|
108
|
-
importStatements.add(newImportText);
|
|
109
|
-
} else {
|
|
110
|
-
importStatements.add(importDeclaration.getText());
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
81
|
for (const iface of sourceFile.getInterfaces()) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
82
|
+
if (iface.isExported() && !iface.getName()?.endsWith("_")) {
|
|
83
|
+
exportedDeclarations.push(iface);
|
|
84
|
+
exportedDeclarationNames.add(iface.getName());
|
|
118
85
|
}
|
|
119
|
-
globalTypeDefinitions.push(iface.getText());
|
|
120
86
|
}
|
|
121
87
|
for (const typeAlias of sourceFile.getTypeAliases()) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
88
|
+
if (typeAlias.isExported() && !typeAlias.getName().endsWith("_")) {
|
|
89
|
+
exportedDeclarations.push(typeAlias);
|
|
90
|
+
exportedDeclarationNames.add(typeAlias.getName());
|
|
125
91
|
}
|
|
126
|
-
globalTypeDefinitions.push(typeAlias.getText());
|
|
127
92
|
}
|
|
128
|
-
for (const
|
|
129
|
-
|
|
130
|
-
|
|
93
|
+
for (const func of sourceFile.getFunctions()) {
|
|
94
|
+
const name = func.getName();
|
|
95
|
+
if (func.isExported() && name && !name.endsWith("_") && !SIMPLE_TRIGGER_FUNCTION_NAMES.includes(name)) {
|
|
96
|
+
exportedDeclarations.push(func);
|
|
97
|
+
exportedDeclarationNames.add(name);
|
|
98
|
+
methodDefinitions.push(getInterfaceMethodDefinition_(name, func));
|
|
99
|
+
exportedFunctions.push(func);
|
|
131
100
|
}
|
|
132
101
|
}
|
|
133
|
-
for (const
|
|
134
|
-
if (!
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
102
|
+
for (const varStmt of sourceFile.getVariableStatements()) {
|
|
103
|
+
if (!varStmt.isExported()) continue;
|
|
104
|
+
for (const varDecl of varStmt.getDeclarations()) {
|
|
105
|
+
const name = varDecl.getName();
|
|
106
|
+
const initializer = varDecl.getInitializer();
|
|
107
|
+
if (!name.endsWith("_") && !SIMPLE_TRIGGER_FUNCTION_NAMES.includes(name) && initializer && (initializer.getKind() === SyntaxKind.ArrowFunction || initializer.getKind() === SyntaxKind.FunctionExpression)) {
|
|
108
|
+
const funcExpr = initializer;
|
|
109
|
+
exportedDeclarations.push(varDecl);
|
|
110
|
+
exportedDeclarationNames.add(name);
|
|
111
|
+
methodDefinitions.push(getInterfaceMethodDefinition_(name, funcExpr));
|
|
112
|
+
exportedFunctions.push(funcExpr);
|
|
138
113
|
}
|
|
139
114
|
}
|
|
140
115
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
)
|
|
152
|
-
);
|
|
116
|
+
}
|
|
117
|
+
const collectSymbolsFromType = (type, foundSymbols) => {
|
|
118
|
+
const symbol = type.getAliasSymbol() ?? type.getSymbol();
|
|
119
|
+
if (symbol && !foundSymbols.has(symbol)) {
|
|
120
|
+
foundSymbols.add(symbol);
|
|
121
|
+
if (type.isObject()) {
|
|
122
|
+
for (const prop of type.getProperties()) {
|
|
123
|
+
const propDecl = prop.getDeclarations()[0];
|
|
124
|
+
if (propDecl) {
|
|
125
|
+
collectSymbolsFromType(propDecl.getType(), foundSymbols);
|
|
153
126
|
}
|
|
154
127
|
}
|
|
155
128
|
}
|
|
156
129
|
}
|
|
130
|
+
for (const typeArg of type.getTypeArguments()) {
|
|
131
|
+
collectSymbolsFromType(typeArg, foundSymbols);
|
|
132
|
+
}
|
|
133
|
+
if (type.isUnion()) {
|
|
134
|
+
for (const unionType of type.getUnionTypes()) {
|
|
135
|
+
collectSymbolsFromType(unionType, foundSymbols);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (type.isIntersection()) {
|
|
139
|
+
for (const intersectionType of type.getIntersectionTypes()) {
|
|
140
|
+
collectSymbolsFromType(intersectionType, foundSymbols);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
const returnValueSymbols = /* @__PURE__ */ new Set();
|
|
145
|
+
for (const func of exportedFunctions) {
|
|
146
|
+
collectSymbolsFromType(func.getReturnType(), returnValueSymbols);
|
|
147
|
+
}
|
|
148
|
+
const importsMap = /* @__PURE__ */ new Map();
|
|
149
|
+
const inlineDefinitions = /* @__PURE__ */ new Map();
|
|
150
|
+
const symbolsToProcess = /* @__PURE__ */ new Set();
|
|
151
|
+
const processedSymbols = /* @__PURE__ */ new Set();
|
|
152
|
+
for (const decl of exportedDeclarations) {
|
|
153
|
+
for (const descendant of decl.getDescendantsOfKind(
|
|
154
|
+
SyntaxKind.TypeReference
|
|
155
|
+
)) {
|
|
156
|
+
const symbol = descendant.getType().getAliasSymbol() ?? descendant.getType().getSymbol();
|
|
157
|
+
if (symbol) {
|
|
158
|
+
symbolsToProcess.add(symbol);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
while (symbolsToProcess.size > 0) {
|
|
163
|
+
const symbol = symbolsToProcess.values().next().value;
|
|
164
|
+
if (!symbol) continue;
|
|
165
|
+
symbolsToProcess.delete(symbol);
|
|
166
|
+
const symbolName = symbol.getName();
|
|
167
|
+
if (processedSymbols.has(symbolName) || exportedDeclarationNames.has(symbolName) || symbolName === "__type") {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const symbolFlags = symbol.getFlags();
|
|
171
|
+
if (symbolFlags & SymbolFlags.TypeParameter) {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
const declaration = symbol.getDeclarations()[0];
|
|
175
|
+
if (!declaration) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
const sourceFile = declaration.getSourceFile();
|
|
179
|
+
if (sourceFile.getFilePath().includes("node_modules")) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
processedSymbols.add(symbolName);
|
|
183
|
+
const isLocalDefinition = declaration.getParent()?.getKind() !== SyntaxKind.SourceFile;
|
|
184
|
+
if (isLocalDefinition) {
|
|
185
|
+
if (returnValueSymbols.has(symbol)) {
|
|
186
|
+
const declText = declaration.getText();
|
|
187
|
+
inlineDefinitions.set(symbolName, declText);
|
|
188
|
+
const tempSourceFile = project.createSourceFile(
|
|
189
|
+
`__temp_${symbolName}.ts`,
|
|
190
|
+
declText
|
|
191
|
+
);
|
|
192
|
+
for (const descendant of tempSourceFile.getDescendantsOfKind(
|
|
193
|
+
SyntaxKind.TypeReference
|
|
194
|
+
)) {
|
|
195
|
+
const newSymbol = descendant.getType().getAliasSymbol() ?? descendant.getType().getSymbol();
|
|
196
|
+
if (newSymbol) {
|
|
197
|
+
symbolsToProcess.add(newSymbol);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
tempSourceFile.delete();
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
let modulePath = path.relative(absoluteOutDir, sourceFile.getFilePath()).replace(/\\/g, "/");
|
|
204
|
+
modulePath = modulePath.replace(/\.(d\.)?ts$/, "");
|
|
205
|
+
if (modulePath.endsWith("/index")) {
|
|
206
|
+
modulePath = modulePath.slice(0, -6);
|
|
207
|
+
}
|
|
208
|
+
if (modulePath === "index" || modulePath === "") {
|
|
209
|
+
modulePath = ".";
|
|
210
|
+
}
|
|
211
|
+
if (!modulePath.startsWith(".")) {
|
|
212
|
+
modulePath = `./${modulePath}`;
|
|
213
|
+
}
|
|
214
|
+
if (!importsMap.has(modulePath)) {
|
|
215
|
+
importsMap.set(modulePath, /* @__PURE__ */ new Set());
|
|
216
|
+
}
|
|
217
|
+
importsMap.get(modulePath)?.add(symbolName);
|
|
218
|
+
}
|
|
157
219
|
}
|
|
158
220
|
if (!fs.existsSync(absoluteOutDir)) {
|
|
159
221
|
fs.mkdirSync(absoluteOutDir, { recursive: true });
|
|
@@ -162,14 +224,34 @@ const generateAppsScriptTypes = async ({
|
|
|
162
224
|
const generatorName = "gasnuki";
|
|
163
225
|
let outputContent = `// Auto-generated by ${generatorName}
|
|
164
226
|
// Do NOT edit this file manually.
|
|
227
|
+
|
|
165
228
|
`;
|
|
166
|
-
|
|
167
|
-
|
|
229
|
+
const sortedModulePaths = [...importsMap.keys()].sort((a, b) => {
|
|
230
|
+
const aIsRelative = a.startsWith(".");
|
|
231
|
+
const bIsRelative = b.startsWith(".");
|
|
232
|
+
if (aIsRelative !== bIsRelative) return aIsRelative ? 1 : -1;
|
|
233
|
+
return a.localeCompare(b);
|
|
234
|
+
});
|
|
235
|
+
if (sortedModulePaths.length > 0) {
|
|
236
|
+
const importStatements = sortedModulePaths.map((modulePath) => {
|
|
237
|
+
const imports = [...importsMap.get(modulePath) ?? []].sort();
|
|
238
|
+
const finalModulePath = modulePath === "." ? "./index" : modulePath;
|
|
239
|
+
return `import type { ${imports.join(", ")} } from '${finalModulePath}';`;
|
|
240
|
+
});
|
|
241
|
+
outputContent += `${importStatements.join("\n")}
|
|
242
|
+
|
|
243
|
+
`;
|
|
244
|
+
}
|
|
245
|
+
if (inlineDefinitions.size > 0) {
|
|
246
|
+
outputContent += `${[...inlineDefinitions.values()].join("\n\n")}
|
|
168
247
|
|
|
169
248
|
`;
|
|
170
249
|
}
|
|
171
|
-
|
|
172
|
-
|
|
250
|
+
const exportedTypeDefinitions = exportedDeclarations.filter(
|
|
251
|
+
(d) => d.getKind() === SyntaxKind.InterfaceDeclaration || d.getKind() === SyntaxKind.TypeAliasDeclaration
|
|
252
|
+
).map((decl) => decl.getText());
|
|
253
|
+
if (exportedTypeDefinitions.length > 0) {
|
|
254
|
+
outputContent += `${exportedTypeDefinitions.join("\n\n")}
|
|
173
255
|
|
|
174
256
|
`;
|
|
175
257
|
}
|
|
@@ -182,7 +264,7 @@ ${formattedMethods}
|
|
|
182
264
|
}
|
|
183
265
|
`;
|
|
184
266
|
consola.info(
|
|
185
|
-
`Interface 'ServerScript' type definitions written to ${absoluteOutputFile} (${methodDefinitions.length} function(s), ${
|
|
267
|
+
`Interface 'ServerScript' type definitions written to ${absoluteOutputFile} (${methodDefinitions.length} function(s), ${exportedTypeDefinitions.length + inlineDefinitions.size} type(s)).`
|
|
186
268
|
);
|
|
187
269
|
} else {
|
|
188
270
|
outputContent += "export type ServerScripts = {}\n";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ciderjs/gasnuki",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
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",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
23
|
"generate": "jiti .bin/generate.ts",
|
|
24
|
-
"dev": "pnpm
|
|
24
|
+
"dev": "pnpm run generate && jiti src/cli.ts -p playground/react -s src/server",
|
|
25
25
|
"start": "node dist/cli.mjs -p playground/react -s src/server",
|
|
26
26
|
"check": "biome check --write",
|
|
27
27
|
"build": "unbuild",
|