@marcfargas/odoo-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.d.ts +27 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +152 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/accounting.d.ts +16 -0
- package/dist/commands/accounting.d.ts.map +1 -0
- package/dist/commands/accounting.js +363 -0
- package/dist/commands/accounting.js.map +1 -0
- package/dist/commands/attendance.d.ts +14 -0
- package/dist/commands/attendance.d.ts.map +1 -0
- package/dist/commands/attendance.js +339 -0
- package/dist/commands/attendance.js.map +1 -0
- package/dist/commands/config.d.ts +12 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +159 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/mail.d.ts +12 -0
- package/dist/commands/mail.d.ts.map +1 -0
- package/dist/commands/mail.js +236 -0
- package/dist/commands/mail.js.map +1 -0
- package/dist/commands/modules.d.ts +14 -0
- package/dist/commands/modules.d.ts.map +1 -0
- package/dist/commands/modules.js +351 -0
- package/dist/commands/modules.js.map +1 -0
- package/dist/commands/records.d.ts +15 -0
- package/dist/commands/records.d.ts.map +1 -0
- package/dist/commands/records.js +591 -0
- package/dist/commands/records.js.map +1 -0
- package/dist/commands/schema.d.ts +16 -0
- package/dist/commands/schema.d.ts.map +1 -0
- package/dist/commands/schema.js +381 -0
- package/dist/commands/schema.js.map +1 -0
- package/dist/commands/state.d.ts +14 -0
- package/dist/commands/state.d.ts.map +1 -0
- package/dist/commands/state.js +373 -0
- package/dist/commands/state.js.map +1 -0
- package/dist/commands/timesheets.d.ts +15 -0
- package/dist/commands/timesheets.d.ts.map +1 -0
- package/dist/commands/timesheets.js +453 -0
- package/dist/commands/timesheets.js.map +1 -0
- package/dist/commands/url.d.ts +12 -0
- package/dist/commands/url.d.ts.map +1 -0
- package/dist/commands/url.js +149 -0
- package/dist/commands/url.js.map +1 -0
- package/dist/help/extra-help.d.ts +18 -0
- package/dist/help/extra-help.d.ts.map +1 -0
- package/dist/help/extra-help.js +207 -0
- package/dist/help/extra-help.js.map +1 -0
- package/dist/middleware/auth.d.ts +29 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +68 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/common-params.d.ts +90 -0
- package/dist/middleware/common-params.d.ts.map +1 -0
- package/dist/middleware/common-params.js +169 -0
- package/dist/middleware/common-params.js.map +1 -0
- package/dist/middleware/safety.d.ts +30 -0
- package/dist/middleware/safety.d.ts.map +1 -0
- package/dist/middleware/safety.js +64 -0
- package/dist/middleware/safety.js.map +1 -0
- package/dist/output/errors.d.ts +69 -0
- package/dist/output/errors.d.ts.map +1 -0
- package/dist/output/errors.js +193 -0
- package/dist/output/errors.js.map +1 -0
- package/dist/output/formatter.d.ts +80 -0
- package/dist/output/formatter.d.ts.map +1 -0
- package/dist/output/formatter.js +285 -0
- package/dist/output/formatter.js.map +1 -0
- package/dist/output/stream-writer.d.ts +33 -0
- package/dist/output/stream-writer.d.ts.map +1 -0
- package/dist/output/stream-writer.js +74 -0
- package/dist/output/stream-writer.js.map +1 -0
- package/dist/parsing/domain-parser.d.ts +61 -0
- package/dist/parsing/domain-parser.d.ts.map +1 -0
- package/dist/parsing/domain-parser.js +427 -0
- package/dist/parsing/domain-parser.js.map +1 -0
- package/dist/parsing/json-arg.d.ts +48 -0
- package/dist/parsing/json-arg.d.ts.map +1 -0
- package/dist/parsing/json-arg.js +165 -0
- package/dist/parsing/json-arg.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Safety enforcement middleware for odoo-cli.
|
|
4
|
+
*
|
|
5
|
+
* Every command has a safety level: READ | WRITE | DESTRUCTIVE.
|
|
6
|
+
*
|
|
7
|
+
* - READ: No requirements. Safe to run anywhere.
|
|
8
|
+
* - WRITE: Requires --confirm. Clear error if missing.
|
|
9
|
+
* - DESTRUCTIVE: Requires --confirm. Prints a DESTRUCTIVE warning.
|
|
10
|
+
*
|
|
11
|
+
* The CLI enforces safety at the command level, independently of the
|
|
12
|
+
* odoo-client safety guard (which uses a confirm callback). Here we
|
|
13
|
+
* use a simpler model: just check if the --confirm flag is present.
|
|
14
|
+
*/
|
|
15
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.requireConfirm = requireConfirm;
|
|
20
|
+
exports.printDryRun = printDryRun;
|
|
21
|
+
const debug_1 = __importDefault(require("debug"));
|
|
22
|
+
const errors_1 = require("../output/errors");
|
|
23
|
+
const log = (0, debug_1.default)('odoo-cli:safety');
|
|
24
|
+
/**
|
|
25
|
+
* Assert that a WRITE or DESTRUCTIVE operation has --confirm.
|
|
26
|
+
*
|
|
27
|
+
* Throws CliUsageError (exit 1) if --confirm is missing.
|
|
28
|
+
* In --dry-run mode, skips the check (we're not actually mutating).
|
|
29
|
+
*/
|
|
30
|
+
function requireConfirm(level, options, commandDescription) {
|
|
31
|
+
log('Safety check: level=%s confirm=%s dryRun=%s', level, options.confirm, options.dryRun);
|
|
32
|
+
if (level === 'READ')
|
|
33
|
+
return;
|
|
34
|
+
// --dry-run bypasses confirm: safe because no RPC is executed.
|
|
35
|
+
// This allows previewing any operation without --confirm.
|
|
36
|
+
if (options.dryRun) {
|
|
37
|
+
log('Skipping safety check: --dry-run mode');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (!options.confirm) {
|
|
41
|
+
const levelStr = level === 'DESTRUCTIVE' ? 'DESTRUCTIVE ⚠' : 'WRITE';
|
|
42
|
+
throw new errors_1.CliUsageError(`${commandDescription} is a ${levelStr} operation and requires --confirm`, [
|
|
43
|
+
'Add --confirm to execute the operation',
|
|
44
|
+
'Add --dry-run to preview the RPC call without executing',
|
|
45
|
+
`This command modifies Odoo data. Safety level: ${level}`,
|
|
46
|
+
]);
|
|
47
|
+
}
|
|
48
|
+
if (level === 'DESTRUCTIVE') {
|
|
49
|
+
process.stderr.write(`⚠ DESTRUCTIVE operation: ${commandDescription}\n`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Format a dry-run message to stderr showing what WOULD be called.
|
|
54
|
+
*/
|
|
55
|
+
function printDryRun(model, method, args, kwargs = {}) {
|
|
56
|
+
process.stderr.write(`DRY RUN: Would call execute_kw\n`);
|
|
57
|
+
process.stderr.write(` model: ${model}\n`);
|
|
58
|
+
process.stderr.write(` method: ${method}\n`);
|
|
59
|
+
process.stderr.write(` args: ${JSON.stringify(args)}\n`);
|
|
60
|
+
if (Object.keys(kwargs).length > 0) {
|
|
61
|
+
process.stderr.write(` kwargs: ${JSON.stringify(kwargs)}\n`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=safety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safety.js","sourceRoot":"","sources":["../../src/middleware/safety.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;;;AAoBH,wCA8BC;AAKD,kCAaC;AAlED,kDAA0B;AAC1B,6CAAiD;AAEjD,MAAM,GAAG,GAAG,IAAA,eAAK,EAAC,iBAAiB,CAAC,CAAC;AASrC;;;;;GAKG;AACH,SAAgB,cAAc,CAC5B,KAAkB,EAClB,OAAsB,EACtB,kBAA0B;IAE1B,GAAG,CAAC,6CAA6C,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAE3F,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO;IAC7B,+DAA+D;IAC/D,0DAA0D;IAC1D,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,GAAG,CAAC,uCAAuC,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAG,KAAK,KAAK,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC;QACrE,MAAM,IAAI,sBAAa,CACrB,GAAG,kBAAkB,SAAS,QAAQ,mCAAmC,EACzE;YACE,wCAAwC;YACxC,yDAAyD;YACzD,kDAAkD,KAAK,EAAE;SAC1D,CACF,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,KAAK,aAAa,EAAE,CAAC;QAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,kBAAkB,IAAI,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,WAAW,CACzB,KAAa,EACb,MAAc,EACd,IAAW,EACX,SAA8B,EAAE;IAEhC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACzD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,KAAK,IAAI,CAAC,CAAC;IAC7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,MAAM,IAAI,CAAC,CAAC;IAC9C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5D,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error formatting and exit-code mapping for odoo-cli.
|
|
3
|
+
*
|
|
4
|
+
* ALL error output goes to stderr. stdout is reserved for data.
|
|
5
|
+
*
|
|
6
|
+
* Exit codes:
|
|
7
|
+
* 0 = success
|
|
8
|
+
* 1 = usage error (bad flags, missing args, --confirm missing)
|
|
9
|
+
* 2 = auth / network error
|
|
10
|
+
* 3 = not found (record, model, module)
|
|
11
|
+
* 4 = permission denied
|
|
12
|
+
* 5 = validation error (Odoo rejected write)
|
|
13
|
+
* 6 = conflict (already clocked in, timer running)
|
|
14
|
+
* 10 = partial success (batch, some failed)
|
|
15
|
+
*/
|
|
16
|
+
/** Suppress stderr progress/warnings. Called from cli.ts preAction hook. */
|
|
17
|
+
export declare function setQuiet(v: boolean): void;
|
|
18
|
+
/** Disable ANSI color in stderr output. Called from cli.ts preAction hook. */
|
|
19
|
+
export declare function setNoColor(v: boolean): void;
|
|
20
|
+
export declare const EXIT_CODES: {
|
|
21
|
+
readonly SUCCESS: 0;
|
|
22
|
+
readonly USAGE_ERROR: 1;
|
|
23
|
+
readonly AUTH_NETWORK_ERROR: 2;
|
|
24
|
+
readonly NOT_FOUND: 3;
|
|
25
|
+
readonly PERMISSION_DENIED: 4;
|
|
26
|
+
readonly VALIDATION_ERROR: 5;
|
|
27
|
+
readonly CONFLICT: 6;
|
|
28
|
+
readonly PARTIAL_SUCCESS: 10;
|
|
29
|
+
};
|
|
30
|
+
export type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];
|
|
31
|
+
/**
|
|
32
|
+
* Format and print an error to stderr, return the appropriate exit code.
|
|
33
|
+
*/
|
|
34
|
+
export declare function handleError(err: unknown): ExitCode;
|
|
35
|
+
/**
|
|
36
|
+
* Print a formatted error to stderr.
|
|
37
|
+
*/
|
|
38
|
+
export declare function printError(message: string, detail?: string, hints?: string[]): void;
|
|
39
|
+
/**
|
|
40
|
+
* Print a success message to stderr (decorative, not data).
|
|
41
|
+
*/
|
|
42
|
+
export declare function printSuccess(message: string): void;
|
|
43
|
+
/**
|
|
44
|
+
* Print an info/progress message to stderr.
|
|
45
|
+
* Suppressed in --quiet mode.
|
|
46
|
+
*/
|
|
47
|
+
export declare function printInfo(message: string): void;
|
|
48
|
+
/**
|
|
49
|
+
* Print a warning to stderr.
|
|
50
|
+
* Suppressed in --quiet mode.
|
|
51
|
+
*/
|
|
52
|
+
export declare function printWarning(message: string): void;
|
|
53
|
+
export declare class CliUsageError extends Error {
|
|
54
|
+
readonly hints: string[];
|
|
55
|
+
constructor(message: string, hints?: string[]);
|
|
56
|
+
}
|
|
57
|
+
export declare class CliNotFoundError extends Error {
|
|
58
|
+
readonly hints: string[];
|
|
59
|
+
constructor(message: string, hints?: string[]);
|
|
60
|
+
}
|
|
61
|
+
export declare class CliConflictError extends Error {
|
|
62
|
+
readonly hints: string[];
|
|
63
|
+
constructor(message: string, hints?: string[]);
|
|
64
|
+
}
|
|
65
|
+
export declare class CliAuthError extends Error {
|
|
66
|
+
readonly hints: string[];
|
|
67
|
+
constructor(message: string, hints?: string[]);
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/output/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAgBH,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAEzC;AAED,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAE3C;AAED,eAAO,MAAM,UAAU;;;;;;;;;CASb,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC;AAEpE;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CAoElD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAanF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAKlD;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAG/C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAMlD;AAID,qBAAa,aAAc,SAAQ,KAAK;aAGpB,KAAK,EAAE,MAAM,EAAE;gBAD/B,OAAO,EAAE,MAAM,EACC,KAAK,GAAE,MAAM,EAAO;CAKvC;AAED,qBAAa,gBAAiB,SAAQ,KAAK;aAGvB,KAAK,EAAE,MAAM,EAAE;gBAD/B,OAAO,EAAE,MAAM,EACC,KAAK,GAAE,MAAM,EAAO;CAKvC;AAED,qBAAa,gBAAiB,SAAQ,KAAK;aAGvB,KAAK,EAAE,MAAM,EAAE;gBAD/B,OAAO,EAAE,MAAM,EACC,KAAK,GAAE,MAAM,EAAO;CAKvC;AAED,qBAAa,YAAa,SAAQ,KAAK;aAGnB,KAAK,EAAE,MAAM,EAAE;gBAD/B,OAAO,EAAE,MAAM,EACC,KAAK,GAAE,MAAM,EAAO;CAKvC"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Error formatting and exit-code mapping for odoo-cli.
|
|
4
|
+
*
|
|
5
|
+
* ALL error output goes to stderr. stdout is reserved for data.
|
|
6
|
+
*
|
|
7
|
+
* Exit codes:
|
|
8
|
+
* 0 = success
|
|
9
|
+
* 1 = usage error (bad flags, missing args, --confirm missing)
|
|
10
|
+
* 2 = auth / network error
|
|
11
|
+
* 3 = not found (record, model, module)
|
|
12
|
+
* 4 = permission denied
|
|
13
|
+
* 5 = validation error (Odoo rejected write)
|
|
14
|
+
* 6 = conflict (already clocked in, timer running)
|
|
15
|
+
* 10 = partial success (batch, some failed)
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.CliAuthError = exports.CliConflictError = exports.CliNotFoundError = exports.CliUsageError = exports.EXIT_CODES = void 0;
|
|
19
|
+
exports.setQuiet = setQuiet;
|
|
20
|
+
exports.setNoColor = setNoColor;
|
|
21
|
+
exports.handleError = handleError;
|
|
22
|
+
exports.printError = printError;
|
|
23
|
+
exports.printSuccess = printSuccess;
|
|
24
|
+
exports.printInfo = printInfo;
|
|
25
|
+
exports.printWarning = printWarning;
|
|
26
|
+
const odoo_client_1 = require("@marcfargas/odoo-client");
|
|
27
|
+
// ── Global quiet / no-color flags ────────────────────────────────────
|
|
28
|
+
let _quiet = false;
|
|
29
|
+
let _noColor = false;
|
|
30
|
+
/** Suppress stderr progress/warnings. Called from cli.ts preAction hook. */
|
|
31
|
+
function setQuiet(v) {
|
|
32
|
+
_quiet = v;
|
|
33
|
+
}
|
|
34
|
+
/** Disable ANSI color in stderr output. Called from cli.ts preAction hook. */
|
|
35
|
+
function setNoColor(v) {
|
|
36
|
+
_noColor = v;
|
|
37
|
+
}
|
|
38
|
+
exports.EXIT_CODES = {
|
|
39
|
+
SUCCESS: 0,
|
|
40
|
+
USAGE_ERROR: 1,
|
|
41
|
+
AUTH_NETWORK_ERROR: 2,
|
|
42
|
+
NOT_FOUND: 3,
|
|
43
|
+
PERMISSION_DENIED: 4,
|
|
44
|
+
VALIDATION_ERROR: 5,
|
|
45
|
+
CONFLICT: 6,
|
|
46
|
+
PARTIAL_SUCCESS: 10,
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Format and print an error to stderr, return the appropriate exit code.
|
|
50
|
+
*/
|
|
51
|
+
function handleError(err) {
|
|
52
|
+
if (err instanceof odoo_client_1.OdooAuthError) {
|
|
53
|
+
printError('Cannot authenticate to Odoo', err.message, [
|
|
54
|
+
'Check ODOO_URL, ODOO_DB, ODOO_USERNAME, ODOO_PASSWORD',
|
|
55
|
+
]);
|
|
56
|
+
return exports.EXIT_CODES.AUTH_NETWORK_ERROR;
|
|
57
|
+
}
|
|
58
|
+
if (err instanceof odoo_client_1.OdooTimeoutError || err instanceof odoo_client_1.OdooNetworkError) {
|
|
59
|
+
printError('Connection failed', err.message, ['Check that ODOO_URL is reachable']);
|
|
60
|
+
return exports.EXIT_CODES.AUTH_NETWORK_ERROR;
|
|
61
|
+
}
|
|
62
|
+
if (err instanceof odoo_client_1.OdooAccessError) {
|
|
63
|
+
printError('Permission denied', err.message, ['You may lack the required access rights']);
|
|
64
|
+
return exports.EXIT_CODES.PERMISSION_DENIED;
|
|
65
|
+
}
|
|
66
|
+
if (err instanceof odoo_client_1.OdooMissingError) {
|
|
67
|
+
printError('Record not found', err.message);
|
|
68
|
+
return exports.EXIT_CODES.NOT_FOUND;
|
|
69
|
+
}
|
|
70
|
+
if (err instanceof odoo_client_1.OdooValidationError) {
|
|
71
|
+
printError('Validation error', err.message, ['Odoo rejected the request']);
|
|
72
|
+
return exports.EXIT_CODES.VALIDATION_ERROR;
|
|
73
|
+
}
|
|
74
|
+
if (err instanceof CliUsageError) {
|
|
75
|
+
printError(err.message, undefined, err.hints);
|
|
76
|
+
return exports.EXIT_CODES.USAGE_ERROR;
|
|
77
|
+
}
|
|
78
|
+
if (err instanceof CliNotFoundError) {
|
|
79
|
+
printError(err.message, undefined, err.hints);
|
|
80
|
+
return exports.EXIT_CODES.NOT_FOUND;
|
|
81
|
+
}
|
|
82
|
+
if (err instanceof CliConflictError) {
|
|
83
|
+
printError(err.message, undefined, err.hints);
|
|
84
|
+
return exports.EXIT_CODES.CONFLICT;
|
|
85
|
+
}
|
|
86
|
+
if (err instanceof CliAuthError) {
|
|
87
|
+
printError(err.message, undefined, err.hints);
|
|
88
|
+
return exports.EXIT_CODES.AUTH_NETWORK_ERROR;
|
|
89
|
+
}
|
|
90
|
+
if (err instanceof Error) {
|
|
91
|
+
// Check message patterns for categorization
|
|
92
|
+
const msg = err.message.toLowerCase();
|
|
93
|
+
if (msg.includes('not found') || msg.includes("doesn't exist")) {
|
|
94
|
+
printError('Not found', err.message);
|
|
95
|
+
return exports.EXIT_CODES.NOT_FOUND;
|
|
96
|
+
}
|
|
97
|
+
if (msg.includes('missing environment variable') || msg.includes('missing env')) {
|
|
98
|
+
printError('Configuration error', err.message, [
|
|
99
|
+
'Set ODOO_URL, ODOO_DB, ODOO_USERNAME, ODOO_PASSWORD',
|
|
100
|
+
'Or use --url, --db, --user, --password flags',
|
|
101
|
+
]);
|
|
102
|
+
return exports.EXIT_CODES.AUTH_NETWORK_ERROR;
|
|
103
|
+
}
|
|
104
|
+
printError('Unexpected error', err.message);
|
|
105
|
+
return exports.EXIT_CODES.USAGE_ERROR;
|
|
106
|
+
}
|
|
107
|
+
printError('Unknown error', String(err));
|
|
108
|
+
return exports.EXIT_CODES.USAGE_ERROR;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Print a formatted error to stderr.
|
|
112
|
+
*/
|
|
113
|
+
function printError(message, detail, hints) {
|
|
114
|
+
const noColor = _noColor || process.env.NO_COLOR !== undefined || !process.stderr.isTTY;
|
|
115
|
+
const red = noColor ? '' : '\x1b[31m';
|
|
116
|
+
const dim = noColor ? '' : '\x1b[2m';
|
|
117
|
+
const reset = noColor ? '' : '\x1b[0m';
|
|
118
|
+
process.stderr.write(`${red}✗ Error:${reset} ${message}\n`);
|
|
119
|
+
if (detail) {
|
|
120
|
+
process.stderr.write(` ${dim}Details:${reset} ${detail}\n`);
|
|
121
|
+
}
|
|
122
|
+
for (const hint of hints ?? []) {
|
|
123
|
+
process.stderr.write(` → ${hint}\n`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Print a success message to stderr (decorative, not data).
|
|
128
|
+
*/
|
|
129
|
+
function printSuccess(message) {
|
|
130
|
+
const noColor = _noColor || process.env.NO_COLOR !== undefined || !process.stderr.isTTY;
|
|
131
|
+
const green = noColor ? '' : '\x1b[32m';
|
|
132
|
+
const reset = noColor ? '' : '\x1b[0m';
|
|
133
|
+
process.stderr.write(`${green}✓${reset} ${message}\n`);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Print an info/progress message to stderr.
|
|
137
|
+
* Suppressed in --quiet mode.
|
|
138
|
+
*/
|
|
139
|
+
function printInfo(message) {
|
|
140
|
+
if (_quiet)
|
|
141
|
+
return;
|
|
142
|
+
process.stderr.write(` ${message}\n`);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Print a warning to stderr.
|
|
146
|
+
* Suppressed in --quiet mode.
|
|
147
|
+
*/
|
|
148
|
+
function printWarning(message) {
|
|
149
|
+
if (_quiet)
|
|
150
|
+
return;
|
|
151
|
+
const noColor = _noColor || process.env.NO_COLOR !== undefined || !process.stderr.isTTY;
|
|
152
|
+
const yellow = noColor ? '' : '\x1b[33m';
|
|
153
|
+
const reset = noColor ? '' : '\x1b[0m';
|
|
154
|
+
process.stderr.write(`${yellow}⚠${reset} ${message}\n`);
|
|
155
|
+
}
|
|
156
|
+
// ── CLI-specific errors ──────────────────────────────────────────────
|
|
157
|
+
class CliUsageError extends Error {
|
|
158
|
+
hints;
|
|
159
|
+
constructor(message, hints = []) {
|
|
160
|
+
super(message);
|
|
161
|
+
this.hints = hints;
|
|
162
|
+
this.name = 'CliUsageError';
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
exports.CliUsageError = CliUsageError;
|
|
166
|
+
class CliNotFoundError extends Error {
|
|
167
|
+
hints;
|
|
168
|
+
constructor(message, hints = []) {
|
|
169
|
+
super(message);
|
|
170
|
+
this.hints = hints;
|
|
171
|
+
this.name = 'CliNotFoundError';
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
exports.CliNotFoundError = CliNotFoundError;
|
|
175
|
+
class CliConflictError extends Error {
|
|
176
|
+
hints;
|
|
177
|
+
constructor(message, hints = []) {
|
|
178
|
+
super(message);
|
|
179
|
+
this.hints = hints;
|
|
180
|
+
this.name = 'CliConflictError';
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
exports.CliConflictError = CliConflictError;
|
|
184
|
+
class CliAuthError extends Error {
|
|
185
|
+
hints;
|
|
186
|
+
constructor(message, hints = []) {
|
|
187
|
+
super(message);
|
|
188
|
+
this.hints = hints;
|
|
189
|
+
this.name = 'CliAuthError';
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
exports.CliAuthError = CliAuthError;
|
|
193
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/output/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatter for odoo-cli.
|
|
3
|
+
*
|
|
4
|
+
* Formats: json | table | csv | ndjson
|
|
5
|
+
*
|
|
6
|
+
* Conventions:
|
|
7
|
+
* - stdout = data only (all formats write to stdout)
|
|
8
|
+
* - stderr = decorative messages, warnings (caller's responsibility)
|
|
9
|
+
* - Many2one fields [id, name]: expanded to two columns in table/csv
|
|
10
|
+
* - table warns above 5000 rows and suggests ndjson
|
|
11
|
+
* - ndjson: streams one JSON object per line
|
|
12
|
+
*/
|
|
13
|
+
export type OutputFormat = 'json' | 'table' | 'csv' | 'ndjson';
|
|
14
|
+
/** Disable ANSI colors in table/CLI output. Called from cli.ts preAction hook. */
|
|
15
|
+
export declare function setNoColor(v: boolean): void;
|
|
16
|
+
/** Suppress stderr progress and warnings. Called from cli.ts preAction hook. */
|
|
17
|
+
export declare function setQuiet(v: boolean): void;
|
|
18
|
+
/** Whether quiet mode is active (used by other output modules). */
|
|
19
|
+
export declare function isQuiet(): boolean;
|
|
20
|
+
/** Whether no-color mode is active. */
|
|
21
|
+
export declare function isNoColor(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Detect the default output format.
|
|
24
|
+
* TTY → table, pipe → json.
|
|
25
|
+
*/
|
|
26
|
+
export declare function detectFormat(): OutputFormat;
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the format from option string, falling back to auto-detect.
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveFormat(fmt: string | undefined): OutputFormat;
|
|
31
|
+
/**
|
|
32
|
+
* Flatten many2one fields for table/csv output.
|
|
33
|
+
*
|
|
34
|
+
* Input record: { id: 1, partner_id: [7, "Marc"] }
|
|
35
|
+
* Output record: { id: 1, partner_id: 7, partner_id_name: "Marc" }
|
|
36
|
+
*
|
|
37
|
+
* For boolean false (no relation): partner_id → null, partner_id_name → ""
|
|
38
|
+
*/
|
|
39
|
+
export declare function flattenRecord(record: Record<string, any>): Record<string, any>;
|
|
40
|
+
/**
|
|
41
|
+
* Get column headers for a set of records, expanding many2one fields.
|
|
42
|
+
*/
|
|
43
|
+
export declare function getColumns(records: Record<string, any>[]): string[];
|
|
44
|
+
/**
|
|
45
|
+
* Write JSON array to stdout.
|
|
46
|
+
*/
|
|
47
|
+
export declare function formatJson(records: Record<string, any>[]): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Write ndjson to stdout — one JSON object per line.
|
|
50
|
+
*/
|
|
51
|
+
export declare function formatNdjson(records: Record<string, any>[]): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Write table to stdout.
|
|
54
|
+
* Warns at >5000 rows and suggests --format ndjson.
|
|
55
|
+
*/
|
|
56
|
+
export declare function formatTable(records: Record<string, any>[]): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Write CSV to stdout.
|
|
59
|
+
* Expands many2one fields to two columns.
|
|
60
|
+
*/
|
|
61
|
+
export declare function formatCsv(records: Record<string, any>[]): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Master render function — routes to the appropriate formatter.
|
|
64
|
+
*/
|
|
65
|
+
export declare function render(records: Record<string, any>[], format: OutputFormat): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Render a single record (e.g., `records get`).
|
|
68
|
+
* JSON outputs an object (not array). Table shows key/value pairs.
|
|
69
|
+
*/
|
|
70
|
+
export declare function renderSingle(record: Record<string, any>, format: OutputFormat): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* Render a simple key/value config-style object (for `config show`).
|
|
73
|
+
*/
|
|
74
|
+
export declare function renderKeyValue(data: Record<string, string>, format: OutputFormat): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Paged search-read generator — fetches from Odoo in pages.
|
|
77
|
+
* Used by `records search --all`.
|
|
78
|
+
*/
|
|
79
|
+
export declare function pagedSearchRead(searchFn: (offset: number, limit: number) => Promise<Record<string, any>[]>, pageSize?: number): AsyncGenerator<Record<string, any>[]>;
|
|
80
|
+
//# sourceMappingURL=formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../src/output/formatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;AAO/D,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAE3C;AAED,gFAAgF;AAChF,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAEzC;AAED,mEAAmE;AACnE,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED,uCAAuC;AACvC,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,YAAY,CAE3C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,YAAY,CAKnE;AAaD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAgB9E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,MAAM,EAAE,CAanE;AAID;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAG9E;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhF;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA4B/E;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAa7E;AAaD;;GAEG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhG;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED;;;GAGG;AACH,wBAAuB,eAAe,CACpC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,EAC3E,QAAQ,GAAE,MAAY,GACrB,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,CAOvC"}
|