@gzl10/osx-cli 4.0.3 → 4.0.5

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/README.md CHANGED
@@ -8,49 +8,88 @@ CLI para extraer esquemas de tablas Oracle y generar JSON compatible con Atlas.
8
8
  npm install -g @gzl10/osx-cli
9
9
  ```
10
10
 
11
+ ### Windows: Configurar PATH
12
+
13
+ Agregar `%APPDATA%\npm` al PATH del sistema, o ejecutar antes de usar:
14
+
15
+ ```powershell
16
+ $env:PATH += ";$env:APPDATA\npm"
17
+ ```
18
+
19
+ ## Configuracion Rapida
20
+
21
+ Crea estos archivos en tu home (`~` o `%USERPROFILE%`):
22
+
23
+ **~/.env** - Credenciales Oracle:
24
+
25
+ ```ini
26
+ USER=tu_usuario
27
+ PWD=tu_password
28
+ ```
29
+
30
+ **~/tnsnames.ora** - Conexiones Oracle:
31
+
32
+ ```text
33
+ PROD_DB=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=servidor)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL)))
34
+ ```
35
+
36
+ ## Oracle Instant Client
37
+
38
+ Requerido para bases de datos con autenticacion moderna. El CLI lo detecta automaticamente en:
39
+
40
+ - **Windows:** `C:\oracle\instantclient_*`
41
+ - **Linux/macOS:** `/opt/oracle/instantclient_*`
42
+
43
+ [Descargar Oracle Instant Client](https://www.oracle.com/database/technologies/instant-client/downloads.html)
44
+
11
45
  ## Uso
12
46
 
13
47
  ```bash
14
- # Una tabla
15
- osx extract CUSTOMERS --tns PROD_DB -u USER -p PASS
48
+ # Uso basico (credenciales desde ~/.env)
49
+ osx extract TABLA --tns PROD_DB
16
50
 
17
51
  # Multiples tablas
18
- osx extract CUSTOMERS,ORDERS --tns PROD_DB -u USER -p PASS -o output.json
52
+ osx extract TABLA1,TABLA2,TABLA3 --tns PROD_DB
53
+
54
+ # Guardar en archivo (nombre auto: TABLA.json)
55
+ osx extract TABLA --tns PROD_DB -o --pretty
56
+
57
+ # Guardar con nombre especifico
58
+ osx extract TABLA --tns PROD_DB -o output.json
59
+
60
+ # Credenciales explicitas
61
+ osx extract TABLA --tns PROD_DB -u USER -p PASS
62
+
63
+ # Easy Connect (sin tnsnames.ora)
64
+ osx extract TABLA --tns "servidor:1521/servicio" -u USER -p PASS
19
65
 
20
- # Con variables de entorno
21
- export OSX_USER=USER OSX_PASSWORD=PASS
22
- osx extract PRODUCTS --tns PROD_DB --pretty
66
+ # Extraer de un schema diferente al usuario
67
+ osx extract TABLA --tns PROD_DB --schema OWNER_SCHEMA
23
68
  ```
24
69
 
25
70
  ## Opciones
26
71
 
27
72
  | Opcion | Descripcion |
28
73
  | ------ | ----------- |
29
- | `-t, --tns` | Alias TNS (requerido) |
30
- | `-s, --schema` | Schema Oracle (default: TNS) |
31
- | `-u, --user` | Usuario (o env: OSX_USER) |
32
- | `-p, --password` | Password (o env: OSX_PASSWORD) |
33
- | `-o, --output` | Fichero salida (default: stdout) |
74
+ | `-t, --tns` | Alias TNS o Easy Connect (host:port/service) |
75
+ | `-s, --schema` | Schema Oracle (default: mismo que usuario) |
76
+ | `-u, --user` | Usuario (o env: OSX_USER, o ~/.env USER) |
77
+ | `-p, --password` | Password (o env: OSX_PASSWORD, o ~/.env PWD) |
78
+ | `-o, --output` | Fichero salida (sin nombre: auto, 1 tabla=TABLA.json, N tablas=extractYYYYMMDD.json) |
34
79
  | `--pretty` | JSON formateado |
35
80
  | `-d, --delay` | Delay entre tablas (ms) |
36
81
 
37
- ## Requisitos
38
-
39
- - Node.js >= 20
40
- - Oracle Instant Client
41
- - Oracle Database 11g, 12c, 18c, 19c, 21c o 23ai
82
+ ## Prioridad de Credenciales
42
83
 
43
- ## tnsnames.ora
84
+ 1. Flags de linea de comandos (`-u`, `-p`)
85
+ 2. Variables de entorno (`OSX_USER`, `OSX_PASSWORD`)
86
+ 3. Archivo `~/.env` (`USER`, `PWD`)
44
87
 
45
- ```text
46
- PROD_DB =
47
- (DESCRIPTION =
48
- (ADDRESS = (PROTOCOL = TCP)(HOST = oracle.example.com)(PORT = 1521))
49
- (CONNECT_DATA = (SERVICE_NAME = ORCL))
50
- )
51
- ```
88
+ ## Requisitos
52
89
 
53
- Variable de entorno: `TNS_ADMIN=/path/to/tnsnames`
90
+ - Node.js >= 20
91
+ - Oracle Instant Client (para BD con auth moderna)
92
+ - Oracle Database 11g+
54
93
 
55
94
  ## Licencia
56
95
 
@@ -126,6 +126,14 @@ var TABLE_CHILDREN = `
126
126
  AND ac_child.constraint_type = 'R'
127
127
  AND ac_child.status = 'ENABLED'
128
128
  `;
129
+ var TABLE_STATS = `
130
+ SELECT NUM_ROWS as "count", LAST_ANALYZED as "last_update"
131
+ FROM ALL_TABLES
132
+ WHERE OWNER = :schema AND TABLE_NAME = :tableName
133
+ `;
134
+ function buildExamplesQuery(schema, tableName, limit = 10) {
135
+ return `SELECT * FROM ${schema}.${tableName} ORDER BY ROWID DESC FETCH FIRST ${limit} ROWS ONLY`;
136
+ }
129
137
 
130
138
  // src/services/SchemaExtractor.ts
131
139
  var SchemaExtractor = class {
@@ -135,7 +143,7 @@ var SchemaExtractor = class {
135
143
  /**
136
144
  * Extrae el esquema completo de una tabla
137
145
  */
138
- async extractTable(schema, tableName) {
146
+ async extractTable(bbdd, schema, tableName) {
139
147
  const [commentRow] = await this.oracle.query(TABLE_COMMENT, {
140
148
  schema,
141
149
  tableName
@@ -148,21 +156,31 @@ var SchemaExtractor = class {
148
156
  schema,
149
157
  tableName
150
158
  });
159
+ const [statsRow] = await this.oracle.query(TABLE_STATS, {
160
+ schema,
161
+ tableName
162
+ });
163
+ const examplesQuery = buildExamplesQuery(schema, tableName, 10);
164
+ const examples = await this.oracle.query(examplesQuery, {});
151
165
  return {
166
+ bbdd,
152
167
  schema,
153
168
  name: tableName,
154
169
  comment: commentRow?.COMMENTS || "",
155
170
  columns,
156
- children: childrenRows.map((r) => r.child_table)
171
+ children: childrenRows.map((r) => r.child_table),
172
+ count: statsRow?.count ?? 0,
173
+ lastUpdate: statsRow?.last_update?.toISOString() ?? null,
174
+ examples
157
175
  };
158
176
  }
159
177
  /**
160
178
  * Extrae múltiples tablas con delay opcional entre ellas
161
179
  */
162
- async extractTables(schema, tableNames, delayMs = 0) {
180
+ async extractTables(bbdd, schema, tableNames, delayMs = 0) {
163
181
  const results = [];
164
182
  for (let i = 0; i < tableNames.length; i++) {
165
- const table = await this.extractTable(schema, tableNames[i]);
183
+ const table = await this.extractTable(bbdd, schema, tableNames[i]);
166
184
  results.push(table);
167
185
  if (delayMs > 0 && i < tableNames.length - 1) {
168
186
  await new Promise((r) => setTimeout(r, delayMs));
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  OracleService,
4
4
  SchemaExtractor
5
- } from "./chunk-AI3SXYL3.js";
5
+ } from "./chunk-R65IT4N7.js";
6
6
 
7
7
  // src/cli.ts
8
8
  import { readFileSync as readFileSync2 } from "fs";
@@ -120,7 +120,7 @@ async function extractCommand(tables, options) {
120
120
  const homeEnv = loadHomeEnv();
121
121
  const user = options.user || process.env.OSX_USER || homeEnv.user;
122
122
  const password = options.password || process.env.OSX_PASSWORD || homeEnv.password;
123
- const schema = options.schema || options.tns;
123
+ const schema = options.schema || user?.toUpperCase();
124
124
  if (!options.tns) {
125
125
  console.error(
126
126
  '\n\u274C Error: Debes especificar el TNS o conexi\xF3n\n\nUso:\n osx extract <TABLA> --tns <ALIAS> # Usa tnsnames.ora\n osx extract <TABLA> --tns host:port/sid # Easy Connect\n\nEjemplos:\n osx extract D0001 --tns MDI1\n osx extract D0001 --tns "BDMDI1:1523/MDI1"\n'
@@ -148,12 +148,24 @@ async function extractCommand(tables, options) {
148
148
  console.error(`Extrayendo ${tableNames.length} tabla(s) de ${schema}...`);
149
149
  const extractor = new SchemaExtractor(oracle);
150
150
  const delayMs = options.delay ? parseInt(options.delay, 10) : 0;
151
- const results = await extractor.extractTables(schema, tableNames, delayMs);
151
+ const results = await extractor.extractTables(options.tns, schema, tableNames, delayMs);
152
152
  const output = results.length === 1 ? results[0] : results;
153
153
  const json = options.pretty ? JSON.stringify(output, null, 2) : JSON.stringify(output);
154
- if (options.output) {
155
- writeFileSync(options.output, json, "utf-8");
156
- console.error(`Escrito: ${options.output}`);
154
+ let outputFile;
155
+ if (options.output === true) {
156
+ if (tableNames.length === 1) {
157
+ outputFile = `${tableNames[0]}.json`;
158
+ } else {
159
+ const now = /* @__PURE__ */ new Date();
160
+ const ts = now.toISOString().replace(/[-:T]/g, "").slice(0, 15);
161
+ outputFile = `extract${ts}.json`;
162
+ }
163
+ } else if (typeof options.output === "string") {
164
+ outputFile = options.output;
165
+ }
166
+ if (outputFile) {
167
+ writeFileSync(outputFile, json, "utf-8");
168
+ console.error(`Escrito: ${outputFile}`);
157
169
  } else {
158
170
  console.log(json);
159
171
  }
@@ -171,5 +183,5 @@ async function extractCommand(tables, options) {
171
183
  var __dirname2 = dirname(fileURLToPath(import.meta.url));
172
184
  var pkg = JSON.parse(readFileSync2(join2(__dirname2, "..", "package.json"), "utf-8"));
173
185
  program.name("osx").description("Oracle Schema Extractor - Genera JSON compatible con Atlas OriginType=BBDD").version(pkg.version);
174
- program.command("extract <tables>").description("Extrae esquema de tabla(s) Oracle. Tablas separadas por coma.").option("-t, --tns <alias>", "Alias TNS o Easy Connect (host:port/service)").option("-s, --schema <name>", "Schema Oracle (default: mismo que TNS)").option("-u, --user <user>", "Usuario Oracle (o env: OSX_USER)").option("-p, --password <pass>", "Password Oracle (o env: OSX_PASSWORD)").option("-o, --output <file>", "Fichero de salida (default: stdout)").option("--pretty", "JSON formateado con indentacion").option("-d, --delay <ms>", "Delay entre tablas en ms", "0").action(extractCommand);
186
+ program.command("extract <tables>").description("Extrae esquema de tabla(s) Oracle. Tablas separadas por coma.").option("-t, --tns <alias>", "Alias TNS o Easy Connect (host:port/service)").option("-s, --schema <name>", "Schema Oracle (default: mismo que TNS)").option("-u, --user <user>", "Usuario Oracle (o env: OSX_USER)").option("-p, --password <pass>", "Password Oracle (o env: OSX_PASSWORD)").option("-o, --output [file]", "Fichero de salida (sin nombre: auto)").option("--pretty", "JSON formateado con indentacion").option("-d, --delay <ms>", "Delay entre tablas en ms", "0").action(extractCommand);
175
187
  program.parse();
package/dist/index.d.ts CHANGED
@@ -14,11 +14,15 @@ interface OracleColumn {
14
14
  * Esquema de tabla compatible con Atlas OriginType=BBDD
15
15
  */
16
16
  interface TableSchema {
17
+ bbdd: string;
17
18
  schema: string;
18
19
  name: string;
19
20
  comment: string;
20
21
  columns: OracleColumn[];
21
22
  children: string[];
23
+ count: number;
24
+ lastUpdate: string | null;
25
+ examples: Record<string, unknown>[];
22
26
  }
23
27
  /**
24
28
  * Opciones del comando extract
@@ -28,7 +32,7 @@ interface ExtractOptions {
28
32
  schema?: string;
29
33
  user?: string;
30
34
  password?: string;
31
- output?: string;
35
+ output?: string | true;
32
36
  pretty?: boolean;
33
37
  delay?: string;
34
38
  }
@@ -69,11 +73,11 @@ declare class SchemaExtractor {
69
73
  /**
70
74
  * Extrae el esquema completo de una tabla
71
75
  */
72
- extractTable(schema: string, tableName: string): Promise<TableSchema>;
76
+ extractTable(bbdd: string, schema: string, tableName: string): Promise<TableSchema>;
73
77
  /**
74
78
  * Extrae múltiples tablas con delay opcional entre ellas
75
79
  */
76
- extractTables(schema: string, tableNames: string[], delayMs?: number): Promise<TableSchema[]>;
80
+ extractTables(bbdd: string, schema: string, tableNames: string[], delayMs?: number): Promise<TableSchema[]>;
77
81
  }
78
82
 
79
83
  /**
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  TABLE_CHILDREN,
5
5
  TABLE_COLUMNS,
6
6
  TABLE_COMMENT
7
- } from "./chunk-AI3SXYL3.js";
7
+ } from "./chunk-R65IT4N7.js";
8
8
  export {
9
9
  OracleService,
10
10
  SchemaExtractor,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gzl10/osx-cli",
3
- "version": "4.0.3",
3
+ "version": "4.0.5",
4
4
  "description": "Oracle Schema Extractor CLI - Genera JSON compatible con Atlas OriginType=BBDD",
5
5
  "type": "module",
6
6
  "bin": {