Skip to content

Commit

Permalink
Migrate tutorials to @withease/contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
igorkamyshev committed Jul 31, 2024
1 parent 9c015db commit 56db427
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 49 deletions.
2 changes: 1 addition & 1 deletion apps/website/docs/.vitepress/theme/LiveDemo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const customSetup = {
dependencies: {
effector: packageJson.dependencies.effector,
'effector-vue': packageJson.dependencies['effector-vue'],
runtypes: packageJson.dependencies.runtypes,
'@withease/contracts': packageJson.dependencies['@withease/contracts'],
},
};
Expand Down
17 changes: 7 additions & 10 deletions apps/website/docs/api/factories/create_json_query.live.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<script setup>
import { createJsonQuery } from '@farfetched/core';
import { runtypeContract } from '@farfetched/runtypes';
import { obj, str, arr } from '@withease/contracts';
import { useUnit } from 'effector-vue/composition';
import { Record, String, Array } from 'runtypes';
const randomQuotesQuery = createJsonQuery({
initialData: [],
Expand All @@ -13,17 +12,15 @@ const randomQuotesQuery = createJsonQuery({
},
response: {
/*
* We use runtypes to validate response,
* We use @withease/contracts to validate response,
* but you can replace it with other library, see 👇
* https://ff.effector.dev/tutorial/contracts.html#third-party-solutions
*/
contract: runtypeContract(
Array(
Record({
author: String,
quote: String,
})
)
contract: arr(
obj({
author: str,
quote: str,
})
),
},
});
Expand Down
16 changes: 7 additions & 9 deletions apps/website/docs/recipes/feature_flags.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,19 +115,18 @@ It's time to find out arguments of the `createFlag` function.
4. `contract` — we need to know how to check the value of the feature flag. It will be used to prevent unexpected structure that can break the application. Since Farfetched has a built-in [structure to do it](/api/primitives/contract), we can use it here.

```ts
import { runtypeContract } from '@farftehced/runtypes';
import { Boolean } from 'runtypes';
import { bool } from '@withease/contracts';

const { $value: $dynamicFaviconEnabled } = createFlag({
key: 'exp-dynamic-favicon',
defaultValue: false,
contract: runtypeContract(Boolean),
contract: bool,
fetchOn: applicationInitialized,
});
```

::: tip
We use `runtypes` as a library for creating [_Contracts_](/api/primitives/contract) there. However, you can use any library you want. Read more in [the tutorial](/tutorial/contracts).
We use `@withease/contracts` as a library for creating [_Contracts_](/api/primitives/contract) there. However, you can use any library you want. Read more in [the tutorial](/tutorial/contracts).
:::

## Implementation
Expand Down Expand Up @@ -257,7 +256,7 @@ So, we have an internal implementation that handles fetching, context passing, e
const { $value: $dynamicFaviconEnabled } = createFlag({
key: 'exp-dynamic-favicon',
defaultValue: false,
contract: runtypeContract(Boolean),
contract: bool,
fetchOn: applicationInitialized,
});
```
Expand Down Expand Up @@ -302,7 +301,7 @@ The last thing we need to do is to return a store with a value of the feature fl
function createFlag({ key, requestOn }) {
// ...

// find patricular flag
// find particular flag
const $value = featureFlagsQuery.$data.map((data) => data.find((flag) => flag.flagKey === key) ?? null);

return { $value };
Expand Down Expand Up @@ -362,16 +361,15 @@ Now, we have a feature flags service. Let's integrate it with our application.

```ts
import { createEvent, createEffect, sample } from 'effector';
import { runtypeContract } from '@farfetched/runtypes';
import { Boolean } from 'runtypes';
import { bool } from '@withease/contracts';

// Do not forget to call it after application initialization
const applicationInitialized = createEvent();

const { $value: $dynamicFaviconEnabled } = createFlag({
key: 'exp-dynamic-favicon',
defaultValue: false,
contract: runtypeContract(Boolean),
contract: bool,
fetchOn: applicationInitialized,
});

Expand Down
12 changes: 6 additions & 6 deletions apps/website/docs/tutorial/built_in_query_factories.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Built-in factories are easier to use, and they are more declarative, which makes

## JSON API

A lot of modern APIs work with JSON. It accepts JSON as input and returns JSON as output. It's a very convenient format, because it's easy to read and write. Not only that, but it's also very flexible, because it allows you to send only the data you need. So, Farfetch has a built-in factory for JSON API — `createJsonQuery`.
A lot of modern APIs work with JSON. It accepts JSON as input and returns JSON as output. It's a very convenient format, because it's easy to read and write. Not only that, but it's also very flexible, because it allows you to send only the data you need. So, Farfetched has a built-in factory for JSON API — `createJsonQuery`.

Let's start with an example, and then we'll explain what's going on.

Expand All @@ -30,7 +30,7 @@ const characterQuery = createJsonQuery({
url: ({ id }) => `https://rickandmortyapi.com/api/character/${id}`,
},
response: {
contract: runtypeContract(Character),
contract: Character,
},
});
```
Expand All @@ -53,7 +53,7 @@ const characterQuery = createJsonQuery({
url: ({ id }) => `https://rickandmortyapi.com/api/character/${id}`,
},
response: {
contract: runtypeContract(Character),
contract: Character,
},
});
```
Expand All @@ -67,7 +67,7 @@ By default, `createJsonQuery` returns a [_Query_](/api/primitives/query) without
- `request.method` has to be a _string_ with an HTTP method in uppercase, e.g. `GET` or `POST`.
- `request.url` is used to formulate a URL of the request, it could be declared in many forms, but two the most interesting for us:
- just static _string_
- function that accepts [_Query_](/api/primitives/query) paramters and returns a _string_
- function that accepts [_Query_](/api/primitives/query) parameters and returns a _string_

```ts{3-6}
const characterQuery = createJsonQuery({
Expand All @@ -77,7 +77,7 @@ const characterQuery = createJsonQuery({
url: ({ id }) => `https://rickandmortyapi.com/api/character/${id}`,
},
response: {
contract: runtypeContract(Character),
contract: Character,
},
});
```
Expand All @@ -96,7 +96,7 @@ const characterQuery = createJsonQuery({
url: ({ id }) => `https://rickandmortyapi.com/api/character/${id}`,
},
response: {
contract: runtypeContract(Character),
contract: Character,
},
});
```
Expand Down
40 changes: 20 additions & 20 deletions apps/website/docs/tutorial/contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,38 +60,38 @@ const someQuery = createQuery({

Even though Farfetched provides a way to create your own [_Contract_](/api/primitives/contract), it's way more convenient to use third-party solutions for contracts.

### Runtypes
### `@withease/contracts`

We recommend using [Runtypes](https://github.com/pelotom/runtypes), it has first class TS-support, it is well-documented and has a lot of useful features. Farfetched provides [an integration to use Runtype as a Contract](/api/contracts/runtypes).
We recommend using [`@withease/contracts`](https://withease.effector.dev/contracts/) as a default solution for contracts. It is extremely lightweight, has a lot of useful features and is well-documented. Futhermore, it is a part of Effector's family, so it is well-integrated with any Effector-based solution and does not require any additional compatibility layers.

```ts
import { Number } from 'runtypes';
import { runtypeContract } from '@farfetched/runtypes';
import { num } from '@withease/contracts';

const numberContract = runtypeContract(Number);
const someQuery = createQuery({
// ...
contract: num,
});
```

That is a complete equivalent of the previous example. For such a simple contract, it's not a big deal, but for more complex contracts, it's much more convenient to use Runtypes than to create a contract by hand.
Let us write a more complete equivalent of the previous example. For such a simple contract, it's not a big deal, but for more complex contracts, it's much more convenient to use `@withease/contracts` than to create a contract by hand.

```ts
import { Record, String, Number, Union, Literal } from 'runtypes';

const characterContract = runtypeContract(
Record({
id: Number,
name: String,
status: Union(Literal('Alive'), Literal('Dead'), Literal('unknown')),
species: String,
type: String,
origin: Record({ name: String, url: Url }),
location: Record({ name: String, url: Url }),
})
);
import { obj, str, num, or, val } from '`@withease/contracts`';

const characterContract = obj({
id: num,
name: str,
status: or(val('Alive'), val('Dead'), val('unknown')),
species: str,
type: str,
origin: obj({ name: str, url: str }),
location: obj({ name: str, url: str }),
});
```

## Other integrations

Farfetched provides integrations for the following third-party solutions:
In case you are using some other solution for contracts, Farfetched provides a plenty of integrations for the following third-party solutions:

- [Runtypes](/api/contracts/runtypes)
- [Zod](/api/contracts/zod)
Expand Down
2 changes: 1 addition & 1 deletion packages/io-ts/src/__tests__/contract.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as t from 'io-ts';

import { ioTsContract } from '../contract';

describe('runtypeContract', () => {
describe('ioTsContract', () => {
const contract = ioTsContract(t.string);

const smth: unknown = null;
Expand Down
2 changes: 1 addition & 1 deletion packages/superstruct/src/__tests__/contract.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { string } from 'superstruct';

import { superstructContract } from '../contract';

describe('runtypeContract', () => {
describe('superstructContract', () => {
const contract = superstructContract(string());

const smth: unknown = null;
Expand Down
2 changes: 1 addition & 1 deletion packages/typed-contracts/src/__tests__/contract.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { string } from 'typed-contracts';

import { typedContract } from '../contract';

describe('runtypeContract', () => {
describe('typedContract', () => {
const contract = typedContract(string);

const smth: unknown = null;
Expand Down

0 comments on commit 56db427

Please sign in to comment.