├── .gitignore ├── LICENSE ├── README.md ├── bsconfig.json ├── package.json ├── src └── reasonFirebase.re └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | *.obj 3 | *.out 4 | *.compile 5 | *.native 6 | *.byte 7 | *.cmo 8 | *.annot 9 | *.cmi 10 | *.cmx 11 | *.cmt 12 | *.cmti 13 | *.cma 14 | *.a 15 | *.cmxa 16 | *.obj 17 | *~ 18 | *.annot 19 | *.cmj 20 | *.bak 21 | lib 22 | *.mlast 23 | *.mliast 24 | .vscode 25 | .merlin 26 | *.js 27 | node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Viska Learning ehf 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BuckleScript bindings for firebase 2 | Add type for in reason to google's firebase api documented 3 | [here](https://firebase.google.com/docs/reference/js/). 4 | ## Install 5 | yarn add (git url) 6 | add to your bsconfig.json 7 | ```json 8 | "bs-dependencies": [ 9 | ... 10 | "bs-firebase" 11 | ], 12 | ``` 13 | 14 | ## Example 15 | 16 | ```ocaml 17 | let options = 18 | { 19 | "apiKey": "...", 20 | "authDomain": "...", 21 | "databaseURL": "...", 22 | "storageBucket": "...", 23 | "messagingSenderId": "..." 24 | }; 25 | 26 | let app = BsFirebase.ReasonFirebase.initializeApp(options); 27 | 28 | let db = BsFirebase.ReasonFirebase.App.database(app); 29 | 30 | BsFirebase.ReasonFirebase.Database.Reference.once( 31 | BsFirebase.ReasonFirebase.Database.ref(db, ~path="ticket", ()), 32 | ~eventType="value", 33 | () 34 | ) 35 | |> Js.Promise.then_( 36 | (teamDomain) => BsFirebase.ReasonFirebase.Database.DataSnapshot.val_(teamDomain) 37 | |> (ticket) => parseTicket(ticket) 38 | |> (ticketJson) => Js.log(ticketJson) //here you got a record of ticket type 39 | |> Js.Promise.resolve 40 | ); 41 | 42 | type ticket = { 43 | id: int, 44 | name: string 45 | }; 46 | 47 | type state = { 48 | ticket : ticket 49 | }; 50 | 51 | let parseTicket = (json): ticket => 52 | Json.Decode.{ //Json.Decode is from module https://github.com/reasonml-community/bs-json 53 | id: json |> field("id",int), 54 | name: json |> field("name", string) 55 | }; 56 | ``` 57 | -------------------------------------------------------------------------------- /bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bs-firebase", 3 | "version": "0.1.0", 4 | "refmt": 3, 5 | "sources": [ 6 | "src" 7 | ], 8 | "bs-dependencies" : [ 9 | "bs-webapi", 10 | ], 11 | "package-specs": [ 12 | { 13 | "module": "commonjs", 14 | "in-source": true 15 | } 16 | ], 17 | "namespace": true, 18 | "generate-merlin": true, 19 | "bsc-flags": ["-bs-super-errors"], 20 | "suffix": ".bs.js" 21 | } 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bs-firebase", 3 | "version": "0.1.0", 4 | "scripts": { 5 | "clean": "bsb -clean-world", 6 | "build": "bsb -make-world", 7 | "watch": "bsb -make-world -w" 8 | }, 9 | "keywords": [ 10 | "BuckleScript" 11 | ], 12 | "license": "MIT", 13 | "peerDependencies": { 14 | "bs-platform": "^2.0.0", 15 | "bs-webapi": "git+https://github.com/viskahq/bs-webapi-incubator.git" 16 | }, 17 | "dependencies": { 18 | "firebase": "^4.4.0" 19 | }, 20 | "repository": "git@github.com:viskahq/bs-firebase.git", 21 | "author": "" 22 | } 23 | -------------------------------------------------------------------------------- /src/reasonFirebase.re: -------------------------------------------------------------------------------- 1 | open BsWebapi.Webapi.Dom; 2 | 3 | module Error = { 4 | type t('e) = Js.t('e); 5 | }; 6 | 7 | module Database = { 8 | type t; 9 | module rec Reference: { 10 | type t; 11 | [@bs.get] external key : t => Js.nullable(string) = ""; 12 | [@bs.get] external parent : t => Js.nullable(t) = ""; 13 | [@bs.get] external root : t => t = ""; 14 | [@bs.send] external child : (t, ~path: string) => t = ""; 15 | [@bs.send] 16 | external once : 17 | (t, ~eventType: string, ~successCallback: DataSnapshot.t => unit=?, unit) => 18 | Js.Promise.t(DataSnapshot.t) = 19 | ""; 20 | type cb = DataSnapshot.t => unit; 21 | [@bs.send] 22 | external on : 23 | ( 24 | t, 25 | ~eventType: string, 26 | ~callback: DataSnapshot.t => unit, 27 | ~cancelCallback: Error.t('e) => unit=?, 28 | unit 29 | ) => 30 | cb = 31 | ""; 32 | [@bs.send] 33 | external off : (t, ~eventType: string, ~callback: DataSnapshot.t => unit=?, unit) => unit = 34 | ""; 35 | [@bs.send] 36 | external set : 37 | (t, ~value: 'a, ~onComplete: Js.nullable(Error.t('e)) => unit=?, unit) => Js.Promise.t(unit) = 38 | ""; 39 | [@bs.send] 40 | external update : 41 | (t, ~value: 'a, ~onComplete: Js.nullable(Error.t('e)) => unit=?, unit) => Js.Promise.t(unit) = 42 | ""; 43 | [@bs.send] 44 | external push : (t, ~value: 'a=?, ~onComplete: Js.nullable(Error.t('e)) => unit=?, unit) => t = 45 | ""; 46 | } = Reference 47 | and DataSnapshot: { 48 | type t; 49 | [@bs.get] external key : t => Js.null(string) = ""; 50 | [@bs.get] external ref : t => Reference.t = ""; 51 | [@bs.send] external child : (t, ~path: string) => t = ""; 52 | [@bs.send] external exists : t => bool = ""; 53 | [@bs.send] external exportVal : t => Js.Json.t = "exportVal"; 54 | [@bs.send] external foreach : (t, t => bool) => bool = "forEach"; 55 | /*external getPriority*/ 56 | [@bs.send] external hasChild : (t, ~path: string) => bool = "hasChild"; 57 | [@bs.send] external hasChildren : t => bool = "hasChildren"; 58 | [@bs.send] external numChildren : t => int = "numChildren"; 59 | [@bs.send] external toJson : t => Js.Json.t = "toJSON"; 60 | [@bs.send] external val_ : t => Js.Json.t = "val"; 61 | } = DataSnapshot; 62 | module OnDisconnect = { 63 | type t; 64 | [@bs.send] 65 | external cancel : (t, ~onComplete: Js.nullable(Error.t('e)) => unit=?) => Js.Promise.t(unit) = 66 | ""; 67 | [@bs.send] 68 | external remove : (t, ~onComplete: Js.nullable(Error.t('e)) => unit=?) => Js.Promise.t(unit) = 69 | ""; 70 | [@bs.send] 71 | external set : 72 | (t, Js.Json.t, ~onComplete: Js.nullable(Error.t('e)) => unit=?) => Js.Promise.t(unit) = 73 | ""; 74 | /*external setWithPriority*/ 75 | [@bs.send] 76 | external update : 77 | (t, Js.Json.t, ~onComplete: Js.nullable(Error.t('e)) => unit=?) => Js.Promise.t(unit) = 78 | ""; 79 | }; 80 | module ThenableReference = { 81 | type t; 82 | }; 83 | module Query = { 84 | type t; 85 | }; 86 | /*external app : t => App.t = "" [@@bs.get];*/ 87 | [@bs.send] external goOffline : t => unit = "goOffline"; 88 | [@bs.send] external goOnline : t => unit = "goOnline"; 89 | [@bs.send] external ref : (t, ~path: string=?, unit) => Reference.t = ""; 90 | [@bs.scope ("database", "ServerValue")] [@bs.val] [@bs.module "firebase"] 91 | external serverTimestamp : Js.null(string) = 92 | "TIMESTAMP"; 93 | [@bs.send] external refFromUrl : (t, ~url: string) => Reference.t = "refFromURL"; 94 | }; 95 | 96 | module Storage = { 97 | type t; 98 | module UploadTask = { 99 | type t; 100 | }; 101 | module Reference = { 102 | type t; 103 | [@bs.get] external bucket : t => string = ""; 104 | [@bs.get] external fullPath : t => string = ""; 105 | [@bs.get] external name : t => string = ""; 106 | [@bs.get] external parent : t => option(t) = ""; 107 | [@bs.get] external root : t => t = ""; 108 | /*external storage : t => Storage.t = "" [@@bs.get];*/ 109 | [@bs.send] external path : (t, ~path: string) => t = ""; 110 | [@bs.send] 111 | external put : 112 | (t, ~data: Window.File.t, ~metadata: Js.t('a)=?, unit) => Js.Promise.t(UploadTask.t) = 113 | ""; 114 | [@bs.send] external delete : t => Js.Promise.t(unit) = ""; 115 | [@bs.send] external getDownloadURL : t => Js.Promise.t(string) = ""; 116 | }; 117 | [@bs.send] external ref : (t, ~path: string=?, unit) => Reference.t = ""; 118 | }; 119 | 120 | module Auth = { 121 | type t; 122 | module User = { 123 | type t; 124 | type profile = {. "displayName": Js.nullable(string), "photoURL": Js.nullable(string)}; 125 | [@bs.get] external displayName : t => string = "displayName"; 126 | [@bs.get] external email : t => Js.nullable(string) = "email"; 127 | [@bs.get] external emailVerified : t => bool = "emailVerified"; 128 | [@bs.get] external isAnonymous : t => bool = "isAnonymous"; 129 | [@bs.get] external phoneNumber : t => Js.nullable(string) = "phoneNumber"; 130 | [@bs.get] external photoUrl : t => Js.nullable(string) = "photoURL"; 131 | [@bs.get] external uid : t => string = "uid"; 132 | [@bs.send] external updateProfile : (t, ~profile: profile) => Js.Promise.t(unit) = 133 | "updateProfile"; 134 | [@bs.send] external getIdToken : t => Js.Promise.t(Js.nullable(string)) = ""; 135 | }; 136 | module Error = { 137 | type t; 138 | }; 139 | module AuthCredential = { 140 | type t; 141 | }; 142 | [@bs.get] external currentUser : t => Js.null(User.t) = "currentUser"; 143 | [@bs.send] 144 | external createUserWithEmailAndPassword : ( 145 | t, 146 | ~email:string, 147 | ~password:string 148 | ) => Js.Promise.t(User.t) = "createUserWithEmailAndPassword"; 149 | [@bs.send] 150 | external onAuthStateChanged : 151 | ( 152 | t, 153 | ~nextOrObserver: Js.Null.t(User.t) => unit, 154 | ~error: Error.t => unit=?, 155 | ~completed: unit => unit=? 156 | ) => 157 | unit = 158 | "onAuthStateChanged"; 159 | [@bs.send] external signInAnonymously : (t, unit) => Js.Promise.t(User.t) = "signInAnonymously"; 160 | [@bs.send] 161 | external signInWithCredential : (t, ~credential: AuthCredential.t) => Js.Promise.t(User.t) = 162 | "signInWithCredential"; 163 | [@bs.send] external signInWithCustomToken : (t, ~token: string) => Js.Promise.t(User.t) = 164 | "signInWithCustomToken"; 165 | [@bs.send] external signOut : t => Js.Promise.t(unit) = "signOut"; 166 | }; 167 | 168 | module App = { 169 | type t; 170 | [@bs.send] external auth : t => Auth.t = ""; 171 | [@bs.send] external database : t => Database.t = ""; 172 | /*external delete*/ 173 | /*external messaging*/ 174 | [@bs.send] external storage : t => Storage.t = ""; 175 | [@bs.get] external options : t => Js.t('a) = ""; 176 | }; 177 | 178 | type options = { 179 | . 180 | "apiKey": string, 181 | "authDomain": string, 182 | "databaseURL": string, 183 | "storageBucket": string, 184 | "messagingSenderId": string 185 | }; 186 | 187 | [@bs.module "firebase"] external initializeApp : (~options: options) => App.t = "initializeApp"; 188 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@firebase/app@^0.1.1": 6 | version "0.1.1" 7 | resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.1.1.tgz#26e660bff8b4242860dea57eb934a5f71d2b81c2" 8 | dependencies: 9 | "@firebase/util" "^0.1.1" 10 | 11 | "@firebase/auth@^0.2.0": 12 | version "0.2.0" 13 | resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.2.0.tgz#1d1c264285fba74013bb10a49baa2bb0598dad73" 14 | 15 | "@firebase/database@^0.1.2": 16 | version "0.1.2" 17 | resolved "https://registry.yarnpkg.com/@firebase/database/-/database-0.1.2.tgz#de7992fdf7c34b9fee603317c6e89f8e62b76bdc" 18 | dependencies: 19 | "@firebase/util" "^0.1.1" 20 | faye-websocket "0.9.3" 21 | 22 | "@firebase/firestore@^0.1.2": 23 | version "0.1.2" 24 | resolved "https://registry.yarnpkg.com/@firebase/firestore/-/firestore-0.1.2.tgz#ebf53cab0bca8ca4d7caec3aa3f27a3cb7a940b6" 25 | dependencies: 26 | "@firebase/webchannel-wrapper" "^0.2.3" 27 | 28 | "@firebase/messaging@^0.1.2": 29 | version "0.1.2" 30 | resolved "https://registry.yarnpkg.com/@firebase/messaging/-/messaging-0.1.2.tgz#4dfd73abe4fa962ccb015d71e214960559ad271e" 31 | dependencies: 32 | "@firebase/util" "^0.1.1" 33 | 34 | "@firebase/polyfill@^0.1.1": 35 | version "0.1.1" 36 | resolved "https://registry.yarnpkg.com/@firebase/polyfill/-/polyfill-0.1.1.tgz#fd31789b58357f619245aac1f76b982c07398a6f" 37 | dependencies: 38 | promise-polyfill "^6.0.2" 39 | 40 | "@firebase/storage@^0.1.1": 41 | version "0.1.1" 42 | resolved "https://registry.yarnpkg.com/@firebase/storage/-/storage-0.1.1.tgz#5604405d59010f34f90ecc4bbb0b19b7afd05e82" 43 | 44 | "@firebase/util@^0.1.1": 45 | version "0.1.1" 46 | resolved "https://registry.yarnpkg.com/@firebase/util/-/util-0.1.1.tgz#4faa625ffd6e7c518088758cba08790973f7abf9" 47 | 48 | "@firebase/webchannel-wrapper@^0.2.3": 49 | version "0.2.3" 50 | resolved "https://registry.yarnpkg.com/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.2.3.tgz#e94f7e772f40e48a2dc52e57d1df38b28bf98e39" 51 | 52 | dom-storage@^2.0.2: 53 | version "2.0.2" 54 | resolved "https://registry.yarnpkg.com/dom-storage/-/dom-storage-2.0.2.tgz#ed17cbf68abd10e0aef8182713e297c5e4b500b0" 55 | 56 | faye-websocket@0.9.3: 57 | version "0.9.3" 58 | resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.9.3.tgz#482a505b0df0ae626b969866d3bd740cdb962e83" 59 | dependencies: 60 | websocket-driver ">=0.5.1" 61 | 62 | firebase@^4.4.0: 63 | version "4.6.0" 64 | resolved "https://registry.yarnpkg.com/firebase/-/firebase-4.6.0.tgz#59f68cda7085465b46210f816ffef4e94451d891" 65 | dependencies: 66 | "@firebase/app" "^0.1.1" 67 | "@firebase/auth" "^0.2.0" 68 | "@firebase/database" "^0.1.2" 69 | "@firebase/firestore" "^0.1.2" 70 | "@firebase/messaging" "^0.1.2" 71 | "@firebase/polyfill" "^0.1.1" 72 | "@firebase/storage" "^0.1.1" 73 | dom-storage "^2.0.2" 74 | xmlhttprequest "^1.8.0" 75 | 76 | http-parser-js@>=0.4.0: 77 | version "0.4.9" 78 | resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.9.tgz#ea1a04fb64adff0242e9974f297dd4c3cad271e1" 79 | 80 | promise-polyfill@^6.0.2: 81 | version "6.0.2" 82 | resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-6.0.2.tgz#d9c86d3dc4dc2df9016e88946defd69b49b41162" 83 | 84 | websocket-driver@>=0.5.1: 85 | version "0.7.0" 86 | resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb" 87 | dependencies: 88 | http-parser-js ">=0.4.0" 89 | websocket-extensions ">=0.1.1" 90 | 91 | websocket-extensions@>=0.1.1: 92 | version "0.1.2" 93 | resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.2.tgz#0e18781de629a18308ce1481650f67ffa2693a5d" 94 | 95 | xmlhttprequest@^1.8.0: 96 | version "1.8.0" 97 | resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" 98 | --------------------------------------------------------------------------------