@vocoder/cli 0.1.17 → 0.1.19

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.
@@ -34,7 +34,8 @@ function detectLocalEcosystem(cwd = process.cwd()) {
34
34
  }
35
35
  function detectPackageManager(cwd) {
36
36
  if (existsSync(join(cwd, "pnpm-lock.yaml"))) return "pnpm";
37
- if (existsSync(join(cwd, "bun.lockb")) || existsSync(join(cwd, "bun.lock"))) return "bun";
37
+ if (existsSync(join(cwd, "bun.lockb")) || existsSync(join(cwd, "bun.lock")))
38
+ return "bun";
38
39
  if (existsSync(join(cwd, "yarn.lock"))) return "yarn";
39
40
  return "npm";
40
41
  }
@@ -57,7 +58,11 @@ function detectFromDeps(allDeps, cwd) {
57
58
  return { ecosystem: "svelte", framework, uiPackage: "@vocoder/svelte" };
58
59
  }
59
60
  if ("@angular/core" in allDeps || existsSync(join(cwd, "angular.json"))) {
60
- return { ecosystem: "angular", framework: "angular", uiPackage: "@vocoder/angular" };
61
+ return {
62
+ ecosystem: "angular",
63
+ framework: "angular",
64
+ uiPackage: "@vocoder/angular"
65
+ };
61
66
  }
62
67
  if ("react" in allDeps) {
63
68
  let framework = null;
@@ -86,7 +91,8 @@ function buildInstallCommand(packageManager, packages) {
86
91
  function getPackagesToInstall(detection) {
87
92
  const packages = [];
88
93
  if (!detection.hasUnplugin) packages.push("@vocoder/unplugin");
89
- if (detection.uiPackage && !detection.hasUiPackage) packages.push(detection.uiPackage);
94
+ if (detection.uiPackage && !detection.hasUiPackage)
95
+ packages.push(detection.uiPackage);
90
96
  return packages;
91
97
  }
92
98
 
@@ -258,4 +264,4 @@ export {
258
264
  getSetupSnippets,
259
265
  StringExtractor
260
266
  };
261
- //# sourceMappingURL=chunk-3QBORM6T.mjs.map
267
+ //# sourceMappingURL=chunk-OFQLREXF.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/detect-local.ts","../src/utils/setup-snippets.ts","../src/utils/extract.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport type PackageManager = \"pnpm\" | \"npm\" | \"yarn\" | \"bun\";\n\nexport type DetectedFramework =\n\t| \"nextjs\"\n\t| \"vite\"\n\t| \"remix\"\n\t| \"nuxt\"\n\t| \"sveltekit\"\n\t| \"gatsby\"\n\t| \"angular\"\n\t| null;\n\nexport type DetectedEcosystem = \"react\" | \"vue\" | \"svelte\" | \"angular\" | null;\n\nexport interface LocalDetectionResult {\n\tecosystem: DetectedEcosystem;\n\tframework: DetectedFramework;\n\tpackageManager: PackageManager;\n\tuiPackage: string | null;\n\thasUnplugin: boolean;\n\thasUiPackage: boolean;\n\tsourceLocale: string | null;\n}\n\n/**\n * Detect the local project's ecosystem, framework, and package manager\n * by inspecting filesystem artifacts. No network calls.\n */\nexport function detectLocalEcosystem(\n\tcwd: string = process.cwd(),\n): LocalDetectionResult {\n\tconst packageManager = detectPackageManager(cwd);\n\tconst pkg = readPackageJson(cwd);\n\n\tif (!pkg) {\n\t\treturn {\n\t\t\tecosystem: null,\n\t\t\tframework: null,\n\t\t\tpackageManager,\n\t\t\tuiPackage: null,\n\t\t\thasUnplugin: false,\n\t\t\thasUiPackage: false,\n\t\t\tsourceLocale: null,\n\t\t};\n\t}\n\n\tconst allDeps = {\n\t\t...((pkg.dependencies as Record<string, string>) ?? {}),\n\t\t...((pkg.devDependencies as Record<string, string>) ?? {}),\n\t};\n\n\tconst hasUnplugin = \"@vocoder/unplugin\" in allDeps;\n\n\t// Detect ecosystem + framework\n\tconst { ecosystem, framework, uiPackage } = detectFromDeps(allDeps, cwd);\n\tconst hasUiPackage = uiPackage !== null && uiPackage in allDeps;\n\n\treturn {\n\t\tecosystem,\n\t\tframework,\n\t\tpackageManager,\n\t\tuiPackage,\n\t\thasUnplugin,\n\t\thasUiPackage,\n\t\tsourceLocale: null,\n\t};\n}\n\nfunction detectPackageManager(cwd: string): PackageManager {\n\tif (existsSync(join(cwd, \"pnpm-lock.yaml\"))) return \"pnpm\";\n\tif (existsSync(join(cwd, \"bun.lockb\")) || existsSync(join(cwd, \"bun.lock\")))\n\t\treturn \"bun\";\n\tif (existsSync(join(cwd, \"yarn.lock\"))) return \"yarn\";\n\treturn \"npm\";\n}\n\nfunction readPackageJson(cwd: string): Record<string, unknown> | null {\n\tconst pkgPath = join(cwd, \"package.json\");\n\tif (!existsSync(pkgPath)) return null;\n\ttry {\n\t\treturn JSON.parse(readFileSync(pkgPath, \"utf-8\")) as Record<\n\t\t\tstring,\n\t\t\tunknown\n\t\t>;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction detectFromDeps(\n\tallDeps: Record<string, string>,\n\tcwd: string,\n): {\n\tecosystem: DetectedEcosystem;\n\tframework: DetectedFramework;\n\tuiPackage: string | null;\n} {\n\t// Vue ecosystem\n\tif (\"vue\" in allDeps) {\n\t\tconst framework = \"nuxt\" in allDeps ? (\"nuxt\" as const) : null;\n\t\treturn { ecosystem: \"vue\", framework, uiPackage: \"@vocoder/vue\" };\n\t}\n\n\t// Svelte ecosystem\n\tif (\"svelte\" in allDeps) {\n\t\tconst framework =\n\t\t\t\"@sveltejs/kit\" in allDeps ? (\"sveltekit\" as const) : null;\n\t\treturn { ecosystem: \"svelte\", framework, uiPackage: \"@vocoder/svelte\" };\n\t}\n\n\t// Angular ecosystem\n\tif (\"@angular/core\" in allDeps || existsSync(join(cwd, \"angular.json\"))) {\n\t\treturn {\n\t\t\tecosystem: \"angular\",\n\t\t\tframework: \"angular\",\n\t\t\tuiPackage: \"@vocoder/angular\",\n\t\t};\n\t}\n\n\t// React ecosystem (most common — check last)\n\tif (\"react\" in allDeps) {\n\t\tlet framework: DetectedFramework = null;\n\t\tif (\"next\" in allDeps) framework = \"nextjs\";\n\t\telse if (\"@remix-run/react\" in allDeps) framework = \"remix\";\n\t\telse if (\"gatsby\" in allDeps) framework = \"gatsby\";\n\t\telse if (\"vite\" in allDeps) framework = \"vite\";\n\t\treturn { ecosystem: \"react\", framework, uiPackage: \"@vocoder/react\" };\n\t}\n\n\treturn { ecosystem: null, framework: null, uiPackage: null };\n}\n\n/**\n * Build the install command for packages that aren't already installed.\n */\nexport function buildInstallCommand(\n\tpackageManager: PackageManager,\n\tpackages: string[],\n): string {\n\tif (packages.length === 0) return \"\";\n\tconst pkgList = packages.join(\" \");\n\tswitch (packageManager) {\n\t\tcase \"pnpm\":\n\t\t\treturn `pnpm add ${pkgList}`;\n\t\tcase \"yarn\":\n\t\t\treturn `yarn add ${pkgList}`;\n\t\tcase \"bun\":\n\t\t\treturn `bun add ${pkgList}`;\n\t\tdefault:\n\t\t\treturn `npm install ${pkgList}`;\n\t}\n}\n\n/**\n * Get the list of packages that need to be installed.\n */\nexport function getPackagesToInstall(\n\tdetection: LocalDetectionResult,\n): string[] {\n\tconst packages: string[] = [];\n\tif (!detection.hasUnplugin) packages.push(\"@vocoder/unplugin\");\n\tif (detection.uiPackage && !detection.hasUiPackage)\n\t\tpackages.push(detection.uiPackage);\n\treturn packages;\n}\n","import type { DetectedEcosystem, DetectedFramework } from \"./detect-local.js\";\n\nexport interface SetupSnippets {\n\tpluginStep: { file: string; code: string } | null;\n\tproviderStep: { file: string; code: string } | null;\n\twrapStep: { code: string };\n\twhatsNext: string;\n}\n\n/**\n * Generate framework-specific setup snippets.\n */\nexport function getSetupSnippets(params: {\n\tframework: DetectedFramework;\n\tecosystem: DetectedEcosystem;\n\tsourceLocale: string;\n\ttargetBranches: string[];\n}): SetupSnippets {\n\tconst { framework, ecosystem, sourceLocale } = params;\n\n\treturn {\n\t\tpluginStep: getPluginSnippet(framework, ecosystem),\n\t\tproviderStep: getProviderSnippet(ecosystem, sourceLocale),\n\t\twrapStep: getWrapSnippet(ecosystem),\n\t\twhatsNext: \"Push to a target branch to trigger translations.\",\n\t};\n}\n\nfunction getPluginSnippet(\n\tframework: DetectedFramework,\n\tecosystem: DetectedEcosystem,\n): { file: string; code: string } | null {\n\tswitch (framework) {\n\t\tcase \"nextjs\":\n\t\t\treturn {\n\t\t\t\tfile: \"next.config.ts\",\n\t\t\t\tcode: `import { withVocoder } from '@vocoder/unplugin/next';\n\nexport default withVocoder({\n // your existing Next.js config\n});`,\n\t\t\t};\n\n\t\tcase \"vite\":\n\t\tcase \"remix\":\n\t\t\treturn {\n\t\t\t\tfile: \"vite.config.ts\",\n\t\t\t\tcode: `import vocoder from '@vocoder/unplugin/vite';\n\nexport default defineConfig({\n plugins: [\n vocoder(),\n // your other plugins\n ],\n});`,\n\t\t\t};\n\n\t\tcase \"nuxt\":\n\t\t\treturn {\n\t\t\t\tfile: \"nuxt.config.ts\",\n\t\t\t\tcode: `import vocoder from '@vocoder/unplugin/vite';\n\nexport default defineNuxtConfig({\n vite: {\n plugins: [vocoder()],\n },\n});`,\n\t\t\t};\n\n\t\tcase \"sveltekit\":\n\t\t\treturn {\n\t\t\t\tfile: \"vite.config.ts\",\n\t\t\t\tcode: `import vocoder from '@vocoder/unplugin/vite';\nimport { sveltekit } from '@sveltejs/kit/vite';\n\nexport default defineConfig({\n plugins: [\n sveltekit(),\n vocoder(),\n ],\n});`,\n\t\t\t};\n\n\t\tcase \"gatsby\":\n\t\t\treturn {\n\t\t\t\tfile: \"gatsby-node.js\",\n\t\t\t\tcode: `const vocoder = require('@vocoder/unplugin/webpack');\n\nexports.onCreateWebpackConfig = ({ actions }) => {\n actions.setWebpackConfig({\n plugins: [vocoder()],\n });\n};`,\n\t\t\t};\n\n\t\tcase \"angular\":\n\t\t\treturn null; // Angular CLI doesn't expose plugin config easily\n\n\t\tdefault:\n\t\t\t// No known framework — if they have React/Vue/Svelte, they likely have a bundler\n\t\t\t// but we can't guess which config file. Give generic advice.\n\t\t\tif (ecosystem) {\n\t\t\t\treturn {\n\t\t\t\t\tfile: \"your bundler config\",\n\t\t\t\t\tcode: `// Vite\nimport vocoder from '@vocoder/unplugin/vite';\n// Webpack\nconst vocoder = require('@vocoder/unplugin/webpack');\n\n// Add vocoder() to your plugins array`,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn null;\n\t}\n}\n\nfunction getProviderSnippet(\n\tecosystem: DetectedEcosystem,\n\tsourceLocale: string,\n): { file: string; code: string } | null {\n\tswitch (ecosystem) {\n\t\tcase \"react\":\n\t\t\treturn {\n\t\t\t\tfile: \"your root layout or App component\",\n\t\t\t\tcode: `import { VocoderProvider } from '@vocoder/react';\n\n<VocoderProvider defaultLocale=\"${sourceLocale}\">\n {children}\n</VocoderProvider>`,\n\t\t\t};\n\n\t\tcase \"vue\":\n\t\t\treturn {\n\t\t\t\tfile: \"your app entry\",\n\t\t\t\tcode: `import { createVocoder } from '@vocoder/vue';\n\nconst vocoder = createVocoder({\n defaultLocale: '${sourceLocale}',\n});\n\napp.use(vocoder);`,\n\t\t\t};\n\n\t\tcase \"svelte\":\n\t\t\treturn {\n\t\t\t\tfile: \"your root layout\",\n\t\t\t\tcode: `<script>\n import { VocoderProvider } from '@vocoder/svelte';\n</script>\n\n<VocoderProvider defaultLocale=\"${sourceLocale}\">\n <slot />\n</VocoderProvider>`,\n\t\t\t};\n\n\t\tdefault:\n\t\t\treturn null;\n\t}\n}\n\nfunction getWrapSnippet(ecosystem: DetectedEcosystem): { code: string } {\n\tswitch (ecosystem) {\n\t\tcase \"react\":\n\t\t\treturn {\n\t\t\t\tcode: `import { T } from '@vocoder/react';\n\n<T>Hello, world!</T>`,\n\t\t\t};\n\n\t\tcase \"vue\":\n\t\t\treturn {\n\t\t\t\tcode: `<template>\n <T>Hello, world!</T>\n</template>\n\n<script setup>\nimport { T } from '@vocoder/vue';\n</script>`,\n\t\t\t};\n\n\t\tcase \"svelte\":\n\t\t\treturn {\n\t\t\t\tcode: `<script>\n import { T } from '@vocoder/svelte';\n</script>\n\n<T>Hello, world!</T>`,\n\t\t\t};\n\n\t\tdefault:\n\t\t\treturn {\n\t\t\t\tcode: `// Wrap translatable strings with <T>\n<T>Hello, world!</T>`,\n\t\t\t};\n\t}\n}\n","export { type ExtractedString, StringExtractor } from \"@vocoder/extractor\";\n"],"mappings":"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","names":[]}
package/dist/lib.d.mts CHANGED
@@ -1,56 +1,6 @@
1
1
  export { ExtractedString, StringExtractor } from '@vocoder/extractor';
2
2
 
3
- type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun';
4
- type DetectedFramework = 'nextjs' | 'vite' | 'remix' | 'nuxt' | 'sveltekit' | 'gatsby' | 'angular' | null;
5
- type DetectedEcosystem = 'react' | 'vue' | 'svelte' | 'angular' | null;
6
- interface LocalDetectionResult {
7
- ecosystem: DetectedEcosystem;
8
- framework: DetectedFramework;
9
- packageManager: PackageManager;
10
- uiPackage: string | null;
11
- hasUnplugin: boolean;
12
- hasUiPackage: boolean;
13
- sourceLocale: string | null;
14
- }
15
- /**
16
- * Detect the local project's ecosystem, framework, and package manager
17
- * by inspecting filesystem artifacts. No network calls.
18
- */
19
- declare function detectLocalEcosystem(cwd?: string): LocalDetectionResult;
20
- /**
21
- * Build the install command for packages that aren't already installed.
22
- */
23
- declare function buildInstallCommand(packageManager: PackageManager, packages: string[]): string;
24
- /**
25
- * Get the list of packages that need to be installed.
26
- */
27
- declare function getPackagesToInstall(detection: LocalDetectionResult): string[];
28
-
29
- interface SetupSnippets {
30
- pluginStep: {
31
- file: string;
32
- code: string;
33
- } | null;
34
- providerStep: {
35
- file: string;
36
- code: string;
37
- } | null;
38
- wrapStep: {
39
- code: string;
40
- };
41
- whatsNext: string;
42
- }
43
- /**
44
- * Generate framework-specific setup snippets.
45
- */
46
- declare function getSetupSnippets(params: {
47
- framework: DetectedFramework;
48
- ecosystem: DetectedEcosystem;
49
- sourceLocale: string;
50
- targetBranches: string[];
51
- }): SetupSnippets;
52
-
53
- type EffectiveSyncMode = 'required' | 'best-effort';
3
+ type EffectiveSyncMode = "required" | "best-effort";
54
4
  interface SyncPolicyConfig {
55
5
  blockingBranches: string[];
56
6
  blockingMode: EffectiveSyncMode;
@@ -71,17 +21,17 @@ interface TranslationBatchResponse {
71
21
  newStrings: number;
72
22
  deletedStrings?: number;
73
23
  totalStrings: number;
74
- status: 'PENDING' | 'TRANSLATING' | 'COMPLETED' | 'FAILED' | 'UP_TO_DATE';
24
+ status: "PENDING" | "TRANSLATING" | "COMPLETED" | "FAILED" | "UP_TO_DATE";
75
25
  noChanges?: boolean;
76
26
  estimatedTime?: number;
77
27
  effectiveMode?: EffectiveSyncMode;
78
- queueStatus?: 'QUEUED' | 'PROCESSING' | 'COMPLETED' | 'FAILED';
28
+ queueStatus?: "QUEUED" | "PROCESSING" | "COMPLETED" | "FAILED";
79
29
  snapshotAvailable?: boolean;
80
30
  latestCompletedBatchId?: string;
81
31
  translations?: Record<string, Record<string, string>>;
82
32
  }
83
33
  interface TranslationStatusResponse {
84
- status: 'PENDING' | 'TRANSLATING' | 'COMPLETED' | 'FAILED';
34
+ status: "PENDING" | "TRANSLATING" | "COMPLETED" | "FAILED";
85
35
  progress: number;
86
36
  jobs?: Array<{
87
37
  locale: string;
@@ -91,12 +41,12 @@ interface TranslationStatusResponse {
91
41
  translations?: Record<string, Record<string, string>>;
92
42
  localeMetadata?: Record<string, {
93
43
  nativeName: string;
94
- dir?: 'rtl';
44
+ dir?: "rtl";
95
45
  }>;
96
46
  errorMessage?: string;
97
47
  }
98
48
  interface TranslationSnapshotResponse {
99
- status: 'FOUND' | 'NOT_FOUND';
49
+ status: "FOUND" | "NOT_FOUND";
100
50
  branch: string;
101
51
  sourceLocale?: string;
102
52
  targetLocales?: string[];
@@ -105,12 +55,12 @@ interface TranslationSnapshotResponse {
105
55
  translations?: Record<string, Record<string, string>>;
106
56
  localeMetadata?: Record<string, {
107
57
  nativeName: string;
108
- dir?: 'rtl';
58
+ dir?: "rtl";
109
59
  }>;
110
60
  }
111
61
  interface LimitErrorResponse {
112
- errorCode: 'LIMIT_EXCEEDED' | 'INSUFFICIENT_CREDITS';
113
- limitType: 'organizations' | 'projects' | 'git_connections' | 'members' | 'providers' | 'translation_chars' | 'source_strings' | 'credits';
62
+ errorCode: "LIMIT_EXCEEDED" | "INSUFFICIENT_CREDITS";
63
+ limitType: "organizations" | "projects" | "git_connections" | "members" | "providers" | "translation_chars" | "source_strings" | "credits";
114
64
  planId: string;
115
65
  current: number;
116
66
  required: number;
@@ -118,11 +68,61 @@ interface LimitErrorResponse {
118
68
  message: string;
119
69
  }
120
70
  interface SyncPolicyErrorResponse {
121
- errorCode: 'BRANCH_NOT_ALLOWED' | 'PROJECT_REPOSITORY_MISMATCH';
71
+ errorCode: "BRANCH_NOT_ALLOWED" | "PROJECT_REPOSITORY_MISMATCH";
122
72
  message: string;
123
73
  branch?: string;
124
74
  boundRepoLabel?: string | null;
125
75
  boundScopePath?: string | null;
126
76
  }
127
77
 
78
+ type PackageManager = "pnpm" | "npm" | "yarn" | "bun";
79
+ type DetectedFramework = "nextjs" | "vite" | "remix" | "nuxt" | "sveltekit" | "gatsby" | "angular" | null;
80
+ type DetectedEcosystem = "react" | "vue" | "svelte" | "angular" | null;
81
+ interface LocalDetectionResult {
82
+ ecosystem: DetectedEcosystem;
83
+ framework: DetectedFramework;
84
+ packageManager: PackageManager;
85
+ uiPackage: string | null;
86
+ hasUnplugin: boolean;
87
+ hasUiPackage: boolean;
88
+ sourceLocale: string | null;
89
+ }
90
+ /**
91
+ * Detect the local project's ecosystem, framework, and package manager
92
+ * by inspecting filesystem artifacts. No network calls.
93
+ */
94
+ declare function detectLocalEcosystem(cwd?: string): LocalDetectionResult;
95
+ /**
96
+ * Build the install command for packages that aren't already installed.
97
+ */
98
+ declare function buildInstallCommand(packageManager: PackageManager, packages: string[]): string;
99
+ /**
100
+ * Get the list of packages that need to be installed.
101
+ */
102
+ declare function getPackagesToInstall(detection: LocalDetectionResult): string[];
103
+
104
+ interface SetupSnippets {
105
+ pluginStep: {
106
+ file: string;
107
+ code: string;
108
+ } | null;
109
+ providerStep: {
110
+ file: string;
111
+ code: string;
112
+ } | null;
113
+ wrapStep: {
114
+ code: string;
115
+ };
116
+ whatsNext: string;
117
+ }
118
+ /**
119
+ * Generate framework-specific setup snippets.
120
+ */
121
+ declare function getSetupSnippets(params: {
122
+ framework: DetectedFramework;
123
+ ecosystem: DetectedEcosystem;
124
+ sourceLocale: string;
125
+ targetBranches: string[];
126
+ }): SetupSnippets;
127
+
128
128
  export { type APIProjectConfig, type DetectedEcosystem, type DetectedFramework, type LimitErrorResponse, type LocalDetectionResult, type PackageManager, type SetupSnippets, type SyncPolicyConfig, type SyncPolicyErrorResponse, type TranslationBatchResponse, type TranslationSnapshotResponse, type TranslationStatusResponse, buildInstallCommand, detectLocalEcosystem, getPackagesToInstall, getSetupSnippets };
package/dist/lib.mjs CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  detectLocalEcosystem,
5
5
  getPackagesToInstall,
6
6
  getSetupSnippets
7
- } from "./chunk-3QBORM6T.mjs";
7
+ } from "./chunk-OFQLREXF.mjs";
8
8
  export {
9
9
  StringExtractor,
10
10
  buildInstallCommand,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vocoder/cli",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "CLI tool for Vocoder translation workflow",
5
5
  "files": [
6
6
  "dist"
@@ -45,7 +45,7 @@
45
45
  "commander": "^11.1.0",
46
46
  "dotenv": "^16.3.1",
47
47
  "tsx": "^4.7.0",
48
- "@vocoder/extractor": "0.1.0"
48
+ "@vocoder/extractor": "0.1.1"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/node": "^20.19.9",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/detect-local.ts","../src/utils/setup-snippets.ts","../src/utils/extract.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun';\n\nexport type DetectedFramework =\n | 'nextjs'\n | 'vite'\n | 'remix'\n | 'nuxt'\n | 'sveltekit'\n | 'gatsby'\n | 'angular'\n | null;\n\nexport type DetectedEcosystem =\n | 'react'\n | 'vue'\n | 'svelte'\n | 'angular'\n | null;\n\nexport interface LocalDetectionResult {\n ecosystem: DetectedEcosystem;\n framework: DetectedFramework;\n packageManager: PackageManager;\n uiPackage: string | null;\n hasUnplugin: boolean;\n hasUiPackage: boolean;\n sourceLocale: string | null;\n}\n\n/**\n * Detect the local project's ecosystem, framework, and package manager\n * by inspecting filesystem artifacts. No network calls.\n */\nexport function detectLocalEcosystem(cwd: string = process.cwd()): LocalDetectionResult {\n const packageManager = detectPackageManager(cwd);\n const pkg = readPackageJson(cwd);\n\n if (!pkg) {\n return {\n ecosystem: null,\n framework: null,\n packageManager,\n uiPackage: null,\n hasUnplugin: false,\n hasUiPackage: false,\n sourceLocale: null,\n };\n }\n\n const allDeps = {\n ...((pkg.dependencies as Record<string, string>) ?? {}),\n ...((pkg.devDependencies as Record<string, string>) ?? {}),\n };\n\n const hasUnplugin = '@vocoder/unplugin' in allDeps;\n\n // Detect ecosystem + framework\n const { ecosystem, framework, uiPackage } = detectFromDeps(allDeps, cwd);\n const hasUiPackage = uiPackage !== null && uiPackage in allDeps;\n\n return {\n ecosystem,\n framework,\n packageManager,\n uiPackage,\n hasUnplugin,\n hasUiPackage,\n sourceLocale: null,\n };\n}\n\nfunction detectPackageManager(cwd: string): PackageManager {\n if (existsSync(join(cwd, 'pnpm-lock.yaml'))) return 'pnpm';\n if (existsSync(join(cwd, 'bun.lockb')) || existsSync(join(cwd, 'bun.lock'))) return 'bun';\n if (existsSync(join(cwd, 'yarn.lock'))) return 'yarn';\n return 'npm';\n}\n\nfunction readPackageJson(cwd: string): Record<string, unknown> | null {\n const pkgPath = join(cwd, 'package.json');\n if (!existsSync(pkgPath)) return null;\n try {\n return JSON.parse(readFileSync(pkgPath, 'utf-8')) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nfunction detectFromDeps(\n allDeps: Record<string, string>,\n cwd: string,\n): { ecosystem: DetectedEcosystem; framework: DetectedFramework; uiPackage: string | null } {\n // Vue ecosystem\n if ('vue' in allDeps) {\n const framework = 'nuxt' in allDeps ? 'nuxt' as const : null;\n return { ecosystem: 'vue', framework, uiPackage: '@vocoder/vue' };\n }\n\n // Svelte ecosystem\n if ('svelte' in allDeps) {\n const framework = '@sveltejs/kit' in allDeps ? 'sveltekit' as const : null;\n return { ecosystem: 'svelte', framework, uiPackage: '@vocoder/svelte' };\n }\n\n // Angular ecosystem\n if ('@angular/core' in allDeps || existsSync(join(cwd, 'angular.json'))) {\n return { ecosystem: 'angular', framework: 'angular', uiPackage: '@vocoder/angular' };\n }\n\n // React ecosystem (most common — check last)\n if ('react' in allDeps) {\n let framework: DetectedFramework = null;\n if ('next' in allDeps) framework = 'nextjs';\n else if ('@remix-run/react' in allDeps) framework = 'remix';\n else if ('gatsby' in allDeps) framework = 'gatsby';\n else if ('vite' in allDeps) framework = 'vite';\n return { ecosystem: 'react', framework, uiPackage: '@vocoder/react' };\n }\n\n return { ecosystem: null, framework: null, uiPackage: null };\n}\n\n/**\n * Build the install command for packages that aren't already installed.\n */\nexport function buildInstallCommand(\n packageManager: PackageManager,\n packages: string[],\n): string {\n if (packages.length === 0) return '';\n const pkgList = packages.join(' ');\n switch (packageManager) {\n case 'pnpm':\n return `pnpm add ${pkgList}`;\n case 'yarn':\n return `yarn add ${pkgList}`;\n case 'bun':\n return `bun add ${pkgList}`;\n default:\n return `npm install ${pkgList}`;\n }\n}\n\n/**\n * Get the list of packages that need to be installed.\n */\nexport function getPackagesToInstall(detection: LocalDetectionResult): string[] {\n const packages: string[] = [];\n if (!detection.hasUnplugin) packages.push('@vocoder/unplugin');\n if (detection.uiPackage && !detection.hasUiPackage) packages.push(detection.uiPackage);\n return packages;\n}\n","import type { DetectedEcosystem, DetectedFramework } from './detect-local.js';\n\nexport interface SetupSnippets {\n pluginStep: { file: string; code: string } | null;\n providerStep: { file: string; code: string } | null;\n wrapStep: { code: string };\n whatsNext: string;\n}\n\n/**\n * Generate framework-specific setup snippets.\n */\nexport function getSetupSnippets(params: {\n framework: DetectedFramework;\n ecosystem: DetectedEcosystem;\n sourceLocale: string;\n targetBranches: string[];\n}): SetupSnippets {\n const { framework, ecosystem, sourceLocale } = params;\n\n return {\n pluginStep: getPluginSnippet(framework, ecosystem),\n providerStep: getProviderSnippet(ecosystem, sourceLocale),\n wrapStep: getWrapSnippet(ecosystem),\n whatsNext: 'Push to a target branch to trigger translations.',\n };\n}\n\nfunction getPluginSnippet(\n framework: DetectedFramework,\n ecosystem: DetectedEcosystem,\n): { file: string; code: string } | null {\n switch (framework) {\n case 'nextjs':\n return {\n file: 'next.config.ts',\n code: `import { withVocoder } from '@vocoder/unplugin/next';\n\nexport default withVocoder({\n // your existing Next.js config\n});`,\n };\n\n case 'vite':\n case 'remix':\n return {\n file: 'vite.config.ts',\n code: `import vocoder from '@vocoder/unplugin/vite';\n\nexport default defineConfig({\n plugins: [\n vocoder(),\n // your other plugins\n ],\n});`,\n };\n\n case 'nuxt':\n return {\n file: 'nuxt.config.ts',\n code: `import vocoder from '@vocoder/unplugin/vite';\n\nexport default defineNuxtConfig({\n vite: {\n plugins: [vocoder()],\n },\n});`,\n };\n\n case 'sveltekit':\n return {\n file: 'vite.config.ts',\n code: `import vocoder from '@vocoder/unplugin/vite';\nimport { sveltekit } from '@sveltejs/kit/vite';\n\nexport default defineConfig({\n plugins: [\n sveltekit(),\n vocoder(),\n ],\n});`,\n };\n\n case 'gatsby':\n return {\n file: 'gatsby-node.js',\n code: `const vocoder = require('@vocoder/unplugin/webpack');\n\nexports.onCreateWebpackConfig = ({ actions }) => {\n actions.setWebpackConfig({\n plugins: [vocoder()],\n });\n};`,\n };\n\n case 'angular':\n return null; // Angular CLI doesn't expose plugin config easily\n\n default:\n // No known framework — if they have React/Vue/Svelte, they likely have a bundler\n // but we can't guess which config file. Give generic advice.\n if (ecosystem) {\n return {\n file: 'your bundler config',\n code: `// Vite\nimport vocoder from '@vocoder/unplugin/vite';\n// Webpack\nconst vocoder = require('@vocoder/unplugin/webpack');\n\n// Add vocoder() to your plugins array`,\n };\n }\n return null;\n }\n}\n\nfunction getProviderSnippet(\n ecosystem: DetectedEcosystem,\n sourceLocale: string,\n): { file: string; code: string } | null {\n switch (ecosystem) {\n case 'react':\n return {\n file: 'your root layout or App component',\n code: `import { VocoderProvider } from '@vocoder/react';\n\n<VocoderProvider defaultLocale=\"${sourceLocale}\">\n {children}\n</VocoderProvider>`,\n };\n\n case 'vue':\n return {\n file: 'your app entry',\n code: `import { createVocoder } from '@vocoder/vue';\n\nconst vocoder = createVocoder({\n defaultLocale: '${sourceLocale}',\n});\n\napp.use(vocoder);`,\n };\n\n case 'svelte':\n return {\n file: 'your root layout',\n code: `<script>\n import { VocoderProvider } from '@vocoder/svelte';\n</script>\n\n<VocoderProvider defaultLocale=\"${sourceLocale}\">\n <slot />\n</VocoderProvider>`,\n };\n\n default:\n return null;\n }\n}\n\nfunction getWrapSnippet(ecosystem: DetectedEcosystem): { code: string } {\n switch (ecosystem) {\n case 'react':\n return {\n code: `import { T } from '@vocoder/react';\n\n<T>Hello, world!</T>`,\n };\n\n case 'vue':\n return {\n code: `<template>\n <T>Hello, world!</T>\n</template>\n\n<script setup>\nimport { T } from '@vocoder/vue';\n</script>`,\n };\n\n case 'svelte':\n return {\n code: `<script>\n import { T } from '@vocoder/svelte';\n</script>\n\n<T>Hello, world!</T>`,\n };\n\n default:\n return {\n code: `// Wrap translatable strings with <T>\n<T>Hello, world!</T>`,\n };\n }\n}\n\n","export { StringExtractor, type ExtractedString } from '@vocoder/extractor';\n"],"mappings":"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","names":[]}