package extism-manifest

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file extism_manifest.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
open Ppx_yojson_conv_lib.Yojson_conv

type base64 = string

let yojson_of_base64 x = `String (Base64.encode_exn x)
let base64_of_yojson j = Yojson.Safe.Util.to_string j

type memory_options = {
  max_pages : int option; [@yojson.option]
  max_http_response_bytes : int option; [@yojson.option]
  max_var_bytes : int option; [@yojson.option]
}
[@@deriving yojson]

type dict = (string * string) list
type config = (string * string option) list

let is_null = function `Null -> true | _ -> false

let dict_of_yojson j =
  let assoc = Yojson.Safe.Util.to_assoc j in
  List.map (fun (k, v) -> (k, Yojson.Safe.Util.to_string v)) assoc

let yojson_of_dict c = `Assoc (List.map (fun (k, v) -> (k, `String v)) c)

let config_of_yojson j =
  let assoc = Yojson.Safe.Util.to_assoc j in
  List.map
    (fun (k, v) ->
      (k, if is_null v then None else Some (Yojson.Safe.Util.to_string v)))
    assoc

let yojson_of_config c =
  `Assoc
    (List.map
       (fun (k, v) -> (k, match v with None -> `Null | Some v -> `String v))
       c)

module Wasm = struct
  type file = {
    path : string;
    name : string option; [@yojson.option]
    hash : string option; [@yojson.option]
  }
  [@@deriving yojson]

  type data = {
    data : base64;
    name : string option; [@yojson.option]
    hash : string option; [@yojson.option]
  }
  [@@deriving yojson]

  type url = {
    url : string;
    headers : dict option; [@yojson.option]
    meth : string option; [@yojson.option] [@key "method"]
    name : string option; [@yojson.option]
    hash : string option; [@yojson.option]
  }
  [@@deriving yojson]

  type t = File of file | Data of data | Url of url

  let yojson_of_t = function
    | File f -> yojson_of_file f
    | Data d -> yojson_of_data d
    | Url u -> yojson_of_url u

  let t_of_yojson x =
    try File (file_of_yojson x)
    with _ -> ( try Data (data_of_yojson x) with _ -> Url (url_of_yojson x))

  let file ?name ?hash path = File { path; name; hash }
  let data ?name ?hash data = Data { data; name; hash }

  let url ?headers ?name ?meth ?hash url =
    Url { headers; name; meth; hash; url }
end

type t = {
  wasm : Wasm.t list;
  memory : memory_options option; [@yojson.option]
  config : config option; [@yojson.option]
  allowed_hosts : string list option; [@yojson.option]
  allowed_paths : dict option; [@yojson.option]
  timeout_ms : int option; [@yojson.option]
}
[@@deriving yojson]

let create ?config ?memory ?allowed_hosts ?allowed_paths ?timeout_ms wasm =
  { config; wasm; memory; allowed_hosts; allowed_paths; timeout_ms }

let to_json t = yojson_of_t t |> Yojson.Safe.to_string

let of_json s =
  let j = Yojson.Safe.from_string s in
  t_of_yojson j

let of_file filename =
  let j = Yojson.Safe.from_file filename in
  t_of_yojson j

let with_config config t = { t with config = Some config }

let with_memory_max max t =
  match t.memory with
  | None ->
      {
        t with
        memory =
          Some
            {
              max_http_response_bytes = None;
              max_pages = Some max;
              max_var_bytes = None;
            };
      }
  | Some m -> { t with memory = Some { m with max_pages = Some max } }

let with_http_response_max_bytes max t =
  match t.memory with
  | None ->
      {
        t with
        memory =
          Some
            {
              max_http_response_bytes = Some max;
              max_pages = None;
              max_var_bytes = None;
            };
      }
  | Some m ->
      { t with memory = Some { m with max_http_response_bytes = Some max } }

let with_var_max_bytes max t =
  match t.memory with
  | None ->
      {
        t with
        memory =
          Some
            {
              max_var_bytes = Some max;
              max_pages = None;
              max_http_response_bytes = None;
            };
      }
  | Some m ->
      { t with memory = Some { m with max_http_response_bytes = Some max } }

let%test "rountrip" =
  let config = [ ("a", Some "b"); ("b", Some "c") ] in
  let memory =
    {
      max_pages = Some 5;
      max_http_response_bytes = Some 9999;
      max_var_bytes = Some 12300;
    }
  in
  let t =
    create ~config ~memory ~allowed_hosts:[ "example.com" ]
      ~allowed_paths:[ ("a", "b") ]
      ~timeout_ms:1000 []
  in
  let a = to_json t in
  let b = of_json a in
  let c = to_json b in
  String.equal a c