Skip to content

Commit 0186282

Browse files
committed
doveadm: Abstract data parsing code out into reusable library/module
1 parent 8b715fd commit 0186282

File tree

4 files changed

+203
-196
lines changed

4 files changed

+203
-196
lines changed

data/doveadm.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { doveadm_arg_types,
33
doveadm_args_human_timestamp,
44
doveadm_args_query,
55
doveadm_args_usermask,
6-
doveadm_flag_types } from '../lib/doveadm.js'
6+
doveadm_flag_types } from '../lib/constants/doveadm.js'
77

88
export const doveadm = {
99

lib/constants/doveadm.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* List of Doveadm argument value types. */
2+
export const doveadm_arg_types = {
3+
ARRAY: 1,
4+
BOOL: 2,
5+
INTEGER: 3,
6+
STRING: 4,
7+
SEARCH_QUERY: 5, // Search query is an ARG_ARRAY
8+
ISTREAM: 6,
9+
}
10+
11+
/* List of Doveadm flag value types. */
12+
export const doveadm_flag_types = {
13+
NONE: 0,
14+
USER: 1,
15+
USERFILE: 2,
16+
USERMASK: 4,
17+
}
18+
19+
export const doveadm_args_query = {
20+
example: ['mailbox', 'INBOX/myfoldertoo', 'savedbefore', 'since', '30d'],
21+
positional: true,
22+
type: doveadm_arg_types.SEARCH_QUERY,
23+
text: `Search query to apply.`,
24+
}
25+
26+
export const doveadm_args_usermask = {
27+
example: 'username',
28+
positional: true,
29+
type: doveadm_arg_types.STRING,
30+
text: `User Mask.`
31+
}
32+
33+
export const doveadm_args_human_timestamp = `
34+
Allowable formats:
35+
36+
* yyyy-mm-dd (non-UTC),
37+
* IMAP date ("dd-mm-yyyy"; see [[rfc,3501]]) (non-UTC)
38+
* IMAP date-time ("dd-mm-yyy HH:MM:SS +0000; see [[rfc,3501]]) (UTC supported)
39+
* Unix timestamp (UTC supported)
40+
* Interval ("n days", UTC supported)`

lib/data/doveadm.data.js

Lines changed: 3 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,8 @@
1-
import { doveadm_arg_types, doveadm_flag_types, getDoveadmCmdLine } from '../doveadm.js'
2-
import { getVitepressMd } from '../markdown.js'
3-
import { addWatchPaths, loadData, normalizeArrayData } from '../utility.js'
4-
import camelCase from 'camelcase'
5-
import slugify from '@sindresorhus/slugify'
6-
7-
const doveadm_userargs = {
8-
'all-users': {
9-
cli: 'A',
10-
example: false,
11-
type: doveadm_arg_types.BOOL,
12-
text: `Apply operation to all users.`
13-
},
14-
'socket-path': {
15-
cli: 'S',
16-
example: '/var/run/dovecot/doveadm-server',
17-
type: doveadm_arg_types.STRING,
18-
text: `Path to doveadm socket.`
19-
},
20-
user: {
21-
cli: 'u',
22-
example: 'username',
23-
type: doveadm_arg_types.STRING,
24-
text: `UID of user to apply operation to.`,
25-
},
26-
}
27-
28-
const doveadm_userfileargs = {
29-
/* Hidden from documentation.
30-
'trans-flags': {
31-
type: doveadm_arg_types.INTEGER,
32-
text: `Transaction flags.`
33-
},
34-
*/
35-
'user-file': {
36-
cli: 'F',
37-
type: doveadm_arg_types.STRING,
38-
text: `A filename. If set, fetch usernames from file. One username per line.`
39-
},
40-
}
41-
42-
function typeToString(type) {
43-
switch (type) {
44-
case doveadm_arg_types.ARRAY:
45-
return 'array'
46-
case doveadm_arg_types.BOOL:
47-
return 'boolean'
48-
case doveadm_arg_types.INTEGER:
49-
return 'integer'
50-
case doveadm_arg_types.STRING:
51-
return 'string'
52-
case doveadm_arg_types.SEARCH_QUERY:
53-
return 'search_query'
54-
case doveadm_arg_types.ISTREAM:
55-
return 'istream'
56-
}
57-
}
58-
59-
function argToHttpParam(arg) {
60-
return arg.split('-').reduce((s, c) =>
61-
s + (c.charAt(0).toUpperCase() + c.slice(1)))
62-
}
63-
64-
async function normalizeDoveadm(doveadm) {
65-
const md = await getVitepressMd()
66-
67-
for (const [k, v] of Object.entries(doveadm)) {
68-
if (!v) {
69-
delete doveadm[k]
70-
continue
71-
}
72-
73-
if (v.flags && (v.flags & doveadm_flag_types.USER)) {
74-
v.args = { ...v.args, ...doveadm_userargs }
75-
}
76-
77-
if (v.flags && (v.flags & doveadm_flag_types.USERFILE)) {
78-
v.args = { ...v.args, ...doveadm_userfileargs }
79-
}
80-
81-
/* Convert 'man' entry into a markdown link to man page.
82-
* We will add the hash to all URLs for simplicity; for those man
83-
* pages that don't have individual command names, this will just
84-
* be ignored by the browser. */
85-
if (v.man) {
86-
v.man_link = md.renderInline('[[man,' + v.man + ',' + slugify(k) + ']]')
87-
}
88-
89-
/* Change entries. */
90-
for (const k2 of ['added', 'changed', 'deprecated', 'removed']) {
91-
if (v[k2]) {
92-
const changes = []
93-
for (const[k3, v3] of Object.entries(v[k2])) {
94-
changes.push({
95-
text: v3 ? md.render(v3.trim()) : null,
96-
version: md.renderInline('[[' + k2 + ',' + k3 + ']]')
97-
})
98-
}
99-
v[k2] = changes
100-
}
101-
}
102-
103-
/* Response values. */
104-
if (v.response) {
105-
if (v.response.text) {
106-
v.response.text = md.render(String(v.response.text))
107-
}
108-
} else {
109-
delete v['response']
110-
}
111-
112-
/* Text Description. */
113-
if (v.text) {
114-
v.text = md.render(v.text)
115-
}
116-
117-
/* Cmd line arguments. */
118-
v.usage = k + (v.args ? ' ' + getDoveadmCmdLine(v.args) : '')
119-
120-
if (v.args) {
121-
const args = []
122-
for (const [k2, v2] of Object.entries(v.args)) {
123-
if (!v2.hidden) {
124-
args.push({
125-
/* Undefined examples will resolve to undefined. */
126-
cli_only: v2.cli_only,
127-
example: v2.example,
128-
flag: v2.cli ? '-' + v2.cli : (v2.positional ? k2 : '--' + k2),
129-
param: argToHttpParam(k2),
130-
type: typeToString(v2.type),
131-
text: v2.text ? md.render(v2.text) : null
132-
})
133-
}
134-
}
135-
v.args = args
136-
}
137-
if (!v.args || !v.args.length) {
138-
delete v['args']
139-
}
140-
141-
/* HTTP API info. */
142-
v.http_cmd = camelCase(k)
143-
}
144-
145-
return {
146-
doveadm: normalizeArrayData(
147-
doveadm,
148-
['tags']
149-
),
150-
http_api_link: md.renderInline('[[link,doveadm_http_api,HTTP API]]')
151-
}
152-
}
1+
import { addWatchPaths } from '../utility.js'
2+
import { loadDoveadm } from '../doveadm.js'
1533

1544
export default addWatchPaths({
1555
async load() {
156-
return await normalizeDoveadm(
157-
structuredClone(loadData('doveadm').doveadm)
158-
)
6+
return await loadDoveadm()
1597
}
1608
})

0 commit comments

Comments
 (0)