@ciderjs/gasnuki 0.3.7 → 0.4.0
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 +4 -3
- package/dist/cli.mjs +4 -3
- package/dist/index.cjs +14 -3
- package/dist/index.d.cts +2 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.mjs +15 -4
- package/dist/shared/{gasnuki.CooUv3Bz.cjs → gasnuki.DfLTmLhN.cjs} +62 -22
- package/dist/shared/{gasnuki.Md02V2Fd.mjs → gasnuki.SJQVcSIQ.mjs} +61 -22
- package/dist/vite.cjs +2 -1
- package/dist/vite.mjs +2 -1
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @ciderjs/gasnuki
|
|
2
2
|
|
|
3
3
|
[](./README.md)
|
|
4
|
-
[](https://github.com/luthpg/gasnuki)
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[](https://www.npmjs.com/package/@ciderjs/gasnuki)
|
|
7
7
|
[](https://github.com/luthpg/gasnuki/issues)
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @ciderjs/gasnuki
|
|
2
2
|
|
|
3
3
|
[](./README.ja.md)
|
|
4
|
-
[](https://github.com/luthpg/gasnuki)
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[](https://www.npmjs.com/package/@ciderjs/gasnuki)
|
|
7
7
|
[](https://github.com/luthpg/gasnuki/issues)
|
package/dist/cli.cjs
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
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.DfLTmLhN.cjs');
|
|
8
8
|
require('chokidar');
|
|
9
9
|
require('consola');
|
|
10
|
+
require('node:crypto');
|
|
10
11
|
require('node:fs');
|
|
11
12
|
require('ts-morph');
|
|
12
13
|
require('jiti');
|
|
@@ -25,7 +26,7 @@ function _interopNamespaceCompat(e) {
|
|
|
25
26
|
|
|
26
27
|
const path__namespace = /*#__PURE__*/_interopNamespaceCompat(path);
|
|
27
28
|
|
|
28
|
-
const version = "0.
|
|
29
|
+
const version = "0.4.0";
|
|
29
30
|
|
|
30
31
|
const parseArgs = async (command) => {
|
|
31
32
|
const cliOpts = command.opts();
|
|
@@ -69,7 +70,7 @@ const runCli = async () => {
|
|
|
69
70
|
"-o, --outDir <dir>",
|
|
70
71
|
"Output directory name (relative to project root)",
|
|
71
72
|
"types"
|
|
72
|
-
).option("-f, --outputFile <file>", "Output file name", "appsscript.ts").option("-w, --watch", "Watch for changes and re-generate types", false);
|
|
73
|
+
).option("-f, --outputFile <file>", "Output file name", "appsscript.ts").option("-w, --watch", "Watch for changes and re-generate types", false).option("--cache", "Enable checking generation cache", true).option("--no-cache", "Disable checking generation cache", true);
|
|
73
74
|
await program.parseAsync(process.argv);
|
|
74
75
|
};
|
|
75
76
|
const isMainModule = typeof require !== "undefined" && require.main === module;
|
package/dist/cli.mjs
CHANGED
|
@@ -2,14 +2,15 @@
|
|
|
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.SJQVcSIQ.mjs';
|
|
6
6
|
import 'chokidar';
|
|
7
7
|
import 'consola';
|
|
8
|
+
import 'node:crypto';
|
|
8
9
|
import 'node:fs';
|
|
9
10
|
import 'ts-morph';
|
|
10
11
|
import 'jiti';
|
|
11
12
|
|
|
12
|
-
const version = "0.
|
|
13
|
+
const version = "0.4.0";
|
|
13
14
|
|
|
14
15
|
const parseArgs = async (command) => {
|
|
15
16
|
const cliOpts = command.opts();
|
|
@@ -53,7 +54,7 @@ const runCli = async () => {
|
|
|
53
54
|
"-o, --outDir <dir>",
|
|
54
55
|
"Output directory name (relative to project root)",
|
|
55
56
|
"types"
|
|
56
|
-
).option("-f, --outputFile <file>", "Output file name", "appsscript.ts").option("-w, --watch", "Watch for changes and re-generate types", false);
|
|
57
|
+
).option("-f, --outputFile <file>", "Output file name", "appsscript.ts").option("-w, --watch", "Watch for changes and re-generate types", false).option("--cache", "Enable checking generation cache", true).option("--no-cache", "Disable checking generation cache", true);
|
|
57
58
|
await program.parseAsync(process.argv);
|
|
58
59
|
};
|
|
59
60
|
const isMainModule = typeof require !== "undefined" && require.main === module;
|
package/dist/index.cjs
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
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.DfLTmLhN.cjs');
|
|
7
|
+
require('node:crypto');
|
|
7
8
|
require('node:fs');
|
|
8
9
|
require('ts-morph');
|
|
9
10
|
require('jiti');
|
|
@@ -28,13 +29,23 @@ const generateTypes = async ({
|
|
|
28
29
|
srcDir,
|
|
29
30
|
outDir,
|
|
30
31
|
outputFile,
|
|
31
|
-
watch
|
|
32
|
+
watch,
|
|
33
|
+
cache
|
|
32
34
|
}) => {
|
|
35
|
+
if (cache === false) {
|
|
36
|
+
consola.consola.info("Generation cache is disabled");
|
|
37
|
+
}
|
|
33
38
|
const runGeneration = async (triggeredBy) => {
|
|
34
39
|
const reason = triggeredBy ? ` (${triggeredBy})` : "";
|
|
35
40
|
consola.consola.info(`Generating AppsScript types${reason}...`);
|
|
36
41
|
try {
|
|
37
|
-
await config.generateAppsScriptTypes({
|
|
42
|
+
await config.generateAppsScriptTypes({
|
|
43
|
+
project,
|
|
44
|
+
srcDir,
|
|
45
|
+
outDir,
|
|
46
|
+
outputFile,
|
|
47
|
+
cache
|
|
48
|
+
});
|
|
38
49
|
consola.consola.info("Type generation complete.");
|
|
39
50
|
} catch (e) {
|
|
40
51
|
consola.consola.error(`Type generation failed: ${e.message}`, e);
|
package/dist/index.d.cts
CHANGED
|
@@ -16,8 +16,9 @@ interface GenerateOptions {
|
|
|
16
16
|
outDir: string;
|
|
17
17
|
outputFile: string;
|
|
18
18
|
watch: boolean;
|
|
19
|
+
cache?: boolean;
|
|
19
20
|
}
|
|
20
|
-
declare const generateTypes: ({ project, srcDir, outDir, outputFile, watch, }: GenerateOptions) => Promise<void>;
|
|
21
|
+
declare const generateTypes: ({ project, srcDir, outDir, outputFile, watch, cache, }: GenerateOptions) => Promise<void>;
|
|
21
22
|
|
|
22
23
|
export { defineConfig, generateTypes };
|
|
23
24
|
export type { GenerateOptions, UserConfig };
|
package/dist/index.d.mts
CHANGED
|
@@ -16,8 +16,9 @@ interface GenerateOptions {
|
|
|
16
16
|
outDir: string;
|
|
17
17
|
outputFile: string;
|
|
18
18
|
watch: boolean;
|
|
19
|
+
cache?: boolean;
|
|
19
20
|
}
|
|
20
|
-
declare const generateTypes: ({ project, srcDir, outDir, outputFile, watch, }: GenerateOptions) => Promise<void>;
|
|
21
|
+
declare const generateTypes: ({ project, srcDir, outDir, outputFile, watch, cache, }: GenerateOptions) => Promise<void>;
|
|
21
22
|
|
|
22
23
|
export { defineConfig, generateTypes };
|
|
23
24
|
export type { GenerateOptions, UserConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -16,8 +16,9 @@ interface GenerateOptions {
|
|
|
16
16
|
outDir: string;
|
|
17
17
|
outputFile: string;
|
|
18
18
|
watch: boolean;
|
|
19
|
+
cache?: boolean;
|
|
19
20
|
}
|
|
20
|
-
declare const generateTypes: ({ project, srcDir, outDir, outputFile, watch, }: GenerateOptions) => Promise<void>;
|
|
21
|
+
declare const generateTypes: ({ project, srcDir, outDir, outputFile, watch, cache, }: GenerateOptions) => Promise<void>;
|
|
21
22
|
|
|
22
23
|
export { defineConfig, generateTypes };
|
|
23
24
|
export type { GenerateOptions, UserConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
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.SJQVcSIQ.mjs';
|
|
5
|
+
export { d as defineConfig } from './shared/gasnuki.SJQVcSIQ.mjs';
|
|
6
|
+
import 'node:crypto';
|
|
6
7
|
import 'node:fs';
|
|
7
8
|
import 'ts-morph';
|
|
8
9
|
import 'jiti';
|
|
@@ -12,13 +13,23 @@ const generateTypes = async ({
|
|
|
12
13
|
srcDir,
|
|
13
14
|
outDir,
|
|
14
15
|
outputFile,
|
|
15
|
-
watch
|
|
16
|
+
watch,
|
|
17
|
+
cache
|
|
16
18
|
}) => {
|
|
19
|
+
if (cache === false) {
|
|
20
|
+
consola.info("Generation cache is disabled");
|
|
21
|
+
}
|
|
17
22
|
const runGeneration = async (triggeredBy) => {
|
|
18
23
|
const reason = triggeredBy ? ` (${triggeredBy})` : "";
|
|
19
24
|
consola.info(`Generating AppsScript types${reason}...`);
|
|
20
25
|
try {
|
|
21
|
-
await generateAppsScriptTypes({
|
|
26
|
+
await generateAppsScriptTypes({
|
|
27
|
+
project,
|
|
28
|
+
srcDir,
|
|
29
|
+
outDir,
|
|
30
|
+
outputFile,
|
|
31
|
+
cache
|
|
32
|
+
});
|
|
22
33
|
consola.info("Type generation complete.");
|
|
23
34
|
} catch (e) {
|
|
24
35
|
consola.error(`Type generation failed: ${e.message}`, e);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const crypto = require('node:crypto');
|
|
3
4
|
const fs = require('node:fs');
|
|
4
5
|
const path = require('node:path');
|
|
5
6
|
const consola = require('consola');
|
|
@@ -18,11 +19,24 @@ function _interopNamespaceCompat(e) {
|
|
|
18
19
|
return n;
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
const crypto__namespace = /*#__PURE__*/_interopNamespaceCompat(crypto);
|
|
21
23
|
const fs__namespace = /*#__PURE__*/_interopNamespaceCompat(fs);
|
|
22
24
|
const path__namespace = /*#__PURE__*/_interopNamespaceCompat(path);
|
|
23
25
|
|
|
24
26
|
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 _WebAppLocationType {\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: (callback: (location: _WebAppLocationType) => void) => void;\n };\n history: {\n push: _AppsScriptHistoryFunction;\n replace: _AppsScriptHistoryFunction;\n setChangeHandler: (\n callback: (e: { state: object; location: _WebAppLocationType }) => void,\n ) => void;\n };\n };\n}\n\ndeclare global {\n const google: GoogleClientSideApi;\n}\n";
|
|
25
27
|
|
|
28
|
+
const generationCache = /* @__PURE__ */ new Map();
|
|
29
|
+
const computeSourceHash = (sourceFiles) => {
|
|
30
|
+
const hash = crypto__namespace.createHash("md5");
|
|
31
|
+
const sortedFiles = [...sourceFiles].sort(
|
|
32
|
+
(a, b) => a.getFilePath().localeCompare(b.getFilePath())
|
|
33
|
+
);
|
|
34
|
+
for (const file of sortedFiles) {
|
|
35
|
+
hash.update(file.getFilePath());
|
|
36
|
+
hash.update(file.getFullText());
|
|
37
|
+
}
|
|
38
|
+
return hash.digest("hex");
|
|
39
|
+
};
|
|
26
40
|
const getInterfaceMethodDefinition_ = (name, node) => {
|
|
27
41
|
const typeParameters = node.getTypeParameters?.() ?? [];
|
|
28
42
|
const typeParamsString = typeParameters.length > 0 ? `<${typeParameters.map((tp) => tp.getText()).join(", ")}>` : "";
|
|
@@ -103,7 +117,9 @@ const generateAppsScriptTypes = async ({
|
|
|
103
117
|
srcDir,
|
|
104
118
|
outDir,
|
|
105
119
|
outputFile,
|
|
106
|
-
projectInstance
|
|
120
|
+
projectInstance,
|
|
121
|
+
cache = true
|
|
122
|
+
// Default to true
|
|
107
123
|
}) => {
|
|
108
124
|
const absoluteSrcDir = path__namespace.resolve(projectPath, srcDir);
|
|
109
125
|
const absoluteOutDir = path__namespace.resolve(projectPath, outDir);
|
|
@@ -120,6 +136,16 @@ const generateAppsScriptTypes = async ({
|
|
|
120
136
|
project.addSourceFilesAtPaths([sourceFilesPattern, testFilesPattern]);
|
|
121
137
|
const sourceFiles = project.getSourceFiles();
|
|
122
138
|
consola.consola.info(`Found ${sourceFiles.length} source file(s).`);
|
|
139
|
+
if (cache) {
|
|
140
|
+
const currentHash = computeSourceHash(sourceFiles);
|
|
141
|
+
const cacheKey = absoluteOutputFile;
|
|
142
|
+
if (generationCache.get(cacheKey) === currentHash && fs__namespace.existsSync(absoluteOutputFile)) {
|
|
143
|
+
consola.consola.success(
|
|
144
|
+
`Skipping generation: Source files have not changed (Hash: ${currentHash.slice(0, 8)}).`
|
|
145
|
+
);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
123
149
|
const methodDefinitions = [];
|
|
124
150
|
const exportedDeclarations = [];
|
|
125
151
|
const exportedDeclarationNames = /* @__PURE__ */ new Set();
|
|
@@ -354,24 +380,9 @@ const generateAppsScriptTypes = async ({
|
|
|
354
380
|
// Do NOT edit this file manually.
|
|
355
381
|
|
|
356
382
|
`;
|
|
357
|
-
|
|
358
|
-
const aIsRelative = a.startsWith(".");
|
|
359
|
-
const bIsRelative = b.startsWith(".");
|
|
360
|
-
if (aIsRelative !== bIsRelative) return aIsRelative ? 1 : -1;
|
|
361
|
-
return a.localeCompare(b);
|
|
362
|
-
});
|
|
363
|
-
if (sortedModulePaths.length > 0) {
|
|
364
|
-
const importStatements = sortedModulePaths.map((modulePath) => {
|
|
365
|
-
const imports = [...importsMap.get(modulePath) ?? []].sort();
|
|
366
|
-
const finalModulePath = modulePath === "." ? "./index" : modulePath;
|
|
367
|
-
return `import type { ${imports.join(", ")} } from '${finalModulePath}';`;
|
|
368
|
-
});
|
|
369
|
-
outputContent += `${importStatements.join("\n")}
|
|
370
|
-
|
|
371
|
-
`;
|
|
372
|
-
}
|
|
383
|
+
let bodyContent = "";
|
|
373
384
|
if (inlineDefinitions.size > 0) {
|
|
374
|
-
|
|
385
|
+
bodyContent += `${[...inlineDefinitions.values()].join("\n\n")}
|
|
375
386
|
|
|
376
387
|
`;
|
|
377
388
|
}
|
|
@@ -379,7 +390,7 @@ const generateAppsScriptTypes = async ({
|
|
|
379
390
|
(d) => d.getKind() === tsMorph.SyntaxKind.InterfaceDeclaration || d.getKind() === tsMorph.SyntaxKind.TypeAliasDeclaration
|
|
380
391
|
).map((decl) => decl.getText());
|
|
381
392
|
if (exportedTypeDefinitions.length > 0) {
|
|
382
|
-
|
|
393
|
+
bodyContent += `${exportedTypeDefinitions.join("\n\n")}
|
|
383
394
|
|
|
384
395
|
`;
|
|
385
396
|
}
|
|
@@ -387,7 +398,7 @@ const generateAppsScriptTypes = async ({
|
|
|
387
398
|
const formattedMethods = methodDefinitions.map(
|
|
388
399
|
(method) => method.split("\n").map((line) => ` ${line}`).join("\n")
|
|
389
400
|
).join("\n\n");
|
|
390
|
-
|
|
401
|
+
bodyContent += `export type ServerScripts = {
|
|
391
402
|
${formattedMethods}
|
|
392
403
|
}
|
|
393
404
|
`;
|
|
@@ -395,16 +406,45 @@ ${formattedMethods}
|
|
|
395
406
|
`Interface 'ServerScript' type definitions written to ${absoluteOutputFile} (${methodDefinitions.length} function(s), ${exportedTypeDefinitions.length + inlineDefinitions.size} type(s)).`
|
|
396
407
|
);
|
|
397
408
|
} else {
|
|
398
|
-
|
|
409
|
+
bodyContent += "export type ServerScripts = {}\n";
|
|
399
410
|
consola.consola.info(
|
|
400
411
|
`Interface 'ServerScript' type definitions written to ${absoluteOutputFile} (no functions found).`
|
|
401
412
|
);
|
|
402
413
|
}
|
|
403
|
-
|
|
414
|
+
bodyContent += `
|
|
404
415
|
// Auto-generated Types for GoogleAppsScript in client-side code
|
|
405
416
|
|
|
406
417
|
${text}`;
|
|
418
|
+
const sortedModulePaths = [...importsMap.keys()].sort((a, b) => {
|
|
419
|
+
const aIsRelative = a.startsWith(".");
|
|
420
|
+
const bIsRelative = b.startsWith(".");
|
|
421
|
+
if (aIsRelative !== bIsRelative) return aIsRelative ? 1 : -1;
|
|
422
|
+
return a.localeCompare(b);
|
|
423
|
+
});
|
|
424
|
+
if (sortedModulePaths.length > 0) {
|
|
425
|
+
const importStatements = sortedModulePaths.map((modulePath) => {
|
|
426
|
+
const imports = [...importsMap.get(modulePath) ?? []].sort().filter((importName) => {
|
|
427
|
+
const regex = new RegExp(`\\b${importName}\\b`);
|
|
428
|
+
return regex.test(bodyContent);
|
|
429
|
+
});
|
|
430
|
+
if (imports.length === 0) {
|
|
431
|
+
return null;
|
|
432
|
+
}
|
|
433
|
+
const finalModulePath = modulePath === "." ? "./index" : modulePath;
|
|
434
|
+
return `import type { ${imports.join(", ")} } from '${finalModulePath}';`;
|
|
435
|
+
}).filter((s) => s !== null);
|
|
436
|
+
if (importStatements.length > 0) {
|
|
437
|
+
outputContent += `${importStatements.join("\n")}
|
|
438
|
+
|
|
439
|
+
`;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
outputContent += bodyContent;
|
|
407
443
|
fs__namespace.writeFileSync(absoluteOutputFile, outputContent);
|
|
444
|
+
if (cache) {
|
|
445
|
+
const currentHash = computeSourceHash(sourceFiles);
|
|
446
|
+
generationCache.set(absoluteOutputFile, currentHash);
|
|
447
|
+
}
|
|
408
448
|
};
|
|
409
449
|
|
|
410
450
|
function defineConfig(config) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as crypto from 'node:crypto';
|
|
1
2
|
import * as fs from 'node:fs';
|
|
2
3
|
import * as path from 'node:path';
|
|
3
4
|
import { consola } from 'consola';
|
|
@@ -6,6 +7,18 @@ import { createJiti } from 'jiti';
|
|
|
6
7
|
|
|
7
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 _WebAppLocationType {\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: (callback: (location: _WebAppLocationType) => void) => void;\n };\n history: {\n push: _AppsScriptHistoryFunction;\n replace: _AppsScriptHistoryFunction;\n setChangeHandler: (\n callback: (e: { state: object; location: _WebAppLocationType }) => void,\n ) => void;\n };\n };\n}\n\ndeclare global {\n const google: GoogleClientSideApi;\n}\n";
|
|
8
9
|
|
|
10
|
+
const generationCache = /* @__PURE__ */ new Map();
|
|
11
|
+
const computeSourceHash = (sourceFiles) => {
|
|
12
|
+
const hash = crypto.createHash("md5");
|
|
13
|
+
const sortedFiles = [...sourceFiles].sort(
|
|
14
|
+
(a, b) => a.getFilePath().localeCompare(b.getFilePath())
|
|
15
|
+
);
|
|
16
|
+
for (const file of sortedFiles) {
|
|
17
|
+
hash.update(file.getFilePath());
|
|
18
|
+
hash.update(file.getFullText());
|
|
19
|
+
}
|
|
20
|
+
return hash.digest("hex");
|
|
21
|
+
};
|
|
9
22
|
const getInterfaceMethodDefinition_ = (name, node) => {
|
|
10
23
|
const typeParameters = node.getTypeParameters?.() ?? [];
|
|
11
24
|
const typeParamsString = typeParameters.length > 0 ? `<${typeParameters.map((tp) => tp.getText()).join(", ")}>` : "";
|
|
@@ -86,7 +99,9 @@ const generateAppsScriptTypes = async ({
|
|
|
86
99
|
srcDir,
|
|
87
100
|
outDir,
|
|
88
101
|
outputFile,
|
|
89
|
-
projectInstance
|
|
102
|
+
projectInstance,
|
|
103
|
+
cache = true
|
|
104
|
+
// Default to true
|
|
90
105
|
}) => {
|
|
91
106
|
const absoluteSrcDir = path.resolve(projectPath, srcDir);
|
|
92
107
|
const absoluteOutDir = path.resolve(projectPath, outDir);
|
|
@@ -103,6 +118,16 @@ const generateAppsScriptTypes = async ({
|
|
|
103
118
|
project.addSourceFilesAtPaths([sourceFilesPattern, testFilesPattern]);
|
|
104
119
|
const sourceFiles = project.getSourceFiles();
|
|
105
120
|
consola.info(`Found ${sourceFiles.length} source file(s).`);
|
|
121
|
+
if (cache) {
|
|
122
|
+
const currentHash = computeSourceHash(sourceFiles);
|
|
123
|
+
const cacheKey = absoluteOutputFile;
|
|
124
|
+
if (generationCache.get(cacheKey) === currentHash && fs.existsSync(absoluteOutputFile)) {
|
|
125
|
+
consola.success(
|
|
126
|
+
`Skipping generation: Source files have not changed (Hash: ${currentHash.slice(0, 8)}).`
|
|
127
|
+
);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
106
131
|
const methodDefinitions = [];
|
|
107
132
|
const exportedDeclarations = [];
|
|
108
133
|
const exportedDeclarationNames = /* @__PURE__ */ new Set();
|
|
@@ -337,24 +362,9 @@ const generateAppsScriptTypes = async ({
|
|
|
337
362
|
// Do NOT edit this file manually.
|
|
338
363
|
|
|
339
364
|
`;
|
|
340
|
-
|
|
341
|
-
const aIsRelative = a.startsWith(".");
|
|
342
|
-
const bIsRelative = b.startsWith(".");
|
|
343
|
-
if (aIsRelative !== bIsRelative) return aIsRelative ? 1 : -1;
|
|
344
|
-
return a.localeCompare(b);
|
|
345
|
-
});
|
|
346
|
-
if (sortedModulePaths.length > 0) {
|
|
347
|
-
const importStatements = sortedModulePaths.map((modulePath) => {
|
|
348
|
-
const imports = [...importsMap.get(modulePath) ?? []].sort();
|
|
349
|
-
const finalModulePath = modulePath === "." ? "./index" : modulePath;
|
|
350
|
-
return `import type { ${imports.join(", ")} } from '${finalModulePath}';`;
|
|
351
|
-
});
|
|
352
|
-
outputContent += `${importStatements.join("\n")}
|
|
353
|
-
|
|
354
|
-
`;
|
|
355
|
-
}
|
|
365
|
+
let bodyContent = "";
|
|
356
366
|
if (inlineDefinitions.size > 0) {
|
|
357
|
-
|
|
367
|
+
bodyContent += `${[...inlineDefinitions.values()].join("\n\n")}
|
|
358
368
|
|
|
359
369
|
`;
|
|
360
370
|
}
|
|
@@ -362,7 +372,7 @@ const generateAppsScriptTypes = async ({
|
|
|
362
372
|
(d) => d.getKind() === SyntaxKind.InterfaceDeclaration || d.getKind() === SyntaxKind.TypeAliasDeclaration
|
|
363
373
|
).map((decl) => decl.getText());
|
|
364
374
|
if (exportedTypeDefinitions.length > 0) {
|
|
365
|
-
|
|
375
|
+
bodyContent += `${exportedTypeDefinitions.join("\n\n")}
|
|
366
376
|
|
|
367
377
|
`;
|
|
368
378
|
}
|
|
@@ -370,7 +380,7 @@ const generateAppsScriptTypes = async ({
|
|
|
370
380
|
const formattedMethods = methodDefinitions.map(
|
|
371
381
|
(method) => method.split("\n").map((line) => ` ${line}`).join("\n")
|
|
372
382
|
).join("\n\n");
|
|
373
|
-
|
|
383
|
+
bodyContent += `export type ServerScripts = {
|
|
374
384
|
${formattedMethods}
|
|
375
385
|
}
|
|
376
386
|
`;
|
|
@@ -378,16 +388,45 @@ ${formattedMethods}
|
|
|
378
388
|
`Interface 'ServerScript' type definitions written to ${absoluteOutputFile} (${methodDefinitions.length} function(s), ${exportedTypeDefinitions.length + inlineDefinitions.size} type(s)).`
|
|
379
389
|
);
|
|
380
390
|
} else {
|
|
381
|
-
|
|
391
|
+
bodyContent += "export type ServerScripts = {}\n";
|
|
382
392
|
consola.info(
|
|
383
393
|
`Interface 'ServerScript' type definitions written to ${absoluteOutputFile} (no functions found).`
|
|
384
394
|
);
|
|
385
395
|
}
|
|
386
|
-
|
|
396
|
+
bodyContent += `
|
|
387
397
|
// Auto-generated Types for GoogleAppsScript in client-side code
|
|
388
398
|
|
|
389
399
|
${text}`;
|
|
400
|
+
const sortedModulePaths = [...importsMap.keys()].sort((a, b) => {
|
|
401
|
+
const aIsRelative = a.startsWith(".");
|
|
402
|
+
const bIsRelative = b.startsWith(".");
|
|
403
|
+
if (aIsRelative !== bIsRelative) return aIsRelative ? 1 : -1;
|
|
404
|
+
return a.localeCompare(b);
|
|
405
|
+
});
|
|
406
|
+
if (sortedModulePaths.length > 0) {
|
|
407
|
+
const importStatements = sortedModulePaths.map((modulePath) => {
|
|
408
|
+
const imports = [...importsMap.get(modulePath) ?? []].sort().filter((importName) => {
|
|
409
|
+
const regex = new RegExp(`\\b${importName}\\b`);
|
|
410
|
+
return regex.test(bodyContent);
|
|
411
|
+
});
|
|
412
|
+
if (imports.length === 0) {
|
|
413
|
+
return null;
|
|
414
|
+
}
|
|
415
|
+
const finalModulePath = modulePath === "." ? "./index" : modulePath;
|
|
416
|
+
return `import type { ${imports.join(", ")} } from '${finalModulePath}';`;
|
|
417
|
+
}).filter((s) => s !== null);
|
|
418
|
+
if (importStatements.length > 0) {
|
|
419
|
+
outputContent += `${importStatements.join("\n")}
|
|
420
|
+
|
|
421
|
+
`;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
outputContent += bodyContent;
|
|
390
425
|
fs.writeFileSync(absoluteOutputFile, outputContent);
|
|
426
|
+
if (cache) {
|
|
427
|
+
const currentHash = computeSourceHash(sourceFiles);
|
|
428
|
+
generationCache.set(absoluteOutputFile, currentHash);
|
|
429
|
+
}
|
|
391
430
|
};
|
|
392
431
|
|
|
393
432
|
function defineConfig(config) {
|
package/dist/vite.cjs
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const path = require('node:path');
|
|
4
4
|
const consola = require('consola');
|
|
5
|
-
const config = require('./shared/gasnuki.
|
|
5
|
+
const config = require('./shared/gasnuki.DfLTmLhN.cjs');
|
|
6
|
+
require('node:crypto');
|
|
6
7
|
require('node:fs');
|
|
7
8
|
require('ts-morph');
|
|
8
9
|
require('jiti');
|
package/dist/vite.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
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.SJQVcSIQ.mjs';
|
|
4
|
+
import 'node:crypto';
|
|
4
5
|
import 'node:fs';
|
|
5
6
|
import 'ts-morph';
|
|
6
7
|
import 'jiti';
|