farseer-cli 1.0.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/LICENSE +15 -0
- package/README.md +741 -0
- package/dist/commands/app.d.ts +2 -0
- package/dist/commands/app.js +349 -0
- package/dist/commands/app.js.map +7 -0
- package/dist/commands/apps.d.ts +2 -0
- package/dist/commands/apps.js +111 -0
- package/dist/commands/apps.js.map +7 -0
- package/dist/commands/checkout.d.ts +2 -0
- package/dist/commands/checkout.js +166 -0
- package/dist/commands/checkout.js.map +7 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.js +139 -0
- package/dist/commands/config.js.map +7 -0
- package/dist/commands/diff.d.ts +2 -0
- package/dist/commands/diff.js +183 -0
- package/dist/commands/diff.js.map +7 -0
- package/dist/commands/files.js +99 -0
- package/dist/commands/files.js.map +7 -0
- package/dist/commands/install.d.ts +2 -0
- package/dist/commands/install.js +79 -0
- package/dist/commands/install.js.map +7 -0
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/list.js +92 -0
- package/dist/commands/list.js.map +7 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +134 -0
- package/dist/commands/login.js.map +7 -0
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/logout.js +59 -0
- package/dist/commands/logout.js.map +7 -0
- package/dist/commands/mcp-server.d.ts +8 -0
- package/dist/commands/mcp-server.js +41 -0
- package/dist/commands/mcp-server.js.map +7 -0
- package/dist/commands/model.d.ts +2 -0
- package/dist/commands/model.js +189 -0
- package/dist/commands/model.js.map +7 -0
- package/dist/commands/pull.d.ts +2 -0
- package/dist/commands/pull.js +287 -0
- package/dist/commands/pull.js.map +7 -0
- package/dist/commands/push.d.ts +2 -0
- package/dist/commands/push.js +251 -0
- package/dist/commands/push.js.map +7 -0
- package/dist/commands/run.d.ts +2 -0
- package/dist/commands/run.js +246 -0
- package/dist/commands/run.js.map +7 -0
- package/dist/commands/setup.d.ts +2 -0
- package/dist/commands/setup.js +137 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +145 -0
- package/dist/commands/status.js.map +7 -0
- package/dist/commands/unsetup.d.ts +2 -0
- package/dist/commands/unsetup.js +122 -0
- package/dist/commands/whoami.d.ts +2 -0
- package/dist/commands/whoami.js +63 -0
- package/dist/commands/whoami.js.map +7 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +135 -0
- package/dist/index.js.map +7 -0
- package/dist/mcp/index.d.ts +7 -0
- package/dist/mcp/index.js +35 -0
- package/dist/mcp/index.js.map +7 -0
- package/dist/mcp/prompts/workflows.d.ts +7 -0
- package/dist/mcp/prompts/workflows.js +374 -0
- package/dist/mcp/prompts/workflows.js.map +7 -0
- package/dist/mcp/resources/documentation.d.ts +8 -0
- package/dist/mcp/resources/documentation.js +167 -0
- package/dist/mcp/resources/documentation.js.map +7 -0
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.js +49 -0
- package/dist/mcp/server.js.map +7 -0
- package/dist/mcp/tools/appTools.d.ts +7 -0
- package/dist/mcp/tools/appTools.js +377 -0
- package/dist/mcp/tools/appTools.js.map +7 -0
- package/dist/mcp/tools/authTools.d.ts +7 -0
- package/dist/mcp/tools/authTools.js +158 -0
- package/dist/mcp/tools/authTools.js.map +7 -0
- package/dist/mcp/tools/modelTools.d.ts +7 -0
- package/dist/mcp/tools/modelTools.js +331 -0
- package/dist/mcp/tools/modelTools.js.map +7 -0
- package/dist/mcp/tools/runTools.d.ts +7 -0
- package/dist/mcp/tools/runTools.js +231 -0
- package/dist/mcp/tools/runTools.js.map +7 -0
- package/dist/mcp/tools/syncTools.d.ts +7 -0
- package/dist/mcp/tools/syncTools.js +382 -0
- package/dist/mcp/tools/syncTools.js.map +7 -0
- package/dist/mcp/utils/helpers.d.ts +69 -0
- package/dist/mcp/utils/helpers.js +113 -0
- package/dist/mcp/utils/helpers.js.map +7 -0
- package/dist/services/appSyncService.d.ts +75 -0
- package/dist/services/appSyncService.js +370 -0
- package/dist/services/appSyncService.js.map +7 -0
- package/dist/services/configService.d.ts +39 -0
- package/dist/services/configService.js +196 -0
- package/dist/services/configService.js.map +7 -0
- package/dist/services/farseerApi.d.ts +166 -0
- package/dist/services/farseerApi.js +378 -0
- package/dist/services/farseerApi.js.map +7 -0
- package/dist/services/farseerFactory.d.ts +88 -0
- package/dist/services/farseerFactory.js +179 -0
- package/dist/services/farseerFactory.js.map +7 -0
- package/dist/services/farseerService.d.ts +96 -0
- package/dist/services/farseerService.js +614 -0
- package/dist/services/farseerService.js.map +7 -0
- package/dist/services/gitService.d.ts +31 -0
- package/dist/services/gitService.js +134 -0
- package/dist/services/gitService.js.map +7 -0
- package/dist/services/syncService.d.ts +44 -0
- package/dist/services/syncService.js +320 -0
- package/dist/services/syncService.js.map +7 -0
- package/dist/utils/constants.d.ts +7 -0
- package/dist/utils/constants.js +46 -0
- package/dist/utils/constants.js.map +7 -0
- package/dist/utils/helpers.d.ts +69 -0
- package/dist/utils/helpers.js +413 -0
- package/dist/utils/helpers.js.map +7 -0
- package/dist/utils/logger.d.ts +14 -0
- package/dist/utils/logger.js +76 -0
- package/dist/utils/logger.js.map +7 -0
- package/package.json +62 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var model_exports = {};
|
|
19
|
+
__export(model_exports, {
|
|
20
|
+
registerModelCommand: () => registerModelCommand
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(model_exports);
|
|
23
|
+
var import_logger = require("../utils/logger");
|
|
24
|
+
var import_farseerFactory = require("../services/farseerFactory");
|
|
25
|
+
var import_helpers = require("../utils/helpers");
|
|
26
|
+
function registerModelCommand(program) {
|
|
27
|
+
program.command("model [tenant]").description("Export and display the model structure (dimensions, variables)").option("--json", "Output raw JSON").option("--tables", "Show only dimension tables").option("--variables", "Show only variables").option("--variable <name>", "Show details for specific variable").option("--table <name>", "Show details for specific dimension table").action(async (tenantArg, options) => {
|
|
28
|
+
const { organisation, tenant } = (0, import_helpers.resolveTenantWithOrgMapping)(tenantArg);
|
|
29
|
+
const result = await (0, import_farseerFactory.getFarseerClientWithFallback)(organisation, tenant);
|
|
30
|
+
if (!result) {
|
|
31
|
+
(0, import_farseerFactory.showLoginPrompt)(tenant);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
const api = result.client;
|
|
35
|
+
try {
|
|
36
|
+
const model = await api.exportModel();
|
|
37
|
+
if (options.json) {
|
|
38
|
+
console.log(JSON.stringify(model, null, 2));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (options.variable) {
|
|
42
|
+
const variable = model.variables.find(
|
|
43
|
+
(v) => v.name.toLowerCase() === options.variable.toLowerCase()
|
|
44
|
+
);
|
|
45
|
+
if (!variable) {
|
|
46
|
+
import_logger.logger.error(`Variable "${options.variable}" not found.`);
|
|
47
|
+
import_logger.logger.dim("Available variables:");
|
|
48
|
+
model.variables.slice(0, 10).forEach((v) => import_logger.logger.dim(` - ${v.name}`));
|
|
49
|
+
if (model.variables.length > 10) {
|
|
50
|
+
import_logger.logger.dim(` ... and ${model.variables.length - 10} more`);
|
|
51
|
+
}
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
import_logger.logger.header(`Variable: ${variable.name}`);
|
|
55
|
+
console.log();
|
|
56
|
+
if (variable.description) {
|
|
57
|
+
console.log(` Description: ${variable.description}`);
|
|
58
|
+
}
|
|
59
|
+
if (variable.formula) {
|
|
60
|
+
console.log(` Formula: ${variable.formula}`);
|
|
61
|
+
}
|
|
62
|
+
console.log(` Dimensions: ${variable.tables.join(", ")}`);
|
|
63
|
+
if (variable.members.length > 0) {
|
|
64
|
+
console.log(` Specific members: ${variable.members.join(", ")}`);
|
|
65
|
+
}
|
|
66
|
+
console.log(` Roll-up type: ${variable.rollupType}`);
|
|
67
|
+
console.log(` Data type: ${variable.dataType}`);
|
|
68
|
+
if (variable.numberFormat) {
|
|
69
|
+
console.log(` Format: ${variable.numberFormat.type}${variable.numberFormat.formatString ? ` (${variable.numberFormat.formatString})` : ""}`);
|
|
70
|
+
}
|
|
71
|
+
console.log(` Readonly: ${variable.readonly}`);
|
|
72
|
+
console.log(` Calculate on demand: ${variable.calculateOnDemand}`);
|
|
73
|
+
if (variable.folderPath) {
|
|
74
|
+
console.log(` Folder: ${variable.folderPath.join(" / ")}`);
|
|
75
|
+
}
|
|
76
|
+
if (variable.cells && variable.cells.length > 0) {
|
|
77
|
+
console.log(` Cells with data: ${variable.cells.length}`);
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (options.table) {
|
|
82
|
+
const table = model.tables.find(
|
|
83
|
+
(t) => t.name.toLowerCase() === options.table.toLowerCase()
|
|
84
|
+
);
|
|
85
|
+
if (!table) {
|
|
86
|
+
import_logger.logger.error(`Table "${options.table}" not found.`);
|
|
87
|
+
import_logger.logger.dim("Available tables:");
|
|
88
|
+
model.tables.slice(0, 10).forEach((t) => import_logger.logger.dim(` - ${t.name}`));
|
|
89
|
+
if (model.tables.length > 10) {
|
|
90
|
+
import_logger.logger.dim(` ... and ${model.tables.length - 10} more`);
|
|
91
|
+
}
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
import_logger.logger.header(`Dimension Table: ${table.name}`);
|
|
95
|
+
console.log();
|
|
96
|
+
console.log(` Columns:`);
|
|
97
|
+
table.columns.forEach((col, i) => {
|
|
98
|
+
let colInfo = ` ${i + 1}. ${col.type}`;
|
|
99
|
+
if (col.name) colInfo += ` (${col.name})`;
|
|
100
|
+
if (col.foreignKeyTableName) colInfo += ` \u2192 ${col.foreignKeyTableName}`;
|
|
101
|
+
console.log(colInfo);
|
|
102
|
+
});
|
|
103
|
+
console.log(` Members: ${table.rows.length}`);
|
|
104
|
+
if (table.folderPath) {
|
|
105
|
+
console.log(` Folder: ${table.folderPath.join(" / ")}`);
|
|
106
|
+
}
|
|
107
|
+
if (table.rows.length > 0) {
|
|
108
|
+
console.log(` Sample members:`);
|
|
109
|
+
table.rows.slice(0, 5).forEach((row) => {
|
|
110
|
+
console.log(` - ${row[0]}`);
|
|
111
|
+
});
|
|
112
|
+
if (table.rows.length > 5) {
|
|
113
|
+
console.log(` ... and ${table.rows.length - 5} more`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (options.tables) {
|
|
119
|
+
import_logger.logger.header(`Dimension Tables (${model.tables.length})`);
|
|
120
|
+
console.log();
|
|
121
|
+
for (const table of model.tables) {
|
|
122
|
+
const fkColumns = table.columns.filter((c) => c.type === "FOREIGN_KEY");
|
|
123
|
+
let info = ` \u{1F4CB} ${table.name} (${table.rows.length} members)`;
|
|
124
|
+
if (fkColumns.length > 0) {
|
|
125
|
+
info += ` \u2192 ${fkColumns.map((c) => c.foreignKeyTableName).join(", ")}`;
|
|
126
|
+
}
|
|
127
|
+
console.log(info);
|
|
128
|
+
}
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (options.variables) {
|
|
132
|
+
import_logger.logger.header(`Variables (${model.variables.length})`);
|
|
133
|
+
console.log();
|
|
134
|
+
for (const variable of model.variables) {
|
|
135
|
+
console.log(` \u{1F4CA} ${variable.name}`);
|
|
136
|
+
console.log(` Dimensions: ${variable.tables.join(", ")}`);
|
|
137
|
+
if (variable.formula) {
|
|
138
|
+
console.log(` Formula: ${variable.formula.substring(0, 50)}${variable.formula.length > 50 ? "..." : ""}`);
|
|
139
|
+
}
|
|
140
|
+
console.log();
|
|
141
|
+
}
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
import_logger.logger.header(`Model Summary for ${tenant}`);
|
|
145
|
+
console.log();
|
|
146
|
+
console.log(` Dimension Tables: ${model.tables.length}`);
|
|
147
|
+
console.log(` Variables: ${model.variables.length}`);
|
|
148
|
+
console.log();
|
|
149
|
+
import_logger.logger.dim("Dimension Tables:");
|
|
150
|
+
model.tables.slice(0, 10).forEach((t) => {
|
|
151
|
+
import_logger.logger.dim(` - ${t.name} (${t.rows.length} members)`);
|
|
152
|
+
});
|
|
153
|
+
if (model.tables.length > 10) {
|
|
154
|
+
import_logger.logger.dim(` ... and ${model.tables.length - 10} more`);
|
|
155
|
+
}
|
|
156
|
+
console.log();
|
|
157
|
+
import_logger.logger.dim("Variables (first 10):");
|
|
158
|
+
model.variables.slice(0, 10).forEach((v) => {
|
|
159
|
+
import_logger.logger.dim(` - ${v.name} [${v.tables.join(", ")}]`);
|
|
160
|
+
});
|
|
161
|
+
if (model.variables.length > 10) {
|
|
162
|
+
import_logger.logger.dim(` ... and ${model.variables.length - 10} more`);
|
|
163
|
+
}
|
|
164
|
+
console.log();
|
|
165
|
+
import_logger.logger.dim("Use --tables, --variables, --table <name>, or --variable <name> for details.");
|
|
166
|
+
import_logger.logger.dim("Use --json for raw JSON output.");
|
|
167
|
+
} catch (error) {
|
|
168
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
169
|
+
if ((0, import_farseerFactory.isAuthError)(error)) {
|
|
170
|
+
(0, import_farseerFactory.showLoginPrompt)(tenant);
|
|
171
|
+
} else if (errorMessage.includes("404")) {
|
|
172
|
+
import_logger.logger.error(`Tenant "${tenant}" not found or not accessible.`);
|
|
173
|
+
import_logger.logger.dim("Check that the tenant name is correct.");
|
|
174
|
+
} else if (errorMessage.includes("ENOTFOUND") || errorMessage.includes("ECONNREFUSED")) {
|
|
175
|
+
import_logger.logger.error("Failed to connect to Farseer.");
|
|
176
|
+
import_logger.logger.dim("Check your network connection.");
|
|
177
|
+
} else {
|
|
178
|
+
import_logger.logger.error("Failed to export model.");
|
|
179
|
+
import_logger.logger.dim(errorMessage);
|
|
180
|
+
}
|
|
181
|
+
process.exit(1);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
186
|
+
0 && (module.exports = {
|
|
187
|
+
registerModelCommand
|
|
188
|
+
});
|
|
189
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/commands/model.ts"],
|
|
4
|
+
"sourcesContent": ["import { Command } from 'commander';\nimport { logger } from '../utils/logger';\nimport { getFarseerClientWithFallback, showLoginPrompt, isAuthError } from '../services/farseerFactory';\nimport { resolveTenantWithOrgMapping } from '../utils/helpers';\n\nexport function registerModelCommand(program: Command): void {\n program\n .command('model [tenant]')\n .description('Export and display the model structure (dimensions, variables)')\n .option('--json', 'Output raw JSON')\n .option('--tables', 'Show only dimension tables')\n .option('--variables', 'Show only variables')\n .option('--variable <name>', 'Show details for specific variable')\n .option('--table <name>', 'Show details for specific dimension table')\n .action(async (tenantArg, options) => {\n const { organisation, tenant } = resolveTenantWithOrgMapping(tenantArg);\n const result = await getFarseerClientWithFallback(organisation, tenant);\n\n if (!result) {\n showLoginPrompt(tenant);\n process.exit(1);\n }\n\n const api = result.client;\n\n try {\n const model = await api.exportModel();\n\n // Raw JSON output\n if (options.json) {\n console.log(JSON.stringify(model, null, 2));\n return;\n }\n\n // Specific variable details\n if (options.variable) {\n const variable = model.variables.find(\n v => v.name.toLowerCase() === options.variable.toLowerCase()\n );\n if (!variable) {\n logger.error(`Variable \"${options.variable}\" not found.`);\n logger.dim('Available variables:');\n model.variables.slice(0, 10).forEach(v => logger.dim(` - ${v.name}`));\n if (model.variables.length > 10) {\n logger.dim(` ... and ${model.variables.length - 10} more`);\n }\n process.exit(1);\n }\n\n logger.header(`Variable: ${variable.name}`);\n console.log();\n if (variable.description) {\n console.log(` Description: ${variable.description}`);\n }\n if (variable.formula) {\n console.log(` Formula: ${variable.formula}`);\n }\n console.log(` Dimensions: ${variable.tables.join(', ')}`);\n if (variable.members.length > 0) {\n console.log(` Specific members: ${variable.members.join(', ')}`);\n }\n console.log(` Roll-up type: ${variable.rollupType}`);\n console.log(` Data type: ${variable.dataType}`);\n if (variable.numberFormat) {\n console.log(` Format: ${variable.numberFormat.type}${variable.numberFormat.formatString ? ` (${variable.numberFormat.formatString})` : ''}`);\n }\n console.log(` Readonly: ${variable.readonly}`);\n console.log(` Calculate on demand: ${variable.calculateOnDemand}`);\n if (variable.folderPath) {\n console.log(` Folder: ${variable.folderPath.join(' / ')}`);\n }\n if (variable.cells && variable.cells.length > 0) {\n console.log(` Cells with data: ${variable.cells.length}`);\n }\n return;\n }\n\n // Specific table details\n if (options.table) {\n const table = model.tables.find(\n t => t.name.toLowerCase() === options.table.toLowerCase()\n );\n if (!table) {\n logger.error(`Table \"${options.table}\" not found.`);\n logger.dim('Available tables:');\n model.tables.slice(0, 10).forEach(t => logger.dim(` - ${t.name}`));\n if (model.tables.length > 10) {\n logger.dim(` ... and ${model.tables.length - 10} more`);\n }\n process.exit(1);\n }\n\n logger.header(`Dimension Table: ${table.name}`);\n console.log();\n console.log(` Columns:`);\n table.columns.forEach((col, i) => {\n let colInfo = ` ${i + 1}. ${col.type}`;\n if (col.name) colInfo += ` (${col.name})`;\n if (col.foreignKeyTableName) colInfo += ` \u2192 ${col.foreignKeyTableName}`;\n console.log(colInfo);\n });\n console.log(` Members: ${table.rows.length}`);\n if (table.folderPath) {\n console.log(` Folder: ${table.folderPath.join(' / ')}`);\n }\n if (table.rows.length > 0) {\n console.log(` Sample members:`);\n table.rows.slice(0, 5).forEach(row => {\n console.log(` - ${row[0]}`);\n });\n if (table.rows.length > 5) {\n console.log(` ... and ${table.rows.length - 5} more`);\n }\n }\n return;\n }\n\n // Tables only\n if (options.tables) {\n logger.header(`Dimension Tables (${model.tables.length})`);\n console.log();\n for (const table of model.tables) {\n const fkColumns = table.columns.filter(c => c.type === 'FOREIGN_KEY');\n let info = ` \uD83D\uDCCB ${table.name} (${table.rows.length} members)`;\n if (fkColumns.length > 0) {\n info += ` \u2192 ${fkColumns.map(c => c.foreignKeyTableName).join(', ')}`;\n }\n console.log(info);\n }\n return;\n }\n\n // Variables only\n if (options.variables) {\n logger.header(`Variables (${model.variables.length})`);\n console.log();\n for (const variable of model.variables) {\n console.log(` \uD83D\uDCCA ${variable.name}`);\n console.log(` Dimensions: ${variable.tables.join(', ')}`);\n if (variable.formula) {\n console.log(` Formula: ${variable.formula.substring(0, 50)}${variable.formula.length > 50 ? '...' : ''}`);\n }\n console.log();\n }\n return;\n }\n\n // Default: summary\n logger.header(`Model Summary for ${tenant}`);\n console.log();\n console.log(` Dimension Tables: ${model.tables.length}`);\n console.log(` Variables: ${model.variables.length}`);\n console.log();\n\n logger.dim('Dimension Tables:');\n model.tables.slice(0, 10).forEach(t => {\n logger.dim(` - ${t.name} (${t.rows.length} members)`);\n });\n if (model.tables.length > 10) {\n logger.dim(` ... and ${model.tables.length - 10} more`);\n }\n console.log();\n\n logger.dim('Variables (first 10):');\n model.variables.slice(0, 10).forEach(v => {\n logger.dim(` - ${v.name} [${v.tables.join(', ')}]`);\n });\n if (model.variables.length > 10) {\n logger.dim(` ... and ${model.variables.length - 10} more`);\n }\n console.log();\n\n logger.dim('Use --tables, --variables, --table <name>, or --variable <name> for details.');\n logger.dim('Use --json for raw JSON output.');\n\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (isAuthError(error)) {\n showLoginPrompt(tenant);\n } else if (errorMessage.includes('404')) {\n logger.error(`Tenant \"${tenant}\" not found or not accessible.`);\n logger.dim('Check that the tenant name is correct.');\n } else if (errorMessage.includes('ENOTFOUND') || errorMessage.includes('ECONNREFUSED')) {\n logger.error('Failed to connect to Farseer.');\n logger.dim('Check your network connection.');\n } else {\n logger.error('Failed to export model.');\n logger.dim(errorMessage);\n }\n process.exit(1);\n }\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var pull_exports = {};
|
|
29
|
+
__export(pull_exports, {
|
|
30
|
+
registerPullCommand: () => registerPullCommand
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(pull_exports);
|
|
33
|
+
var import_chalk = __toESM(require("chalk"));
|
|
34
|
+
var import_logger = require("../utils/logger");
|
|
35
|
+
var import_farseerFactory = require("../services/farseerFactory");
|
|
36
|
+
var import_syncService = require("../services/syncService");
|
|
37
|
+
var import_appSyncService = require("../services/appSyncService");
|
|
38
|
+
var import_gitService = require("../services/gitService");
|
|
39
|
+
var import_helpers = require("../utils/helpers");
|
|
40
|
+
var import_constants = require("../utils/constants");
|
|
41
|
+
function registerPullCommand(program) {
|
|
42
|
+
program.command("pull [arg1] [arg2]").description("Pull files from Farseer instance to local\n\nUsage: pull <org> <tenant> OR pull <tenant> (if org is known)").option("--git", "Enable git operations (commit & push) - internal use only").option("--all", "Pull all files (default: only scripts .ts, .js)").action(async (arg1, arg2, options) => {
|
|
43
|
+
const { organisation, tenant } = (0, import_helpers.resolveTenantWithOrgMapping)(arg1, arg2);
|
|
44
|
+
const clientResult = await (0, import_farseerFactory.getFarseerClientWithFallback)(organisation, tenant);
|
|
45
|
+
if (!clientResult) {
|
|
46
|
+
(0, import_farseerFactory.showLoginPrompt)(tenant);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
const gitService = new import_gitService.GitService();
|
|
50
|
+
const syncService = new import_syncService.SyncService(tenant, clientResult.client);
|
|
51
|
+
const inRemotejobsRepo = (0, import_helpers.isInRemotejobsRepo)();
|
|
52
|
+
const gitEnabled = options.git === true && inRemotejobsRepo && !process.env.FARSEER_NO_GIT;
|
|
53
|
+
if (options.git === true && !inRemotejobsRepo) {
|
|
54
|
+
import_logger.logger.error("Git operations are only available in remotejobs repository.");
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
if (gitEnabled) {
|
|
58
|
+
import_logger.logger.info("Pulling latest changes from git...");
|
|
59
|
+
const gitPullResult = await gitService.pull();
|
|
60
|
+
if (!gitPullResult.success) {
|
|
61
|
+
import_logger.logger.error("Git pull failed.");
|
|
62
|
+
import_logger.logger.dim(gitPullResult.message);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
import_logger.logger.dim(gitPullResult.message);
|
|
66
|
+
}
|
|
67
|
+
const tenantDir = (0, import_helpers.getTenantDir)(tenant);
|
|
68
|
+
(0, import_helpers.ensureDirectoryExists)(tenantDir);
|
|
69
|
+
await createDefaultPackageJson(tenantDir, tenant);
|
|
70
|
+
console.log();
|
|
71
|
+
console.log(import_chalk.default.bold("\u2550\u2550\u2550 Files \u2550\u2550\u2550"));
|
|
72
|
+
import_logger.logger.info(`Pulling files from ${tenant}...`);
|
|
73
|
+
try {
|
|
74
|
+
const result = await syncService.pull({ all: options.all });
|
|
75
|
+
if (result.downloaded.length > 0) {
|
|
76
|
+
console.log(import_chalk.default.green("Downloaded:"));
|
|
77
|
+
for (const file of result.downloaded) {
|
|
78
|
+
console.log(import_chalk.default.green(` + ${file}`));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (result.deleted.length > 0) {
|
|
82
|
+
console.log(import_chalk.default.red("Deleted (removed from remote):"));
|
|
83
|
+
for (const file of result.deleted) {
|
|
84
|
+
console.log(import_chalk.default.red(` - ${file}`));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
import_logger.logger.dim(`Files: +${result.downloaded.length} -${result.deleted.length} (${result.unchanged.length} unchanged)`);
|
|
88
|
+
if (result.downloaded.length > 0) {
|
|
89
|
+
const syncState = syncService.loadSyncState();
|
|
90
|
+
const auditEntries = result.downloaded.map((filePath) => ({
|
|
91
|
+
operation: "pulled",
|
|
92
|
+
filePath,
|
|
93
|
+
uploadTime: syncState.files[filePath]?.metadata?.uploadTime,
|
|
94
|
+
uploaderEmail: syncState.files[filePath]?.metadata?.uploaderEmail,
|
|
95
|
+
uploaderName: syncState.files[filePath]?.metadata?.uploaderName
|
|
96
|
+
}));
|
|
97
|
+
(0, import_helpers.appendToAuditLog)(tenant, auditEntries);
|
|
98
|
+
}
|
|
99
|
+
let hasChanges = result.downloaded.length > 0 || result.deleted.length > 0;
|
|
100
|
+
let appResult = { created: [], updated: [], deleted: [], unchanged: [] };
|
|
101
|
+
console.log();
|
|
102
|
+
console.log(import_chalk.default.bold("\u2550\u2550\u2550 Apps \u2550\u2550\u2550"));
|
|
103
|
+
import_logger.logger.info(`Pulling apps from ${tenant}...`);
|
|
104
|
+
const appSyncService = new import_appSyncService.AppSyncService(tenant, clientResult.client);
|
|
105
|
+
appResult = await appSyncService.pull();
|
|
106
|
+
if (appResult.created.length > 0) {
|
|
107
|
+
console.log(import_chalk.default.green("New apps:"));
|
|
108
|
+
for (const app of appResult.created) {
|
|
109
|
+
console.log(import_chalk.default.green(` + ${app}`));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (appResult.updated.length > 0) {
|
|
113
|
+
console.log(import_chalk.default.yellow("Updated apps:"));
|
|
114
|
+
for (const app of appResult.updated) {
|
|
115
|
+
console.log(import_chalk.default.yellow(` ~ ${app}`));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (appResult.deleted.length > 0) {
|
|
119
|
+
console.log(import_chalk.default.red("Deleted apps (removed from remote):"));
|
|
120
|
+
for (const app of appResult.deleted) {
|
|
121
|
+
console.log(import_chalk.default.red(` - ${app}`));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
import_logger.logger.dim(`Apps: +${appResult.created.length} ~${appResult.updated.length} -${appResult.deleted.length} (${appResult.unchanged.length} unchanged)`);
|
|
125
|
+
hasChanges = hasChanges || appResult.created.length > 0 || appResult.updated.length > 0 || appResult.deleted.length > 0;
|
|
126
|
+
if (gitEnabled) {
|
|
127
|
+
const appsPath = `apps/${tenant}`;
|
|
128
|
+
const gitStatus = await gitService.status();
|
|
129
|
+
const hasUncommittedChanges = gitStatus.modified.some((f) => f.startsWith(appsPath)) || gitStatus.added.some((f) => f.startsWith(appsPath)) || gitStatus.deleted.some((f) => f.startsWith(appsPath)) || gitStatus.untracked.some((f) => f.startsWith(appsPath));
|
|
130
|
+
if (hasChanges || hasUncommittedChanges) {
|
|
131
|
+
import_logger.logger.info("Committing changes to git...");
|
|
132
|
+
await gitService.add([appsPath]);
|
|
133
|
+
const syncState = syncService.loadSyncState();
|
|
134
|
+
let commitMessage = `Sync with remote ${tenant}
|
|
135
|
+
|
|
136
|
+
`;
|
|
137
|
+
if (result.downloaded.length > 0) {
|
|
138
|
+
commitMessage += "Modified files:\n";
|
|
139
|
+
for (const file of result.downloaded) {
|
|
140
|
+
const metadata = syncState.files[file]?.metadata;
|
|
141
|
+
const author = metadata?.uploaderName || metadata?.uploaderEmail || "Unknown";
|
|
142
|
+
commitMessage += `- ${file} (${author})
|
|
143
|
+
`;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (result.deleted.length > 0) {
|
|
147
|
+
commitMessage += "\nDeleted files:\n";
|
|
148
|
+
result.deleted.forEach((f) => commitMessage += `- ${f}
|
|
149
|
+
`);
|
|
150
|
+
}
|
|
151
|
+
if (appResult.created.length > 0 || appResult.updated.length > 0) {
|
|
152
|
+
commitMessage += "\nModified apps:\n";
|
|
153
|
+
appResult.created.forEach((a) => commitMessage += `- ${a} (new)
|
|
154
|
+
`);
|
|
155
|
+
appResult.updated.forEach((a) => commitMessage += `- ${a} (updated)
|
|
156
|
+
`);
|
|
157
|
+
}
|
|
158
|
+
if (appResult.deleted.length > 0) {
|
|
159
|
+
commitMessage += "\nDeleted apps:\n";
|
|
160
|
+
appResult.deleted.forEach((a) => commitMessage += `- ${a}
|
|
161
|
+
`);
|
|
162
|
+
}
|
|
163
|
+
const commitResult = await gitService.commit(commitMessage, import_constants.CLI_GIT_AUTHOR);
|
|
164
|
+
if (commitResult.success) {
|
|
165
|
+
import_logger.logger.dim(`Committed: ${commitResult.commitHash}`);
|
|
166
|
+
import_logger.logger.info("Pushing to remote...");
|
|
167
|
+
const pushResult = await gitService.push();
|
|
168
|
+
if (pushResult.success) {
|
|
169
|
+
import_logger.logger.dim(pushResult.message);
|
|
170
|
+
} else {
|
|
171
|
+
import_logger.logger.warning("Failed to push to remote.");
|
|
172
|
+
import_logger.logger.dim(pushResult.message);
|
|
173
|
+
import_logger.logger.dim("You may need to push manually.");
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
import_logger.logger.warning("Nothing to commit.");
|
|
177
|
+
}
|
|
178
|
+
} else {
|
|
179
|
+
import_logger.logger.success("Already up to date (no changes to commit).");
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
} else if (!hasChanges) {
|
|
183
|
+
import_logger.logger.success("Already up to date.");
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
console.log();
|
|
187
|
+
console.log(import_chalk.default.bold("\u2550\u2550\u2550 Summary \u2550\u2550\u2550"));
|
|
188
|
+
import_logger.logger.success("Pull complete!");
|
|
189
|
+
import_logger.logger.dim(`Files: +${result.downloaded.length} -${result.deleted.length} (${result.unchanged.length} unchanged)`);
|
|
190
|
+
import_logger.logger.dim(`Apps: +${appResult.created.length} ~${appResult.updated.length} -${appResult.deleted.length} (${appResult.unchanged.length} unchanged)`);
|
|
191
|
+
} catch (error) {
|
|
192
|
+
import_logger.logger.error("Pull failed.");
|
|
193
|
+
if (error instanceof Error) {
|
|
194
|
+
import_logger.logger.dim(error.message);
|
|
195
|
+
}
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
async function createDefaultPackageJson(tenantDir, tenant) {
|
|
201
|
+
const fs = await import("fs");
|
|
202
|
+
const path = await import("path");
|
|
203
|
+
const packageJsonPath = path.join(tenantDir, "package.json");
|
|
204
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const packageJson = {
|
|
208
|
+
name: `farseer-scripts-${tenant}`,
|
|
209
|
+
version: "1.0.0",
|
|
210
|
+
description: `Farseer App scripts for ${tenant}`,
|
|
211
|
+
main: "src/index.ts",
|
|
212
|
+
scripts: {},
|
|
213
|
+
keywords: ["farseer", "scripts", tenant],
|
|
214
|
+
author: "Farseer",
|
|
215
|
+
license: "ISC",
|
|
216
|
+
dependencies: {
|
|
217
|
+
"@google-cloud/bigquery": "^7.9.0",
|
|
218
|
+
"@google-cloud/storage": "^7.12.1",
|
|
219
|
+
"@googleapis/sheets": "^5.0.5",
|
|
220
|
+
"@sendgrid/mail": "^7.7.0",
|
|
221
|
+
"@types/node-forge": "^1.3.11",
|
|
222
|
+
"@xmldom/xmldom": "^0.9.8",
|
|
223
|
+
"arquero": "^5.4.1",
|
|
224
|
+
"axios": "^1.10.0",
|
|
225
|
+
"axios-retry": "^3.9.1",
|
|
226
|
+
"basic-ftp": "^5.0.5",
|
|
227
|
+
"client-oauth2": "^4.3.3",
|
|
228
|
+
"csv-parser": "^3.0.0",
|
|
229
|
+
"dotenv": "^16.4.5",
|
|
230
|
+
"draft-js": "^0.11.7",
|
|
231
|
+
"exceljs": "^4.4.0",
|
|
232
|
+
"farseer-client": "https://storage.googleapis.com/farseer-remote-jobs-results/farseer-client/release-1.4.5.tar",
|
|
233
|
+
"farseer-client-axios": "https://storage.googleapis.com/farseer-remote-jobs-results/farseer-client-axios/6898c0cb-5dca-4b2f-b325-119efc7f099e/v1.0.1.tar",
|
|
234
|
+
"fast-xml-parser": "^4.5.0",
|
|
235
|
+
"form-data": "^4.0.0",
|
|
236
|
+
"googleapis": "^144.0.0",
|
|
237
|
+
"heapdump": "^0.3.15",
|
|
238
|
+
"image-size": "^1.1.1",
|
|
239
|
+
"jszip": "^3.10.1",
|
|
240
|
+
"lossless-json": "^4.0.1",
|
|
241
|
+
"mssql": "^10.0.4",
|
|
242
|
+
"node-fetch": "^2.7.0",
|
|
243
|
+
"node-forge": "^1.3.1",
|
|
244
|
+
"node-sp-auth": "^3.0.8",
|
|
245
|
+
"numeral": "^2.0.6",
|
|
246
|
+
"oracledb": "^6.6.0",
|
|
247
|
+
"papaparse": "^5.5.1",
|
|
248
|
+
"pdfkit": "^0.14.0",
|
|
249
|
+
"pdfmake": "^0.2.20",
|
|
250
|
+
"soap": "^1.1.11",
|
|
251
|
+
"ssh2-sftp-client": "^11.0.0",
|
|
252
|
+
"strong-soap": "^4.1.13",
|
|
253
|
+
"ts-node": "^10.9.2",
|
|
254
|
+
"typescript": "^5.5.4",
|
|
255
|
+
"undici": "^6.19.8",
|
|
256
|
+
"uuid": "^11.1.0",
|
|
257
|
+
"winston": "^3.17.0",
|
|
258
|
+
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
|
|
259
|
+
"xml-crypto": "^6.1.2"
|
|
260
|
+
},
|
|
261
|
+
devDependencies: {
|
|
262
|
+
"@types/draft-js": "^0.11.18",
|
|
263
|
+
"@types/heapdump": "^0.3.4",
|
|
264
|
+
"@types/mssql": "^9.1.5",
|
|
265
|
+
"@types/node": "^18.19.50",
|
|
266
|
+
"@types/node-fetch": "^2.6.11",
|
|
267
|
+
"@types/numeral": "^2.0.5",
|
|
268
|
+
"@types/oracledb": "^6.5.3",
|
|
269
|
+
"@types/papaparse": "^5.3.15",
|
|
270
|
+
"@types/pdfmake": "^0.2.11",
|
|
271
|
+
"@types/soap": "^0.18.0",
|
|
272
|
+
"@types/ssh2-sftp-client": "^9.0.4",
|
|
273
|
+
"@types/tough-cookie": "^4.0.5",
|
|
274
|
+
"@types/uuid": "^10.0.0",
|
|
275
|
+
"@types/xmldom": "^0.1.34",
|
|
276
|
+
"ts-node": "^10.9.2",
|
|
277
|
+
"typescript": "^5.5.4"
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf-8");
|
|
281
|
+
import_logger.logger.dim(`Created package.json for ${tenant}`);
|
|
282
|
+
}
|
|
283
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
284
|
+
0 && (module.exports = {
|
|
285
|
+
registerPullCommand
|
|
286
|
+
});
|
|
287
|
+
//# sourceMappingURL=pull.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/commands/pull.ts"],
|
|
4
|
+
"sourcesContent": ["import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { logger } from '../utils/logger';\nimport { getFarseerClientWithFallback, showLoginPrompt } from '../services/farseerFactory';\nimport { SyncService } from '../services/syncService';\nimport { AppSyncService } from '../services/appSyncService';\nimport { GitService } from '../services/gitService';\nimport { getTenantDir, ensureDirectoryExists, resolveTenantWithOrgMapping, isInRemotejobsRepo, appendToAuditLog, AuditLogEntry } from '../utils/helpers';\nimport { CLI_GIT_AUTHOR } from '../utils/constants';\n\nexport function registerPullCommand(program: Command): void {\n program\n .command('pull [arg1] [arg2]')\n .description('Pull files from Farseer instance to local\\n\\nUsage: pull <org> <tenant> OR pull <tenant> (if org is known)')\n .option('--git', 'Enable git operations (commit & push) - internal use only')\n .option('--all', 'Pull all files (default: only scripts .ts, .js)')\n .action(async (arg1, arg2, options) => {\n const { organisation, tenant } = resolveTenantWithOrgMapping(arg1, arg2);\n const clientResult = await getFarseerClientWithFallback(organisation, tenant);\n\n if (!clientResult) {\n showLoginPrompt(tenant);\n process.exit(1);\n }\n\n const gitService = new GitService();\n const syncService = new SyncService(tenant, clientResult.client);\n\n // Git operations are opt-in with --git flag (internal developer feature)\n const inRemotejobsRepo = isInRemotejobsRepo();\n\n // Git enabled ONLY if:\n // 1. User explicitly requested it (--git flag)\n // 2. We're in remotejobs repo (safety check)\n // 3. FARSEER_NO_GIT env var is not set\n const gitEnabled = options.git === true && inRemotejobsRepo && !process.env.FARSEER_NO_GIT;\n\n // Show error if --git requested but not in remotejobs repo\n if (options.git === true && !inRemotejobsRepo) {\n logger.error('Git operations are only available in remotejobs repository.');\n process.exit(1);\n }\n\n // Step 1: Git pull\n if (gitEnabled) {\n logger.info('Pulling latest changes from git...');\n const gitPullResult = await gitService.pull();\n\n if (!gitPullResult.success) {\n logger.error('Git pull failed.');\n logger.dim(gitPullResult.message);\n process.exit(1);\n }\n\n logger.dim(gitPullResult.message);\n }\n\n // Step 2: Ensure tenant folder exists\n const tenantDir = getTenantDir(tenant);\n ensureDirectoryExists(tenantDir);\n\n // Create default package.json if it doesn't exist\n await createDefaultPackageJson(tenantDir, tenant);\n\n // Step 3: Pull files from Farseer\n console.log();\n console.log(chalk.bold('\u2550\u2550\u2550 Files \u2550\u2550\u2550'));\n logger.info(`Pulling files from ${tenant}...`);\n\n try {\n const result = await syncService.pull({ all: options.all });\n\n if (result.downloaded.length > 0) {\n console.log(chalk.green('Downloaded:'));\n for (const file of result.downloaded) {\n console.log(chalk.green(` + ${file}`));\n }\n }\n\n if (result.deleted.length > 0) {\n console.log(chalk.red('Deleted (removed from remote):'));\n for (const file of result.deleted) {\n console.log(chalk.red(` - ${file}`));\n }\n }\n\n logger.dim(`Files: +${result.downloaded.length} -${result.deleted.length} (${result.unchanged.length} unchanged)`);\n\n // Create audit log entries for downloaded files\n if (result.downloaded.length > 0) {\n const syncState = syncService.loadSyncState();\n const auditEntries: AuditLogEntry[] = result.downloaded.map(filePath => ({\n operation: 'pulled' as const,\n filePath,\n uploadTime: syncState.files[filePath]?.metadata?.uploadTime,\n uploaderEmail: syncState.files[filePath]?.metadata?.uploaderEmail,\n uploaderName: syncState.files[filePath]?.metadata?.uploaderName,\n }));\n\n appendToAuditLog(tenant, auditEntries);\n }\n\n let hasChanges = result.downloaded.length > 0 || result.deleted.length > 0;\n\n // Step 4: Pull apps (works with both JWT and API key)\n let appResult = { created: [] as string[], updated: [] as string[], deleted: [] as string[], unchanged: [] as string[] };\n\n console.log();\n console.log(chalk.bold('\u2550\u2550\u2550 Apps \u2550\u2550\u2550'));\n logger.info(`Pulling apps from ${tenant}...`);\n\n const appSyncService = new AppSyncService(tenant, clientResult.client);\n appResult = await appSyncService.pull();\n\n if (appResult.created.length > 0) {\n console.log(chalk.green('New apps:'));\n for (const app of appResult.created) {\n console.log(chalk.green(` + ${app}`));\n }\n }\n\n if (appResult.updated.length > 0) {\n console.log(chalk.yellow('Updated apps:'));\n for (const app of appResult.updated) {\n console.log(chalk.yellow(` ~ ${app}`));\n }\n }\n\n if (appResult.deleted.length > 0) {\n console.log(chalk.red('Deleted apps (removed from remote):'));\n for (const app of appResult.deleted) {\n console.log(chalk.red(` - ${app}`));\n }\n }\n\n logger.dim(`Apps: +${appResult.created.length} ~${appResult.updated.length} -${appResult.deleted.length} (${appResult.unchanged.length} unchanged)`);\n\n hasChanges = hasChanges || appResult.created.length > 0 || appResult.updated.length > 0 || appResult.deleted.length > 0;\n\n // Step 5: Git commit & push\n if (gitEnabled) {\n const appsPath = `apps/${tenant}`;\n\n // Check for any uncommitted changes (including from previous pulls without --git)\n const gitStatus = await gitService.status();\n const hasUncommittedChanges =\n gitStatus.modified.some(f => f.startsWith(appsPath)) ||\n gitStatus.added.some(f => f.startsWith(appsPath)) ||\n gitStatus.deleted.some(f => f.startsWith(appsPath)) ||\n gitStatus.untracked.some(f => f.startsWith(appsPath));\n\n if (hasChanges || hasUncommittedChanges) {\n logger.info('Committing changes to git...');\n\n await gitService.add([appsPath]);\n\n // Build detailed commit message with metadata\n const syncState = syncService.loadSyncState();\n let commitMessage = `Sync with remote ${tenant}\\n\\n`;\n\n if (result.downloaded.length > 0) {\n commitMessage += 'Modified files:\\n';\n for (const file of result.downloaded) {\n const metadata = syncState.files[file]?.metadata;\n const author = metadata?.uploaderName || metadata?.uploaderEmail || 'Unknown';\n commitMessage += `- ${file} (${author})\\n`;\n }\n }\n\n if (result.deleted.length > 0) {\n commitMessage += '\\nDeleted files:\\n';\n result.deleted.forEach(f => commitMessage += `- ${f}\\n`);\n }\n\n if (appResult.created.length > 0 || appResult.updated.length > 0) {\n commitMessage += '\\nModified apps:\\n';\n appResult.created.forEach(a => commitMessage += `- ${a} (new)\\n`);\n appResult.updated.forEach(a => commitMessage += `- ${a} (updated)\\n`);\n }\n\n if (appResult.deleted.length > 0) {\n commitMessage += '\\nDeleted apps:\\n';\n appResult.deleted.forEach(a => commitMessage += `- ${a}\\n`);\n }\n\n const commitResult = await gitService.commit(commitMessage, CLI_GIT_AUTHOR);\n\n if (commitResult.success) {\n logger.dim(`Committed: ${commitResult.commitHash}`);\n\n logger.info('Pushing to remote...');\n const pushResult = await gitService.push();\n\n if (pushResult.success) {\n logger.dim(pushResult.message);\n } else {\n logger.warning('Failed to push to remote.');\n logger.dim(pushResult.message);\n logger.dim('You may need to push manually.');\n }\n } else {\n logger.warning('Nothing to commit.');\n }\n } else {\n logger.success('Already up to date (no changes to commit).');\n return;\n }\n } else if (!hasChanges) {\n logger.success('Already up to date.');\n return;\n }\n\n console.log();\n console.log(chalk.bold('\u2550\u2550\u2550 Summary \u2550\u2550\u2550'));\n logger.success('Pull complete!');\n logger.dim(`Files: +${result.downloaded.length} -${result.deleted.length} (${result.unchanged.length} unchanged)`);\n logger.dim(`Apps: +${appResult.created.length} ~${appResult.updated.length} -${appResult.deleted.length} (${appResult.unchanged.length} unchanged)`);\n } catch (error) {\n logger.error('Pull failed.');\n if (error instanceof Error) {\n logger.dim(error.message);\n }\n process.exit(1);\n }\n });\n}\n\nasync function createDefaultPackageJson(tenantDir: string, tenant: string): Promise<void> {\n const fs = await import('fs');\n const path = await import('path');\n\n const packageJsonPath = path.join(tenantDir, 'package.json');\n\n if (fs.existsSync(packageJsonPath)) {\n return;\n }\n\n const packageJson = {\n name: `farseer-scripts-${tenant}`,\n version: '1.0.0',\n description: `Farseer App scripts for ${tenant}`,\n main: 'src/index.ts',\n scripts: {},\n keywords: ['farseer', 'scripts', tenant],\n author: 'Farseer',\n license: 'ISC',\n dependencies: {\n '@google-cloud/bigquery': '^7.9.0',\n '@google-cloud/storage': '^7.12.1',\n '@googleapis/sheets': '^5.0.5',\n '@sendgrid/mail': '^7.7.0',\n '@types/node-forge': '^1.3.11',\n '@xmldom/xmldom': '^0.9.8',\n 'arquero': '^5.4.1',\n 'axios': '^1.10.0',\n 'axios-retry': '^3.9.1',\n 'basic-ftp': '^5.0.5',\n 'client-oauth2': '^4.3.3',\n 'csv-parser': '^3.0.0',\n 'dotenv': '^16.4.5',\n 'draft-js': '^0.11.7',\n 'exceljs': '^4.4.0',\n 'farseer-client': 'https://storage.googleapis.com/farseer-remote-jobs-results/farseer-client/release-1.4.5.tar',\n 'farseer-client-axios': 'https://storage.googleapis.com/farseer-remote-jobs-results/farseer-client-axios/6898c0cb-5dca-4b2f-b325-119efc7f099e/v1.0.1.tar',\n 'fast-xml-parser': '^4.5.0',\n 'form-data': '^4.0.0',\n 'googleapis': '^144.0.0',\n 'heapdump': '^0.3.15',\n 'image-size': '^1.1.1',\n 'jszip': '^3.10.1',\n 'lossless-json': '^4.0.1',\n 'mssql': '^10.0.4',\n 'node-fetch': '^2.7.0',\n 'node-forge': '^1.3.1',\n 'node-sp-auth': '^3.0.8',\n 'numeral': '^2.0.6',\n 'oracledb': '^6.6.0',\n 'papaparse': '^5.5.1',\n 'pdfkit': '^0.14.0',\n 'pdfmake': '^0.2.20',\n 'soap': '^1.1.11',\n 'ssh2-sftp-client': '^11.0.0',\n 'strong-soap': '^4.1.13',\n 'ts-node': '^10.9.2',\n 'typescript': '^5.5.4',\n 'undici': '^6.19.8',\n 'uuid': '^11.1.0',\n 'winston': '^3.17.0',\n 'xlsx': 'https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz',\n 'xml-crypto': '^6.1.2',\n },\n devDependencies: {\n '@types/draft-js': '^0.11.18',\n '@types/heapdump': '^0.3.4',\n '@types/mssql': '^9.1.5',\n '@types/node': '^18.19.50',\n '@types/node-fetch': '^2.6.11',\n '@types/numeral': '^2.0.5',\n '@types/oracledb': '^6.5.3',\n '@types/papaparse': '^5.3.15',\n '@types/pdfmake': '^0.2.11',\n '@types/soap': '^0.18.0',\n '@types/ssh2-sftp-client': '^9.0.4',\n '@types/tough-cookie': '^4.0.5',\n '@types/uuid': '^10.0.0',\n '@types/xmldom': '^0.1.34',\n 'ts-node': '^10.9.2',\n 'typescript': '^5.5.4',\n },\n };\n\n fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf-8');\n logger.dim(`Created package.json for ${tenant}`);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["chalk"]
|
|
7
|
+
}
|