nuxt-og-image 6.0.0-beta.1 → 6.0.0-beta.2

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.
@@ -3,7 +3,7 @@
3
3
  const promises = require('node:fs/promises');
4
4
  const compilerSfc = require('@vue/compiler-sfc');
5
5
  const tinyglobby = require('tinyglobby');
6
- const module$1 = require('../shared/nuxt-og-image.DroaQ3v-.cjs');
6
+ const module$1 = require('../shared/nuxt-og-image.iluFGbPR.cjs');
7
7
  require('node:fs');
8
8
  require('@nuxt/kit');
9
9
  require('defu');
@@ -1,7 +1,7 @@
1
1
  import { readFile } from 'node:fs/promises';
2
2
  import { parse } from '@vue/compiler-sfc';
3
3
  import { glob } from 'tinyglobby';
4
- import { w as walkTemplateAst } from '../shared/nuxt-og-image.HMyihp-D.mjs';
4
+ import { w as walkTemplateAst } from '../shared/nuxt-og-image.D-QhzI76.mjs';
5
5
  import 'node:fs';
6
6
  import '@nuxt/kit';
7
7
  import 'defu';
@@ -6,7 +6,7 @@ const postcss = require('postcss');
6
6
  const postcssCalc = require('postcss-calc');
7
7
  const postcssCustomProperties = require('postcss-custom-properties');
8
8
  const tailwindcss = require('tailwindcss');
9
- const module$1 = require('../shared/nuxt-og-image.DroaQ3v-.cjs');
9
+ const module$1 = require('../shared/nuxt-og-image.iluFGbPR.cjs');
10
10
  require('node:fs');
11
11
  require('@nuxt/kit');
12
12
  require('defu');
@@ -4,7 +4,7 @@ import postcss from 'postcss';
4
4
  import postcssCalc from 'postcss-calc';
5
5
  import postcssCustomProperties from 'postcss-custom-properties';
6
6
  import { compile } from 'tailwindcss';
7
- import { c as createStylesheetLoader, a as convertOklchToHex, b as buildNuxtUiVars, d as decodeCssClassName } from '../shared/nuxt-og-image.HMyihp-D.mjs';
7
+ import { c as createStylesheetLoader, a as convertOklchToHex, b as buildNuxtUiVars, d as decodeCssClassName } from '../shared/nuxt-og-image.D-QhzI76.mjs';
8
8
  import 'node:fs';
9
9
  import '@nuxt/kit';
10
10
  import 'defu';
package/dist/cli.cjs CHANGED
@@ -1,30 +1,51 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- const node_child_process = require('node:child_process');
5
4
  const fs = require('node:fs');
6
5
  const node_path = require('node:path');
7
- const node_readline = require('node:readline');
8
6
  const node_url = require('node:url');
7
+ const p = require('@clack/prompts');
8
+ const magicast = require('magicast');
9
+ const nypm = require('nypm');
9
10
 
10
11
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
11
- async function confirm(message) {
12
- const rl = node_readline.createInterface({ input: process.stdin, output: process.stdout });
13
- return new Promise((resolve2) => {
14
- rl.question(`${message} (y/N) `, (answer) => {
15
- rl.close();
16
- resolve2(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
17
- });
18
- });
12
+ function _interopNamespaceCompat(e) {
13
+ if (e && typeof e === 'object' && 'default' in e) return e;
14
+ const n = Object.create(null);
15
+ if (e) {
16
+ for (const k in e) {
17
+ n[k] = e[k];
18
+ }
19
+ }
20
+ n.default = e;
21
+ return n;
19
22
  }
23
+
24
+ const p__namespace = /*#__PURE__*/_interopNamespaceCompat(p);
25
+
20
26
  const __dirname$1 = node_path.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.cjs', document.baseURI).href))));
21
27
  const communityDir = node_path.resolve(__dirname$1, "runtime/app/components/Templates/Community");
22
28
  const defaultComponentDirs = ["OgImage", "OgImageCommunity", "og-image", "OgImageTemplate"];
23
- const RENDERER_DEPS = {
24
- satori: ["satori", "@resvg/resvg-js"],
25
- chromium: ["playwright-core"],
26
- takumi: ["@aspect-build/aspect", "linkedom"]
27
- };
29
+ const RENDERERS = [
30
+ {
31
+ name: "satori",
32
+ label: "Satori",
33
+ description: "SVG-based renderer - fast, works everywhere (recommended)",
34
+ deps: ["satori", "@resvg/resvg-js"]
35
+ },
36
+ {
37
+ name: "takumi",
38
+ label: "Takumi",
39
+ description: "Rust-based high-performance renderer",
40
+ deps: ["@takumi-rs/core"]
41
+ },
42
+ {
43
+ name: "chromium",
44
+ label: "Chromium",
45
+ description: "Browser screenshot renderer - pixel-perfect but slower",
46
+ deps: ["playwright-core"]
47
+ }
48
+ ];
28
49
  function getBaseName(filename) {
29
50
  return filename.replace(/\.(satori|chromium|takumi)\.vue$/, "");
30
51
  }
@@ -45,7 +66,7 @@ function findTemplateFile(name) {
45
66
  function ejectTemplate(name, targetDir) {
46
67
  const templateFile = findTemplateFile(name);
47
68
  if (!templateFile) {
48
- console.error(`Template "${name}" not found.`);
69
+ p__namespace.log.error(`Template "${name}" not found.`);
49
70
  listTemplates();
50
71
  process.exit(1);
51
72
  }
@@ -55,12 +76,12 @@ function ejectTemplate(name, targetDir) {
55
76
  fs.mkdirSync(outputDir, { recursive: true });
56
77
  const outputPath = node_path.join(outputDir, templateFile);
57
78
  if (fs.existsSync(outputPath)) {
58
- console.error(`File already exists: ${outputPath}`);
79
+ p__namespace.log.error(`File already exists: ${outputPath}`);
59
80
  process.exit(1);
60
81
  }
61
82
  const content = fs.readFileSync(templatePath, "utf-8");
62
83
  fs.writeFileSync(outputPath, content, "utf-8");
63
- console.log(`\u2713 Ejected "${name}" to ${outputPath}`);
84
+ p__namespace.log.success(`Ejected "${name}" to ${outputPath}`);
64
85
  }
65
86
  function findOgImageComponents(dir) {
66
87
  const components = [];
@@ -96,14 +117,62 @@ function globFiles(dir, pattern, exclude = []) {
96
117
  walk(dir);
97
118
  return results;
98
119
  }
120
+ async function checkNuxtConfig(rootDir) {
121
+ const configPaths = ["nuxt.config.ts", "nuxt.config.js", "nuxt.config.mjs"];
122
+ let configPath = null;
123
+ for (const _p of configPaths) {
124
+ const fullPath = node_path.join(rootDir, _p);
125
+ if (fs.existsSync(fullPath)) {
126
+ configPath = fullPath;
127
+ break;
128
+ }
129
+ }
130
+ if (!configPath)
131
+ return { hasDeprecatedFonts: false, hasNuxtFonts: false, configPath: null };
132
+ const mod = await magicast.loadFile(configPath).catch(() => null);
133
+ if (!mod)
134
+ return { hasDeprecatedFonts: false, hasNuxtFonts: false, configPath };
135
+ const config = mod.exports.default;
136
+ const hasDeprecatedFonts = !!config?.ogImage?.fonts;
137
+ const modules = config?.modules || [];
138
+ const hasNuxtFonts = modules.some(
139
+ (m) => typeof m === "string" && m === "@nuxt/fonts" || Array.isArray(m) && m[0] === "@nuxt/fonts"
140
+ );
141
+ return { hasDeprecatedFonts, hasNuxtFonts, configPath };
142
+ }
143
+ async function checkMigrationNeeded(rootDir) {
144
+ const result = {
145
+ needsComponentRename: false,
146
+ needsFontsMigration: false,
147
+ needsNuxtFonts: false,
148
+ componentsToRename: []
149
+ };
150
+ const dirs = [rootDir];
151
+ if (fs.existsSync(node_path.join(rootDir, "app")))
152
+ dirs.push(node_path.join(rootDir, "app"));
153
+ const layersDir = node_path.join(rootDir, "layers");
154
+ if (fs.existsSync(layersDir)) {
155
+ const layerDirs = fs.readdirSync(layersDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => node_path.join(layersDir, d.name));
156
+ dirs.push(...layerDirs);
157
+ }
158
+ for (const dir of dirs) {
159
+ const components = findOgImageComponents(dir);
160
+ for (const filepath of components) {
161
+ const filename = filepath.split("/").pop();
162
+ if (!hasRendererSuffix(filename)) {
163
+ result.componentsToRename.push({ from: filepath, to: "" });
164
+ }
165
+ }
166
+ }
167
+ result.needsComponentRename = result.componentsToRename.length > 0;
168
+ const configCheck = await checkNuxtConfig(rootDir);
169
+ result.needsFontsMigration = configCheck.hasDeprecatedFonts;
170
+ result.needsNuxtFonts = !configCheck.hasNuxtFonts;
171
+ return result;
172
+ }
99
173
  function migrateDefineOgImageApi(dryRun) {
100
174
  const cwd = process.cwd();
101
- const excludePatterns = [
102
- /node_modules/,
103
- /\.nuxt/,
104
- /\.output/,
105
- /dist/
106
- ];
175
+ const excludePatterns = [/node_modules/, /\.nuxt/, /\.output/, /dist/];
107
176
  const files = globFiles(cwd, /\.(?:vue|ts|tsx|js|jsx)$/, excludePatterns);
108
177
  const changes = [];
109
178
  for (const file of files) {
@@ -124,10 +193,7 @@ function migrateDefineOgImageApi(dryRun) {
124
193
  const remaining = inner.replace(/renderer\s*:\s*['"][^'"]+['"]\s*,?\s*/g, "").replace(/,\s*$/, "").trim();
125
194
  modified = true;
126
195
  changeCount++;
127
- if (remaining) {
128
- return `defineOgImageScreenshot({ ${remaining} })`;
129
- }
130
- return `defineOgImageScreenshot()`;
196
+ return remaining ? `defineOgImageScreenshot({ ${remaining} })` : `defineOgImageScreenshot()`;
131
197
  }
132
198
  if (componentMatch || rendererMatch) {
133
199
  const componentName = componentMatch ? componentMatch[1] : "NuxtSeo";
@@ -161,108 +227,178 @@ function migrateDefineOgImageApi(dryRun) {
161
227
  }
162
228
  }
163
229
  }
164
- if (changes.length === 0) {
165
- console.log("\u2713 No defineOgImage calls need migration.");
230
+ return { changes };
231
+ }
232
+ function migrateV6Components(componentsToRename, defaultRenderer, dryRun) {
233
+ for (const item of componentsToRename) {
234
+ const filename = item.from.split("/").pop();
235
+ const newName = filename.replace(".vue", `.${defaultRenderer}.vue`);
236
+ item.to = item.from.replace(filename, newName);
237
+ }
238
+ if (dryRun) {
239
+ console.log("\nWould rename:");
240
+ for (const { from, to } of componentsToRename) {
241
+ console.log(` ${from.split("/").pop()} \u2192 ${to.split("/").pop()}`);
242
+ }
166
243
  return;
167
244
  }
168
- console.log(`
169
- Found ${changes.length} file(s) with changes:
170
- `);
171
- for (const { file, count } of changes) {
172
- const relPath = file.replace(`${cwd}/`, "");
173
- console.log(` ${relPath} (${count} change${count > 1 ? "s" : ""})`);
245
+ for (const { from, to } of componentsToRename) {
246
+ fs.renameSync(from, to);
247
+ console.log(`\u2713 Renamed ${from.split("/").pop()}`);
174
248
  }
175
- if (dryRun) {
176
- console.log("\n[Dry run - no changes made]");
177
- console.log(`
178
- Run without --dry-run to apply changes.`);
179
- } else {
180
- console.log(`
181
- \u2713 Migration complete. ${changes.length} file(s) updated.`);
249
+ }
250
+ async function installRendererDeps(renderers) {
251
+ const cwd = process.cwd();
252
+ const pm = await nypm.detectPackageManager(cwd);
253
+ const pmName = pm?.name || "npm";
254
+ const allDeps = [];
255
+ for (const renderer of renderers) {
256
+ const def = RENDERERS.find((r) => r.name === renderer);
257
+ if (def) {
258
+ allDeps.push(...def.deps);
259
+ }
260
+ }
261
+ if (allDeps.length === 0)
262
+ return;
263
+ const spinner = p__namespace.spinner();
264
+ spinner.start(`Installing dependencies with ${pmName}...`);
265
+ for (const dep of allDeps) {
266
+ await nypm.addDependency(dep, { cwd, dev: false }).catch(() => {
267
+ spinner.stop(`Failed to install ${dep}`);
268
+ p__namespace.log.warn(`Run manually: ${pmName} add ${dep}`);
269
+ });
182
270
  }
271
+ spinner.stop("Dependencies installed");
183
272
  }
184
- function migrateV6(dryRun, defaultRenderer = "satori") {
273
+ async function installNuxtFonts() {
185
274
  const cwd = process.cwd();
186
- const dirs = [cwd];
187
- if (fs.existsSync(node_path.join(cwd, "app")))
188
- dirs.push(node_path.join(cwd, "app"));
189
- const layersDir = node_path.join(cwd, "layers");
190
- if (fs.existsSync(layersDir)) {
191
- const layerDirs = fs.readdirSync(layersDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => node_path.join(layersDir, d.name));
192
- dirs.push(...layerDirs);
275
+ const spinner = p__namespace.spinner();
276
+ spinner.start("Adding @nuxt/fonts module...");
277
+ const { execa } = await import('execa');
278
+ await execa("npx", ["nuxi", "module", "add", "@nuxt/fonts"], { cwd }).then(() => {
279
+ spinner.stop("@nuxt/fonts module added");
280
+ }).catch(() => {
281
+ spinner.stop("Failed to add @nuxt/fonts");
282
+ p__namespace.log.warn("Run manually: npx nuxi module add @nuxt/fonts");
283
+ });
284
+ }
285
+ async function runMigrate(args2) {
286
+ const dryRun = args2.includes("--dry-run") || args2.includes("-d");
287
+ const skipConfirm = args2.includes("--yes") || args2.includes("-y");
288
+ const rendererIdx = args2.indexOf("--renderer");
289
+ const cliRenderer = rendererIdx !== -1 ? args2[rendererIdx + 1] : null;
290
+ if (cliRenderer && !["satori", "chromium", "takumi"].includes(cliRenderer)) {
291
+ console.error(`Invalid renderer: ${cliRenderer}. Must be satori, chromium, or takumi.`);
292
+ process.exit(1);
193
293
  }
194
- const toRename = [];
195
- for (const dir of dirs) {
196
- const components = findOgImageComponents(dir);
197
- for (const filepath of components) {
198
- const filename = filepath.split("/").pop();
199
- if (!hasRendererSuffix(filename)) {
200
- const newName = filename.replace(".vue", `.${defaultRenderer}.vue`);
201
- toRename.push({
202
- from: filepath,
203
- to: filepath.replace(filename, newName)
204
- });
294
+ p__namespace.intro("nuxt-og-image v6 Migration");
295
+ const cwd = process.cwd();
296
+ const migrationCheck = await checkMigrationNeeded(cwd);
297
+ const noComponentWork = !migrationCheck.needsComponentRename;
298
+ const noFontsWork = !migrationCheck.needsFontsMigration && !migrationCheck.needsNuxtFonts;
299
+ if (noComponentWork && noFontsWork) {
300
+ console.log("\u2713 All OG Image components already have renderer suffixes.");
301
+ p__namespace.outro("Done");
302
+ return;
303
+ }
304
+ const tasks = [];
305
+ if (migrationCheck.needsComponentRename) {
306
+ tasks.push(`Rename ${migrationCheck.componentsToRename.length} component(s) to include renderer suffix`);
307
+ }
308
+ if (migrationCheck.needsFontsMigration) {
309
+ tasks.push("Migrate ogImage.fonts to @nuxt/fonts config");
310
+ }
311
+ if (migrationCheck.needsNuxtFonts) {
312
+ tasks.push("Install @nuxt/fonts module");
313
+ }
314
+ tasks.push("Update defineOgImage() calls to new API");
315
+ p__namespace.note(tasks.map((t) => `\u2022 ${t}`).join("\n"), "Migration tasks");
316
+ if (dryRun) {
317
+ p__namespace.log.warn("[Dry run mode - no changes will be made]");
318
+ }
319
+ let selectedRenderers;
320
+ if (skipConfirm) {
321
+ selectedRenderers = cliRenderer ? [cliRenderer] : ["satori"];
322
+ } else {
323
+ const confirmed = await p__namespace.confirm({
324
+ message: "This will modify files. Continue?",
325
+ initialValue: false
326
+ });
327
+ if (p__namespace.isCancel(confirmed) || !confirmed) {
328
+ p__namespace.cancel("Migration cancelled");
329
+ process.exit(0);
330
+ }
331
+ const rendererSelection = await p__namespace.multiselect({
332
+ message: "Which renderers do you want to use?",
333
+ options: RENDERERS.map((r) => ({
334
+ value: r.name,
335
+ label: r.label,
336
+ hint: r.description
337
+ })),
338
+ initialValues: ["satori"],
339
+ required: true
340
+ });
341
+ if (p__namespace.isCancel(rendererSelection)) {
342
+ p__namespace.cancel("Migration cancelled");
343
+ process.exit(0);
344
+ }
345
+ selectedRenderers = rendererSelection;
346
+ if (!dryRun) {
347
+ const installDeps = await p__namespace.confirm({
348
+ message: "Install renderer dependencies?",
349
+ initialValue: true
350
+ });
351
+ if (!p__namespace.isCancel(installDeps) && installDeps) {
352
+ await installRendererDeps(selectedRenderers);
205
353
  }
206
354
  }
207
355
  }
208
- if (toRename.length === 0) {
209
- console.log("\u2713 All OG Image components already have renderer suffixes.");
210
- return;
356
+ if (migrationCheck.needsComponentRename) {
357
+ console.log("\nRenaming components...");
358
+ migrateV6Components(migrationCheck.componentsToRename, selectedRenderers[0] || "satori", dryRun);
359
+ }
360
+ console.log("\nMigrating defineOgImage calls...");
361
+ const apiChanges = migrateDefineOgImageApi(dryRun);
362
+ if (apiChanges.changes.length > 0) {
363
+ for (const { file, count } of apiChanges.changes) {
364
+ const relPath = file.replace(`${cwd}/`, "");
365
+ console.log(` ${relPath} (${count} change${count > 1 ? "s" : ""})`);
366
+ }
367
+ } else {
368
+ console.log(" No API changes needed");
211
369
  }
212
- console.log(`
213
- Found ${toRename.length} component(s) to rename:
214
- `);
215
- for (const { from, to } of toRename) {
216
- const fromName = from.split("/").pop();
217
- const toName = to.split("/").pop();
218
- console.log(` ${fromName} \u2192 ${toName}`);
370
+ if (migrationCheck.needsNuxtFonts && !dryRun && !skipConfirm) {
371
+ const addFonts = await p__namespace.confirm({
372
+ message: "@nuxt/fonts is recommended for custom fonts. Add it?",
373
+ initialValue: true
374
+ });
375
+ if (!p__namespace.isCancel(addFonts) && addFonts) {
376
+ await installNuxtFonts();
377
+ }
219
378
  }
220
379
  if (dryRun) {
221
380
  console.log("\n[Dry run - no changes made]");
222
- console.log(`
223
- Run without --dry-run to apply changes.`);
224
- return;
225
- }
226
- console.log("");
227
- for (const { from, to } of toRename) {
228
- fs.renameSync(from, to);
229
- console.log(`\u2713 Renamed ${from.split("/").pop()}`);
381
+ console.log("Run without --dry-run to apply changes.");
230
382
  }
231
- console.log(`
232
- \u2713 Migration complete. ${toRename.length} file(s) renamed.`);
383
+ p__namespace.outro(dryRun ? "Dry run complete" : "Migration complete!");
233
384
  }
234
- function enableRenderer(renderer) {
235
- const deps = RENDERER_DEPS[renderer];
236
- if (!deps) {
237
- console.error(`Unknown renderer: ${renderer}`);
238
- console.log("Available renderers: satori, chromium, takumi");
385
+ async function runEnable(renderer) {
386
+ const def = RENDERERS.find((r) => r.name === renderer);
387
+ if (!def) {
388
+ p__namespace.log.error(`Unknown renderer: ${renderer}`);
389
+ p__namespace.log.info(`Available: ${RENDERERS.map((r) => r.name).join(", ")}`);
239
390
  process.exit(1);
240
391
  }
241
- console.log(`Installing dependencies for ${renderer} renderer:`);
242
- console.log(` ${deps.join(", ")}
243
- `);
244
- const cwd = process.cwd();
245
- let pm = "npm";
246
- if (fs.existsSync(node_path.join(cwd, "pnpm-lock.yaml")))
247
- pm = "pnpm";
248
- else if (fs.existsSync(node_path.join(cwd, "yarn.lock")))
249
- pm = "yarn";
250
- else if (fs.existsSync(node_path.join(cwd, "bun.lockb")))
251
- pm = "bun";
252
- const installCmd = pm === "npm" ? `${pm} install` : `${pm} add`;
253
- const cmd = `${installCmd} ${deps.join(" ")}`;
254
- console.log(`Running: ${cmd}
255
- `);
256
- node_child_process.execSync(cmd, { stdio: "inherit", cwd });
257
- console.log(`
258
- \u2713 ${renderer} renderer enabled.`);
392
+ p__namespace.intro(`Enable ${def.label} renderer`);
393
+ await installRendererDeps([renderer]);
394
+ p__namespace.outro("Done");
259
395
  }
260
396
  const args = process.argv.slice(2);
261
397
  const command = args[0];
262
398
  if (command === "eject") {
263
399
  const templateName = args[1];
264
400
  if (!templateName) {
265
- console.error("Please specify a template name.");
401
+ p__namespace.log.error("Please specify a template name.");
266
402
  listTemplates();
267
403
  process.exit(1);
268
404
  }
@@ -274,60 +410,24 @@ if (command === "eject") {
274
410
  } else if (command === "migrate") {
275
411
  const version = args[1];
276
412
  if (version !== "v6") {
277
- console.error("Usage: npx nuxt-og-image migrate v6 [--dry-run] [--renderer <satori|chromium|takumi>]");
278
- process.exit(1);
279
- }
280
- const dryRun = args.includes("--dry-run") || args.includes("-d");
281
- const skipConfirm = args.includes("--yes") || args.includes("-y");
282
- const rendererIdx = args.indexOf("--renderer");
283
- const renderer = rendererIdx !== -1 ? args[rendererIdx + 1] || "satori" : "satori";
284
- if (!["satori", "chromium", "takumi"].includes(renderer)) {
285
- console.error(`Invalid renderer: ${renderer}. Must be satori, chromium, or takumi.`);
413
+ p__namespace.log.error("Usage: npx nuxt-og-image migrate v6 [--dry-run] [--yes] [--renderer <satori|chromium|takumi>]");
286
414
  process.exit(1);
287
415
  }
288
- console.log("nuxt-og-image v6 Migration\n");
289
- console.log("This will:");
290
- console.log(" 1. Rename OgImage components to include renderer suffix (.satori.vue, etc.)");
291
- console.log(" 2. Update defineOgImage() calls to new component-first API");
292
- console.log("");
293
- console.log("\x1B[33m\u26A0 WARNING: This modifies files directly and could break your code.\x1B[0m");
294
- console.log("\x1B[33m Make sure you have committed or backed up your changes first.\x1B[0m");
295
- console.log("");
296
- if (dryRun) {
297
- console.log("[Dry run mode - no files will be modified]\n");
298
- migrateV6(true, renderer);
299
- console.log("");
300
- migrateDefineOgImageApi(true);
301
- } else if (skipConfirm) {
302
- migrateV6(false, renderer);
303
- console.log("");
304
- migrateDefineOgImageApi(false);
305
- } else {
306
- confirm("Continue with migration?").then((confirmed) => {
307
- if (!confirmed) {
308
- console.log("Migration cancelled.");
309
- process.exit(0);
310
- }
311
- console.log("");
312
- migrateV6(false, renderer);
313
- console.log("");
314
- migrateDefineOgImageApi(false);
315
- });
316
- }
416
+ runMigrate(args);
317
417
  } else if (command === "enable") {
318
418
  const renderer = args[1];
319
419
  if (!renderer) {
320
- console.error("Usage: npx nuxt-og-image enable <renderer>");
321
- console.log("Available renderers: satori, chromium, takumi");
420
+ p__namespace.log.error("Usage: npx nuxt-og-image enable <renderer>");
421
+ p__namespace.log.info(`Available: ${RENDERERS.map((r) => r.name).join(", ")}`);
322
422
  process.exit(1);
323
423
  }
324
- enableRenderer(renderer);
424
+ runEnable(renderer);
325
425
  } else {
326
426
  console.log("nuxt-og-image CLI\n");
327
427
  console.log("Commands:");
328
428
  console.log(" list List available community templates");
329
429
  console.log(" eject <name> Eject a community template to your project");
330
430
  console.log(" migrate v6 Migrate to v6 (component suffixes + new API)");
331
- console.log(" Options: --dry-run, --renderer <satori|chromium|takumi>");
431
+ console.log(" Options: --dry-run, --yes, --renderer <satori|chromium|takumi>");
332
432
  console.log(" enable <renderer> Install dependencies for a renderer (satori, chromium, takumi)");
333
433
  }