Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React native SDK #794

Merged
merged 21 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions example.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Appwrite\SDK\Language\Flutter;
use Appwrite\SDK\Language\Android;
use Appwrite\SDK\Language\Kotlin;
use Appwrite\SDK\Language\ReactNative;

try {

Expand Down Expand Up @@ -292,6 +293,33 @@ function getSSLPage($url) {

$sdk->generate(__DIR__ . '/examples/flutter');

// React Native
$reactNative = new ReactNative();
$reactNative->setNPMPackage('react-native-appwrite');
$sdk = new SDK($reactNative, new Swagger2($spec));

$sdk
->setName('NAME')
->setDescription('Repo description goes here')
->setShortDescription('Repo short description goes here')
->setURL('https://example.com')
->setLogo('https://appwrite.io/v1/images/console.png')
->setLicenseContent('test test test')
->setWarning('**WORK IN PROGRESS - NOT READY FOR USAGE**')
->setChangelog('**CHANGELOG**')
->setExamples('**EXAMPLES** <HTML>')
->setVersion('0.0.1')
->setGitUserName('repoowner')
->setGitRepoName('reponame')
->setTwitter('appwrite_io')
->setDiscord('564160730845151244', 'https://appwrite.io/discord')
->setDefaultHeaders([
'X-Appwrite-Response-Format' => '1.5.0',
])
;

$sdk->generate(__DIR__ . '/examples/react-native');

// GO

$sdk = new SDK(new Go(), new Swagger2($spec));
Expand Down
247 changes: 247 additions & 0 deletions src/SDK/Language/ReactNative.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
<?php

namespace Appwrite\SDK\Language;

use Twig\TwigFilter;

class ReactNative extends Web
{
/**
* @return string
*/
public function getName(): string
{
return 'ReactNative';
}

/**
* @return array
*/
public function getFiles(): array
{
return [
[
'scope' => 'default',
'destination' => 'src/index.ts',
'template' => 'react-native/src/index.ts.twig',
],
[
'scope' => 'default',
'destination' => 'src/client.ts',
'template' => 'react-native/src/client.ts.twig',
],
[
'scope' => 'default',
'destination' => 'src/service.ts',
'template' => 'react-native/src/service.ts.twig',
],
[
'scope' => 'service',
'destination' => 'src/services/{{service.name | caseDash}}.ts',
'template' => 'react-native/src/services/template.ts.twig',
],
[
'scope' => 'default',
'destination' => 'src/models.ts',
'template' => 'react-native/src/models.ts.twig',
],
[
'scope' => 'default',
'destination' => 'src/permission.ts',
'template' => 'react-native/src/permission.ts.twig',
],
[
'scope' => 'default',
'destination' => 'src/role.ts',
'template' => 'react-native/src/role.ts.twig',
],
[
'scope' => 'default',
'destination' => 'src/id.ts',
'template' => 'react-native/src/id.ts.twig',
],
[
'scope' => 'default',
'destination' => 'src/query.ts',
'template' => 'react-native/src/query.ts.twig',
],
[
'scope' => 'default',
'destination' => 'README.md',
'template' => 'react-native/README.md.twig',
],
[
'scope' => 'default',
'destination' => 'CHANGELOG.md',
'template' => 'react-native/CHANGELOG.md.twig',
],
[
'scope' => 'default',
'destination' => 'LICENSE',
'template' => 'react-native/LICENSE.twig',
],
[
'scope' => 'default',
'destination' => 'package.json',
'template' => 'react-native/package.json.twig',
],
[
'scope' => 'method',
'destination' => 'docs/examples/{{service.name | caseLower}}/{{method.name | caseDash}}.md',
'template' => 'react-native/docs/example.md.twig',
],
[
'scope' => 'default',
'destination' => 'tsconfig.json',
'template' => '/react-native/tsconfig.json.twig',
],
[
'scope' => 'default',
'destination' => 'rollup.config.js',
'template' => '/react-native/rollup.config.js.twig',
],
[
'scope' => 'default',
'destination' => 'dist/cjs/package.json',
'template' => '/react-native/dist/cjs/package.json.twig',
],
[
'scope' => 'default',
'destination' => 'dist/esm/package.json',
'template' => '/react-native/dist/esm/package.json.twig',
],
[
'scope' => 'default',
'destination' => '.github/workflows/publish.yml',
'template' => 'react-native/.github/workflows/publish.yml.twig',
],
[
'scope' => 'enum',
'destination' => 'src/enums/{{ enum.name | caseDash }}.ts',
'template' => 'react-native/src/enums/enum.ts.twig',
],
];
}

/**
* @param array $parameter
* @param array $nestedTypes
* @return string
*/
public function getTypeName(array $parameter, array $spec = []): string
{
if (isset($parameter['enumName'])) {
return \ucfirst($parameter['enumName']);
}
if (!empty($parameter['enumValues'])) {
return \ucfirst($parameter['name']);
}
switch ($parameter['type']) {
case self::TYPE_INTEGER:
case self::TYPE_NUMBER:
return 'number';
case self::TYPE_ARRAY:
if (!empty(($parameter['array'] ?? [])['type']) && !\is_array($parameter['array']['type'])) {
return $this->getTypeName($parameter['array']) . '[]';
}
return 'string[]';
case self::TYPE_FILE:
return 'any';
}

return $parameter['type'];
}

/**
* @param array $param
* @return string
*/
public function getParamExample(array $param): string
{
$type = $param['type'] ?? '';
$example = $param['example'] ?? '';

$output = '';

if (empty($example) && $example !== 0 && $example !== false) {
switch ($type) {
case self::TYPE_NUMBER:
case self::TYPE_INTEGER:
case self::TYPE_BOOLEAN:
$output .= 'null';
break;
case self::TYPE_STRING:
$output .= "''";
break;
case self::TYPE_ARRAY:
$output .= '[]';
break;
case self::TYPE_OBJECT:
$output .= '{}';
break;
case self::TYPE_FILE:
$output .= "await pickSingle()";
break;
}
} else {
switch ($type) {
case self::TYPE_NUMBER:
case self::TYPE_INTEGER:
case self::TYPE_ARRAY:
case self::TYPE_OBJECT:
$output .= $example;
break;
case self::TYPE_BOOLEAN:
$output .= ($example) ? 'true' : 'false';
break;
case self::TYPE_STRING:
$output .= "'{$example}'";
break;
case self::TYPE_FILE:
$output .= "await pickSingle()";
break;
}
}

return $output;
}

public function getReturn(array $method, array $spec): string
{
if ($method['type'] === 'webAuth') {
return 'void | URL';
} elseif ($method['type'] === 'location') {
return 'URL';
}

if (array_key_exists('responseModel', $method) && !empty($method['responseModel']) && $method['responseModel'] !== 'any') {
$ret = 'Promise<';

if (
array_key_exists($method['responseModel'], $spec['definitions']) &&
array_key_exists('additionalProperties', $spec['definitions'][$method['responseModel']]) &&
!$spec['definitions'][$method['responseModel']]['additionalProperties']
) {
$ret .= 'Models.';
}

$ret .= $this->toPascalCase($method['responseModel']);

$models = [];

$this->populateGenerics($method['responseModel'], $spec, $models);

$models = array_unique($models);
$models = array_filter($models, fn ($model) => $model != $this->toPascalCase($method['responseModel']));

if (!empty($models)) {
$ret .= '<' . implode(', ', $models) . '>';
}

$ret .= '>';

return $ret;
}
return 'Promise<{}>';
}
}
42 changes: 42 additions & 0 deletions templates/react-native/.github/workflows/publish.yml.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Publish to NPM

on:
release:
types: [published]
workflow_dispatch:

jobs:
publish:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

# Setup Node.js environment
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
registry-url: 'https://registry.npmjs.org'

# Determine release tag based on the tag name
- name: Determine release tag
id: release_tag
run: |
if [[ "${{ '{{' }} github.ref {{ '}}' }}" == *"-rc"* ]]; then
echo "tag=next" >> "$GITHUB_OUTPUT"
else
echo "tag=latest" >> "$GITHUB_OUTPUT"
fi

# Install dependencies (if any) and build your project (if necessary)
- name: Install dependencies and build
run: |
npm install
npm run build

# Publish to NPM with the appropriate tag
- name: Publish
run: npm publish --tag ${{ '{{' }} steps.release_tag.outputs.tag {{ '}}' }}
env:
NODE_AUTH_TOKEN: ${{ '{{' }} secrets.NPM_TOKEN {{ '}}' }}
1 change: 1 addition & 0 deletions templates/react-native/CHANGELOG.md.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{sdk.changelog}}
1 change: 1 addition & 0 deletions templates/react-native/LICENSE.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{sdk.licenseContent | raw}}
42 changes: 42 additions & 0 deletions templates/react-native/README.md.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# {{ spec.title }} {{sdk.name}} SDK

![License](https://img.shields.io/github/license/{{ sdk.gitUserName|url_encode }}/{{ sdk.gitRepoName|url_encode }}.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-{{ spec.version|url_encode }}-blue.svg?style=flat-square)
[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator)
{% if sdk.twitterHandle %}
[![Twitter Account](https://img.shields.io/twitter/follow/{{ sdk.twitterHandle }}?color=00acee&label=twitter&style=flat-square)](https://twitter.com/{{ sdk.twitterHandle }})
{% endif %}
{% if sdk.discordChannel %}
[![Discord](https://img.shields.io/discord/{{ sdk.discordChannel }}?label=discord&style=flat-square)]({{ sdk.discordUrl }})
{% endif %}
{% if sdk.warning %}

{{ sdk.warning|raw }}
{% endif %}

{{ sdk.description }}

{% if sdk.logo %}
![{{ spec.title }}]({{ sdk.logo }})
{% endif %}

## Installation

To install

```bash
npx expo install react-native-appwrite react-native-url-polyfill
```

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need

For iOS apps, you will need to install cocoapod dependencies.

```sh
cd iOS && pod install && cd ..
```

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have it in the getting started section

{% if sdk.gettingStarted %}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where did we add this? I can't find it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In appwrite/appwrite


{{ sdk.gettingStarted|raw }}
{% endif %}

## Contribution

This library is auto-generated by Appwrite custom [SDK Generator](https://github.com/appwrite/sdk-generator). To learn more about how you can help us improve this SDK, please check the [contribution guide](https://github.com/appwrite/sdk-generator/blob/master/CONTRIBUTING.md) before sending a pull-request.

## License

Please see the [{{spec.licenseName}} license]({{spec.licenseURL}}) file for more information.
3 changes: 3 additions & 0 deletions templates/react-native/dist/cjs/package.json.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "commonjs"
}
3 changes: 3 additions & 0 deletions templates/react-native/dist/esm/package.json.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
Loading