@luquimbo/bi-superpowers 3.1.0 → 3.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.claude-plugin/skill-manifest.json +1 -1
- package/.plugin/plugin.json +1 -1
- package/README.md +2 -2
- package/bin/build-plugin.js +6 -6
- package/bin/cli.js +169 -310
- package/bin/commands/install.js +87 -70
- package/bin/commands/install.test.js +2 -2
- package/bin/lib/agents.js +21 -2
- package/bin/lib/mcp-config.js +27 -5
- package/bin/lib/mcp-config.test.js +1 -1
- package/desktop-extension/manifest.json +4 -11
- package/desktop-extension/server.js +34 -25
- package/package.json +3 -9
- package/skills/pbi-connect/SKILL.md +1 -1
- package/skills/project-kickoff/SKILL.md +1 -1
- package/bin/commands/add.js +0 -533
- package/bin/commands/add.test.js +0 -77
- package/bin/commands/changelog.js +0 -443
- package/bin/commands/pull.js +0 -287
- package/bin/commands/pull.test.js +0 -36
- package/bin/commands/push.js +0 -231
- package/bin/commands/push.test.js +0 -14
- package/bin/commands/search.js +0 -344
- package/bin/commands/search.test.js +0 -115
- package/bin/commands/setup.js +0 -545
- package/bin/commands/setup.test.js +0 -46
- package/bin/commands/sync-profile.js +0 -405
- package/bin/commands/sync-profile.test.js +0 -14
- package/bin/commands/sync-source.js +0 -418
- package/bin/commands/sync-source.test.js +0 -14
- package/bin/utils/errors.js +0 -159
- package/bin/utils/git.js +0 -298
- package/bin/utils/logger.js +0 -142
- package/bin/utils/pbix.js +0 -305
- package/bin/utils/pbix.test.js +0 -37
- package/bin/utils/profiles.js +0 -312
- package/bin/utils/projects.js +0 -169
- package/bin/utils/readline.js +0 -206
- package/bin/utils/readline.test.js +0 -47
- package/docs/openrouter-free-models.md +0 -92
- package/library/examples/README.md +0 -151
- package/library/examples/finance-reporting/README.md +0 -351
- package/library/examples/finance-reporting/data-model.md +0 -267
- package/library/examples/finance-reporting/measures.dax +0 -557
- package/library/examples/hr-analytics/README.md +0 -371
- package/library/examples/hr-analytics/data-model.md +0 -315
- package/library/examples/hr-analytics/measures.dax +0 -460
- package/library/examples/marketing-analytics/README.md +0 -37
- package/library/examples/marketing-analytics/data-model.md +0 -62
- package/library/examples/marketing-analytics/measures.dax +0 -110
- package/library/examples/retail-analytics/README.md +0 -439
- package/library/examples/retail-analytics/data-model.md +0 -288
- package/library/examples/retail-analytics/measures.dax +0 -481
- package/library/examples/supply-chain/README.md +0 -37
- package/library/examples/supply-chain/data-model.md +0 -69
- package/library/examples/supply-chain/measures.dax +0 -77
- package/library/examples/udf-library/README.md +0 -228
- package/library/examples/udf-library/functions.dax +0 -571
- package/library/snippets/dax/README.md +0 -292
- package/library/snippets/dax/business-domains.md +0 -576
- package/library/snippets/dax/calculate-patterns.md +0 -276
- package/library/snippets/dax/calculation-groups.md +0 -489
- package/library/snippets/dax/error-handling.md +0 -495
- package/library/snippets/dax/iterators-and-aggregations.md +0 -474
- package/library/snippets/dax/kpis-and-metrics.md +0 -293
- package/library/snippets/dax/rankings-and-topn.md +0 -235
- package/library/snippets/dax/security-patterns.md +0 -413
- package/library/snippets/dax/text-and-formatting.md +0 -316
- package/library/snippets/dax/time-intelligence.md +0 -196
- package/library/snippets/dax/user-defined-functions.md +0 -477
- package/library/snippets/dax/virtual-tables.md +0 -546
- package/library/snippets/excel-formulas/README.md +0 -84
- package/library/snippets/excel-formulas/aggregations.md +0 -330
- package/library/snippets/excel-formulas/dates-and-times.md +0 -361
- package/library/snippets/excel-formulas/dynamic-arrays.md +0 -314
- package/library/snippets/excel-formulas/lookups.md +0 -169
- package/library/snippets/excel-formulas/text-functions.md +0 -363
- package/library/snippets/governance/naming-conventions.md +0 -97
- package/library/snippets/governance/review-checklists.md +0 -107
- package/library/snippets/power-query/README.md +0 -389
- package/library/snippets/power-query/api-integration.md +0 -707
- package/library/snippets/power-query/connections.md +0 -434
- package/library/snippets/power-query/data-cleaning.md +0 -298
- package/library/snippets/power-query/error-handling.md +0 -526
- package/library/snippets/power-query/parameters.md +0 -350
- package/library/snippets/power-query/performance.md +0 -506
- package/library/snippets/power-query/transformations.md +0 -330
- package/library/snippets/report-design/accessibility.md +0 -78
- package/library/snippets/report-design/chart-selection.md +0 -54
- package/library/snippets/report-design/layout-patterns.md +0 -87
- package/library/templates/data-models/README.md +0 -93
- package/library/templates/data-models/finance-model.md +0 -627
- package/library/templates/data-models/retail-star-schema.md +0 -473
- package/library/templates/excel/README.md +0 -83
- package/library/templates/excel/budget-tracker.md +0 -432
- package/library/templates/excel/data-entry-form.md +0 -533
- package/library/templates/power-bi/README.md +0 -72
- package/library/templates/power-bi/finance-report.md +0 -449
- package/library/templates/power-bi/kpi-scorecard.md +0 -461
- package/library/templates/power-bi/sales-dashboard.md +0 -281
- package/library/themes/excel/README.md +0 -436
- package/library/themes/power-bi/README.md +0 -271
- package/library/themes/power-bi/accessible.json +0 -307
- package/library/themes/power-bi/bi-superpowers-default.json +0 -858
- package/library/themes/power-bi/corporate-blue.json +0 -291
- package/library/themes/power-bi/dark-mode.json +0 -291
- package/library/themes/power-bi/minimal.json +0 -292
- package/library/themes/power-bi/print-friendly.json +0 -309
package/bin/commands/pull.js
DELETED
|
@@ -1,287 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pull Command - Sync from Original to Repo
|
|
3
|
-
* ==========================================
|
|
4
|
-
*
|
|
5
|
-
* Pulls changes from the original BI file to the repo.
|
|
6
|
-
* Extracts updated TMDL/content and creates a Git commit.
|
|
7
|
-
*
|
|
8
|
-
* Usage:
|
|
9
|
-
* super pull Pull current project
|
|
10
|
-
* super pull <project-name> Pull specific project
|
|
11
|
-
* super pull --all Pull all projects
|
|
12
|
-
*
|
|
13
|
-
* @module commands/pull
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
const fs = require('fs');
|
|
17
|
-
const path = require('path');
|
|
18
|
-
|
|
19
|
-
const git = require('../utils/git');
|
|
20
|
-
const profiles = require('../utils/profiles');
|
|
21
|
-
const pbix = require('../utils/pbix');
|
|
22
|
-
const { getAllProjects, getProject, detectCurrentProject } = require('../utils/projects');
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Parse command line arguments
|
|
26
|
-
* @param {string[]} args - CLI arguments
|
|
27
|
-
* @returns {Object} Parsed options
|
|
28
|
-
*/
|
|
29
|
-
function parseArgs(args) {
|
|
30
|
-
const options = {
|
|
31
|
-
projectName: null,
|
|
32
|
-
all: false,
|
|
33
|
-
force: false,
|
|
34
|
-
help: false,
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
for (let i = 0; i < args.length; i++) {
|
|
38
|
-
const arg = args[i];
|
|
39
|
-
|
|
40
|
-
if (arg === '--all' || arg === '-a') {
|
|
41
|
-
options.all = true;
|
|
42
|
-
} else if (arg === '--force' || arg === '-f') {
|
|
43
|
-
options.force = true;
|
|
44
|
-
} else if (arg === '--help' || arg === '-h') {
|
|
45
|
-
options.help = true;
|
|
46
|
-
} else if (!arg.startsWith('-') && !options.projectName) {
|
|
47
|
-
options.projectName = arg;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return options;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Show help message
|
|
56
|
-
*/
|
|
57
|
-
function showHelp() {
|
|
58
|
-
console.log(`
|
|
59
|
-
super pull - Traer cambios del archivo original al repo
|
|
60
|
-
|
|
61
|
-
Uso:
|
|
62
|
-
super pull Pull del proyecto actual (si estás en la carpeta)
|
|
63
|
-
super pull <nombre-proyecto> Pull de un proyecto específico
|
|
64
|
-
super pull --all Pull de todos los proyectos
|
|
65
|
-
|
|
66
|
-
Opciones:
|
|
67
|
-
--all, -a Pull de todos los proyectos
|
|
68
|
-
--force, -f Forzar pull aunque no haya cambios detectados
|
|
69
|
-
--help, -h Mostrar esta ayuda
|
|
70
|
-
|
|
71
|
-
Ejemplos:
|
|
72
|
-
super pull sales-q4
|
|
73
|
-
super pull --all
|
|
74
|
-
super pull hr-dashboard --force
|
|
75
|
-
`);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Note: getAllProjects, getProject, and detectCurrentProject are imported from ../utils/projects
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Pull changes for a single project
|
|
82
|
-
* @param {Object} project - Project config
|
|
83
|
-
* @param {boolean} force - Force pull even if no changes
|
|
84
|
-
* @returns {Object} Result object
|
|
85
|
-
*/
|
|
86
|
-
function pullProject(project, force = false) {
|
|
87
|
-
const result = {
|
|
88
|
-
success: false,
|
|
89
|
-
project: project.name,
|
|
90
|
-
message: '',
|
|
91
|
-
filesChanged: 0,
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
// Check if source file exists
|
|
95
|
-
const sourcePath = project.source?.path;
|
|
96
|
-
if (!sourcePath || !fs.existsSync(sourcePath)) {
|
|
97
|
-
result.message = `Archivo original no encontrado: ${sourcePath || 'no configurado'}`;
|
|
98
|
-
return result;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Check if file has changed (by modification time or hash)
|
|
102
|
-
const currentHash = pbix.getFileHash(sourcePath);
|
|
103
|
-
const lastHash = project.source?.hash || '';
|
|
104
|
-
|
|
105
|
-
if (currentHash === lastHash && !force) {
|
|
106
|
-
result.success = true;
|
|
107
|
-
result.message = 'Sin cambios';
|
|
108
|
-
return result;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Detect file type and extract
|
|
112
|
-
const fileInfo = pbix.detectFileType(sourcePath);
|
|
113
|
-
|
|
114
|
-
if (fileInfo.type === 'power-bi-project') {
|
|
115
|
-
// PBIP - extract TMDL
|
|
116
|
-
const definitionPath = pbix.getPbipDefinitionPath(sourcePath);
|
|
117
|
-
|
|
118
|
-
if (definitionPath) {
|
|
119
|
-
const targetDef = path.join(project.projectPath, 'definition');
|
|
120
|
-
|
|
121
|
-
// Compare directories to show changes
|
|
122
|
-
const changes = pbix.compareDirectories(targetDef, definitionPath);
|
|
123
|
-
|
|
124
|
-
// Copy new content
|
|
125
|
-
const extraction = pbix.extractPbipToRepo(sourcePath, project.projectPath);
|
|
126
|
-
|
|
127
|
-
if (extraction.success) {
|
|
128
|
-
result.success = true;
|
|
129
|
-
result.filesChanged =
|
|
130
|
-
changes.added.length + changes.modified.length + changes.deleted.length;
|
|
131
|
-
result.message = `Actualizado: +${changes.added.length} ~${changes.modified.length} -${changes.deleted.length}`;
|
|
132
|
-
} else {
|
|
133
|
-
result.message = extraction.error;
|
|
134
|
-
}
|
|
135
|
-
} else {
|
|
136
|
-
result.message = 'No se encontró carpeta definition en PBIP';
|
|
137
|
-
}
|
|
138
|
-
} else if (fileInfo.type === 'power-bi') {
|
|
139
|
-
// PBIX - just update modification time and hash
|
|
140
|
-
result.success = true;
|
|
141
|
-
result.message = 'Archivo .pbix actualizado (binario, sin diff detallado)';
|
|
142
|
-
|
|
143
|
-
// Update the README with latest info
|
|
144
|
-
const readmePath = path.join(project.projectPath, 'README.md');
|
|
145
|
-
if (fs.existsSync(readmePath)) {
|
|
146
|
-
let content = fs.readFileSync(readmePath, 'utf8');
|
|
147
|
-
const lastMod = pbix.getLastModified(sourcePath);
|
|
148
|
-
|
|
149
|
-
// Add update note
|
|
150
|
-
if (!content.includes('## Historial de Actualizaciones')) {
|
|
151
|
-
content += '\n\n## Historial de Actualizaciones\n';
|
|
152
|
-
}
|
|
153
|
-
content += `\n- ${lastMod?.toISOString()}: Pull desde archivo original`;
|
|
154
|
-
fs.writeFileSync(readmePath, content);
|
|
155
|
-
}
|
|
156
|
-
} else if (fileInfo.type === 'excel' || fileInfo.type === 'excel-macro') {
|
|
157
|
-
// Excel - update modification tracking
|
|
158
|
-
result.success = true;
|
|
159
|
-
result.message = 'Archivo Excel actualizado';
|
|
160
|
-
} else {
|
|
161
|
-
result.message = 'Tipo de archivo no soportado para pull';
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Update project.json with new hash and sync time
|
|
165
|
-
if (result.success) {
|
|
166
|
-
project.source.hash = currentHash;
|
|
167
|
-
project.source.lastSync = new Date().toISOString();
|
|
168
|
-
|
|
169
|
-
const configPath = path.join(project.projectPath, 'project.json');
|
|
170
|
-
fs.writeFileSync(configPath, JSON.stringify(project, null, 2));
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return result;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Main pull command handler
|
|
178
|
-
*/
|
|
179
|
-
async function pullCommand(args, _config) {
|
|
180
|
-
const options = parseArgs(args);
|
|
181
|
-
|
|
182
|
-
if (options.help) {
|
|
183
|
-
showHelp();
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Check if repo exists
|
|
188
|
-
const repoPath = profiles.getRepoPath();
|
|
189
|
-
if (!repoPath || !fs.existsSync(repoPath)) {
|
|
190
|
-
console.log(`
|
|
191
|
-
No se encontró el repositorio de BI.
|
|
192
|
-
|
|
193
|
-
Ejecuta primero:
|
|
194
|
-
super setup
|
|
195
|
-
`);
|
|
196
|
-
process.exit(1);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
console.log(`
|
|
200
|
-
════════════════════════════════════════════════════════════════
|
|
201
|
-
Pull - Traer cambios de archivos originales
|
|
202
|
-
════════════════════════════════════════════════════════════════
|
|
203
|
-
`);
|
|
204
|
-
|
|
205
|
-
let projectsToPull = [];
|
|
206
|
-
|
|
207
|
-
if (options.all) {
|
|
208
|
-
// Pull all projects
|
|
209
|
-
projectsToPull = getAllProjects(repoPath);
|
|
210
|
-
console.log(`Proyectos encontrados: ${projectsToPull.length}\n`);
|
|
211
|
-
} else if (options.projectName) {
|
|
212
|
-
// Pull specific project
|
|
213
|
-
const project = getProject(repoPath, options.projectName);
|
|
214
|
-
if (!project) {
|
|
215
|
-
console.log(`✗ Proyecto no encontrado: ${options.projectName}`);
|
|
216
|
-
console.log('\nProyectos disponibles:');
|
|
217
|
-
getAllProjects(repoPath).forEach((p) => {
|
|
218
|
-
console.log(` - ${p.name}`);
|
|
219
|
-
});
|
|
220
|
-
process.exit(1);
|
|
221
|
-
}
|
|
222
|
-
projectsToPull = [project];
|
|
223
|
-
} else {
|
|
224
|
-
// Try to detect current project
|
|
225
|
-
const current = detectCurrentProject(repoPath);
|
|
226
|
-
if (current) {
|
|
227
|
-
projectsToPull = [current];
|
|
228
|
-
} else {
|
|
229
|
-
// No project specified, show help
|
|
230
|
-
console.log('Especifica un proyecto o usa --all:\n');
|
|
231
|
-
console.log(' super pull <nombre-proyecto>');
|
|
232
|
-
console.log(' super pull --all\n');
|
|
233
|
-
console.log('Proyectos disponibles:');
|
|
234
|
-
getAllProjects(repoPath).forEach((p) => {
|
|
235
|
-
console.log(` - ${p.name}`);
|
|
236
|
-
});
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (projectsToPull.length === 0) {
|
|
242
|
-
console.log('No hay proyectos para actualizar.');
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
// Pull each project
|
|
247
|
-
const results = [];
|
|
248
|
-
|
|
249
|
-
for (const project of projectsToPull) {
|
|
250
|
-
process.stdout.write(` ${project.name}... `);
|
|
251
|
-
|
|
252
|
-
const result = pullProject(project, options.force);
|
|
253
|
-
results.push(result);
|
|
254
|
-
|
|
255
|
-
if (result.success) {
|
|
256
|
-
console.log(`✓ ${result.message}`);
|
|
257
|
-
} else {
|
|
258
|
-
console.log(`✗ ${result.message}`);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// Git commit if there were changes
|
|
263
|
-
const changedProjects = results.filter((r) => r.success && r.filesChanged > 0);
|
|
264
|
-
|
|
265
|
-
if (changedProjects.length > 0 && git.isGitRepo(repoPath)) {
|
|
266
|
-
console.log('\nGuardando cambios en Git...');
|
|
267
|
-
|
|
268
|
-
git.stageFiles(repoPath, '.');
|
|
269
|
-
|
|
270
|
-
const projectNames = changedProjects.map((r) => r.project).join(', ');
|
|
271
|
-
git.commit(repoPath, `Pull updates: ${projectNames}`);
|
|
272
|
-
|
|
273
|
-
console.log(` ✓ Commit: "Pull updates: ${projectNames}"`);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
// Summary
|
|
277
|
-
const successful = results.filter((r) => r.success).length;
|
|
278
|
-
const failed = results.filter((r) => !r.success).length;
|
|
279
|
-
|
|
280
|
-
console.log(`
|
|
281
|
-
════════════════════════════════════════════════════════════════
|
|
282
|
-
Resumen: ${successful} exitosos, ${failed} fallidos
|
|
283
|
-
════════════════════════════════════════════════════════════════
|
|
284
|
-
`);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
module.exports = pullCommand;
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for Pull Command
|
|
3
|
-
* @module commands/pull.test
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { test, describe } = require('node:test');
|
|
7
|
-
const assert = require('node:assert');
|
|
8
|
-
|
|
9
|
-
describe('Pull Command', () => {
|
|
10
|
-
test('module exports a function', () => {
|
|
11
|
-
const pullCommand = require('./pull');
|
|
12
|
-
assert.strictEqual(typeof pullCommand, 'function');
|
|
13
|
-
});
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
describe('Pull Command - Directory Comparison', () => {
|
|
17
|
-
test('compareDirectories returns diff structure', () => {
|
|
18
|
-
const pbix = require('../utils/pbix');
|
|
19
|
-
|
|
20
|
-
// Test with non-existent directories (should return empty diff)
|
|
21
|
-
const result = pbix.compareDirectories('/non/existent/dir1', '/non/existent/dir2');
|
|
22
|
-
|
|
23
|
-
assert.ok(Array.isArray(result.added));
|
|
24
|
-
assert.ok(Array.isArray(result.modified));
|
|
25
|
-
assert.ok(Array.isArray(result.deleted));
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
describe('Pull Command - File Hashing', () => {
|
|
30
|
-
test('getFileHash returns empty string for non-existent file', () => {
|
|
31
|
-
const pbix = require('../utils/pbix');
|
|
32
|
-
const result = pbix.getFileHash('/non/existent/file.txt');
|
|
33
|
-
|
|
34
|
-
assert.strictEqual(result, '');
|
|
35
|
-
});
|
|
36
|
-
});
|
package/bin/commands/push.js
DELETED
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Push Command - Apply Repo Changes to Original File
|
|
3
|
-
* ====================================================
|
|
4
|
-
*
|
|
5
|
-
* Pushes changes from the repo back to the original BI file.
|
|
6
|
-
* This is a Phase 2 feature - currently provides guidance for PBIP workflow.
|
|
7
|
-
*
|
|
8
|
-
* Usage:
|
|
9
|
-
* super push Push current project
|
|
10
|
-
* super push <project-name> Push specific project
|
|
11
|
-
*
|
|
12
|
-
* @module commands/push
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
const fs = require('fs');
|
|
16
|
-
const path = require('path');
|
|
17
|
-
|
|
18
|
-
const profiles = require('../utils/profiles');
|
|
19
|
-
const pbix = require('../utils/pbix');
|
|
20
|
-
const { getAllProjects, getProject, detectCurrentProject } = require('../utils/projects');
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Parse command line arguments
|
|
24
|
-
* @param {string[]} args - CLI arguments
|
|
25
|
-
* @returns {Object} Parsed options
|
|
26
|
-
*/
|
|
27
|
-
function parseArgs(args) {
|
|
28
|
-
const options = {
|
|
29
|
-
projectName: null,
|
|
30
|
-
force: false,
|
|
31
|
-
help: false,
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
for (let i = 0; i < args.length; i++) {
|
|
35
|
-
const arg = args[i];
|
|
36
|
-
|
|
37
|
-
if (arg === '--force' || arg === '-f') {
|
|
38
|
-
options.force = true;
|
|
39
|
-
} else if (arg === '--help' || arg === '-h') {
|
|
40
|
-
options.help = true;
|
|
41
|
-
} else if (!arg.startsWith('-') && !options.projectName) {
|
|
42
|
-
options.projectName = arg;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return options;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Show help message
|
|
51
|
-
*/
|
|
52
|
-
function showHelp() {
|
|
53
|
-
console.log(`
|
|
54
|
-
super push - Aplicar cambios del repo al archivo original
|
|
55
|
-
|
|
56
|
-
Uso:
|
|
57
|
-
super push Push del proyecto actual
|
|
58
|
-
super push <nombre-proyecto> Push de un proyecto específico
|
|
59
|
-
|
|
60
|
-
Opciones:
|
|
61
|
-
--force, -f Forzar push aunque haya advertencias
|
|
62
|
-
--help, -h Mostrar esta ayuda
|
|
63
|
-
|
|
64
|
-
Nota:
|
|
65
|
-
Este comando actualmente soporta proyectos PBIP.
|
|
66
|
-
Para archivos .pbix, usa el workflow PBIP (recomendado).
|
|
67
|
-
|
|
68
|
-
Ejemplos:
|
|
69
|
-
super push sales-q4
|
|
70
|
-
super push --force
|
|
71
|
-
`);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Note: getAllProjects, getProject, and detectCurrentProject are imported from ../utils/projects
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Push changes for a PBIP project
|
|
78
|
-
* @param {Object} project - Project config
|
|
79
|
-
* @returns {Object} Result object
|
|
80
|
-
*/
|
|
81
|
-
function pushPbipProject(project) {
|
|
82
|
-
const result = {
|
|
83
|
-
success: false,
|
|
84
|
-
message: '',
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
const sourcePath = project.source?.path;
|
|
88
|
-
if (!sourcePath) {
|
|
89
|
-
result.message = 'No source path configured';
|
|
90
|
-
return result;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const definitionPath = pbix.getPbipDefinitionPath(sourcePath);
|
|
94
|
-
if (!definitionPath) {
|
|
95
|
-
result.message = 'Could not find PBIP definition folder';
|
|
96
|
-
return result;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const repoDefinition = path.join(project.projectPath, 'definition');
|
|
100
|
-
if (!fs.existsSync(repoDefinition)) {
|
|
101
|
-
result.message = 'No definition folder in repo';
|
|
102
|
-
return result;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
try {
|
|
106
|
-
// Copy files from repo to PBIP project
|
|
107
|
-
const files = pbix.copyDirectoryRecursive(repoDefinition, definitionPath);
|
|
108
|
-
|
|
109
|
-
// Update project.json with sync time
|
|
110
|
-
project.source.lastSync = new Date().toISOString();
|
|
111
|
-
const configPath = path.join(project.projectPath, 'project.json');
|
|
112
|
-
fs.writeFileSync(configPath, JSON.stringify(project, null, 2));
|
|
113
|
-
|
|
114
|
-
result.success = true;
|
|
115
|
-
result.message = `Pushed ${files.length} files to PBIP project`;
|
|
116
|
-
} catch (e) {
|
|
117
|
-
result.message = `Error: ${e.message}`;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return result;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Main push command handler
|
|
125
|
-
*/
|
|
126
|
-
async function pushCommand(args, _config) {
|
|
127
|
-
const options = parseArgs(args);
|
|
128
|
-
|
|
129
|
-
if (options.help) {
|
|
130
|
-
showHelp();
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Check if repo exists
|
|
135
|
-
const repoPath = profiles.getRepoPath();
|
|
136
|
-
if (!repoPath || !fs.existsSync(repoPath)) {
|
|
137
|
-
console.log(`
|
|
138
|
-
No se encontró el repositorio de BI.
|
|
139
|
-
|
|
140
|
-
Ejecuta primero:
|
|
141
|
-
super setup
|
|
142
|
-
`);
|
|
143
|
-
process.exit(1);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
console.log(`
|
|
147
|
-
════════════════════════════════════════════════════════════════
|
|
148
|
-
Push - Aplicar cambios del repo al archivo original
|
|
149
|
-
════════════════════════════════════════════════════════════════
|
|
150
|
-
`);
|
|
151
|
-
|
|
152
|
-
let project;
|
|
153
|
-
|
|
154
|
-
if (options.projectName) {
|
|
155
|
-
project = getProject(repoPath, options.projectName);
|
|
156
|
-
if (!project) {
|
|
157
|
-
console.log(`✗ Proyecto no encontrado: ${options.projectName}`);
|
|
158
|
-
console.log('\nProyectos disponibles:');
|
|
159
|
-
getAllProjects(repoPath).forEach((p) => {
|
|
160
|
-
console.log(` - ${p.name}`);
|
|
161
|
-
});
|
|
162
|
-
process.exit(1);
|
|
163
|
-
}
|
|
164
|
-
} else {
|
|
165
|
-
project = detectCurrentProject(repoPath);
|
|
166
|
-
if (!project) {
|
|
167
|
-
console.log('Especifica un proyecto:\n');
|
|
168
|
-
console.log(' super push <nombre-proyecto>\n');
|
|
169
|
-
console.log('Proyectos disponibles:');
|
|
170
|
-
getAllProjects(repoPath).forEach((p) => {
|
|
171
|
-
console.log(` - ${p.name}`);
|
|
172
|
-
});
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
console.log(`Proyecto: ${project.name}`);
|
|
178
|
-
console.log(`Tipo: ${project.type}`);
|
|
179
|
-
console.log(`Archivo original: ${project.source?.path || 'No configurado'}\n`);
|
|
180
|
-
|
|
181
|
-
// Handle based on project type
|
|
182
|
-
if (project.type === 'power-bi-project') {
|
|
183
|
-
// PBIP - we can push directly
|
|
184
|
-
const result = pushPbipProject(project);
|
|
185
|
-
|
|
186
|
-
if (result.success) {
|
|
187
|
-
console.log(`✓ ${result.message}`);
|
|
188
|
-
console.log(`
|
|
189
|
-
Los cambios se han aplicado al proyecto PBIP.
|
|
190
|
-
Abre Power BI Desktop y recarga el proyecto para ver los cambios.
|
|
191
|
-
`);
|
|
192
|
-
} else {
|
|
193
|
-
console.log(`✗ ${result.message}`);
|
|
194
|
-
}
|
|
195
|
-
} else if (project.type === 'power-bi') {
|
|
196
|
-
// PBIX - binary file, cannot push directly
|
|
197
|
-
console.log(`
|
|
198
|
-
⚠ Los archivos .pbix son binarios y no se pueden modificar directamente.
|
|
199
|
-
|
|
200
|
-
Para aplicar cambios del repo al modelo, tienes estas opciones:
|
|
201
|
-
|
|
202
|
-
OPCIÓN 1: Convertir a PBIP (Recomendado)
|
|
203
|
-
1. Abre el .pbix en Power BI Desktop
|
|
204
|
-
2. File → Save as → Power BI Project (.pbip)
|
|
205
|
-
3. Ejecuta: super add "ruta/al/proyecto.pbip"
|
|
206
|
-
4. Los cambios del repo se pueden aplicar con: super push
|
|
207
|
-
|
|
208
|
-
OPCIÓN 2: Copiar manualmente
|
|
209
|
-
1. Abre el .pbix en Power BI Desktop
|
|
210
|
-
2. Copia las medidas/queries del repo manualmente
|
|
211
|
-
3. Guarda el archivo
|
|
212
|
-
|
|
213
|
-
Los archivos del repo están en:
|
|
214
|
-
${project.projectPath}
|
|
215
|
-
`);
|
|
216
|
-
} else if (project.type === 'excel' || project.type === 'excel-macro') {
|
|
217
|
-
console.log(`
|
|
218
|
-
⚠ Los archivos Excel no se pueden modificar automáticamente.
|
|
219
|
-
|
|
220
|
-
La documentación del workbook está en:
|
|
221
|
-
${path.join(project.projectPath, 'workbook')}
|
|
222
|
-
|
|
223
|
-
Usa esta documentación como referencia para aplicar
|
|
224
|
-
cambios manualmente en Excel.
|
|
225
|
-
`);
|
|
226
|
-
} else {
|
|
227
|
-
console.log(`✗ Tipo de proyecto no soportado para push: ${project.type}`);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
module.exports = pushCommand;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for Push Command
|
|
3
|
-
* @module commands/push.test
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { test, describe } = require('node:test');
|
|
7
|
-
const assert = require('node:assert');
|
|
8
|
-
|
|
9
|
-
describe('Push Command', () => {
|
|
10
|
-
test('module exports a function', () => {
|
|
11
|
-
const pushCommand = require('./push');
|
|
12
|
-
assert.strictEqual(typeof pushCommand, 'function');
|
|
13
|
-
});
|
|
14
|
-
});
|