latinfo 0.14.0 → 0.15.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.
Files changed (2) hide show
  1. package/dist/index.js +97 -29
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -47,7 +47,7 @@ const local_search_1 = require("./local-search");
47
47
  const client_search_1 = require("./client-search");
48
48
  const odis_search_1 = require("./odis-search");
49
49
  const mphf_search_1 = require("./mphf-search");
50
- const VERSION = '0.14.0';
50
+ const VERSION = '0.15.0';
51
51
  const API_URL = process.env.LATINFO_API_URL || 'https://api.latinfo.dev';
52
52
  const GITHUB_CLIENT_ID = process.env.GITHUB_CLIENT_ID || 'Ov23li5fcQaiCsVtaMKK';
53
53
  const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.latinfo');
@@ -1724,16 +1724,31 @@ async function pipeScript(args) {
1724
1724
  console.log(`[pipe] Gates reset — run: latinfo pipe test ${sourceName}`);
1725
1725
  }
1726
1726
  async function pipeDeps(args) {
1727
+ // Parse flags
1727
1728
  const isPython = args.includes('--python');
1728
- const filtered = args.filter(a => a !== '--python');
1729
+ const isRemove = args.includes('--remove');
1730
+ const isList = args.includes('--list');
1731
+ const filtered = args.filter(a => !a.startsWith('--'));
1729
1732
  const [sourceName, ...deps] = filtered;
1730
- if (!sourceName || deps.length === 0) {
1731
- console.error(`Usage: latinfo pipe deps <source-name> <pkg1> [pkg2] ...
1732
- latinfo pipe deps <source-name> --python <pkg1> [pkg2] ...
1733
+ if (!sourceName) {
1734
+ console.error(`Usage: latinfo pipe deps <source> <pkg[@version]> [pkg2] ... Add npm deps
1735
+ latinfo pipe deps <source> --python <pkg[==version]> [pkg2] Add Python deps
1736
+ latinfo pipe deps <source> --list Show all deps
1737
+ latinfo pipe deps <source> --remove <pkg> Remove a dep
1738
+ latinfo pipe deps <source> --remove --python <pkg> Remove a Python dep
1733
1739
 
1734
1740
  Examples:
1735
- latinfo pipe deps pe-redam-registry playwright # npm package
1736
- latinfo pipe deps pe-redam-registry --python ddddocr # Python package (pip3)`);
1741
+ latinfo pipe deps pe-source playwright # npm, latest
1742
+ latinfo pipe deps pe-source cheerio@1.0.0 # npm, specific version
1743
+ latinfo pipe deps pe-source --python ddddocr # Python, latest
1744
+ latinfo pipe deps pe-source --python ddddocr==1.4.11 # Python, specific version
1745
+ latinfo pipe deps pe-source --python requests numpy # multiple Python deps
1746
+ latinfo pipe deps pe-source --list # show all deps
1747
+ latinfo pipe deps pe-source --remove cheerio # remove npm dep
1748
+ latinfo pipe deps pe-source --remove --python ddddocr # remove Python dep
1749
+
1750
+ npm deps install locally + on Linux Mint during stage.
1751
+ Python deps only install on Linux Mint during stage (not locally).`);
1737
1752
  process.exit(1);
1738
1753
  }
1739
1754
  const repo = getRepoPath();
@@ -1743,31 +1758,82 @@ Examples:
1743
1758
  process.exit(1);
1744
1759
  }
1745
1760
  let yaml = fs_1.default.readFileSync(yamlPath, 'utf-8');
1761
+ // Helper: read deps list from YAML
1762
+ const readDeps = (key) => {
1763
+ const match = yaml.match(new RegExp(`^${key}:\\n([\\s\\S]*?)(?=\\n\\w|\\n$|$)`, 'm'));
1764
+ if (!match)
1765
+ return [];
1766
+ return match[1].split('\n').map(l => l.replace(/^\s*-\s*/, '').trim()).filter(Boolean);
1767
+ };
1768
+ // Helper: write deps list to YAML
1769
+ const writeDeps = (key, list) => {
1770
+ const block = list.length > 0 ? `${key}:\n${list.map(d => ` - ${d}`).join('\n')}\n` : '';
1771
+ if (yaml.includes(`${key}:`)) {
1772
+ yaml = yaml.replace(new RegExp(`${key}:[\\s\\S]*?(?=\\n\\w|\\n$|$)`), block);
1773
+ }
1774
+ else if (block) {
1775
+ yaml += `\n${block}`;
1776
+ }
1777
+ fs_1.default.writeFileSync(yamlPath, yaml);
1778
+ };
1746
1779
  const key = isPython ? 'python_dependencies' : 'dependencies';
1747
- if (yaml.includes(`${key}:`)) {
1748
- yaml = yaml.replace(new RegExp(`${key}:[\\s\\S]*?(?=\\n\\w|\\n$|$)`), `${key}:\n${deps.map(d => ` - ${d}`).join('\n')}\n`);
1780
+ // --list: show all deps
1781
+ if (isList) {
1782
+ const npmDeps = readDeps('dependencies');
1783
+ const pyDeps = readDeps('python_dependencies');
1784
+ console.log(`Source: ${sourceName}\n`);
1785
+ console.log(`npm (${npmDeps.length}):`);
1786
+ for (const d of npmDeps)
1787
+ console.log(` ${d}`);
1788
+ console.log(`\nPython (${pyDeps.length}):`);
1789
+ for (const d of pyDeps)
1790
+ console.log(` ${d}`);
1791
+ return;
1749
1792
  }
1750
- else {
1751
- yaml += `\n${key}:\n${deps.map(d => ` - ${d}`).join('\n')}\n`;
1793
+ if (deps.length === 0) {
1794
+ console.error('No packages specified.');
1795
+ process.exit(1);
1752
1796
  }
1753
- fs_1.default.writeFileSync(yamlPath, yaml);
1754
- const { execSync: run } = await Promise.resolve().then(() => __importStar(require('child_process')));
1755
- if (isPython) {
1756
- console.log(`[pipe] Installing Python: ${deps.join(', ')}...`);
1757
- try {
1758
- run(`pip3 install ${deps.join(' ')}`, { cwd: repo, stdio: 'inherit' });
1759
- console.log(`[pipe] Python dependencies installed and added to YAML.`);
1760
- }
1761
- catch {
1762
- console.error(`[pipe] Failed to install Python dependencies.`);
1763
- process.exit(1);
1797
+ // --remove: remove deps
1798
+ if (isRemove) {
1799
+ const current = readDeps(key);
1800
+ const updated = current.filter(d => {
1801
+ const name = d.split(/[@==]/)[0];
1802
+ return !deps.includes(name) && !deps.includes(d);
1803
+ });
1804
+ writeDeps(key, updated);
1805
+ console.log(`[pipe] Removed ${isPython ? 'Python' : 'npm'} deps: ${deps.join(', ')}`);
1806
+ if (!isPython) {
1807
+ const { execSync: run } = await Promise.resolve().then(() => __importStar(require('child_process')));
1808
+ try {
1809
+ run(`npm uninstall ${deps.join(' ')}`, { cwd: repo, stdio: 'inherit' });
1810
+ }
1811
+ catch { }
1764
1812
  }
1813
+ return;
1814
+ }
1815
+ // Add deps
1816
+ const current = readDeps(key);
1817
+ for (const dep of deps) {
1818
+ const name = dep.split(/[@==]/)[0];
1819
+ // Replace if same package exists with different version
1820
+ const idx = current.findIndex(d => d.split(/[@==]/)[0] === name);
1821
+ if (idx >= 0)
1822
+ current[idx] = dep;
1823
+ else
1824
+ current.push(dep);
1825
+ }
1826
+ writeDeps(key, current);
1827
+ if (isPython) {
1828
+ console.log(`[pipe] Python deps in YAML: ${current.join(', ')}`);
1829
+ console.log(`[pipe] Will be installed on Linux Mint during pipe stage.`);
1765
1830
  }
1766
1831
  else {
1767
1832
  console.log(`[pipe] Installing npm: ${deps.join(', ')}...`);
1833
+ const { execSync: run } = await Promise.resolve().then(() => __importStar(require('child_process')));
1768
1834
  try {
1769
1835
  run(`npm install ${deps.join(' ')}`, { cwd: repo, stdio: 'inherit' });
1770
- console.log(`[pipe] npm dependencies installed and added to YAML.`);
1836
+ console.log(`[pipe] npm deps in YAML: ${current.join(', ')}`);
1771
1837
  }
1772
1838
  catch {
1773
1839
  console.error(`[pipe] Failed to install npm dependencies.`);
@@ -1807,9 +1873,10 @@ async function pipeTest(args) {
1807
1873
  if (pyDepsMatch) {
1808
1874
  const pyDeps = pyDepsMatch[1].split('\n').map(l => l.replace(/^\s*-\s*/, '').trim()).filter(Boolean);
1809
1875
  if (pyDeps.length > 0) {
1810
- console.log(`[pipe] Installing Python deps: ${pyDeps.join(', ')}...`);
1876
+ console.log(`[pipe] Python deps: ${pyDeps.join(', ')} (installed on Linux Mint during stage)`);
1877
+ // Try local install but don't fail if it can't (Mac blocks pip)
1811
1878
  try {
1812
- run(`pip3 install ${pyDeps.join(' ')}`, { cwd: repo, stdio: 'pipe' });
1879
+ run(`pip3 install --user ${pyDeps.join(' ')} 2>/dev/null`, { cwd: repo, stdio: 'pipe' });
1813
1880
  }
1814
1881
  catch { }
1815
1882
  }
@@ -1955,7 +2022,7 @@ async function pipeStage(args) {
1955
2022
  // 3. Install deps on Linux Mint from YAML
1956
2023
  const yamlPath = path_1.default.join(repo, 'sources', `${sourceName}.yaml`);
1957
2024
  const yamlContent = fs_1.default.existsSync(yamlPath) ? fs_1.default.readFileSync(yamlPath, 'utf-8') : '';
1958
- const depsMatch = yamlContent.match(/dependencies:\n([\s\S]*?)(?=\n\w|\n$|$)/);
2025
+ const depsMatch = yamlContent.match(/^dependencies:\n([\s\S]*?)(?=\n\w|\n$|$)/m);
1959
2026
  if (depsMatch) {
1960
2027
  const deps = depsMatch[1].split('\n').map(l => l.replace(/^\s*-\s*/, '').trim()).filter(Boolean);
1961
2028
  if (deps.length > 0) {
@@ -1974,14 +2041,15 @@ async function pipeStage(args) {
1974
2041
  }
1975
2042
  }
1976
2043
  }
1977
- // 3b. Install Python deps on Linux Mint
2044
+ // 3b. Install Python deps on Linux Mint (using venv)
1978
2045
  const pyDepsMatch = yamlContent.match(/python_dependencies:\n([\s\S]*?)(?=\n\w|\n$|$)/);
1979
2046
  if (pyDepsMatch) {
1980
2047
  const pyDeps = pyDepsMatch[1].split('\n').map(l => l.replace(/^\s*-\s*/, '').trim()).filter(Boolean);
1981
2048
  if (pyDeps.length > 0) {
1982
2049
  console.log(`[pipe] Installing Python deps on Linux Mint: ${pyDeps.join(', ')}...`);
1983
2050
  try {
1984
- run(`ssh ${RUNNER} "pip3 install ${pyDeps.join(' ')}"`, { stdio: 'inherit' });
2051
+ // Create venv if not exists, activate, install
2052
+ run(`ssh ${RUNNER} "cd ${remoteRepo} && (test -d .venv || python3 -m venv .venv) && .venv/bin/pip install ${pyDeps.join(' ')}"`, { stdio: 'inherit' });
1985
2053
  }
1986
2054
  catch {
1987
2055
  console.error('[pipe] Failed to install Python deps on Linux Mint');
@@ -1992,7 +2060,7 @@ async function pipeStage(args) {
1992
2060
  // 4. Run import on Linux Mint
1993
2061
  console.log(`[pipe] Running import on Linux Mint...`);
1994
2062
  try {
1995
- run(`ssh ${RUNNER} "cd ${remoteRepo} && set -a && source .env 2>/dev/null; source .dev.vars 2>/dev/null; set +a && R2_BUCKET_NAME=latinfo-data npx tsx src/imports/${sourceName}.ts"`, {
2063
+ run(`ssh ${RUNNER} "cd ${remoteRepo} && set -a && source .env 2>/dev/null; source .dev.vars 2>/dev/null; test -f .venv/bin/activate && source .venv/bin/activate; set +a && R2_BUCKET_NAME=latinfo-data npx tsx src/imports/${sourceName}.ts"`, {
1996
2064
  stdio: 'inherit',
1997
2065
  });
1998
2066
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "latinfo",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "Tax registry & procurement API for Latin America. Query RUC, DNI, NIT, licitaciones from Peru & Colombia. Offline MPHF search, full OCDS data, updated daily.",
5
5
  "homepage": "https://latinfo.dev",
6
6
  "repository": {