Document the JSON schemata used by show and search
[notmuch] / devel / schemata
1 This file describes the schemata used for notmuch's structured output
2 format (currently JSON).
3
4 []'s indicate lists.  List items can be marked with a '?', meaning
5 they are optional; or a '*', meaning there can be zero or more of that
6 item.  {}'s indicate an object that maps from field identifiers to
7 values.  An object field marked '?' is optional.  |'s indicate
8 alternates (e.g., int|string means something can be an int or a
9 string).
10
11 Common non-terminals
12 --------------------
13
14 # Number of seconds since the Epoch
15 unix_time = int
16
17 # Thread ID, sans "thread:"
18 threadid = string
19
20 # Message ID, sans "id:"
21 messageid = string
22
23 notmuch show schema
24 -------------------
25
26 # A top-level set of threads (do_show)
27 # Returned by notmuch show without a --part argument
28 thread_set = [thread*]
29
30 # Top-level messages in a thread (show_messages)
31 thread = [thread_node*]
32
33 # A message and its replies (show_messages)
34 thread_node = [
35     message?,                 # present if --entire-thread or matched
36     [thread_node*]            # children of message
37 ]
38
39 # A message (show_message)
40 message = {
41     # (format_message_json)
42     id:             messageid,
43     match:          bool,
44     filename:       string,
45     timestamp:      unix_time, # date header as unix time
46     date_relative:  string,   # user-friendly timestamp
47     tags:           [string*],
48
49     headers:        headers,
50     body:           [part]
51 }
52
53 # A MIME part (show_message_body)
54 part = {
55     # format_part_start_json
56     id:             int|string, # part id (currently DFS part number)
57
58     # format_part_encstatus_json
59     encstatus?:     encstatus,
60
61     # format_part_sigstatus_json
62     sigstatus?:     sigstatus,
63
64     # format_part_content_json
65     content-type:   string,
66     content-id?:    string,
67     # if content-type starts with "multipart/":
68     content:        [part*],
69     # if content-type is "message/rfc822":
70     content:        [{headers: headers, body: [part]}],
71     # otherwise (leaf parts):
72     filename?:      string,
73     content-charset?: string,
74     # A leaf part's body content is optional, but may be included if
75     # it can be correctly encoded as a string.  Consumers should use
76     # this in preference to fetching the part content separately.
77     content?:       string
78 }
79
80 # The headers of a message (format_headers_json with raw headers) or
81 # a part (format_headers_message_part_json with pretty-printed headers)
82 headers = {
83     Subject:        string,
84     From:           string,
85     To?:            string,
86     Cc?:            string,
87     Bcc?:           string,
88     Date:           string
89 }
90
91 # Encryption status (format_part_encstatus_json)
92 encstatus = [{status: "good"|"bad"}]
93
94 # Signature status (format_part_sigstatus_json)
95 sigstatus = [signature*]
96
97 signature = {
98     # signature_status_to_string
99     status:         "none"|"good"|"bad"|"error"|"unknown",
100     # if status is "good":
101     fingerprint?:   string,
102     created?:       unix_time,
103     expires?:       unix_time,
104     userid?:        string
105     # if status is not "good":
106     keyid?:         string
107     # if the signature has errors:
108     errors?:        int
109 }
110
111 notmuch search schema
112 ---------------------
113
114 # --output=summary
115 summary = [thread*]
116
117 # --output=threads
118 threads = [threadid*]
119
120 # --output=messages
121 messages = [messageid*]
122
123 # --output=files
124 files = [string*]
125
126 # --output=tags
127 tags = [string*]
128
129 thread = {
130     thread:         threadid,
131     timestamp:      unix_time,
132     date_relative:  string,   # user-friendly timestamp
133     matched:        int,      # number of matched messages
134     total:          int,      # total messages in thread
135     authors:        string,   # comma-separated names with | between
136                               # matched and unmatched
137     subject:        string
138 }