@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,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* --help-extra resolver and renderer.
|
|
3
|
+
*
|
|
4
|
+
* When --help-extra is passed, renders skill documentation for the command group.
|
|
5
|
+
*
|
|
6
|
+
* Strategy (hybrid):
|
|
7
|
+
* 1. Runtime primary: if skills/ directory is accessible, read and render full markdown.
|
|
8
|
+
* 2. Runtime fallback: use the built-in summary strings (works in compiled binaries).
|
|
9
|
+
*
|
|
10
|
+
* Skill map: command group → relevant skill files.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Show extended help for a command group.
|
|
14
|
+
*
|
|
15
|
+
* Writes to stdout (so it can be piped / paged).
|
|
16
|
+
*/
|
|
17
|
+
export declare function showHelpExtra(group: string): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=extra-help.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extra-help.d.ts","sourceRoot":"","sources":["../../src/help/extra-help.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA+JH;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2ChE"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* --help-extra resolver and renderer.
|
|
4
|
+
*
|
|
5
|
+
* When --help-extra is passed, renders skill documentation for the command group.
|
|
6
|
+
*
|
|
7
|
+
* Strategy (hybrid):
|
|
8
|
+
* 1. Runtime primary: if skills/ directory is accessible, read and render full markdown.
|
|
9
|
+
* 2. Runtime fallback: use the built-in summary strings (works in compiled binaries).
|
|
10
|
+
*
|
|
11
|
+
* Skill map: command group → relevant skill files.
|
|
12
|
+
*/
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.showHelpExtra = showHelpExtra;
|
|
18
|
+
const debug_1 = __importDefault(require("debug"));
|
|
19
|
+
const fs_1 = require("fs");
|
|
20
|
+
const path_1 = require("path");
|
|
21
|
+
const log = (0, debug_1.default)('odoo-cli:help');
|
|
22
|
+
const HELP_EXTRA_SKILLS = {
|
|
23
|
+
records: ['base/crud.md', 'base/search.md', 'base/domains.md', 'base/field-types.md'],
|
|
24
|
+
mail: ['mail/chatter.md'],
|
|
25
|
+
modules: ['base/modules.md'],
|
|
26
|
+
attendance: ['modules/timesheets.md'], // attendance is in hr module docs
|
|
27
|
+
timesheets: ['modules/timesheets.md'],
|
|
28
|
+
accounting: ['modules/accounting.md'],
|
|
29
|
+
url: ['base/connection.md'],
|
|
30
|
+
schema: ['base/introspection.md'],
|
|
31
|
+
state: [],
|
|
32
|
+
config: ['base/connection.md'],
|
|
33
|
+
};
|
|
34
|
+
const HELP_SUMMARIES = {
|
|
35
|
+
records: `
|
|
36
|
+
## odoo records — Generic CRUD on any Odoo model
|
|
37
|
+
|
|
38
|
+
Search, get, create, update, and delete records on ANY Odoo model.
|
|
39
|
+
|
|
40
|
+
### Examples
|
|
41
|
+
|
|
42
|
+
odoo records search crm.lead --fields id,name,stage_id --limit 20
|
|
43
|
+
odoo records get res.partner 42
|
|
44
|
+
odoo records create res.partner --data '{"name":"Acme Corp"}' --confirm
|
|
45
|
+
odoo records write crm.lead 42 --data '{"stage_id":5}' --confirm
|
|
46
|
+
odoo records delete crm.lead 42 --confirm
|
|
47
|
+
|
|
48
|
+
### Domain syntax
|
|
49
|
+
|
|
50
|
+
--domain '[("active","=",True),("stage_id.name","=","Won")]'
|
|
51
|
+
--filter active=true --filter state=sale (simple AND equality)
|
|
52
|
+
--domain-file domain.json (from file)
|
|
53
|
+
--domain-file - (from stdin)
|
|
54
|
+
|
|
55
|
+
Run 'odoo schema fields <model>' to discover available fields.
|
|
56
|
+
`,
|
|
57
|
+
mail: `
|
|
58
|
+
## odoo mail — Chatter messages and internal notes
|
|
59
|
+
|
|
60
|
+
Post messages on any record's chatter.
|
|
61
|
+
|
|
62
|
+
odoo mail note crm.lead 42 "Called customer" --confirm
|
|
63
|
+
odoo mail post sale.order 88 "Order shipped" --confirm
|
|
64
|
+
echo "Deployed: v1.2.3" | odoo mail note project.task 17 --message-file - --confirm
|
|
65
|
+
|
|
66
|
+
note: internal only (staff), post: public (notifies followers).
|
|
67
|
+
`,
|
|
68
|
+
modules: `
|
|
69
|
+
## odoo modules — Install, upgrade, and list modules
|
|
70
|
+
|
|
71
|
+
odoo modules list --filter installed
|
|
72
|
+
odoo modules install hr_timesheet --confirm
|
|
73
|
+
odoo modules upgrade sale_management --confirm
|
|
74
|
+
odoo modules status sale_management (exits 3 if not found)
|
|
75
|
+
|
|
76
|
+
Scripting pattern:
|
|
77
|
+
if [ "$(odoo modules status sale)" = "installed" ]; then echo ready; fi
|
|
78
|
+
`,
|
|
79
|
+
timesheets: `
|
|
80
|
+
## odoo timesheets — Time tracking
|
|
81
|
+
|
|
82
|
+
Timer workflow:
|
|
83
|
+
odoo timesheets start --task-id 42 --description "Feature work" --confirm
|
|
84
|
+
odoo timesheets stop --confirm
|
|
85
|
+
odoo timesheets running
|
|
86
|
+
|
|
87
|
+
Manual logging:
|
|
88
|
+
odoo timesheets log --task-id 42 --hours 1.5 --description "Review" --confirm
|
|
89
|
+
odoo timesheets log --task-id 42 --hours 1:30 --confirm
|
|
90
|
+
`,
|
|
91
|
+
attendance: `
|
|
92
|
+
## odoo attendance — Clock in/out
|
|
93
|
+
|
|
94
|
+
odoo attendance clock-in --confirm
|
|
95
|
+
odoo attendance clock-out --confirm
|
|
96
|
+
odoo attendance status
|
|
97
|
+
odoo attendance list --from 2024-03-11 --to 2024-03-15
|
|
98
|
+
`,
|
|
99
|
+
accounting: `
|
|
100
|
+
## odoo accounting — Read-only accounting queries (no mutations)
|
|
101
|
+
|
|
102
|
+
odoo accounting cash-accounts
|
|
103
|
+
odoo accounting cash-balance --as-of 2024-03-31
|
|
104
|
+
odoo accounting posted-moves --from 2024-01-01 --to 2024-03-31
|
|
105
|
+
odoo accounting trace-recon 42
|
|
106
|
+
odoo accounting days-to-pay 1042
|
|
107
|
+
`,
|
|
108
|
+
schema: `
|
|
109
|
+
## odoo schema — Model and field introspection
|
|
110
|
+
|
|
111
|
+
odoo schema models --search sale
|
|
112
|
+
odoo schema fields crm.lead --type many2one
|
|
113
|
+
odoo schema describe res.partner
|
|
114
|
+
odoo schema codegen sale.order --out ./types/sale-order.ts
|
|
115
|
+
`,
|
|
116
|
+
url: `
|
|
117
|
+
## odoo url — Generate record URLs
|
|
118
|
+
|
|
119
|
+
odoo url record crm.lead 42
|
|
120
|
+
odoo url portal sale.order 88
|
|
121
|
+
`,
|
|
122
|
+
config: `
|
|
123
|
+
## odoo config — Connection management
|
|
124
|
+
|
|
125
|
+
odoo config check # verify credentials and show current user
|
|
126
|
+
odoo config show # show resolved config (password redacted)
|
|
127
|
+
`,
|
|
128
|
+
state: `
|
|
129
|
+
## odoo state — State management ⚠ EXPERIMENTAL
|
|
130
|
+
|
|
131
|
+
Requires --experimental flag on all commands.
|
|
132
|
+
|
|
133
|
+
odoo state plan ./crm-stages.json --experimental
|
|
134
|
+
odoo state apply ./crm-stages.json --experimental --confirm
|
|
135
|
+
|
|
136
|
+
No extended docs available yet for this experimental feature.
|
|
137
|
+
`,
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Resolve the skills directory relative to this package or the monorepo root.
|
|
141
|
+
*/
|
|
142
|
+
function findSkillsDir() {
|
|
143
|
+
// Try: relative to this file (dev install in monorepo)
|
|
144
|
+
const candidates = [
|
|
145
|
+
// monorepo: packages/odoo-cli → ../../skills/odoo
|
|
146
|
+
(0, path_1.resolve)(__dirname, '..', '..', '..', '..', 'skills', 'odoo'),
|
|
147
|
+
// npm install: alongside package
|
|
148
|
+
(0, path_1.resolve)(__dirname, '..', 'skills', 'odoo'),
|
|
149
|
+
];
|
|
150
|
+
for (const candidate of candidates) {
|
|
151
|
+
if ((0, fs_1.existsSync)(candidate)) {
|
|
152
|
+
log('Found skills dir: %s', candidate);
|
|
153
|
+
return candidate;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
log('Skills directory not found, using built-in summaries');
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Show extended help for a command group.
|
|
161
|
+
*
|
|
162
|
+
* Writes to stdout (so it can be piped / paged).
|
|
163
|
+
*/
|
|
164
|
+
async function showHelpExtra(group) {
|
|
165
|
+
const skillFiles = HELP_EXTRA_SKILLS[group];
|
|
166
|
+
if (skillFiles === undefined) {
|
|
167
|
+
process.stdout.write(`No extended help available for '${group}'.\n`);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (skillFiles.length === 0) {
|
|
171
|
+
const summary = HELP_SUMMARIES[group];
|
|
172
|
+
if (summary) {
|
|
173
|
+
process.stdout.write(summary + '\n');
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
process.stdout.write(`No extended help available for '${group}'.\n`);
|
|
177
|
+
}
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
// Try to read full markdown files
|
|
181
|
+
const skillsDir = findSkillsDir();
|
|
182
|
+
if (skillsDir) {
|
|
183
|
+
let rendered = false;
|
|
184
|
+
for (const file of skillFiles) {
|
|
185
|
+
const fullPath = (0, path_1.join)(skillsDir, file);
|
|
186
|
+
if ((0, fs_1.existsSync)(fullPath)) {
|
|
187
|
+
try {
|
|
188
|
+
const content = (0, fs_1.readFileSync)(fullPath, 'utf8');
|
|
189
|
+
process.stdout.write(`\n${'─'.repeat(60)}\n`);
|
|
190
|
+
process.stdout.write(`# Skill: ${file}\n`);
|
|
191
|
+
process.stdout.write(`${'─'.repeat(60)}\n\n`);
|
|
192
|
+
process.stdout.write(content + '\n');
|
|
193
|
+
rendered = true;
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
log('Could not read %s: %o', fullPath, err);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (rendered)
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
// Fallback: built-in summary
|
|
204
|
+
const summary = HELP_SUMMARIES[group] ?? `No extended help available for '${group}'.`;
|
|
205
|
+
process.stdout.write(summary + '\n');
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=extra-help.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extra-help.js","sourceRoot":"","sources":["../../src/help/extra-help.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication middleware for odoo-cli.
|
|
3
|
+
*
|
|
4
|
+
* Creates an authenticated OdooClient from environment variables,
|
|
5
|
+
* optionally overriding with CLI flags (--url, --db, --user, --password).
|
|
6
|
+
*
|
|
7
|
+
* Priority: CLI flags > env vars
|
|
8
|
+
* CLI flags should be avoided in practice (shell history exposure).
|
|
9
|
+
*/
|
|
10
|
+
import { OdooClient, type OdooClientConfig } from '@marcfargas/odoo-client';
|
|
11
|
+
export interface AuthFlags {
|
|
12
|
+
url?: string;
|
|
13
|
+
db?: string;
|
|
14
|
+
user?: string;
|
|
15
|
+
password?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Build an OdooClientConfig from env vars + CLI flag overrides.
|
|
19
|
+
* Does NOT authenticate yet.
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildConfig(flags: AuthFlags): OdooClientConfig;
|
|
22
|
+
/**
|
|
23
|
+
* Create an authenticated OdooClient from env vars + CLI flag overrides.
|
|
24
|
+
*
|
|
25
|
+
* Throws CliAuthError if credentials are missing.
|
|
26
|
+
* Throws OdooAuthError if authentication fails (propagates from client).
|
|
27
|
+
*/
|
|
28
|
+
export declare function createAuthClient(flags: AuthFlags): Promise<OdooClient>;
|
|
29
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,UAAU,EAAE,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAK5E,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,gBAAgB,CAyB9D;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAa5E"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Authentication middleware for odoo-cli.
|
|
4
|
+
*
|
|
5
|
+
* Creates an authenticated OdooClient from environment variables,
|
|
6
|
+
* optionally overriding with CLI flags (--url, --db, --user, --password).
|
|
7
|
+
*
|
|
8
|
+
* Priority: CLI flags > env vars
|
|
9
|
+
* CLI flags should be avoided in practice (shell history exposure).
|
|
10
|
+
*/
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.buildConfig = buildConfig;
|
|
16
|
+
exports.createAuthClient = createAuthClient;
|
|
17
|
+
const debug_1 = __importDefault(require("debug"));
|
|
18
|
+
const odoo_client_1 = require("@marcfargas/odoo-client");
|
|
19
|
+
const errors_1 = require("../output/errors");
|
|
20
|
+
const log = (0, debug_1.default)('odoo-cli:auth');
|
|
21
|
+
/**
|
|
22
|
+
* Build an OdooClientConfig from env vars + CLI flag overrides.
|
|
23
|
+
* Does NOT authenticate yet.
|
|
24
|
+
*/
|
|
25
|
+
function buildConfig(flags) {
|
|
26
|
+
const url = flags.url || process.env['ODOO_URL'] || '';
|
|
27
|
+
const database = flags.db || process.env['ODOO_DB'] || process.env['ODOO_DATABASE'] || '';
|
|
28
|
+
const username = flags.user || process.env['ODOO_USERNAME'] || process.env['ODOO_USER'] || '';
|
|
29
|
+
const password = flags.password || process.env['ODOO_PASSWORD'] || '';
|
|
30
|
+
const missing = [];
|
|
31
|
+
if (!url)
|
|
32
|
+
missing.push('ODOO_URL');
|
|
33
|
+
if (!database)
|
|
34
|
+
missing.push('ODOO_DB');
|
|
35
|
+
if (!username)
|
|
36
|
+
missing.push('ODOO_USERNAME');
|
|
37
|
+
if (!password)
|
|
38
|
+
missing.push('ODOO_PASSWORD');
|
|
39
|
+
if (missing.length > 0) {
|
|
40
|
+
throw new errors_1.CliAuthError(`Missing Odoo credentials: ${missing.join(', ')}`, [
|
|
41
|
+
'Set the following environment variables:',
|
|
42
|
+
' ODOO_URL=https://mycompany.odoo.com',
|
|
43
|
+
' ODOO_DB=mycompany',
|
|
44
|
+
' ODOO_USERNAME=admin@example.com',
|
|
45
|
+
' ODOO_PASSWORD=secret',
|
|
46
|
+
'Or use --url, --db, --user, --password flags (avoid in CI — use env vars)',
|
|
47
|
+
]);
|
|
48
|
+
}
|
|
49
|
+
log('Config: url=%s db=%s user=%s', url, database, username);
|
|
50
|
+
return { url, database, username, password };
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Create an authenticated OdooClient from env vars + CLI flag overrides.
|
|
54
|
+
*
|
|
55
|
+
* Throws CliAuthError if credentials are missing.
|
|
56
|
+
* Throws OdooAuthError if authentication fails (propagates from client).
|
|
57
|
+
*/
|
|
58
|
+
async function createAuthClient(flags) {
|
|
59
|
+
const config = buildConfig(flags);
|
|
60
|
+
const client = new odoo_client_1.OdooClient(config);
|
|
61
|
+
log('Authenticating as %s @ %s', config.username, config.url);
|
|
62
|
+
// Disable client-side safety guard — we handle confirmation ourselves
|
|
63
|
+
client.setSafetyContext(null);
|
|
64
|
+
await client.authenticate();
|
|
65
|
+
log('Authenticated successfully');
|
|
66
|
+
return client;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;;AAmBH,kCAyBC;AAQD,4CAaC;AA/DD,kDAA0B;AAC1B,yDAA4E;AAC5E,6CAAgD;AAEhD,MAAM,GAAG,GAAG,IAAA,eAAK,EAAC,eAAe,CAAC,CAAC;AASnC;;;GAGG;AACH,SAAgB,WAAW,CAAC,KAAgB;IAC1C,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IACvD,MAAM,QAAQ,GAAG,KAAK,CAAC,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;IAC1F,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;IAC9F,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;IAEtE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,GAAG;QAAE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnC,IAAI,CAAC,QAAQ;QAAE,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvC,IAAI,CAAC,QAAQ;QAAE,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC7C,IAAI,CAAC,QAAQ;QAAE,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAE7C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,qBAAY,CAAC,6BAA6B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE;YACxE,0CAA0C;YAC1C,uCAAuC;YACvC,qBAAqB;YACrB,mCAAmC;YACnC,wBAAwB;YACxB,2EAA2E;SAC5E,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,8BAA8B,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC7D,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAC/C,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,gBAAgB,CAAC,KAAgB;IACrD,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,wBAAU,CAAC,MAAM,CAAC,CAAC;IAEtC,GAAG,CAAC,2BAA2B,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAE9D,sEAAsE;IACtE,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAE9B,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;IAC5B,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized parameter definitions for odoo-cli commands.
|
|
3
|
+
*
|
|
4
|
+
* ONE implementation for all shared flags:
|
|
5
|
+
* - --fields, --domain, --domain-json, --domain-file, --filter
|
|
6
|
+
* - --limit, --all, --offset, --page-size, --order
|
|
7
|
+
* - --format, --confirm, --dry-run, --context
|
|
8
|
+
* - Auth: --url, --db, --user, --password
|
|
9
|
+
*
|
|
10
|
+
* Commands compose these via Commander .addOption() calls.
|
|
11
|
+
* Never duplicate these definitions in individual command files.
|
|
12
|
+
*/
|
|
13
|
+
import { Command, Option } from 'commander';
|
|
14
|
+
/** --url: Odoo base URL */
|
|
15
|
+
export declare const urlOption: () => Option;
|
|
16
|
+
/** --db: Database name */
|
|
17
|
+
export declare const dbOption: () => Option;
|
|
18
|
+
/** --user: Username */
|
|
19
|
+
export declare const userOption: () => Option;
|
|
20
|
+
/** --password: Password (use env var instead) */
|
|
21
|
+
export declare const passwordOption: () => Option;
|
|
22
|
+
/** All auth options as a group */
|
|
23
|
+
export declare function addAuthOptions(cmd: Command): Command;
|
|
24
|
+
/** --format: Output format */
|
|
25
|
+
export declare const formatOption: () => Option;
|
|
26
|
+
/** --fields: Comma-separated fields */
|
|
27
|
+
export declare const fieldsOption: () => Option;
|
|
28
|
+
/** --domain: Odoo domain filter */
|
|
29
|
+
export declare const domainOption: () => Option;
|
|
30
|
+
/** --domain-json: Strict JSON domain */
|
|
31
|
+
export declare const domainJsonOption: () => Option;
|
|
32
|
+
/** --domain-file: Read domain from file */
|
|
33
|
+
export declare const domainFileOption: () => Option;
|
|
34
|
+
/** --filter: Simple K=V equality shorthand — repeatable, values collected into array */
|
|
35
|
+
export declare const filterOption: () => Option;
|
|
36
|
+
/** --limit: Max records */
|
|
37
|
+
export declare const limitOption: (defaultVal?: number) => Option;
|
|
38
|
+
/** --all: Fetch all records (--limit 0 alias) */
|
|
39
|
+
export declare const allOption: () => Option;
|
|
40
|
+
/** --offset: Skip first N records */
|
|
41
|
+
export declare const offsetOption: () => Option;
|
|
42
|
+
/** --page-size: Paging chunk size */
|
|
43
|
+
export declare const pageSizeOption: () => Option;
|
|
44
|
+
/** --order: Sort order */
|
|
45
|
+
export declare const orderOption: () => Option;
|
|
46
|
+
/** --count: Print count instead of records */
|
|
47
|
+
export declare const countOption: () => Option;
|
|
48
|
+
/** --confirm: Required for WRITE/DESTRUCTIVE */
|
|
49
|
+
export declare const confirmOption: () => Option;
|
|
50
|
+
/** --dry-run: Preview without executing */
|
|
51
|
+
export declare const dryRunOption: () => Option;
|
|
52
|
+
/** --context: Extra Odoo context JSON */
|
|
53
|
+
export declare const contextOption: () => Option;
|
|
54
|
+
/** --no-color: Disable ANSI colors */
|
|
55
|
+
export declare const noColorOption: () => Option;
|
|
56
|
+
/** --quiet: Suppress stderr progress/warnings */
|
|
57
|
+
export declare const quietOption: () => Option;
|
|
58
|
+
/** --experimental: Required for experimental commands */
|
|
59
|
+
export declare const experimentalOption: () => Option;
|
|
60
|
+
/**
|
|
61
|
+
* Add search/filter options to a command.
|
|
62
|
+
* Used by: records search, records count, attendance list, timesheets list, etc.
|
|
63
|
+
*/
|
|
64
|
+
export declare function addSearchOptions(cmd: Command): Command;
|
|
65
|
+
/**
|
|
66
|
+
* Add pagination options to a command.
|
|
67
|
+
*/
|
|
68
|
+
export declare function addPaginationOptions(cmd: Command, defaultLimit?: number): Command;
|
|
69
|
+
/**
|
|
70
|
+
* Add output options (format + fields) to a command.
|
|
71
|
+
*/
|
|
72
|
+
export declare function addOutputOptions(cmd: Command): Command;
|
|
73
|
+
/**
|
|
74
|
+
* Add write safety options to a command.
|
|
75
|
+
*/
|
|
76
|
+
export declare function addWriteOptions(cmd: Command): Command;
|
|
77
|
+
/**
|
|
78
|
+
* Parse --fields value into an array of field names.
|
|
79
|
+
* Returns empty array if not specified (means "all fields").
|
|
80
|
+
*/
|
|
81
|
+
export declare function parseFields(fields?: string): string[];
|
|
82
|
+
/**
|
|
83
|
+
* Resolve the effective limit.
|
|
84
|
+
* --all overrides --limit (sets to 0 = all).
|
|
85
|
+
*/
|
|
86
|
+
export declare function resolveLimit(options: {
|
|
87
|
+
limit?: number;
|
|
88
|
+
all?: boolean;
|
|
89
|
+
}): number;
|
|
90
|
+
//# sourceMappingURL=common-params.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common-params.d.ts","sourceRoot":"","sources":["../../src/middleware/common-params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAI5C,2BAA2B;AAC3B,eAAO,MAAM,SAAS,cAA8D,CAAC;AAErF,0BAA0B;AAC1B,eAAO,MAAM,QAAQ,cAAgE,CAAC;AAEtF,uBAAuB;AACvB,eAAO,MAAM,UAAU,cAAqE,CAAC;AAE7F,iDAAiD;AACjD,eAAO,MAAM,cAAc,cACwE,CAAC;AAEpG,kCAAkC;AAClC,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAMpD;AAED,8BAA8B;AAC9B,eAAO,MAAM,YAAY,cAMrB,CAAC;AAEL,uCAAuC;AACvC,eAAO,MAAM,YAAY,cAC6C,CAAC;AAEvE,mCAAmC;AACnC,eAAO,MAAM,YAAY,cACuE,CAAC;AAEjG,wCAAwC;AACxC,eAAO,MAAM,gBAAgB,cACwD,CAAC;AAEtF,2CAA2C;AAC3C,eAAO,MAAM,gBAAgB,cACgD,CAAC;AAE9E,wFAAwF;AACxF,eAAO,MAAM,YAAY,cAGT,CAAC;AAEjB,2BAA2B;AAC3B,eAAO,MAAM,WAAW,GAAI,aAAY,MAAW,WAGb,CAAC;AAEvC,iDAAiD;AACjD,eAAO,MAAM,SAAS,cAAuE,CAAC;AAE9F,qCAAqC;AACrC,eAAO,MAAM,YAAY,cAGa,CAAC;AAEvC,qCAAqC;AACrC,eAAO,MAAM,cAAc,cAGW,CAAC;AAEvC,0BAA0B;AAC1B,eAAO,MAAM,WAAW,cAA0E,CAAC;AAEnG,8CAA8C;AAC9C,eAAO,MAAM,WAAW,cAAgE,CAAC;AAEzF,gDAAgD;AAChD,eAAO,MAAM,aAAa,cAC+D,CAAC;AAE1F,2CAA2C;AAC3C,eAAO,MAAM,YAAY,cACgE,CAAC;AAE1F,yCAAyC;AACzC,eAAO,MAAM,aAAa,cACiE,CAAC;AAE5F,sCAAsC;AACtC,eAAO,MAAM,aAAa,cAAwE,CAAC;AAEnG,iDAAiD;AACjD,eAAO,MAAM,WAAW,cAA2E,CAAC;AAEpG,yDAAyD;AACzD,eAAO,MAAM,kBAAkB,cAC+D,CAAC;AAI/F;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAMtD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,YAAY,GAAE,MAAW,GAAG,OAAO,CAOrF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAErD;AAID;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAMrD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAG/E"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Centralized parameter definitions for odoo-cli commands.
|
|
4
|
+
*
|
|
5
|
+
* ONE implementation for all shared flags:
|
|
6
|
+
* - --fields, --domain, --domain-json, --domain-file, --filter
|
|
7
|
+
* - --limit, --all, --offset, --page-size, --order
|
|
8
|
+
* - --format, --confirm, --dry-run, --context
|
|
9
|
+
* - Auth: --url, --db, --user, --password
|
|
10
|
+
*
|
|
11
|
+
* Commands compose these via Commander .addOption() calls.
|
|
12
|
+
* Never duplicate these definitions in individual command files.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.experimentalOption = exports.quietOption = exports.noColorOption = exports.contextOption = exports.dryRunOption = exports.confirmOption = exports.countOption = exports.orderOption = exports.pageSizeOption = exports.offsetOption = exports.allOption = exports.limitOption = exports.filterOption = exports.domainFileOption = exports.domainJsonOption = exports.domainOption = exports.fieldsOption = exports.formatOption = exports.passwordOption = exports.userOption = exports.dbOption = exports.urlOption = void 0;
|
|
16
|
+
exports.addAuthOptions = addAuthOptions;
|
|
17
|
+
exports.addSearchOptions = addSearchOptions;
|
|
18
|
+
exports.addPaginationOptions = addPaginationOptions;
|
|
19
|
+
exports.addOutputOptions = addOutputOptions;
|
|
20
|
+
exports.addWriteOptions = addWriteOptions;
|
|
21
|
+
exports.parseFields = parseFields;
|
|
22
|
+
exports.resolveLimit = resolveLimit;
|
|
23
|
+
const commander_1 = require("commander");
|
|
24
|
+
// ── Option factories ─────────────────────────────────────────────────
|
|
25
|
+
/** --url: Odoo base URL */
|
|
26
|
+
const urlOption = () => new commander_1.Option('--url <url>', 'Odoo URL').env('ODOO_URL');
|
|
27
|
+
exports.urlOption = urlOption;
|
|
28
|
+
/** --db: Database name */
|
|
29
|
+
const dbOption = () => new commander_1.Option('--db <db>', 'Database name').env('ODOO_DB');
|
|
30
|
+
exports.dbOption = dbOption;
|
|
31
|
+
/** --user: Username */
|
|
32
|
+
const userOption = () => new commander_1.Option('--user <user>', 'Username').env('ODOO_USERNAME');
|
|
33
|
+
exports.userOption = userOption;
|
|
34
|
+
/** --password: Password (use env var instead) */
|
|
35
|
+
const passwordOption = () => new commander_1.Option('--password <password>', 'Password ⚠ use env instead').env('ODOO_PASSWORD').hideHelp();
|
|
36
|
+
exports.passwordOption = passwordOption;
|
|
37
|
+
/** All auth options as a group */
|
|
38
|
+
function addAuthOptions(cmd) {
|
|
39
|
+
return cmd
|
|
40
|
+
.addOption((0, exports.urlOption)())
|
|
41
|
+
.addOption((0, exports.dbOption)())
|
|
42
|
+
.addOption((0, exports.userOption)())
|
|
43
|
+
.addOption((0, exports.passwordOption)());
|
|
44
|
+
}
|
|
45
|
+
/** --format: Output format */
|
|
46
|
+
const formatOption = () => new commander_1.Option('--format <format>', 'Output format: json | table | csv | ndjson').choices([
|
|
47
|
+
'json',
|
|
48
|
+
'table',
|
|
49
|
+
'csv',
|
|
50
|
+
'ndjson',
|
|
51
|
+
]);
|
|
52
|
+
exports.formatOption = formatOption;
|
|
53
|
+
/** --fields: Comma-separated fields */
|
|
54
|
+
const fieldsOption = () => new commander_1.Option('--fields <fields>', 'Comma-separated fields to include');
|
|
55
|
+
exports.fieldsOption = fieldsOption;
|
|
56
|
+
/** --domain: Odoo domain filter */
|
|
57
|
+
const domainOption = () => new commander_1.Option('--domain <domain>', 'Odoo domain filter (Python syntax): \'["name","=","Acme"]\'');
|
|
58
|
+
exports.domainOption = domainOption;
|
|
59
|
+
/** --domain-json: Strict JSON domain */
|
|
60
|
+
const domainJsonOption = () => new commander_1.Option('--domain-json <json>', 'Strict JSON domain: \'[["name","=","Acme"]]\'');
|
|
61
|
+
exports.domainJsonOption = domainJsonOption;
|
|
62
|
+
/** --domain-file: Read domain from file */
|
|
63
|
+
const domainFileOption = () => new commander_1.Option('--domain-file <file>', "Read domain from file ('-' for stdin)");
|
|
64
|
+
exports.domainFileOption = domainFileOption;
|
|
65
|
+
/** --filter: Simple K=V equality shorthand — repeatable, values collected into array */
|
|
66
|
+
const filterOption = () => new commander_1.Option('--filter <k=v>', "Simple equality filter (repeatable, AND'd)")
|
|
67
|
+
.argParser((val, prev = []) => [...prev, val])
|
|
68
|
+
.default([]);
|
|
69
|
+
exports.filterOption = filterOption;
|
|
70
|
+
/** --limit: Max records */
|
|
71
|
+
const limitOption = (defaultVal = 80) => new commander_1.Option('--limit <n>', `Max records (default: ${defaultVal}, 0 = all)`)
|
|
72
|
+
.default(defaultVal)
|
|
73
|
+
.argParser((v) => parseInt(v, 10));
|
|
74
|
+
exports.limitOption = limitOption;
|
|
75
|
+
/** --all: Fetch all records (--limit 0 alias) */
|
|
76
|
+
const allOption = () => new commander_1.Option('--all', 'Fetch all records (alias for --limit 0)');
|
|
77
|
+
exports.allOption = allOption;
|
|
78
|
+
/** --offset: Skip first N records */
|
|
79
|
+
const offsetOption = () => new commander_1.Option('--offset <n>', 'Skip first N records (default: 0)')
|
|
80
|
+
.default(0)
|
|
81
|
+
.argParser((v) => parseInt(v, 10));
|
|
82
|
+
exports.offsetOption = offsetOption;
|
|
83
|
+
/** --page-size: Paging chunk size */
|
|
84
|
+
const pageSizeOption = () => new commander_1.Option('--page-size <n>', 'Records per page when fetching all (default: 500)')
|
|
85
|
+
.default(500)
|
|
86
|
+
.argParser((v) => parseInt(v, 10));
|
|
87
|
+
exports.pageSizeOption = pageSizeOption;
|
|
88
|
+
/** --order: Sort order */
|
|
89
|
+
const orderOption = () => new commander_1.Option('--order <order>', 'Sort: "date_order desc,name asc"');
|
|
90
|
+
exports.orderOption = orderOption;
|
|
91
|
+
/** --count: Print count instead of records */
|
|
92
|
+
const countOption = () => new commander_1.Option('--count', 'Print count instead of records');
|
|
93
|
+
exports.countOption = countOption;
|
|
94
|
+
/** --confirm: Required for WRITE/DESTRUCTIVE */
|
|
95
|
+
const confirmOption = () => new commander_1.Option('--confirm', 'Confirm mutation (required for WRITE/DESTRUCTIVE operations)');
|
|
96
|
+
exports.confirmOption = confirmOption;
|
|
97
|
+
/** --dry-run: Preview without executing */
|
|
98
|
+
const dryRunOption = () => new commander_1.Option('--dry-run', 'Show RPC call without executing — does not require --confirm');
|
|
99
|
+
exports.dryRunOption = dryRunOption;
|
|
100
|
+
/** --context: Extra Odoo context JSON */
|
|
101
|
+
const contextOption = () => new commander_1.Option('--context <json>', 'Extra Odoo context: \'{"lang":"fr_FR","company_id":3}\'');
|
|
102
|
+
exports.contextOption = contextOption;
|
|
103
|
+
/** --no-color: Disable ANSI colors */
|
|
104
|
+
const noColorOption = () => new commander_1.Option('--no-color', 'Disable ANSI colors').env('NO_COLOR');
|
|
105
|
+
exports.noColorOption = noColorOption;
|
|
106
|
+
/** --quiet: Suppress stderr progress/warnings */
|
|
107
|
+
const quietOption = () => new commander_1.Option('-q, --quiet', 'Suppress stderr progress and warnings');
|
|
108
|
+
exports.quietOption = quietOption;
|
|
109
|
+
/** --experimental: Required for experimental commands */
|
|
110
|
+
const experimentalOption = () => new commander_1.Option('--experimental', 'Enable experimental features (required for `state` commands)');
|
|
111
|
+
exports.experimentalOption = experimentalOption;
|
|
112
|
+
// ── Option groups ────────────────────────────────────────────────────
|
|
113
|
+
/**
|
|
114
|
+
* Add search/filter options to a command.
|
|
115
|
+
* Used by: records search, records count, attendance list, timesheets list, etc.
|
|
116
|
+
*/
|
|
117
|
+
function addSearchOptions(cmd) {
|
|
118
|
+
return cmd
|
|
119
|
+
.addOption((0, exports.domainOption)())
|
|
120
|
+
.addOption((0, exports.domainJsonOption)())
|
|
121
|
+
.addOption((0, exports.domainFileOption)())
|
|
122
|
+
.addOption((0, exports.filterOption)());
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Add pagination options to a command.
|
|
126
|
+
*/
|
|
127
|
+
function addPaginationOptions(cmd, defaultLimit = 80) {
|
|
128
|
+
return cmd
|
|
129
|
+
.addOption((0, exports.limitOption)(defaultLimit))
|
|
130
|
+
.addOption((0, exports.allOption)())
|
|
131
|
+
.addOption((0, exports.offsetOption)())
|
|
132
|
+
.addOption((0, exports.pageSizeOption)())
|
|
133
|
+
.addOption((0, exports.orderOption)());
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Add output options (format + fields) to a command.
|
|
137
|
+
*/
|
|
138
|
+
function addOutputOptions(cmd) {
|
|
139
|
+
return cmd.addOption((0, exports.formatOption)()).addOption((0, exports.fieldsOption)());
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Add write safety options to a command.
|
|
143
|
+
*/
|
|
144
|
+
function addWriteOptions(cmd) {
|
|
145
|
+
return cmd.addOption((0, exports.confirmOption)()).addOption((0, exports.dryRunOption)()).addOption((0, exports.contextOption)());
|
|
146
|
+
}
|
|
147
|
+
// ── Helpers ──────────────────────────────────────────────────────────
|
|
148
|
+
/**
|
|
149
|
+
* Parse --fields value into an array of field names.
|
|
150
|
+
* Returns empty array if not specified (means "all fields").
|
|
151
|
+
*/
|
|
152
|
+
function parseFields(fields) {
|
|
153
|
+
if (!fields)
|
|
154
|
+
return [];
|
|
155
|
+
return fields
|
|
156
|
+
.split(',')
|
|
157
|
+
.map((f) => f.trim())
|
|
158
|
+
.filter(Boolean);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Resolve the effective limit.
|
|
162
|
+
* --all overrides --limit (sets to 0 = all).
|
|
163
|
+
*/
|
|
164
|
+
function resolveLimit(options) {
|
|
165
|
+
if (options.all)
|
|
166
|
+
return 0;
|
|
167
|
+
return options.limit ?? 80;
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=common-params.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common-params.js","sourceRoot":"","sources":["../../src/middleware/common-params.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safety enforcement middleware for odoo-cli.
|
|
3
|
+
*
|
|
4
|
+
* Every command has a safety level: READ | WRITE | DESTRUCTIVE.
|
|
5
|
+
*
|
|
6
|
+
* - READ: No requirements. Safe to run anywhere.
|
|
7
|
+
* - WRITE: Requires --confirm. Clear error if missing.
|
|
8
|
+
* - DESTRUCTIVE: Requires --confirm. Prints a DESTRUCTIVE warning.
|
|
9
|
+
*
|
|
10
|
+
* The CLI enforces safety at the command level, independently of the
|
|
11
|
+
* odoo-client safety guard (which uses a confirm callback). Here we
|
|
12
|
+
* use a simpler model: just check if the --confirm flag is present.
|
|
13
|
+
*/
|
|
14
|
+
export type SafetyLevel = 'READ' | 'WRITE' | 'DESTRUCTIVE';
|
|
15
|
+
export interface SafetyOptions {
|
|
16
|
+
confirm?: boolean;
|
|
17
|
+
dryRun?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Assert that a WRITE or DESTRUCTIVE operation has --confirm.
|
|
21
|
+
*
|
|
22
|
+
* Throws CliUsageError (exit 1) if --confirm is missing.
|
|
23
|
+
* In --dry-run mode, skips the check (we're not actually mutating).
|
|
24
|
+
*/
|
|
25
|
+
export declare function requireConfirm(level: SafetyLevel, options: SafetyOptions, commandDescription: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Format a dry-run message to stderr showing what WOULD be called.
|
|
28
|
+
*/
|
|
29
|
+
export declare function printDryRun(model: string, method: string, args: any[], kwargs?: Record<string, any>): void;
|
|
30
|
+
//# sourceMappingURL=safety.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safety.d.ts","sourceRoot":"","sources":["../../src/middleware/safety.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,aAAa,EACtB,kBAAkB,EAAE,MAAM,GACzB,IAAI,CA0BN;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,GAAG,EAAE,EACX,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAC/B,IAAI,CAQN"}
|