@vocoder/cli 0.1.28 → 0.2.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/bin.mjs CHANGED
@@ -5,15 +5,15 @@ import {
5
5
  detectLocalEcosystem,
6
6
  getPackagesToInstall,
7
7
  getSetupSnippets
8
- } from "./chunk-OFQLREXF.mjs";
8
+ } from "./chunk-JTRTTGYF.mjs";
9
9
 
10
10
  // src/bin.ts
11
11
  import { Command } from "commander";
12
12
 
13
13
  // src/commands/init.ts
14
14
  import { execSync as execSync3, spawn as spawn2 } from "child_process";
15
- import { existsSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
16
- import { join as join2 } from "path";
15
+ import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "fs";
16
+ import { join as join3 } from "path";
17
17
  import * as p5 from "@clack/prompts";
18
18
  import chalk6 from "chalk";
19
19
  import { config as loadEnv } from "dotenv";
@@ -739,6 +739,37 @@ function clearAuthData() {
739
739
  }
740
740
  }
741
741
 
742
+ // src/utils/write-config.ts
743
+ import { existsSync, writeFileSync as writeFileSync2 } from "fs";
744
+ import { join as join2 } from "path";
745
+ function writeVocoderConfig(options) {
746
+ const { targetBranches = ["main"], cwd = process.cwd() } = options;
747
+ const configPath = join2(cwd, "vocoder.config.ts");
748
+ if (existsSync(configPath)) return false;
749
+ const branchesStr = targetBranches.map((b) => `'${b}'`).join(", ");
750
+ const content = `import { defineConfig } from '@vocoder/extractor'
751
+
752
+ export default defineConfig({
753
+ targetBranches: [${branchesStr}],
754
+ include: ['**/*.{tsx,jsx,ts,js}'],
755
+ exclude: [
756
+ '**/node_modules/**',
757
+ '**/.next/**',
758
+ '**/dist/**',
759
+ '**/build/**',
760
+ '**/*.test.*',
761
+ '**/*.spec.*',
762
+ ],
763
+ })
764
+ `;
765
+ try {
766
+ writeFileSync2(configPath, content, "utf-8");
767
+ return true;
768
+ } catch {
769
+ return false;
770
+ }
771
+ }
772
+
742
773
  // src/utils/git-identity.ts
743
774
  import { execSync } from "child_process";
744
775
  import { relative, resolve } from "path";
@@ -2029,6 +2060,14 @@ function runScaffold(params) {
2029
2060
  printCodeBlock(step.code);
2030
2061
  if (i < steps.length - 1) p5.log.message("");
2031
2062
  }
2063
+ const written = writeVocoderConfig({ targetBranches });
2064
+ if (written) {
2065
+ p5.log.success(`Created ${chalk6.cyan("vocoder.config.ts")}`);
2066
+ } else if (!existsSync2(join3(process.cwd(), "vocoder.config.ts"))) {
2067
+ p5.log.warn(
2068
+ "Could not write vocoder.config.ts \u2014 create it manually with your extraction patterns."
2069
+ );
2070
+ }
2032
2071
  p5.log.message("");
2033
2072
  const branchList = targetBranches.length > 0 ? targetBranches.map((b) => chalk6.cyan(b)).join(" or ") : chalk6.cyan("your target branch");
2034
2073
  p5.log.success(
@@ -2037,8 +2076,8 @@ function runScaffold(params) {
2037
2076
  p5.log.message(chalk6.gray(" Docs: https://vocoder.app/docs/getting-started"));
2038
2077
  }
2039
2078
  function writeApiKeyToEnv(apiKey) {
2040
- const envPath = join2(process.cwd(), ".env");
2041
- if (!existsSync(envPath)) return false;
2079
+ const envPath = join3(process.cwd(), ".env");
2080
+ if (!existsSync2(envPath)) return false;
2042
2081
  try {
2043
2082
  const content = readFileSync2(envPath, "utf-8");
2044
2083
  const keyLine = `VOCODER_API_KEY=${apiKey}`;
@@ -2050,7 +2089,7 @@ function writeApiKeyToEnv(apiKey) {
2050
2089
  updated = `${content}${sep}${keyLine}
2051
2090
  `;
2052
2091
  }
2053
- writeFileSync2(envPath, updated);
2092
+ writeFileSync3(envPath, updated);
2054
2093
  return true;
2055
2094
  } catch {
2056
2095
  return false;
@@ -2298,6 +2337,8 @@ async function init(options = {}) {
2298
2337
  return 1;
2299
2338
  }
2300
2339
  }
2340
+ const written = writeVocoderConfig({ targetBranches: exactMatch.targetBranches ?? ["main"] });
2341
+ if (written) p5.log.success(`Created ${chalk6.cyan("vocoder.config.ts")}`);
2301
2342
  p5.outro("Vocoder is already set up for this repository.");
2302
2343
  return 0;
2303
2344
  }
@@ -2305,6 +2346,8 @@ async function init(options = {}) {
2305
2346
  const wholeRepo = lookup.existingApps.find((a) => a.appDir === "");
2306
2347
  if (wholeRepo) {
2307
2348
  p5.log.success(`Project: ${chalk6.bold(wholeRepo.projectName)}`);
2349
+ const written = writeVocoderConfig({ targetBranches: ["main"] });
2350
+ if (written) p5.log.success(`Created ${chalk6.cyan("vocoder.config.ts")}`);
2308
2351
  p5.outro("Vocoder is already set up for this repository.");
2309
2352
  return 0;
2310
2353
  }
@@ -2802,8 +2845,8 @@ async function logout(options = {}) {
2802
2845
 
2803
2846
  // src/commands/sync.ts
2804
2847
  import { createHash, randomUUID } from "crypto";
2805
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
2806
- import { join as join3 } from "path";
2848
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "fs";
2849
+ import { join as join4 } from "path";
2807
2850
  import * as p8 from "@clack/prompts";
2808
2851
  import chalk8 from "chalk";
2809
2852
 
@@ -2877,6 +2920,7 @@ function matchBranchPattern(branch, pattern) {
2877
2920
  import * as p7 from "@clack/prompts";
2878
2921
  import chalk7 from "chalk";
2879
2922
  import { config as loadEnv2 } from "dotenv";
2923
+ import { loadVocoderConfig } from "@vocoder/extractor";
2880
2924
  loadEnv2();
2881
2925
  function validateLocalConfig(config) {
2882
2926
  if (!config.apiKey || config.apiKey.length === 0) {
@@ -2931,6 +2975,12 @@ async function getMergedConfig(cliOptions, verbose = false, _startDir) {
2931
2975
  ],
2932
2976
  apiUrl: "https://vocoder.app"
2933
2977
  };
2978
+ const fileConfig = loadVocoderConfig(process.cwd());
2979
+ if (!fileConfig) {
2980
+ p7.log.warn(
2981
+ `No ${chalk7.cyan("vocoder.config.ts")} found \u2014 run ${chalk7.cyan("npx @vocoder/cli init")} to generate one.`
2982
+ );
2983
+ }
2934
2984
  const envExtractionPattern = process.env.VOCODER_INCLUDE_PATTERN;
2935
2985
  const envExcludePattern = process.env.VOCODER_EXCLUDE_PATTERN;
2936
2986
  const envApiUrl = process.env.VOCODER_API_URL;
@@ -2941,6 +2991,9 @@ async function getMergedConfig(cliOptions, verbose = false, _startDir) {
2941
2991
  if (cliOptions.include && cliOptions.include.length > 0) {
2942
2992
  includePattern = cliOptions.include;
2943
2993
  configSources.includePattern = "CLI flag";
2994
+ } else if (fileConfig?.include && fileConfig.include.length > 0) {
2995
+ includePattern = fileConfig.include;
2996
+ configSources.includePattern = "vocoder.config";
2944
2997
  } else if (envExtractionPattern) {
2945
2998
  includePattern = [envExtractionPattern];
2946
2999
  configSources.includePattern = "environment";
@@ -2951,6 +3004,9 @@ async function getMergedConfig(cliOptions, verbose = false, _startDir) {
2951
3004
  if (cliOptions.exclude && cliOptions.exclude.length > 0) {
2952
3005
  excludePattern = cliOptions.exclude;
2953
3006
  configSources.excludePattern = "CLI flag";
3007
+ } else if (fileConfig?.exclude && fileConfig.exclude.length > 0) {
3008
+ excludePattern = fileConfig.exclude;
3009
+ configSources.excludePattern = "vocoder.config";
2954
3010
  } else if (envExcludePattern) {
2955
3011
  excludePattern = envExcludePattern.split(",").map((p10) => p10.trim()).filter(Boolean);
2956
3012
  configSources.excludePattern = "environment";
@@ -3030,7 +3086,7 @@ function computeStringsHash(texts) {
3030
3086
  }
3031
3087
  function readCachedStringsHash(projectRoot, branch) {
3032
3088
  const filePath = getCacheFilePath(projectRoot, branch);
3033
- if (!existsSync2(filePath)) return null;
3089
+ if (!existsSync3(filePath)) return null;
3034
3090
  try {
3035
3091
  const raw = JSON.parse(readFileSync3(filePath, "utf-8"));
3036
3092
  if (isRecord(raw) && typeof raw.stringsHash === "string")
@@ -3084,7 +3140,7 @@ function parseTranslations(value) {
3084
3140
  }
3085
3141
  function getCacheFilePath(projectRoot, branch) {
3086
3142
  const branchHash = createHash("sha1").update(branch).digest("hex").slice(0, 12);
3087
- return join3(
3143
+ return join4(
3088
3144
  projectRoot,
3089
3145
  "node_modules",
3090
3146
  ".vocoder",
@@ -3097,7 +3153,7 @@ function readLocalSnapshotCache(params) {
3097
3153
  const candidateBranches = params.branch === "main" ? ["main"] : [params.branch, "main"];
3098
3154
  for (const candidateBranch of candidateBranches) {
3099
3155
  const cacheFilePath = getCacheFilePath(params.projectRoot, candidateBranch);
3100
- if (!existsSync2(cacheFilePath)) {
3156
+ if (!existsSync3(cacheFilePath)) {
3101
3157
  continue;
3102
3158
  }
3103
3159
  try {
@@ -3127,7 +3183,7 @@ function readLocalSnapshotCache(params) {
3127
3183
  function writeLocalSnapshotCache(params) {
3128
3184
  const cacheFilePath = getCacheFilePath(params.projectRoot, params.branch);
3129
3185
  mkdirSync2(
3130
- join3(params.projectRoot, "node_modules", ".vocoder", "cache", "sync"),
3186
+ join4(params.projectRoot, "node_modules", ".vocoder", "cache", "sync"),
3131
3187
  {
3132
3188
  recursive: true
3133
3189
  }
@@ -3144,7 +3200,7 @@ function writeLocalSnapshotCache(params) {
3144
3200
  ...params.localeMetadata ? { localeMetadata: params.localeMetadata } : {},
3145
3201
  translations: params.translations
3146
3202
  };
3147
- writeFileSync3(cacheFilePath, JSON.stringify(payload, null, 2), "utf-8");
3203
+ writeFileSync4(cacheFilePath, JSON.stringify(payload, null, 2), "utf-8");
3148
3204
  return cacheFilePath;
3149
3205
  }
3150
3206
  function resolveEffectiveModeFromPolicy(params) {