### Common Import Path: Standard Application Setup Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/package-structure.md This import path is used for standard application setups requiring both the core JMAP types and the client. ```go // Standard setup import ( "github.com/foxcpp/go-jmap" "github.com/foxcpp/go-jmap/client" ) ``` -------------------------------- ### Full Featured Client Setup with Autodiscovery Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/package-structure.md This setup includes autodiscovery, client initialization, and registration of custom unmarshalers for handling specific JMAP methods. ```go import ( "encoding/json" "github.com/foxcpp/go-jmap" "github.com/foxcpp/go-jmap/client" "github.com/foxcpp/go-jmap/autodiscovery" ) // Discover + Initialize + Configure sessionURL, _ := autodiscovery.Probe("example.com") cl, _ := client.New(sessionURL, authToken) // Register custom unmarshalers unmarshallers := map[string]jmap.FuncArgsUnmarshal{ "Core/echo": func(args json.RawMessage) (interface{}, error) { return args, nil }, } cl.Enable(unmarshallers) ``` -------------------------------- ### Minimal Client Setup Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/package-structure.md Use this import pattern for basic client initialization when only the client package is needed. ```go import ( "github.com/foxcpp/go-jmap/client" ) cl, _ := client.New(sessionURL, authToken) ``` -------------------------------- ### Common Import Path: Minimal Application Setup Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/package-structure.md This is the minimal import path for application code using the go-jmap client. ```go // Minimal setup import "github.com/foxcpp/go-jmap/client" ``` -------------------------------- ### JMAP Method Responses for Email Query and Get Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Example JMAP method responses for 'Email/query', 'Email/get', and 'Thread/get' calls. These illustrate the structure of returned data, including IDs, states, and lists of objects. ```json [[ "Email/query", { "accountId": "A1", "queryState": "abcdefg", "canCalculateChanges": true, "position": 0, "total": 101, "ids": [ "msg1023", "msg223", "msg110", "msg93", "msg91", "msg38", "msg36", "msg33", "msg11", "msg1" ] }, "t0" ]] ``` ```json [[ "Email/get", { "accountId": "A1", "state": "123456", "list": [{ "id": "msg1023", "threadId": "trd194" }, { "id": "msg223", "threadId": "trd114" }, ... ], "notFound": [] }, "t1" ]] ``` ```json [[ "Thread/get", { "accountId": "A1", "state": "123456", "list": [{ "id": "trd194", "emailIds": [ "msg1020", "msg1021", "msg1023" ] }, { "id": "trd114", "emailIds": [ "msg201", "msg223" ] }, ... ], "notFound": [] }, "t2" ]] ``` -------------------------------- ### Core Types Only Setup Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/package-structure.md Import only the core JMAP package when you need to use JMAP types without the client functionality. ```go import ( "github.com/foxcpp/go-jmap" ) // Use types without client id, _ := jmap.RandomID() var date jmap.Date ``` -------------------------------- ### Example JMAP Request Object Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Demonstrates the structure of a JMAP request, including 'using' for capabilities and 'methodCalls' for operations. ```json { "using": [ "urn:ietf:params:jmap:core", "urn:ietf:params:jmap:mail" ], "methodCalls": [ [ "method1", { "arg1": "arg1data", "arg2": "arg2data" }, "c1" ], [ "method2", { "arg1": "arg1data" }, "c2" ], [ "method3", {}, "c3" ] ] } ``` -------------------------------- ### Common Import Path: Application Setup with Autodiscovery Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/package-structure.md This import path is for application code that utilizes autodiscovery along with core JMAP types and the client. ```go // With autodiscovery import ( "github.com/foxcpp/go-jmap" "github.com/foxcpp/go-jmap/client" "github.com/foxcpp/go-jmap/autodiscovery" ) ``` -------------------------------- ### JMAP StateChange Object Example Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt An example of a StateChange object pushed from the server to the client, indicating changes in various JMAP objects across different accounts. ```json { "@type": "StateChange", "changed": { "a3123": { "Email": "d35ecb040aab", "EmailDelivery": "428d565f2440", "CalendarEvent": "87accfac587a" }, "a43461d": { "Mailbox": "0af7a512ce70", "CalendarEvent": "7a4297cecd76" } } } ``` -------------------------------- ### Example JMAP Response Object Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Illustrates a JMAP response, showing 'methodResponses' with results or errors, and 'sessionState'. ```json { "methodResponses": [ [ "method1", { "arg1": 3, "arg2": "foo" }, "c1" ], [ "method2", { "isBlah": true }, "c2" ], [ "anotherResponseFromMethod2", { "data": 10, "yetmoredata": "Hello" }, "c2"], [ "error", { "type":"unknownMethod" }, "c3" ] ], "sessionState": "75128aab4b1b" } ``` -------------------------------- ### JMAP Session Object Example Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt An example of a JMAP Session object illustrating user capabilities, including mail, contacts, and a custom capability. It shows how the server advertises supported features and user access levels. ```json { "capabilities": { "urn:ietf:params:jmap:core": { "maxSizeUpload": 50000000, } } } ``` -------------------------------- ### Core/echo Method Request Example Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Demonstrates a typical request to the _Core/echo_ method, which is used for testing JMAP API connectivity. It includes method name, arguments, and a request ID. ```jmap [[ "Core/echo", { "hello": true, "high": 5 }, "b3ff" ]] ``` -------------------------------- ### JMAP Todo Get Response Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Example of a JMAP response containing a list of Todo objects, including their IDs, titles, keywords, and estimated neural network time. This shows the structure of data returned by a Todo/get request. ```json [[ "Todo/get", { "accountId": "x", "state": "10324", "list": [ { "id": "a", "title": "Practise Piano", "keywords": { "music": true, "beethoven": true, "mozart": true, "liszt": true, "rachmaninov": true }, "neuralNetworkTimeEstimation": 3600 }, { "id": "b", "title": "Watch Daft Punk music video", "keywords": { "music": true, "video": true, "trance": true }, "neuralNetworkTimeEstimation": 18000 } ] }, "1" ]] ``` -------------------------------- ### BlobInfo Structure Example Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/types.md Demonstrates how to access fields of the BlobInfo structure, which contains metadata about a successfully uploaded binary blob. This includes account ID, blob ID, MIME type, and file size. ```go blobInfo, _ := cl.Upload(accountID, file) fmt.Printf("Account: %s\n", blobInfo.AccountID) fmt.Printf("Blob ID: %s\n", blobInfo.BlobID) fmt.Printf("Type: %s\n", blobInfo.Type) fmt.Printf("Size: %d bytes\n", blobInfo.Size) ``` -------------------------------- ### JMAP Todo/query Method Call Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Example of a JMAP method call to query Todo items, filtering by keywords 'music' or 'video' and sorting by title. ```json [ "Todo/query", { "accountId": "x", "filter": { "operator": "OR", "conditions": [ { "hasKeyword": "music" }, { "hasKeyword": "video" } ] }, "sort": [{ "property": "title" }], "position": 0, "limit": 10 }, "0" ] ``` ```json [ "Todo/get", { "accountId": "x", "#ids": { "resultOf": "0", "name": "Todo/query", "path": "/ids" } }, "1" ] ``` -------------------------------- ### Example JMAP Core/echo Method Request Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt A JMAP request to the Core/echo method. This method is used for testing and demonstrating the request/response cycle by echoing back the provided arguments. ```json { "using": { "urn:ietf:params:jmap:core": "/jmap/core/" }, "args": { "sessionState": "abc123xyz", "data": { "hello": "world", "number": 123 } } } ``` -------------------------------- ### JMAP Todo Copy and Set Response Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Example of a JMAP response for a copy operation, showing the copied item in the new account and the original item being set (destroyed) in the old account. ```json [[ "Todo/copy", { "fromAccountId": "x", "accountId": "y", "created": { "k5122": { "id": "DAf97" } }, "oldState": "c1d64ecb038c", "newState": "33844835152b" }, "0" ], [ "Todo/set", { "accountId": "x", "oldState": "871903", "newState": "871909", "destroyed": [ "a" ], "...": "..." }, "0" ]] ``` -------------------------------- ### Example JMAP Request Object Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt A sample JMAP request object demonstrating the structure for invoking methods. It includes a 'using' property to specify capabilities and an 'args' object for method parameters. ```json { "using": { "urn:ietf:params:jmap:core": "/jmap/core/", "urn:ietf:params:jmap:mail": "/jmap/mail/" }, "args": { "sessionState": "abc123xyz", "maxObjects": 500, "types": ["Message"], "ids": ["msg1", "msg2"] } } ``` -------------------------------- ### JMAP Todo Query Request Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Example of a JMAP request to query for Todos with specific keywords, sorted by title and limited to the first 10 results. This demonstrates the structure for filtering and sorting. ```json [[ "Todo/query", { "accountId": "x", "filter": { "keywords": [ "music", "video" ] }, "sort": [ { "property": "title" } ], "limit": 10 }, "1" ]] ``` -------------------------------- ### JMAP Todo Set Request (Create with Reference) Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Example of a JMAP 'Todo/set' request to create a new subtodo and link it to an existing todo using a creation ID reference. This demonstrates creating related records within the same request. ```json [[ "Todo/set", { "accountId": "x", "create": { "k15": { "title": "Warm up with scales" } }, "update": { "a": { "subTodoIds": [ "#k15" ] } } }, "0" ]] ``` -------------------------------- ### Accessing JMAP Core Capability Fields Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/api-reference-session.md Demonstrates how to access and print various fields of the JMAP Core capability, such as maximum objects for get and set operations, and the list of supported collation algorithms. This snippet is useful for understanding the limits and configurations of a JMAP session. ```go cap := session.CoreCapability fmt.Printf("Max objects per get: %d\n", cap.MaxObjectsInGet) fmt.Printf("Max objects per set: %d\n", cap.MaxObjectsInSet) fmt.Printf("Supported collations: %v\n", cap.CollationAlgorithms) ``` -------------------------------- ### Initialize and Echo Client Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/INDEX.md Demonstrates the basic steps to initialize a client and perform an Echo test. ```go 1. Create client → client.New() 2. Automatic Session fetch 3. Test → client.Echo() ``` -------------------------------- ### Discover Endpoint and Connect Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/INDEX.md Shows how to discover the JMAP endpoint and establish a client connection. ```go 1. Discover endpoint → autodiscovery.Probe() 2. Create client → client.New() 3. Access Session info ``` -------------------------------- ### Initialize JMAP Client Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/api-reference-overview.md Use this to create a new JMAP client instance. Requires the session URL and an authorization header. ```go import ( "github.com/foxcpp/go-jmap" "github.com/foxcpp/go-jmap/client" ) // Initialize client cl, err := client.New(sessionURL, authHeader) ``` -------------------------------- ### New Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/api-reference-client.md Creates a new JMAP Core client using http.DefaultClient. It initializes the client and fetches the Session object immediately. ```APIDOC ## New ### Description Creates a new JMAP Core client using `http.DefaultClient` for all requests. The Session object is fetched immediately during initialization. ### Signature ```go func New(sessionURL, authHeader string) (*Client, error) ``` ### Parameters #### Path Parameters - **sessionURL** (string) - Required - URL of the JMAP Session endpoint (e.g., `https://mail.example.com/.well-known/jmap`). - **authHeader** (string) - Required - Value for the `Authentication` HTTP header (typically a bearer token). ### Returns - **`*Client`** - Initialized client with Session already loaded. - **`error`** - Error if Session fetch fails or parameters are invalid. ### Example ```go cl, err := client.New("https://mail.example.com/.well-known/jmap", "Bearer token123") if err != nil { log.Fatal(err) } // Client is ready to use ``` ``` -------------------------------- ### Configure Session Endpoint via Constructor Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/configuration.md Use the client.New constructor to set the session URL and authentication header, which configures the session endpoint. ```go cl, err := client.New( "https://mail.example.com/.well-known/jmap", "Bearer token123", ) ``` -------------------------------- ### JMAP Todo Query Request Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Example of a JMAP request to query for changes in a Todo list, with filtering, sorting, and state tracking. ```json [[ "Todo/queryChanges", { "accountId": "x", "filter": { "operator": "OR", "conditions": [ { "hasKeyword": "music" }, { "hasKeyword": "video" } ] }, "sort": [{ "property": "title" }], "sinceQueryState": "y13213", "maxChanges": 50 }, "0" ]] ``` -------------------------------- ### Example JMAP Core/echo Method Response Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt The response from the Core/echo method. It returns the same 'data' object that was sent in the request, confirming successful processing. ```json { "sessionState": "abc123xyz", "methodResponses": [ ["Core", "echo", { "data": { "hello": "world", "number": 123 } }] ] } ``` -------------------------------- ### Initialize JMAP Client Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/quick-start.md Create a new JMAP client with a known endpoint and authentication token. The client automatically fetches the Session object upon initialization. ```go import ( "github.com/foxcpp/go-jmap/client" ) // Create client with known endpoint cl, err := client.New( "https://mail.example.com/.well-known/jmap", "Bearer your-auth-token", ) if err != nil { log.Fatal(err) } ``` -------------------------------- ### Upload File and Reference Blob Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/INDEX.md Explains how to upload a file, retrieve its information, and use the BlobID in subsequent requests. ```go 1. Upload file → client.Upload() 2. Get BlobInfo with BlobID 3. Reference BlobID in subsequent requests ``` -------------------------------- ### JMAP Todo Query Changes Response Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Example of a JMAP response for a queryChanges method, detailing removed and added items based on query state. ```json [[ "Todo/queryChanges", { "accountId": "x", "oldQueryState": "y13213", "newQueryState": "y13218", "removed": ["b"], "added": null }, "1" ]] ``` -------------------------------- ### JMAP Query Changes Example Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Illustrates how a client might update its cached sparse array of IDs based on removed and added items from a query. ```text fooIds = [ "id1", "id2", null, null, "id3", "id4", null, null, null ] removed = [ "id2", "id31", ... ]; fooIds => [ "id1", null, null, "id3", "id4", null, null, null ] added = [{ id: "id5", index: 0, ... }]; fooIds => [ "id5", "id1", null, null, "id3", "id4", null, null, null ] ``` -------------------------------- ### Configure HTTP Client with NewWithClient Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/configuration.md Pass a custom-configured http.Client to NewWithClient to control timeout, TLS configuration, proxy settings, connection pooling, cookies, and redirect handling. ```go httpClient := &http.Client{ Timeout: 30 * time.Second, Transport: &http.Transport{ MaxIdleConns: 100, MaxIdleConnsPerHost: 10, TLSClientConfig: &tls.Config{ InsecureSkipVerify: false, // Always verify in production }, }, } cl, err := client.NewWithClient( httpClient, "https://mail.example.com/.well-known/jmap", "Bearer token123", ) ``` -------------------------------- ### One-Time Client Connection Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/usage-patterns.md Use this pattern for scripts or CLI tools that require a single request. It establishes a new client connection for each operation. ```go func main() { cl, err := client.New( "https://mail.example.com/.well-known/jmap", "Bearer token", ) if err != nil { log.Fatal(err) } // Make request batch := &client.Batch{} batch.Add("Core/echo", map[string]interface{}{}) resp, err := cl.RawSend(batch.Request()) if err != nil { log.Fatal(err) } for _, inv := range resp.Responses { fmt.Printf("Call ID: %s\n", inv.CallID) } } ``` -------------------------------- ### Get Nth Call ID from Batch Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/api-reference-client.md Retrieve the call ID for a specific call within a batch. Call IDs are 0-based numeric strings. ```go bt := &client.Batch{} bt.Add("Core/echo", map[string]interface{}{}) bt.Add("Core/echo", map[string]interface{}{}) id := bt.NthCallID(1) // "0" (first call) id = bt.NthCallID(2) // "1" (second call) ``` -------------------------------- ### JMAP Todo Copy Request Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Example of a JMAP request to copy a Todo item from one account to another, with an option to destroy the original upon success. ```json [[ "Todo/copy", { "fromAccountId": "x", "accountId": "y", "create": { "k5122": { "id": "a" } }, "onSuccessDestroyOriginal": true }, "0" ]] ``` -------------------------------- ### Batch Operations Respecting Limits Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/INDEX.md Details how to manage batch operations according to server-defined limits for efficiency. ```go 1. Check server limits → session.CoreCapability 2. Split large operations into size-limited batches 3. Send each batch → client.RawSend() 4. Combine results ``` -------------------------------- ### NewWithClient Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/api-reference-client.md Creates a new JMAP Core client using a user-provided HTTP client. It initializes the client and fetches the Session object immediately. ```APIDOC ## NewWithClient ### Description Creates a new JMAP Core client using a user-provided HTTP client for all requests. The Session object is fetched immediately during initialization. ### Signature ```go func NewWithClient(cl *http.Client, sessionURL, authHeader string) (*Client, error) ``` ### Parameters #### Path Parameters - **cl** (*http.Client) - Required - Custom HTTP client to use for requests. - **sessionURL** (string) - Required - URL of the JMAP Session endpoint. - **authHeader** (string) - Required - Value for the `Authentication` HTTP header. ### Returns - **`*Client`** - Initialized client with Session already loaded. - **`error`** - Error if Session fetch fails. ### Example ```go httpClient := &http.Client{ Timeout: 30 * time.Second, } cl, err := client.NewWithClient(httpClient, sessionURL, authHeader) if err != nil { log.Fatal(err) } ``` ``` -------------------------------- ### Request-Level Error: Limit Exceeded Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt An example of a JSON 'problem details' object for a request-level limit error. This occurs when a request exceeds server-defined limits like maxSizeRequest. ```json { "type": "urn:ietf:params:jmap:error:limit", "limit": "maxSizeRequest", "status": 400, "detail": "The request is larger than the server is willing to process." } ``` -------------------------------- ### Download File with Progress Tracking Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/usage-patterns.md Downloads a file from the JMAP server to a local path, copying data with progress indication. Requires account ID, blob ID, and output path. ```go func downloadFileWithProgress(cl *client.Client, accountID, blobID, outputPath string) error { reader, err := cl.Download(jmap.ID(accountID), jmap.ID(blobID)) if err != nil { return err } defer reader.Close() outFile, err := os.Create(outputPath) if err != nil { return err } defer outFile.Close() fmt.Printf("Downloading to %s... ", outputPath) // Copy with progress (optionally wrap reader with progress tracker) written, err := io.Copy(outFile, reader) if err != nil { return err } fmt.Printf("Download complete: %d bytes ", written) return nil } ``` -------------------------------- ### Request-Level Error: Unknown Capability Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt An example of a JSON 'problem details' object returned for an unknown capability error. This indicates the client requested a capability the server does not support. ```json { "type": "urn:ietf:params:jmap:error:unknownCapability", "status": 400, "detail": "The request object used capability 'https://example.com/apis/foobar', which is not supported by this server." } ``` -------------------------------- ### Example JMAP Method Result with References Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt A JMAP response demonstrating the use of references to previous method results. The 'NewMessage' ID is a reference to a previously created message. ```json { "sessionState": "abc123xyz", "methodResponses": [ ["Message", "set", { "created": { "NewMessage": { "id": "msg4", "from": {"name": "Bob", "email": "bob@example.com"}, "to": [{"name": "Alice", "email": "alice@example.com"}], "subject": "Re: Re: Hello", "date": "2019-03-18T14:10:00Z" } }, "updated": {}, "destroyed": [] }] ] } ``` -------------------------------- ### Complete JMAP Discovery and Connection Flow Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/api-reference-autodiscovery.md Illustrates a typical end-to-end process for discovering a JMAP server endpoint using DNS SRV records, initializing a client, performing a health check, and accessing session information. ```go package main import ( "fmt" "log" "github.com/foxcpp/go-jmap/autodiscovery" "github.com/foxcpp/go-jmap/client" ) func main() { domain := "example.com" authToken := "Bearer token123" // Step 1: Discover JMAP endpoint via DNS SRV sessionURL, err := autodiscovery.Probe(domain) if err != nil { log.Fatalf("Autodiscovery failed: %v\n", err) } fmt.Printf("Discovered endpoint: %s\n", sessionURL) // Step 2: Create client with discovered endpoint cl, err := client.New(sessionURL, authToken) if err != nil { log.Fatalf("Client initialization failed: %v\n", err) } // Step 3: Use client if err := cl.Echo(); err != nil { log.Fatalf("Server health check failed: %v\n", err) } fmt.Println("Connected successfully!") // Step 4: Access session info session := cl.Session fmt.Printf("Primary account: %v\n", session.PrimaryAccounts) } ``` -------------------------------- ### Send JMAP Request using Batch Helper Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/quick-start.md Use the `Batch` helper to easily construct and send JMAP requests. This approach simplifies adding multiple method calls to a single request. ```go import ( "github.com/foxcpp/go-jmap/client" ) // Create batch batch := &client.Batch{} // Add calls batch.Use("urn:ietf:params:jmap:core") batch.Add("Core/echo", map[string]interface{}{}) // Send resp, err := cl.RawSend(batch.Request()) if err != nil { log.Fatal(err) } // Handle response for _, inv := range resp.Responses { fmt.Printf("Response: %s\n", inv.Name) } ``` -------------------------------- ### Example JMAP Method-Level Error Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt A JMAP response indicating a method-level error. This occurs when a specific method within a request fails, while other methods might still succeed. ```json { "sessionState": "abc123xyz", "methodResponses": [ ["Message", "get", { "notFound": ["msg3"] }] ], "errors": [ ["Message", "get", { "type": "forbidden", "description": "User does not have permission to access this message." }] ] } ``` -------------------------------- ### Direct Instantiation of jmap.Request Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/package-structure.md Create a new jmap.Request object directly. The `Using` field should specify the JMAP capabilities, and `Calls` should contain the invocations. ```go // Direct instantiation req := &jmap.Request{ Using: []string{"urn:ietf:params:jmap:core"}, Calls: []jmap.Invocation{}, } ``` -------------------------------- ### Avoid Modifying Client During Active Requests Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/configuration.md Do not modify the client's `HTTPClient` or `argsUnmarshallers` while requests are in flight to prevent race conditions. Configure these settings before starting any requests. ```go // Unsafe: modifying HTTPClient during active requests go cl.RawSend(req) time.Sleep(100 * time.Millisecond) // req still in flight cl.HTTPClient = newClient // RACE CONDITION // Safe: configure before any requests cl.HTTPClient = newClient cl.Enable(unmarshallers) // Then start requests cl.RawSend(req) ``` -------------------------------- ### JMAP Todo Changes Response Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Example of a JMAP response indicating changes in a Todo list, including old and new states, and lists of created, updated, and destroyed items. ```json [[ "Todo/changes", { "accountId": "x", "oldState": "10324", "newState": "871903", "hasMoreChanges": false, "created": [], "updated": [], "destroyed": ["b"] }, "0" ]] ``` -------------------------------- ### Create Push Subscription Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Client requests to create a new push subscription with a device client ID and URL. ```jmap [[ "PushSubscription/set", { "create": { "4f29": { "deviceClientId": "a889-ffea-910", "url": "https://example.com/push/?device=X8980fc&client=12c6d086", "types": null } } }, "0" ]] ``` -------------------------------- ### JMAP Todo Changes Request Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt Example of a JMAP 'Todo/changes' request to check for updates since a specific state. This is used to efficiently synchronize client state with server-side changes. ```json [[ "Todo/changes", { "accountId": "x", "sinceState": "10324", "maxChanges": 50 } ]] ``` -------------------------------- ### JMAP Method Call with Argument Resolution Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt An example of a JMAP method call where arguments are resolved using the result of a previous call. This demonstrates the use of '#ids' with 'resultOf' and 'path'. ```json [[ "Foo/changes", { "accountId": "A1", "oldState": "abcdef", "newState": "123456", "hasMoreChanges": false, "created": [ "f1", "f4" ], "updated": [], "destroyed": [] }, "t0" ]] ``` ```json [[ "Foo/get", { "accountId": "A1", "#ids": { "resultOf": "t0", "name": "Foo/changes", "path": "/created" } }, "t1" ]] ``` -------------------------------- ### Batch.Use Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/api-reference-client.md Adds a capability URI to the "using" list of the request, indicating to the server which capabilities the client intends to use. ```APIDOC ## Batch.Use ### Description Adds a capability URI to the "using" list of the request. Indicates to the server which capabilities the client intends to use. ### Method Batch.Use ### Parameters #### Path Parameters - **capability** (string) - Required - Capability URI (e.g., "urn:ietf:params:jmap:core"). ### Request Example ```go bt := &client.Batch{} bt.Use("urn:ietf:params:jmap:core") bt.Use("urn:ietf:params:jmap:mail") ``` ``` -------------------------------- ### Example JMAP Request-Level Error Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt A JMAP response indicating a request-level error. This occurs when the entire request is malformed or cannot be processed, such as an invalid JSON structure or missing required fields. ```json { "error": "invalidArguments", "description": "The arguments provided were invalid." } ``` -------------------------------- ### Example JMAP Response Object Source: https://github.com/foxcpp/go-jmap/blob/dev/draft-ietf-jmap-core-17.txt A sample JMAP response object mirroring the request structure. It contains 'sessionState' for state tracking and 'methodResponses' detailing the results of invoked methods. ```json { "sessionState": "abc123xyz", "methodResponses": [ ["Message", "get", { "list": [ { "id": "msg1", "from": {"name": "Alice", "email": "alice@example.com"}, "to": [{"name": "Bob", "email": "bob@example.com"}], "subject": "Hello", "date": "2019-03-18T14:00:00Z" }, { "id": "msg2", "from": {"name": "Bob", "email": "bob@example.com"}, "to": [{"name": "Alice", "email": "alice@example.com"}], "subject": "Re: Hello", "date": "2019-03-18T14:05:00Z" } ], "notFound": [] }] ] } ``` -------------------------------- ### Importing go-jmap Library Types Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/package-structure.md Import only the core types if you are not providing client wrappers. Import both the core library and the client package if you are building client-specific functionality. ```go // If only using types import "github.com/foxcpp/go-jmap" ``` ```go // If providing client wrappers import ( "github.com/foxcpp/go-jmap" "github.com/foxcpp/go-jmap/client" ) ``` -------------------------------- ### Create and Marshal/Unmarshal Date Source: https://github.com/foxcpp/go-jmap/blob/dev/_autodocs/quick-start.md Demonstrates creating a `jmap.Date` from `time.Now()`, marshaling it to JSON, and unmarshaling it back. Use this for standard date representations. ```go import ( "github.com/foxcpp/go-jmap" "time" "encoding/json" ) // Create Date d := jmap.Date(time.Now()) // Marshal to JSON data, _ := json.Marshal(d) fmt.Printf("JSON: %s\n", string(data)) // "2025-05-30T14:30:00Z" // Unmarshal from JSON var d2 jmap.Date json.Unmarshal([]byte(`"2025-05-30T14:30:00Z"`), &d2) ```