trans-spec 1.0.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/LICENSE +21 -0
- package/README.md +547 -0
- package/cli/index.js +329 -0
- package/cli/package-lock.json +278 -0
- package/cli/package.json +22 -0
- package/cli/src/auth.js +98 -0
- package/cli/src/config.js +70 -0
- package/cli/src/setup.js +39 -0
- package/cli/src/translate.js +71 -0
- package/package.json +47 -0
- package/viewer/README.md +16 -0
- package/viewer/eslint.config.js +29 -0
- package/viewer/index.html +12 -0
- package/viewer/package-lock.json +14016 -0
- package/viewer/package.json +35 -0
- package/viewer/public/trans-spec/i18n/en/api2.yaml +130 -0
- package/viewer/public/trans-spec/i18n/es/api2.yaml +137 -0
- package/viewer/public/trans-spec/i18n.json +17 -0
- package/viewer/public/trans-spec/i18n.lock +67 -0
- package/viewer/public/trans-spec/index.json +8 -0
- package/viewer/src/App.jsx +217 -0
- package/viewer/src/components/EndpointDetail.jsx +290 -0
- package/viewer/src/components/LanguageSwitcher.jsx +25 -0
- package/viewer/src/components/Sidebar.jsx +88 -0
- package/viewer/src/index.css +1 -0
- package/viewer/src/main.jsx +14 -0
- package/viewer/src/polyfills.js +2 -0
- package/viewer/src/utils/specLoader.js +79 -0
- package/viewer/vite.config.js +21 -0
package/cli/index.js
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { program } from "commander";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import { checkAuth } from "./src/auth.js";
|
|
7
|
+
import { setup } from "./src/setup.js";
|
|
8
|
+
import { generateConfig } from "./src/config.js";
|
|
9
|
+
import { translate } from "./src/translate.js";
|
|
10
|
+
const TRANSSPEC_DIR = ".trans-spec";
|
|
11
|
+
const EJECTED_VIEWER_DIR = "trans-spec-viewer";
|
|
12
|
+
|
|
13
|
+
program
|
|
14
|
+
.name("trans-spec")
|
|
15
|
+
.description("Translate your OpenAPI spec into multiple languages")
|
|
16
|
+
.version("1.0.0");
|
|
17
|
+
|
|
18
|
+
program
|
|
19
|
+
.command("generate")
|
|
20
|
+
.description("Translate an OpenAPI spec into multiple languages")
|
|
21
|
+
.requiredOption("--spec <path>", "Path to your OpenAPI spec file")
|
|
22
|
+
.option("--languages <languages>", "Target languages e.g. es,fr,de")
|
|
23
|
+
.option("--source <language>", "Source language (default: en)", "en")
|
|
24
|
+
.action(async (options) => {
|
|
25
|
+
console.log(chalk.bold("\nš Trans-Spec\n"));
|
|
26
|
+
|
|
27
|
+
// Step 1: Check authentication
|
|
28
|
+
await checkAuth();
|
|
29
|
+
|
|
30
|
+
// Step 2: Setup folder structure and copy spec
|
|
31
|
+
await setup(options.spec, options.source);
|
|
32
|
+
|
|
33
|
+
// Step 3: Generate i18n.json config
|
|
34
|
+
const targets = await generateConfig(options.languages, options.source);
|
|
35
|
+
|
|
36
|
+
// Step 4: Run translations
|
|
37
|
+
await translate(targets);
|
|
38
|
+
|
|
39
|
+
// Step 5: Tell user where their files are
|
|
40
|
+
console.log(chalk.bold("\nā Done! Your translated specs are in:\n"));
|
|
41
|
+
targets.forEach((lang) => {
|
|
42
|
+
console.log(chalk.cyan(` ${TRANSSPEC_DIR}/i18n/${lang}/api.yaml`));
|
|
43
|
+
});
|
|
44
|
+
console.log(chalk.white("\nTo view your docs, run:"));
|
|
45
|
+
console.log(chalk.cyan(" npx trans-spec serve\n"));
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
program
|
|
49
|
+
.command("eject")
|
|
50
|
+
.description(
|
|
51
|
+
`Copy the viewer source into ./${EJECTED_VIEWER_DIR} so you can customize and deploy it`,
|
|
52
|
+
)
|
|
53
|
+
.action(async () => {
|
|
54
|
+
const fs = await import("fs");
|
|
55
|
+
const { fileURLToPath } = await import("url");
|
|
56
|
+
|
|
57
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
58
|
+
const packageViewerDir = path.resolve(__dirname, "../viewer");
|
|
59
|
+
const ejectedViewerDir = path.join(process.cwd(), EJECTED_VIEWER_DIR);
|
|
60
|
+
|
|
61
|
+
console.log(chalk.bold("\nš¦ Trans-Spec Eject\n"));
|
|
62
|
+
|
|
63
|
+
if (!fs.existsSync(packageViewerDir)) {
|
|
64
|
+
console.log(
|
|
65
|
+
chalk.red("ā Could not find the viewer source inside the package."),
|
|
66
|
+
);
|
|
67
|
+
console.log(chalk.gray(` Looked in: ${packageViewerDir}`));
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (fs.existsSync(ejectedViewerDir)) {
|
|
72
|
+
console.log(
|
|
73
|
+
chalk.red(
|
|
74
|
+
`ā ${EJECTED_VIEWER_DIR}/ already exists. Remove it first if you want to eject again.\n`,
|
|
75
|
+
),
|
|
76
|
+
);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
console.log(
|
|
81
|
+
chalk.white(
|
|
82
|
+
`Copying viewer into ${chalk.cyan(EJECTED_VIEWER_DIR + "/")}...\n`,
|
|
83
|
+
),
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
console.log(chalk.gray(` From: ${packageViewerDir}`));
|
|
88
|
+
console.log(chalk.gray(` To: ${ejectedViewerDir}`));
|
|
89
|
+
fs.cpSync(packageViewerDir, ejectedViewerDir, {
|
|
90
|
+
recursive: true,
|
|
91
|
+
filter: (src) => {
|
|
92
|
+
const parts = src.replace(packageViewerDir, "").split(path.sep);
|
|
93
|
+
return !parts.includes("node_modules");
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
} catch (err) {
|
|
97
|
+
console.log(chalk.red("\nā Failed to copy viewer files:"));
|
|
98
|
+
console.log(err);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
console.log(chalk.green(`ā Viewer ejected to ${EJECTED_VIEWER_DIR}/\n`));
|
|
103
|
+
console.log(chalk.white("Next steps:"));
|
|
104
|
+
console.log(chalk.cyan(` cd ${EJECTED_VIEWER_DIR} && npm install`));
|
|
105
|
+
console.log(
|
|
106
|
+
chalk.white("\nThe viewer will be used automatically when you run:"),
|
|
107
|
+
);
|
|
108
|
+
console.log(chalk.cyan(" npx trans-spec serve\n"));
|
|
109
|
+
console.log(chalk.white("Or run it directly for full control:"));
|
|
110
|
+
console.log(chalk.cyan(` cd ${EJECTED_VIEWER_DIR} && npm run dev\n`));
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
program
|
|
114
|
+
.command("serve")
|
|
115
|
+
.description("Start the local docs viewer")
|
|
116
|
+
.option("-p, --port <port>", "Port to run server on", "3000")
|
|
117
|
+
.action(async (options) => {
|
|
118
|
+
const { spawn, execSync } = await import("child_process");
|
|
119
|
+
const path = await import("path");
|
|
120
|
+
const fs = await import("fs");
|
|
121
|
+
const readline = await import("readline");
|
|
122
|
+
const { fileURLToPath } = await import("url");
|
|
123
|
+
|
|
124
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
125
|
+
|
|
126
|
+
// Prefer ejected viewer in cwd over the package viewer
|
|
127
|
+
const ejectedViewerDir = path.join(process.cwd(), EJECTED_VIEWER_DIR);
|
|
128
|
+
const packageViewerDir = path.resolve(__dirname, "../viewer");
|
|
129
|
+
const isEjected = fs.existsSync(ejectedViewerDir);
|
|
130
|
+
const viewerDir = isEjected ? ejectedViewerDir : packageViewerDir;
|
|
131
|
+
|
|
132
|
+
if (isEjected) {
|
|
133
|
+
console.log(
|
|
134
|
+
chalk.cyan(`\nš§ Using ejected viewer from ./${EJECTED_VIEWER_DIR}\n`),
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const publicDir = path.join(viewerDir, "public");
|
|
139
|
+
const transSpecSource = path.join(process.cwd(), ".trans-spec");
|
|
140
|
+
const transSpecDest = path.join(publicDir, "trans-spec");
|
|
141
|
+
|
|
142
|
+
// Check if .trans-spec exists
|
|
143
|
+
if (!fs.existsSync(transSpecSource)) {
|
|
144
|
+
console.log(
|
|
145
|
+
chalk.red("\nā No .trans-spec folder found in current directory"),
|
|
146
|
+
);
|
|
147
|
+
console.log(
|
|
148
|
+
chalk.white(
|
|
149
|
+
"Run: npx trans-spec generate --spec api.yaml --languages es,fr first\n",
|
|
150
|
+
),
|
|
151
|
+
);
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Read API spec languages
|
|
156
|
+
const i18nConfig = JSON.parse(
|
|
157
|
+
fs.readFileSync(path.join(transSpecSource, "i18n.json"), "utf-8"),
|
|
158
|
+
);
|
|
159
|
+
const sourceLocale = i18nConfig.locale.source;
|
|
160
|
+
const targetLocales = i18nConfig.locale.targets;
|
|
161
|
+
|
|
162
|
+
console.log(chalk.cyan("\nš Starting Trans-Spec viewer...\n"));
|
|
163
|
+
|
|
164
|
+
// Check for API key and prompt if not found
|
|
165
|
+
let apiKey = process.env.LINGODOTDEV_API_KEY;
|
|
166
|
+
const envPath = path.join(viewerDir, ".env");
|
|
167
|
+
|
|
168
|
+
// Check if API key exists in viewer/.env
|
|
169
|
+
if (!apiKey && fs.existsSync(envPath)) {
|
|
170
|
+
const envContent = fs.readFileSync(envPath, "utf-8");
|
|
171
|
+
const match = envContent.match(/LINGODOTDEV_API_KEY=(.+)/);
|
|
172
|
+
if (match) {
|
|
173
|
+
apiKey = match[1].trim();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Prompt for API key if not found
|
|
178
|
+
if (!apiKey) {
|
|
179
|
+
console.log(chalk.yellow("ā Lingo.dev API key not found.\n"));
|
|
180
|
+
console.log(chalk.white("To get your API key:"));
|
|
181
|
+
console.log(chalk.cyan(" 1. Visit https://lingo.dev"));
|
|
182
|
+
console.log(chalk.cyan(" 2. Sign in and go to Settings"));
|
|
183
|
+
console.log(chalk.cyan(" 3. Copy your API key\n"));
|
|
184
|
+
|
|
185
|
+
const rl = readline.createInterface({
|
|
186
|
+
input: process.stdin,
|
|
187
|
+
output: process.stdout,
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
apiKey = await new Promise((resolve) => {
|
|
191
|
+
rl.question(chalk.white("Enter your Lingo.dev API key: "), (answer) => {
|
|
192
|
+
rl.close();
|
|
193
|
+
resolve(answer.trim());
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
if (!apiKey) {
|
|
198
|
+
console.log(chalk.red("\nā API key is required to run the viewer"));
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Save API key to viewer/.env for future use
|
|
203
|
+
let existingEnv = "";
|
|
204
|
+
if (fs.existsSync(envPath)) {
|
|
205
|
+
existingEnv = fs.readFileSync(envPath, "utf-8");
|
|
206
|
+
// Remove existing LINGODOTDEV_API_KEY line if present
|
|
207
|
+
existingEnv = existingEnv
|
|
208
|
+
.split("\n")
|
|
209
|
+
.filter((line) => !line.startsWith("LINGODOTDEV_API_KEY="))
|
|
210
|
+
.join("\n");
|
|
211
|
+
}
|
|
212
|
+
// Add the new API key
|
|
213
|
+
const newEnvContent = existingEnv
|
|
214
|
+
? `${existingEnv}\nLINGODOTDEV_API_KEY=${apiKey}\n`
|
|
215
|
+
: `LINGODOTDEV_API_KEY=${apiKey}\n`;
|
|
216
|
+
|
|
217
|
+
fs.writeFileSync(envPath, newEnvContent);
|
|
218
|
+
console.log(chalk.green("\nā API key saved to viewer/.env\n"));
|
|
219
|
+
} else {
|
|
220
|
+
console.log(chalk.green("ā API key found\n"));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Copy .trans-spec to viewer/public
|
|
224
|
+
if (fs.existsSync(transSpecDest)) {
|
|
225
|
+
fs.rmSync(transSpecDest, { recursive: true });
|
|
226
|
+
}
|
|
227
|
+
fs.cpSync(transSpecSource, transSpecDest, { recursive: true });
|
|
228
|
+
|
|
229
|
+
// Create index of available spec files
|
|
230
|
+
const specI18nDir = path.join(transSpecSource, "i18n");
|
|
231
|
+
const languages = fs.readdirSync(specI18nDir);
|
|
232
|
+
const index = {};
|
|
233
|
+
|
|
234
|
+
languages.forEach((lang) => {
|
|
235
|
+
const langDir = path.join(specI18nDir, lang);
|
|
236
|
+
const files = fs
|
|
237
|
+
.readdirSync(langDir)
|
|
238
|
+
.filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"))
|
|
239
|
+
.sort();
|
|
240
|
+
|
|
241
|
+
index[lang] = files;
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
fs.writeFileSync(
|
|
245
|
+
path.join(transSpecDest, "index.json"),
|
|
246
|
+
JSON.stringify(index, null, 2),
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
// Generate Vite config with Compiler
|
|
250
|
+
const viteConfigContent = `import { defineConfig } from 'vite'
|
|
251
|
+
import react from '@vitejs/plugin-react'
|
|
252
|
+
import { lingoCompilerPlugin } from '@lingo.dev/compiler/vite'
|
|
253
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
254
|
+
|
|
255
|
+
export default defineConfig({
|
|
256
|
+
plugins: [
|
|
257
|
+
lingoCompilerPlugin({
|
|
258
|
+
sourceRoot: 'src',
|
|
259
|
+
sourceLocale: '${sourceLocale}',
|
|
260
|
+
targetLocales: ${JSON.stringify(targetLocales)},
|
|
261
|
+
models: 'lingo.dev',
|
|
262
|
+
dev: {
|
|
263
|
+
usePseudotranslator: false,
|
|
264
|
+
},
|
|
265
|
+
}),
|
|
266
|
+
react(),
|
|
267
|
+
tailwindcss(),
|
|
268
|
+
],
|
|
269
|
+
})
|
|
270
|
+
`;
|
|
271
|
+
|
|
272
|
+
fs.writeFileSync(
|
|
273
|
+
path.join(viewerDir, "vite.config.generated.js"),
|
|
274
|
+
viteConfigContent,
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
console.log(chalk.green("ā Setup complete"));
|
|
278
|
+
// Install viewer dependencies if needed
|
|
279
|
+
const viewerNodeModules = path.join(viewerDir, "node_modules");
|
|
280
|
+
if (!fs.existsSync(viewerNodeModules)) {
|
|
281
|
+
console.log(
|
|
282
|
+
chalk.yellow(
|
|
283
|
+
"\nš¦ Installing viewer dependencies (one-time setup)...\n",
|
|
284
|
+
),
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
try {
|
|
288
|
+
execSync("npm install", {
|
|
289
|
+
cwd: viewerDir,
|
|
290
|
+
stdio: "inherit",
|
|
291
|
+
shell: true,
|
|
292
|
+
});
|
|
293
|
+
console.log(chalk.green("\nā Dependencies installed\n"));
|
|
294
|
+
} catch (err) {
|
|
295
|
+
console.log(chalk.red("\nā Failed to install dependencies"));
|
|
296
|
+
console.log(err);
|
|
297
|
+
process.exit(1);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
console.log(
|
|
301
|
+
chalk.cyan(`\nStarting server on http://localhost:${options.port}\n`),
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
// Start server
|
|
305
|
+
const server = spawn(
|
|
306
|
+
"npm",
|
|
307
|
+
[
|
|
308
|
+
"run",
|
|
309
|
+
"dev",
|
|
310
|
+
"--",
|
|
311
|
+
"--config",
|
|
312
|
+
"vite.config.generated.js",
|
|
313
|
+
"--port",
|
|
314
|
+
options.port,
|
|
315
|
+
],
|
|
316
|
+
{
|
|
317
|
+
cwd: viewerDir,
|
|
318
|
+
stdio: "inherit",
|
|
319
|
+
shell: true,
|
|
320
|
+
},
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
server.on("error", (err) => {
|
|
324
|
+
console.log(chalk.red("Failed to start viewer:", err.message));
|
|
325
|
+
process.exit(1);
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
program.parse();
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"lockfileVersion": 3,
|
|
5
|
+
"requires": true,
|
|
6
|
+
"packages": {
|
|
7
|
+
"": {
|
|
8
|
+
"name": "cli",
|
|
9
|
+
"version": "1.0.0",
|
|
10
|
+
"license": "ISC",
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"chalk": "^5.6.2",
|
|
13
|
+
"commander": "^14.0.3",
|
|
14
|
+
"dotenv": "^17.3.1",
|
|
15
|
+
"ora": "^9.3.0"
|
|
16
|
+
},
|
|
17
|
+
"bin": {
|
|
18
|
+
"trans-spec": "index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"node_modules/ansi-regex": {
|
|
22
|
+
"version": "6.2.2",
|
|
23
|
+
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
|
|
24
|
+
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=12"
|
|
28
|
+
},
|
|
29
|
+
"funding": {
|
|
30
|
+
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"node_modules/chalk": {
|
|
34
|
+
"version": "5.6.2",
|
|
35
|
+
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
|
|
36
|
+
"integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
|
40
|
+
},
|
|
41
|
+
"funding": {
|
|
42
|
+
"url": "https://github.com/chalk/chalk?sponsor=1"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"node_modules/cli-cursor": {
|
|
46
|
+
"version": "5.0.0",
|
|
47
|
+
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
|
|
48
|
+
"integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"restore-cursor": "^5.0.0"
|
|
52
|
+
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=18"
|
|
55
|
+
},
|
|
56
|
+
"funding": {
|
|
57
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"node_modules/cli-spinners": {
|
|
61
|
+
"version": "3.4.0",
|
|
62
|
+
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz",
|
|
63
|
+
"integrity": "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==",
|
|
64
|
+
"license": "MIT",
|
|
65
|
+
"engines": {
|
|
66
|
+
"node": ">=18.20"
|
|
67
|
+
},
|
|
68
|
+
"funding": {
|
|
69
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"node_modules/commander": {
|
|
73
|
+
"version": "14.0.3",
|
|
74
|
+
"resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
|
|
75
|
+
"integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
|
|
76
|
+
"license": "MIT",
|
|
77
|
+
"engines": {
|
|
78
|
+
"node": ">=20"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"node_modules/dotenv": {
|
|
82
|
+
"version": "17.3.1",
|
|
83
|
+
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.1.tgz",
|
|
84
|
+
"integrity": "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==",
|
|
85
|
+
"license": "BSD-2-Clause",
|
|
86
|
+
"engines": {
|
|
87
|
+
"node": ">=12"
|
|
88
|
+
},
|
|
89
|
+
"funding": {
|
|
90
|
+
"url": "https://dotenvx.com"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"node_modules/get-east-asian-width": {
|
|
94
|
+
"version": "1.4.0",
|
|
95
|
+
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz",
|
|
96
|
+
"integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==",
|
|
97
|
+
"license": "MIT",
|
|
98
|
+
"engines": {
|
|
99
|
+
"node": ">=18"
|
|
100
|
+
},
|
|
101
|
+
"funding": {
|
|
102
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"node_modules/is-interactive": {
|
|
106
|
+
"version": "2.0.0",
|
|
107
|
+
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz",
|
|
108
|
+
"integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==",
|
|
109
|
+
"license": "MIT",
|
|
110
|
+
"engines": {
|
|
111
|
+
"node": ">=12"
|
|
112
|
+
},
|
|
113
|
+
"funding": {
|
|
114
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"node_modules/is-unicode-supported": {
|
|
118
|
+
"version": "2.1.0",
|
|
119
|
+
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
|
|
120
|
+
"integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
|
|
121
|
+
"license": "MIT",
|
|
122
|
+
"engines": {
|
|
123
|
+
"node": ">=18"
|
|
124
|
+
},
|
|
125
|
+
"funding": {
|
|
126
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
"node_modules/log-symbols": {
|
|
130
|
+
"version": "7.0.1",
|
|
131
|
+
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz",
|
|
132
|
+
"integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==",
|
|
133
|
+
"license": "MIT",
|
|
134
|
+
"dependencies": {
|
|
135
|
+
"is-unicode-supported": "^2.0.0",
|
|
136
|
+
"yoctocolors": "^2.1.1"
|
|
137
|
+
},
|
|
138
|
+
"engines": {
|
|
139
|
+
"node": ">=18"
|
|
140
|
+
},
|
|
141
|
+
"funding": {
|
|
142
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
"node_modules/mimic-function": {
|
|
146
|
+
"version": "5.0.1",
|
|
147
|
+
"resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
|
|
148
|
+
"integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
|
|
149
|
+
"license": "MIT",
|
|
150
|
+
"engines": {
|
|
151
|
+
"node": ">=18"
|
|
152
|
+
},
|
|
153
|
+
"funding": {
|
|
154
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
"node_modules/onetime": {
|
|
158
|
+
"version": "7.0.0",
|
|
159
|
+
"resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
|
|
160
|
+
"integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
|
|
161
|
+
"license": "MIT",
|
|
162
|
+
"dependencies": {
|
|
163
|
+
"mimic-function": "^5.0.0"
|
|
164
|
+
},
|
|
165
|
+
"engines": {
|
|
166
|
+
"node": ">=18"
|
|
167
|
+
},
|
|
168
|
+
"funding": {
|
|
169
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
"node_modules/ora": {
|
|
173
|
+
"version": "9.3.0",
|
|
174
|
+
"resolved": "https://registry.npmjs.org/ora/-/ora-9.3.0.tgz",
|
|
175
|
+
"integrity": "sha512-lBX72MWFduWEf7v7uWf5DHp9Jn5BI8bNPGuFgtXMmr2uDz2Gz2749y3am3agSDdkhHPHYmmxEGSKH85ZLGzgXw==",
|
|
176
|
+
"license": "MIT",
|
|
177
|
+
"dependencies": {
|
|
178
|
+
"chalk": "^5.6.2",
|
|
179
|
+
"cli-cursor": "^5.0.0",
|
|
180
|
+
"cli-spinners": "^3.2.0",
|
|
181
|
+
"is-interactive": "^2.0.0",
|
|
182
|
+
"is-unicode-supported": "^2.1.0",
|
|
183
|
+
"log-symbols": "^7.0.1",
|
|
184
|
+
"stdin-discarder": "^0.3.1",
|
|
185
|
+
"string-width": "^8.1.0"
|
|
186
|
+
},
|
|
187
|
+
"engines": {
|
|
188
|
+
"node": ">=20"
|
|
189
|
+
},
|
|
190
|
+
"funding": {
|
|
191
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
"node_modules/restore-cursor": {
|
|
195
|
+
"version": "5.1.0",
|
|
196
|
+
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
|
|
197
|
+
"integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
|
|
198
|
+
"license": "MIT",
|
|
199
|
+
"dependencies": {
|
|
200
|
+
"onetime": "^7.0.0",
|
|
201
|
+
"signal-exit": "^4.1.0"
|
|
202
|
+
},
|
|
203
|
+
"engines": {
|
|
204
|
+
"node": ">=18"
|
|
205
|
+
},
|
|
206
|
+
"funding": {
|
|
207
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
"node_modules/signal-exit": {
|
|
211
|
+
"version": "4.1.0",
|
|
212
|
+
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
|
213
|
+
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
|
214
|
+
"license": "ISC",
|
|
215
|
+
"engines": {
|
|
216
|
+
"node": ">=14"
|
|
217
|
+
},
|
|
218
|
+
"funding": {
|
|
219
|
+
"url": "https://github.com/sponsors/isaacs"
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
"node_modules/stdin-discarder": {
|
|
223
|
+
"version": "0.3.1",
|
|
224
|
+
"resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.3.1.tgz",
|
|
225
|
+
"integrity": "sha512-reExS1kSGoElkextOcPkel4NE99S0BWxjUHQeDFnR8S993JxpPX7KU4MNmO19NXhlJp+8dmdCbKQVNgLJh2teA==",
|
|
226
|
+
"license": "MIT",
|
|
227
|
+
"engines": {
|
|
228
|
+
"node": ">=18"
|
|
229
|
+
},
|
|
230
|
+
"funding": {
|
|
231
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
"node_modules/string-width": {
|
|
235
|
+
"version": "8.1.1",
|
|
236
|
+
"resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.1.tgz",
|
|
237
|
+
"integrity": "sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw==",
|
|
238
|
+
"license": "MIT",
|
|
239
|
+
"dependencies": {
|
|
240
|
+
"get-east-asian-width": "^1.3.0",
|
|
241
|
+
"strip-ansi": "^7.1.0"
|
|
242
|
+
},
|
|
243
|
+
"engines": {
|
|
244
|
+
"node": ">=20"
|
|
245
|
+
},
|
|
246
|
+
"funding": {
|
|
247
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
"node_modules/strip-ansi": {
|
|
251
|
+
"version": "7.1.2",
|
|
252
|
+
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
|
|
253
|
+
"integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
|
|
254
|
+
"license": "MIT",
|
|
255
|
+
"dependencies": {
|
|
256
|
+
"ansi-regex": "^6.0.1"
|
|
257
|
+
},
|
|
258
|
+
"engines": {
|
|
259
|
+
"node": ">=12"
|
|
260
|
+
},
|
|
261
|
+
"funding": {
|
|
262
|
+
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
"node_modules/yoctocolors": {
|
|
266
|
+
"version": "2.1.2",
|
|
267
|
+
"resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz",
|
|
268
|
+
"integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==",
|
|
269
|
+
"license": "MIT",
|
|
270
|
+
"engines": {
|
|
271
|
+
"node": ">=18"
|
|
272
|
+
},
|
|
273
|
+
"funding": {
|
|
274
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
package/cli/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"bin": {
|
|
10
|
+
"trans-spec": "./index.js"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [],
|
|
13
|
+
"author": "",
|
|
14
|
+
"license": "ISC",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"chalk": "^5.6.2",
|
|
18
|
+
"commander": "^14.0.3",
|
|
19
|
+
"dotenv": "^17.3.1",
|
|
20
|
+
"ora": "^9.3.0"
|
|
21
|
+
}
|
|
22
|
+
}
|