@tooldeck/plugin-tools 1.1.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/dist/assets/generate-command-types-runner-D_f2_VpM.js +93 -0
- package/dist/assets/generate-command-types-runner-D_f2_VpM.js.map +1 -0
- package/dist/generate-command-types-core.d.ts +3 -0
- package/dist/generate-command-types-core.d.ts.map +1 -0
- package/dist/generate-command-types-runner.d.ts +2 -0
- package/dist/generate-command-types-runner.d.ts.map +1 -0
- package/dist/generate-command-types.d.ts +3 -0
- package/dist/generate-command-types.d.ts.map +1 -0
- package/dist/generate-command-types.js +8 -0
- package/dist/generate-command-types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/package.json +33 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
//#region src/generate-command-types-core.ts
|
|
4
|
+
function generatePluginCommandTypes(manifest) {
|
|
5
|
+
const commands = manifest.contributes?.commands ?? [];
|
|
6
|
+
const declarations = [];
|
|
7
|
+
const mapEntries = [];
|
|
8
|
+
for (const command of commands) {
|
|
9
|
+
const typeName = commandInputTypeName(command.id);
|
|
10
|
+
declarations.push(`export interface ${typeName} ${schemaToType(command.inputSchema)}`);
|
|
11
|
+
mapEntries.push(` ${JSON.stringify(command.id)}: ${typeName};`);
|
|
12
|
+
}
|
|
13
|
+
return [
|
|
14
|
+
"// This file is generated from manifest.json. Do not edit it by hand.",
|
|
15
|
+
"",
|
|
16
|
+
...declarations.flatMap((declaration) => [declaration, ""]),
|
|
17
|
+
"export interface PluginCommandInputs {",
|
|
18
|
+
...mapEntries,
|
|
19
|
+
"}",
|
|
20
|
+
""
|
|
21
|
+
].join("\n");
|
|
22
|
+
}
|
|
23
|
+
function commandInputTypeName(commandId) {
|
|
24
|
+
return `${commandId.split(/[^a-zA-Z0-9]+/).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("") || "Command"}Input`;
|
|
25
|
+
}
|
|
26
|
+
function schemaToType(schema) {
|
|
27
|
+
if (!schema) return "Record<string, unknown>;";
|
|
28
|
+
if (getSchemaType(schema) !== "object") return `${schemaValueToType(schema)};`;
|
|
29
|
+
const properties = normalizeProperties(schema.properties);
|
|
30
|
+
const required = new Set(schema.required ?? []);
|
|
31
|
+
const lines = Object.entries(properties).map(([propertyName, propertySchema]) => {
|
|
32
|
+
const optional = required.has(propertyName) ? "" : "?";
|
|
33
|
+
return ` ${quotePropertyName(propertyName)}${optional}: ${schemaValueToType(propertySchema)};`;
|
|
34
|
+
});
|
|
35
|
+
if (schema.additionalProperties !== false) lines.push(" [key: string]: unknown;");
|
|
36
|
+
return [
|
|
37
|
+
"{",
|
|
38
|
+
...lines,
|
|
39
|
+
"}"
|
|
40
|
+
].join("\n");
|
|
41
|
+
}
|
|
42
|
+
function schemaValueToType(schema) {
|
|
43
|
+
if (schema.enum?.length) return schema.enum.map((value) => JSON.stringify(value)).join(" | ");
|
|
44
|
+
const type = getSchemaType(schema);
|
|
45
|
+
if (type === "integer" || type === "number") return "number";
|
|
46
|
+
if (type === "boolean") return "boolean";
|
|
47
|
+
if (type === "array") {
|
|
48
|
+
const itemSchema = normalizeSchema(schema.items);
|
|
49
|
+
return `${wrapArrayItemType(itemSchema ? schemaValueToType(itemSchema) : "unknown")}[]`;
|
|
50
|
+
}
|
|
51
|
+
if (type === "object") return schemaToType(schema).replace(/;$/, "");
|
|
52
|
+
if (type === "null") return "null";
|
|
53
|
+
return "string";
|
|
54
|
+
}
|
|
55
|
+
function normalizeProperties(properties) {
|
|
56
|
+
const normalized = {};
|
|
57
|
+
if (!properties) return normalized;
|
|
58
|
+
for (const [propertyName, propertySchema] of Object.entries(properties)) {
|
|
59
|
+
const normalizedSchema = normalizeSchema(propertySchema);
|
|
60
|
+
if (normalizedSchema) normalized[propertyName] = normalizedSchema;
|
|
61
|
+
}
|
|
62
|
+
return normalized;
|
|
63
|
+
}
|
|
64
|
+
function normalizeSchema(schema) {
|
|
65
|
+
if (typeof schema !== "object" || schema === null || Array.isArray(schema)) return;
|
|
66
|
+
return schema;
|
|
67
|
+
}
|
|
68
|
+
function getSchemaType(schema) {
|
|
69
|
+
if (!schema.type) return "string";
|
|
70
|
+
return Array.isArray(schema.type) ? schema.type[0] : schema.type;
|
|
71
|
+
}
|
|
72
|
+
function quotePropertyName(propertyName) {
|
|
73
|
+
if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(propertyName)) return propertyName;
|
|
74
|
+
return JSON.stringify(propertyName);
|
|
75
|
+
}
|
|
76
|
+
function wrapArrayItemType(type) {
|
|
77
|
+
return type.includes(" | ") ? `(${type})` : type;
|
|
78
|
+
}
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region src/generate-command-types-runner.ts
|
|
81
|
+
async function runGenerateCommandTypesCli(args) {
|
|
82
|
+
const [manifestArg, outputArg] = args;
|
|
83
|
+
if (!manifestArg || !outputArg) throw new Error("Usage: tooldeck-plugin-types <manifest.json> <output.ts>");
|
|
84
|
+
const manifestPath = path.resolve(manifestArg);
|
|
85
|
+
const outputPath = path.resolve(outputArg);
|
|
86
|
+
const output = generatePluginCommandTypes(JSON.parse(await readFile(manifestPath, "utf8")));
|
|
87
|
+
await mkdir(path.dirname(outputPath), { recursive: true });
|
|
88
|
+
await writeFile(outputPath, output, "utf8");
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
export { generatePluginCommandTypes as n, runGenerateCommandTypesCli as t };
|
|
92
|
+
|
|
93
|
+
//# sourceMappingURL=generate-command-types-runner-D_f2_VpM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-command-types-runner-D_f2_VpM.js","names":[],"sources":["../../src/generate-command-types-core.ts","../../src/generate-command-types-runner.ts"],"sourcesContent":["import type { PluginManifest, TooldeckJsonSchema } from \"@tooldeck/protocol\";\n\nexport function generatePluginCommandTypes(manifest: PluginManifest): string {\n const commands = manifest.contributes?.commands ?? [];\n const declarations: string[] = [];\n const mapEntries: string[] = [];\n\n for (const command of commands) {\n const typeName = commandInputTypeName(command.id);\n\n declarations.push(`export interface ${typeName} ${schemaToType(command.inputSchema)}`);\n mapEntries.push(` ${JSON.stringify(command.id)}: ${typeName};`);\n }\n\n return [\n \"// This file is generated from manifest.json. Do not edit it by hand.\",\n \"\",\n ...declarations.flatMap((declaration) => [declaration, \"\"]),\n \"export interface PluginCommandInputs {\",\n ...mapEntries,\n \"}\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction commandInputTypeName(commandId: string): string {\n const words = commandId\n .split(/[^a-zA-Z0-9]+/)\n .filter(Boolean)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1));\n\n return `${words.join(\"\") || \"Command\"}Input`;\n}\n\nfunction schemaToType(schema: TooldeckJsonSchema | undefined): string {\n if (!schema) {\n return \"Record<string, unknown>;\";\n }\n\n if (getSchemaType(schema) !== \"object\") {\n return `${schemaValueToType(schema)};`;\n }\n\n const properties = normalizeProperties(schema.properties);\n const required = new Set(schema.required ?? []);\n const lines = Object.entries(properties).map(([propertyName, propertySchema]) => {\n const optional = required.has(propertyName) ? \"\" : \"?\";\n\n return ` ${quotePropertyName(propertyName)}${optional}: ${schemaValueToType(propertySchema)};`;\n });\n\n if (schema.additionalProperties !== false) {\n lines.push(\" [key: string]: unknown;\");\n }\n\n return [\"{\", ...lines, \"}\"].join(\"\\n\");\n}\n\nfunction schemaValueToType(schema: TooldeckJsonSchema): string {\n if (schema.enum?.length) {\n return schema.enum.map((value) => JSON.stringify(value)).join(\" | \");\n }\n\n const type = getSchemaType(schema);\n\n if (type === \"integer\" || type === \"number\") {\n return \"number\";\n }\n\n if (type === \"boolean\") {\n return \"boolean\";\n }\n\n if (type === \"array\") {\n const itemSchema = normalizeSchema(schema.items);\n const itemType = itemSchema ? schemaValueToType(itemSchema) : \"unknown\";\n\n return `${wrapArrayItemType(itemType)}[]`;\n }\n\n if (type === \"object\") {\n return schemaToType(schema).replace(/;$/, \"\");\n }\n\n if (type === \"null\") {\n return \"null\";\n }\n\n return \"string\";\n}\n\nfunction normalizeProperties(\n properties: TooldeckJsonSchema[\"properties\"],\n): Record<string, TooldeckJsonSchema> {\n const normalized: Record<string, TooldeckJsonSchema> = {};\n\n if (!properties) {\n return normalized;\n }\n\n for (const [propertyName, propertySchema] of Object.entries(properties)) {\n const normalizedSchema = normalizeSchema(propertySchema);\n\n if (normalizedSchema) {\n normalized[propertyName] = normalizedSchema;\n }\n }\n\n return normalized;\n}\n\nfunction normalizeSchema(schema: unknown): TooldeckJsonSchema | undefined {\n if (typeof schema !== \"object\" || schema === null || Array.isArray(schema)) {\n return undefined;\n }\n\n return schema as TooldeckJsonSchema;\n}\n\nfunction getSchemaType(schema: TooldeckJsonSchema): string {\n if (!schema.type) {\n return \"string\";\n }\n\n return Array.isArray(schema.type) ? schema.type[0] : schema.type;\n}\n\nfunction quotePropertyName(propertyName: string): string {\n if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(propertyName)) {\n return propertyName;\n }\n\n return JSON.stringify(propertyName);\n}\n\nfunction wrapArrayItemType(type: string): string {\n return type.includes(\" | \") ? `(${type})` : type;\n}\n","import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport type { PluginManifest } from \"@tooldeck/protocol\";\n\nimport { generatePluginCommandTypes } from \"./generate-command-types-core\";\n\nexport async function runGenerateCommandTypesCli(args: string[]): Promise<void> {\n const [manifestArg, outputArg] = args;\n\n if (!manifestArg || !outputArg) {\n throw new Error(\"Usage: tooldeck-plugin-types <manifest.json> <output.ts>\");\n }\n\n const manifestPath = path.resolve(manifestArg);\n const outputPath = path.resolve(outputArg);\n const manifest = JSON.parse(await readFile(manifestPath, \"utf8\")) as PluginManifest;\n const output = generatePluginCommandTypes(manifest);\n\n await mkdir(path.dirname(outputPath), { recursive: true });\n await writeFile(outputPath, output, \"utf8\");\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-command-types-core.d.ts","sourceRoot":"","sources":["../src/generate-command-types-core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAsB,MAAM,oBAAoB,CAAC;AAE7E,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAqB3E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-command-types-runner.d.ts","sourceRoot":"","sources":["../src/generate-command-types-runner.ts"],"names":[],"mappings":"AAOA,wBAAsB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAc9E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-command-types.d.ts","sourceRoot":"","sources":["../src/generate-command-types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { t as runGenerateCommandTypesCli } from "./assets/generate-command-types-runner-D_f2_VpM.js";
|
|
3
|
+
//#region src/generate-command-types.ts
|
|
4
|
+
await runGenerateCommandTypesCli(process.argv.slice(2));
|
|
5
|
+
//#endregion
|
|
6
|
+
export {};
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=generate-command-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-command-types.js","names":[],"sources":["../src/generate-command-types.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { runGenerateCommandTypesCli } from \"./generate-command-types-runner\";\n\nawait runGenerateCommandTypesCli(process.argv.slice(2));\n"],"mappings":";;;AAIA,MAAM,2BAA2B,QAAQ,KAAK,MAAM,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC"}
|
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tooldeck/plugin-tools",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Development tools for Tooldeck plugins.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"tooldeck-plugin-types": "dist/generate-command-types.js"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@tooldeck/protocol": "1.1.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^25.9.1"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "vite build --configLoader runner && tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"typecheck": "tsc --noEmit"
|
|
32
|
+
}
|
|
33
|
+
}
|