expo-http-server 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,101 @@
1
+
1
2
  # expo-http-server
2
3
 
3
- HTTP local server for expo apps (not finished and untested)
4
+ [![npm](https://img.shields.io/npm/v/expo-http-server?style=for-the-badge)](https://www.npmjs.com/package/expo-http-server)
5
+ [![npm](https://img.shields.io/npm/dt/expo-http-server?style=for-the-badge)](https://www.npmjs.com/package/expo-http-server)
6
+ [![GitHub contributors](https://img.shields.io/github/contributors/simonsturge/expo-http-server?style=for-the-badge)](https://github.com/simonsturge/expo-http-server)
7
+ [![GitHub Repo stars](https://img.shields.io/github/stars/simonsturge/expo-http-server?style=for-the-badge)](https://github.com/simonsturge/expo-http-server)
8
+
9
+ A simple HTTP Server [Expo module](https://docs.expo.dev/modules/) .
10
+
11
+ Current implementation is for iOS / Android only ([React Native](https://github.com/facebook/react-native)).
12
+
13
+ iOS: [Criollo](https://github.com/thecatalinstan/Criollo)
14
+ Android: [AndroidServer](https://github.com/fengzhizi715/AndroidServer)
15
+ Web: **Not implemented**
16
+
17
+ This is a work in progress and not yet used in a production app (there are surely things I've overlooked), but please do make a PR for any improvements / problems you can see!
18
+
19
+ ## Install
20
+
21
+ ```shell
22
+ npx expo install expo-http-server
23
+ ```
24
+
25
+ ## Example
26
+ ```tsx
27
+ import * as server from "expo-http-server";
28
+ import { useEffect, useState } from "react";
29
+ import { Text, View } from "react-native";
30
+
31
+ export default function App() {
32
+ const [lastCalled, setLastCalled] = useState<number | undefined>();
33
+
34
+ const html = `
35
+ <!DOCTYPE html>
36
+ <html>
37
+ <body style="background-color:powderblue;">
38
+ <h1>expo-http-server</h1>
39
+ <p>You can load HTML!</p>
40
+ </body>
41
+ </html>`;
42
+
43
+ const obj = { app: "expo-http-server", desc: "You can load JSON!" };
44
+
45
+ useEffect(() => {
46
+ server.setup(9666);
47
+ server.route("/", "GET", async (request) => {
48
+ console.log("Request", "/", "GET", JSON.stringify(request));
49
+ setLastCalled(Date.now());
50
+ return {
51
+ statusCode: 200,
52
+ contentType: "application/json",
53
+ body: JSON.stringify(obj),
54
+ };
55
+ });
56
+ server.route("/html", "GET", async (request) => {
57
+ console.log("Request", "/html", "GET", JSON.stringify(request));
58
+ setLastCalled(Date.now());
59
+ return {
60
+ statusCode: 200,
61
+ contentType: "text/html",
62
+ body: html,
63
+ };
64
+ });
65
+ server.start();
66
+ return () => {
67
+ server.stop();
68
+ };
69
+ }, []);
70
+
71
+ return (
72
+ <View
73
+ style={{
74
+ flex: 1,
75
+ backgroundColor: "#fff",
76
+ alignItems: "center",
77
+ justifyContent: "center",
78
+ }}
79
+ >
80
+ <Text>
81
+ {lastCalled === undefined
82
+ ? "Request webserver to change text"
83
+ : "Called at " + new Date(lastCalled).toLocaleString()}
84
+ </Text>
85
+ </View>
86
+ );
87
+ }
88
+
89
+ ```
90
+
91
+ Note that on iOS when the app is backgrounded the server will inevitably get paused. A background task will be started automatically, however you will likely only get 30 seconds of listening time in the background.
92
+
93
+ Send a request to the server in a browser `browser` or `curl`:
4
94
 
5
- TODO: Documentation
95
+ ```shell
96
+ curl http://IP_OF_DEVICE:MY_PORT
97
+ ```
98
+ For example:
99
+ ```shell
100
+ curl http://192.168.1.109:3000
101
+ ```
@@ -29,7 +29,7 @@ class ExpoHttpServerModule : Module() {
29
29
  "uuid" to uuid,
30
30
  "method" to request.method().name,
31
31
  "path" to request.url(),
32
- "content" to request.content(),
32
+ "body" to request.content(),
33
33
  "headersJson" to JSONObject(headers).toString(),
34
34
  "paramsJson" to JSONObject(params).toString(),
35
35
  "cookiesJson" to JSONObject(cookies).toString(),
package/build/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export interface RequestEvent {
3
3
  uuid: string;
4
4
  method: string;
5
5
  path: string;
6
- content: string;
6
+ body: string;
7
7
  headersJson: string;
8
8
  paramsJson: string;
9
9
  cookiesJson: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE3D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CACxD;AAED,eAAO,MAAM,KAAK,YAyBjB,CAAC;AAEF,eAAO,MAAM,KAAK,SACV,MAAM,UACJ,UAAU,sBACE,YAAY,KAAK,QAAQ,QAAQ,CAAC,SAQvD,CAAC;AAEF,eAAO,MAAM,KAAK,SAAU,MAAM,QAAqC,CAAC;AACxE,eAAO,MAAM,IAAI,WAAoC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE3D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CACxD;AAED,eAAO,MAAM,KAAK,YAyBjB,CAAC;AAEF,eAAO,MAAM,KAAK,SACV,MAAM,UACJ,UAAU,sBACE,YAAY,KAAK,QAAQ,QAAQ,CAAC,SAQvD,CAAC;AAEF,eAAO,MAAM,KAAK,SAAU,MAAM,QAAqC,CAAC;AACxE,eAAO,MAAM,IAAI,WAAoC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,oBAAoB,MAAM,wBAAwB,CAAC;AAE1D,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,oBAAoB,CAAC,CAAC;AACvD,MAAM,gBAAgB,GAAe,EAAE,CAAC;AA0BxC,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,EAAE;IACxB,oBAAoB,CAAC,KAAK,EAAE,CAAC;IAC7B,OAAO,CAAC,WAAW,CAAe,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QAC7D,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CACvC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAC1D,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;YACtB,oBAAoB,CAAC,OAAO,CAC1B,KAAK,CAAC,IAAI,EACV,GAAG,EACH,aAAa,EACb,aAAa,CACd,CAAC;YACF,OAAO;QACT,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACzC,oBAAoB,CAAC,OAAO,CAC1B,KAAK,CAAC,IAAI,EACV,QAAQ,CAAC,UAAU,IAAI,GAAG,EAC1B,QAAQ,CAAC,WAAW,IAAI,kBAAkB,EAC1C,QAAQ,CAAC,IAAI,IAAI,IAAI,CACtB,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAG,CACnB,IAAY,EACZ,MAAkB,EAClB,QAAsD,EACtD,EAAE;IACF,gBAAgB,CAAC,IAAI,CAAC;QACpB,MAAM;QACN,IAAI;QACJ,QAAQ;KACT,CAAC,CAAC;IACH,oBAAoB,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACxE,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC","sourcesContent":["import { EventEmitter } from \"expo-modules-core\";\n\nimport ExpoHttpServerModule from \"./ExpoHttpServerModule\";\n\nconst emitter = new EventEmitter(ExpoHttpServerModule);\nconst requestCallbacks: Callback[] = [];\n\nexport type HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n\nexport interface RequestEvent {\n uuid: string;\n method: string;\n path: string;\n content: string;\n headersJson: string;\n paramsJson: string;\n cookiesJson: string;\n}\n\nexport interface Response {\n statusCode?: number;\n contentType?: string;\n body?: string;\n}\n\nexport interface Callback {\n method: string;\n path: string;\n callback: (request: RequestEvent) => Promise<Response>;\n}\n\nexport const start = () => {\n ExpoHttpServerModule.start();\n emitter.addListener<RequestEvent>(\"onRequest\", async (event) => {\n const callbacks = requestCallbacks.filter(\n (c) => event.path === c.path && event.method === c.method,\n );\n if (!callbacks.length) {\n ExpoHttpServerModule.respond(\n event.uuid,\n 200,\n \"No callback\",\n \"No callback\",\n );\n return;\n }\n for (const c of callbacks) {\n const response = await c.callback(event);\n ExpoHttpServerModule.respond(\n event.uuid,\n response.statusCode || 200,\n response.contentType || \"application/json\",\n response.body || \"{}\",\n );\n }\n });\n};\n\nexport const route = (\n path: string,\n method: HttpMethod,\n callback: (request: RequestEvent) => Promise<Response>,\n) => {\n requestCallbacks.push({\n method,\n path,\n callback,\n });\n ExpoHttpServerModule.route(path, method);\n};\n\nexport const setup = (port: number) => ExpoHttpServerModule.setup(port);\nexport const stop = () => ExpoHttpServerModule.stop();\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,oBAAoB,MAAM,wBAAwB,CAAC;AAE1D,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,oBAAoB,CAAC,CAAC;AACvD,MAAM,gBAAgB,GAAe,EAAE,CAAC;AA0BxC,MAAM,CAAC,MAAM,KAAK,GAAG,GAAG,EAAE;IACxB,oBAAoB,CAAC,KAAK,EAAE,CAAC;IAC7B,OAAO,CAAC,WAAW,CAAe,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QAC7D,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CACvC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,CAC1D,CAAC;QACF,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;YACtB,oBAAoB,CAAC,OAAO,CAC1B,KAAK,CAAC,IAAI,EACV,GAAG,EACH,aAAa,EACb,aAAa,CACd,CAAC;YACF,OAAO;QACT,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACzC,oBAAoB,CAAC,OAAO,CAC1B,KAAK,CAAC,IAAI,EACV,QAAQ,CAAC,UAAU,IAAI,GAAG,EAC1B,QAAQ,CAAC,WAAW,IAAI,kBAAkB,EAC1C,QAAQ,CAAC,IAAI,IAAI,IAAI,CACtB,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAG,CACnB,IAAY,EACZ,MAAkB,EAClB,QAAsD,EACtD,EAAE;IACF,gBAAgB,CAAC,IAAI,CAAC;QACpB,MAAM;QACN,IAAI;QACJ,QAAQ;KACT,CAAC,CAAC;IACH,oBAAoB,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACxE,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC","sourcesContent":["import { EventEmitter } from \"expo-modules-core\";\n\nimport ExpoHttpServerModule from \"./ExpoHttpServerModule\";\n\nconst emitter = new EventEmitter(ExpoHttpServerModule);\nconst requestCallbacks: Callback[] = [];\n\nexport type HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n\nexport interface RequestEvent {\n uuid: string;\n method: string;\n path: string;\n body: string;\n headersJson: string;\n paramsJson: string;\n cookiesJson: string;\n}\n\nexport interface Response {\n statusCode?: number;\n contentType?: string;\n body?: string;\n}\n\nexport interface Callback {\n method: string;\n path: string;\n callback: (request: RequestEvent) => Promise<Response>;\n}\n\nexport const start = () => {\n ExpoHttpServerModule.start();\n emitter.addListener<RequestEvent>(\"onRequest\", async (event) => {\n const callbacks = requestCallbacks.filter(\n (c) => event.path === c.path && event.method === c.method,\n );\n if (!callbacks.length) {\n ExpoHttpServerModule.respond(\n event.uuid,\n 200,\n \"No callback\",\n \"No callback\",\n );\n return;\n }\n for (const c of callbacks) {\n const response = await c.callback(event);\n ExpoHttpServerModule.respond(\n event.uuid,\n response.statusCode || 200,\n response.contentType || \"application/json\",\n response.body || \"{}\",\n );\n }\n });\n};\n\nexport const route = (\n path: string,\n method: HttpMethod,\n callback: (request: RequestEvent) => Promise<Response>,\n) => {\n requestCallbacks.push({\n method,\n path,\n callback,\n });\n ExpoHttpServerModule.route(path, method);\n};\n\nexport const setup = (port: number) => ExpoHttpServerModule.setup(port);\nexport const stop = () => ExpoHttpServerModule.stop();\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-http-server",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "A simple HTTP server expo module (iOS/Android)",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
package/src/index.ts CHANGED
@@ -11,7 +11,7 @@ export interface RequestEvent {
11
11
  uuid: string;
12
12
  method: string;
13
13
  path: string;
14
- content: string;
14
+ body: string;
15
15
  headersJson: string;
16
16
  paramsJson: string;
17
17
  cookiesJson: string;