Skip to content

Commit

Permalink
feat: add adaper for Expo.
Browse files Browse the repository at this point in the history
  • Loading branch information
gdethier committed Mar 5, 2024
1 parent 13624d5 commit 8dd68d7
Show file tree
Hide file tree
Showing 8 changed files with 236 additions and 1 deletion.
5 changes: 5 additions & 0 deletions packages/client-expo/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": [
"../../.eslintrc.json"
]
}
4 changes: 4 additions & 0 deletions packages/client-expo/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/src/**
tsconfig*.json
.eslintrc.json
typedoc.json
47 changes: 47 additions & 0 deletions packages/client-expo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Logion Client SDK (Expo)

This project provides a JS/TypeScript SDK enabling an [Expo](https://expo.dev)
application to interact with a logion network.

## Installation

Use your favorite package manager (e.g. yarn) and add `@logion/client` and `@logion/client-expo` packages to your project.
you will also need to install some peer dependencies: `buffer`, `expo-file-system` and `expo-crypto`.

You may have to setup `buffer` by adding the following line as soon as possible in your code:

```js
global.Buffer = Buffer;
```

## Usage

Instantiate the Logion client using `newLogionClient` function. For example, to connect to our test environment use:

```typescript
import { Environment } from "@logion/client";
import { newLogionClient } from '@logion/client-expo';

const client = await newLogionClient(Environment.TEST);
```

See [here](../client/README.md) for instructions about how to use the client.

Each time you need to pass a file to the client (e.g. when creating a collection item or a tokens record),
pass an instance of `ExpoFile`. The constructor expects 3 arguments:

- the [URI](https://docs.expo.dev/versions/latest/sdk/filesystem/#api) of the file,
- its name (e.g. `my-document.pdf`),
- its MIME type (e.g. `application/pdf`).

Here is an example:

```typescript
// ...
import { MimeType } from "@logion/client";
import { ExpoFile } from '@logion/client-expo';
// ...

const fileName = "file.txt";
const file = new ExpoFile(`${FileSystem.cacheDirectory}/${fileName}`, fileName, MimeType.from("text/plain"));
```
51 changes: 51 additions & 0 deletions packages/client-expo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "@logion/client-expo",
"version": "0.1.0-1",
"description": "logion SDK for client applications built with Expo",
"main": "dist/index.js",
"packageManager": "[email protected]",
"type": "module",
"scripts": {
"build": "yarn lint && tsc -p tsconfig.json",
"lint": "yarn eslint src/**",
"test": "echo 'Nothing to test for now'",
"clean": "rm -rf dist"
},
"repository": {
"type": "git",
"url": "git+https://github.com/logion-network/logion-api.git",
"directory": "packages/client-expo"
},
"keywords": [
"logion",
"api",
"client",
"expo"
],
"author": "Logion Team",
"license": "Apache-2.0",
"peerDependencies": {
"@logion/client": "0.x",
"expo-crypto": "12.x",
"expo-file-system": "16.x"
},
"bugs": {
"url": "https://github.com/logion-network/logion-api/issues"
},
"homepage": "https://github.com/logion-network/logion-api/packages/client-expo#readme",
"devDependencies": {
"@logion/client": "workspace:^",
"@tsconfig/node18": "^1.0.1",
"@types/node": "^18.6.1",
"@typescript-eslint/eslint-plugin": "^6.9.1",
"@typescript-eslint/parser": "^6.9.1",
"eslint": "^8.20.0",
"expo-crypto": "^12.8.1",
"expo-file-system": "^16.0.7",
"typescript": "^5.2.2"
},
"engines": {
"node": ">=18"
},
"stableVersion": "0.1.0"
}
71 changes: 71 additions & 0 deletions packages/client-expo/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import {
AxiosFileUploader,
createLogionClientConfig as createConfig,
Environment,
EnvironmentString,
File,
FormDataLike,
HashAndSize,
LogionClient,
MimeType,
} from "@logion/client";
import { Hash } from "@logion/node-api";
import * as Crypto from 'expo-crypto';
import * as FileSystem from "expo-file-system";

export async function newLogionClient(env: Environment | EnvironmentString): Promise<LogionClient> {
return await LogionClient.create(createConfig(env, () => new ExpoFileUploader()))
}

export class ExpoFile extends File {

constructor(uri: string, name: string, mimeType: MimeType) {
super(name, mimeType);
this.uri = uri;
}

private uri: string;

async getHashAndSize(): Promise<HashAndSize> {
const fileInfo = await FileSystem.getInfoAsync(this.uri);
if(!fileInfo.exists) {
throw new Error("File does not exist");
} else {
const base64Data = await FileSystem.readAsStringAsync(this.uri, { encoding: FileSystem.EncodingType.Base64 });
const binaryData = Buffer.from(base64Data, 'base64');
const hash = await Crypto.digest(Crypto.CryptoDigestAlgorithm.SHA256, binaryData);
return {
size: BigInt(fileInfo.size),
hash: new Hash(new Uint8Array(hash)),
};
}
}

getPath(): string {
return this.uri;
}
}

export class ExpoFileUploader extends AxiosFileUploader {

buildFormData(): FormDataLike {
return new FormData();
}

async toFormDataValue(file: File): Promise<{ uri: string, type: string, name: string }> {
const reactNativeFile = this.ensureExpo(file);
return {
uri: `file://${ reactNativeFile.getPath() }`,
type: file.mimeType.mimeType,
name: file.name,
};
}

private ensureExpo(file: File): ExpoFile {
if(file instanceof ExpoFile) {
return file;
} else {
throw new Error("Unexpected file type");
}
}
}
11 changes: 11 additions & 0 deletions packages/client-expo/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"lib": ["dom"],
"baseUrl": "."
},
"include": [
"./src/**/*"
]
}
6 changes: 6 additions & 0 deletions packages/client-expo/typedoc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "client-expo",
"entryPoints": [
"./src/index.ts"
]
}
42 changes: 41 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3135,6 +3135,26 @@ __metadata:
languageName: unknown
linkType: soft

"@logion/client-expo@workspace:packages/client-expo":
version: 0.0.0-use.local
resolution: "@logion/client-expo@workspace:packages/client-expo"
dependencies:
"@logion/client": "workspace:^"
"@tsconfig/node18": ^1.0.1
"@types/node": ^18.6.1
"@typescript-eslint/eslint-plugin": ^6.9.1
"@typescript-eslint/parser": ^6.9.1
eslint: ^8.20.0
expo-crypto: ^12.8.1
expo-file-system: ^16.0.7
typescript: ^5.2.2
peerDependencies:
"@logion/client": 0.x
expo-crypto: 12.x
expo-file-system: 16.x
languageName: unknown
linkType: soft

"@logion/client-node@workspace:packages/client-node":
version: 0.0.0-use.local
resolution: "@logion/client-node@workspace:packages/client-node"
Expand Down Expand Up @@ -5875,7 +5895,7 @@ __metadata:
languageName: node
linkType: hard

"base64-js@npm:^1.3.1":
"base64-js@npm:^1.3.0, base64-js@npm:^1.3.1":
version: 1.5.1
resolution: "base64-js@npm:1.5.1"
checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005
Expand Down Expand Up @@ -8494,6 +8514,26 @@ __metadata:
languageName: node
linkType: hard

"expo-crypto@npm:^12.8.1":
version: 12.8.1
resolution: "expo-crypto@npm:12.8.1"
dependencies:
base64-js: ^1.3.0
peerDependencies:
expo: "*"
checksum: ec3e8cfe65914b05e5ce0cc47180eaa2e6ecad70c9e07ce7ddd0c2fc583350fcdf76a6e746f8dec66267ba4f904817d7967dbd0bb8397758e97a0a49f67397b0
languageName: node
linkType: hard

"expo-file-system@npm:^16.0.7":
version: 16.0.7
resolution: "expo-file-system@npm:16.0.7"
peerDependencies:
expo: "*"
checksum: 4166bfd0c51d618be20fbb5e3734d75a85c27487f9eaf81240bbf597b3afaba5ef3647f8724f55e4fcb5bd1fbdd5ee9958336603039f6fb82ddcca07e6a37e38
languageName: node
linkType: hard

"express@npm:^4.14.0":
version: 4.18.1
resolution: "express@npm:4.18.1"
Expand Down

0 comments on commit 8dd68d7

Please sign in to comment.