Skip to content
This repository has been archived by the owner on Nov 11, 2023. It is now read-only.

Open api import #28

Merged
merged 59 commits into from
Dec 7, 2018
Merged
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
372f35e
Add open-api scripts dependencies
fabien0102 Aug 8, 2018
07cf8e9
Add import open-api script
fabien0102 Aug 14, 2018
4b143d3
Add import-open-api bin and build process
fabien0102 Aug 14, 2018
c0e7e62
Fix commander output options
fabien0102 Aug 14, 2018
150eb5d
Add some unit tests and refactor a bit
fabien0102 Sep 28, 2018
4ddb4ee
Add TBody generic argument to Mutate
fabien0102 Oct 9, 2018
6362070
Deal with object with additional properties
fabien0102 Oct 9, 2018
85c28b7
Deal with object properties and refs
fabien0102 Oct 9, 2018
6008c8f
Deal with object.allOf
fabien0102 Oct 9, 2018
40b83ff
Use a ternary instead of if/else
fabien0102 Oct 9, 2018
f6e3883
Remove the first empty line
fabien0102 Oct 9, 2018
bb10870
Test and fix generateSchemaDefinition
fabien0102 Oct 9, 2018
51cc4f2
Deal with array as additionalProperties
fabien0102 Oct 9, 2018
2a0d48a
Add missing data types
fabien0102 Oct 9, 2018
4b3123e
Remove duplicate types in response
fabien0102 Oct 9, 2018
bd4ca19
Deal with params in path
fabien0102 Oct 9, 2018
121f38b
Add @types/commander
fabien0102 Oct 9, 2018
6f2f155
Move everything to `src`
fabien0102 Oct 9, 2018
454c5bf
Fix the confusion between in: query and in: path
fabien0102 Oct 9, 2018
948c0a7
Import qs
fabien0102 Oct 9, 2018
be99514
Deal with path param
fabien0102 Oct 9, 2018
f79cbd9
Generate Mutate component FTW \o/
fabien0102 Oct 9, 2018
646daa6
Deal with empty object
fabien0102 Nov 19, 2018
fecad05
Add a operationId duplication check
fabien0102 Nov 19, 2018
d8c51e2
Add a section about openAPI
fabien0102 Nov 19, 2018
3dd597a
Add rollup to build correctly the bin part
fabien0102 Nov 19, 2018
fbba9ca
Update operational-scripts
fabien0102 Nov 19, 2018
71cea08
Deal with `verb` prop in Mutate generator
fabien0102 Nov 19, 2018
7b41941
Remove workaround
fabien0102 Nov 19, 2018
26c12b8
Be unsensitive the extension file case
fabien0102 Nov 19, 2018
c60065a
Deal with swagger 2.0 specs
fabien0102 Nov 22, 2018
66ee93a
Implement responses types
fabien0102 Nov 22, 2018
76d2a7b
Deal with parameters
fabien0102 Nov 23, 2018
53d04ba
Better fallback if error is not defined
fabien0102 Nov 23, 2018
7bdf8d5
[Breaking] Reorder generics type of Mutate to be more consistant
fabien0102 Nov 23, 2018
ab7b854
Add a little \n
fabien0102 Nov 23, 2018
7fd5eb9
Don't include the baseUrl in the generated components
fabien0102 Nov 23, 2018
8beee73
Add import from github flow :tada:
fabien0102 Nov 23, 2018
1a38d44
Export better types for custom responses
fabien0102 Nov 26, 2018
69117aa
Fix how delete components works (id is injected after)
fabien0102 Nov 27, 2018
a1095b2
Fix npm build
fabien0102 Nov 27, 2018
4ed5034
Fix npm build
fabien0102 Nov 27, 2018
b62ddc6
Fix delete edge case
fabien0102 Nov 27, 2018
bf76759
Deal with long polling
fabien0102 Nov 27, 2018
f65cd44
Fix polling types
fabien0102 Nov 27, 2018
d76a54e
Deal with no response case
fabien0102 Nov 27, 2018
d3a51af
Introduce query params
fabien0102 Nov 29, 2018
c6756dd
Fix typos
fabien0102 Nov 29, 2018
9a710a7
Rename TBody to TRequestBody
fabien0102 Nov 29, 2018
07ce83f
Refactor overkill discrimination
fabien0102 Nov 29, 2018
6e5027e
Generate query params
fabien0102 Nov 29, 2018
ef52906
Fix swagger2openapi definition
fabien0102 Dec 3, 2018
c9d3a86
Improve code style
fabien0102 Dec 3, 2018
e4dc683
Add a transformer param for advanced cases
fabien0102 Dec 6, 2018
c16fdd2
Add a tslint disable on empty object
fabien0102 Dec 7, 2018
bb0564e
Update documentation about codegen
Dec 7, 2018
3a8aba1
Deal with unused imports
fabien0102 Dec 7, 2018
782349a
Document QueryParams and transformer
Dec 7, 2018
a9dc566
Fix README snippet
Dec 7, 2018
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,13 @@ typings/
public
lib

# End of https://www.gitignore.io/api/node,macos,vscode

# Cache for parcel serverl in example
.cache

package-lock.json

# Files managed by operational-scripts
tslint.json
tsconfig.json
Expand Down
49 changes: 42 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# RESTful React
[![Greenkeeper badge](https://badges.greenkeeper.io/contiamo/restful-react.svg)](https://greenkeeper.io/)

TejasQ marked this conversation as resolved.
Show resolved Hide resolved
[![Build Status](https://travis-ci.org/contiamo/restful-react.svg?branch=master)](https://travis-ci.org/contiamo/restful-react)

Expand All @@ -10,7 +9,6 @@ As an abstraction, this tool allows for greater consistency and maintainability
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->


- [Overview](#overview)
- [Getting Started](#getting-started)
- [Features](#features)
Expand All @@ -28,6 +26,7 @@ As an abstraction, this tool allows for greater consistency and maintainability
- [Polling with `Poll`](#polling-with-poll)
- [Long Polling](#long-polling)
- [`Poll` Component API](#poll-component-api)
- [CLI tool - Code generation](#cli-tool---code-generation)
- [Caching](#caching)
- [Contributing](#contributing)
- [Code](#code)
Expand Down Expand Up @@ -198,7 +197,11 @@ const MyAnimalsList = props => (
Here are all my {props.animal}
s!
</h1>
<ul>{animals.map(animal => <li>{animal}</li>)}</ul>
<ul>
{animals.map(animal => (
<li>{animal}</li>
))}
</ul>
</>
)}
</div>
Expand All @@ -223,7 +226,11 @@ const MyAnimalsList = props => (
Here are all my {props.animal}
s!
</h1>
<ul>{animals.map(animal => <li>{animal}</li>)}</ul>
<ul>
{animals.map(animal => (
<li>{animal}</li>
))}
</ul>
</div>
)
}
Expand All @@ -245,7 +252,13 @@ It is possible to render a `Get` component and defer the fetch to a later stage.
<p>Are you ready to unleash all the magic? If yes, click this button!</p>
<button onClick={get}>GET UNICORNS!!!!!!</button>

{unicorns && <ul>{unicorns.map((unicorn, index) => <li key={index}>{unicorn}</li>)}</ul>}
{unicorns && (
<ul>
{unicorns.map((unicorn, index) => (
<li key={index}>{unicorn}</li>
))}
</ul>
)}
</div>
)}
</Get>
Expand All @@ -270,7 +283,11 @@ const myNestedData = props => (
{data => (
<div>
<h1>Here's all the things I want</h1>
<ul>{data.map(thing => <li>{thing}</li>)}</ul>
<ul>
{data.map(thing => (
<li>{thing}</li>
))}
</ul>
</div>
)}
</Get>
Expand All @@ -291,7 +308,11 @@ const SearchThis = props => (
{data => (
<div>
<h1>Here's all the things I search</h1>
<ul>{data.map(thing => <li>{thing}</li>)}</ul>
<ul>
{data.map(thing => (
<li>{thing}</li>
))}
</ul>
</div>
)}
</Get>
Expand Down Expand Up @@ -463,6 +484,20 @@ To get this functionality in Restful React, it is as simple as specifying a `wai

#### [`Poll` Component API](src/Poll.tsx#L53-L101)

### CLI tool - Code generation

Typing are awesome, nobody will complain about this (exept if you really don't like autocompletion of course). But, manual typing is boring, long, and error prone… Luckily for you, we are lazy and really believe that OpenAPI specs should be only read by a computer (not really, who else want to read 10000+ lines of json or yaml :thinking:).

Bref, `restful-react --file import my-open-api-spec-3-x.yaml --output my-awesome-generated-types.d.tsx` :tada:

Now you can import from this file any component with the types generated from the specs! Say welcome to the autocompletion and say goodbye to swagger :smile:

If you don't want to rely on a local file to generate your components, you can use the `--github` options to specify a github file instead of a local `--file`

Example: `restful-react --github owner:repo:branch:docs/openapi.yaml --output my-awesome-generated-types-from-github.d.tsx`

Note: This is totally experimental for now, so if you have any issue with the generated types -> just open an issue (with the open-api extract and the restful-react component generated/wanted please).

### Caching

This doesn't exist yet.
Expand Down
37 changes: 31 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
"files": [
"lib"
],
"bin": {
"restful-react": "lib/bin/restful-react.js"
},
"keywords": [
"rest",
"restful",
Expand All @@ -24,7 +27,13 @@
"email": "tejas@tejas.qa",
"url": "https://twitter.com/tejaskumar_"
},
"contributors": [],
"contributors": [
{
"name": "Fabien Bernard",
"email": "fabien@contiamo.com",
"url": "https://fabien0102.com/en"
}
],
"repository": {
"type": "git",
"url": "https://github.com/contiamo/restful-react"
Expand All @@ -33,19 +42,25 @@
"start": "operational-scripts start",
"example": "parcel example/index.html",
"test": "operational-scripts test",
"build": "operational-scripts build --for npm",
"build": "operational-scripts build --for npm && rollup -c rollup.config.js",
"preversion": "npm run build",
"version": "auto-changelog -p && git add CHANGELOG.md",
"lint": "tslint src/**/*{ts,tsx} --project .",
"prepublishOnly": "operational-scripts prepare",
"prepublishOnly": "operational-scripts prepare && rollup -c rollup.config.js",
"ci": "[ ! -z $DANGER_GITHUB_API_TOKEN ] && yarn danger ci || echo \"Skipping Danger for External Contributor\""
},
"devDependencies": {
"@operational/scripts": "^1.1.2",
"@operational/scripts": "^1.2.0",
"@types/commander": "^2.12.2",
"@types/inquirer": "0.0.43",
"@types/jest": "^23.3.1",
"@types/lodash": "^4.14.116",
"@types/nock": "^9.3.0",
"@types/node": "^10.5.7",
"@types/qs": "^6.5.1",
"@types/react": "^16.4.1",
"@types/request": "^2.48.1",
"@types/yamljs": "^0.2.30",
"auto-changelog": "^1.8.0",
"danger": "^4.0.1",
"doctoc": "^1.3.1",
Expand All @@ -59,17 +74,27 @@
"prettier": "^1.13.5",
"react-dom": "^16.4.2",
"react-testing-library": "^5.0.0",
"request": "^2.88.0",
TejasQ marked this conversation as resolved.
Show resolved Hide resolved
"rollup": "^0.67.3",
"rollup-plugin-typescript2": "^0.16.1",
"ts-jest": "^23.1.4",
"tslint": "^5.10.0",
"tslint-config-prettier": "^1.13.0",
"tslint-plugin-blank-line": "^0.0.9",
"typescript": "^3.0.3"
},
"dependencies": {
"lodash": "^4.17.11",
"case": "^1.5.5",
"commander": "^2.17.1",
"inquirer": "^6.2.0",
"lodash": "^4.17.10",
"openapi3-ts": "^0.12.0",
TejasQ marked this conversation as resolved.
Show resolved Hide resolved
"qs": "^6.6.0",
"react": "^16.4.1",
"react-fast-compare": "^2.0.1",
"url": "^0.11.0"
"swagger2openapi": "^3.2.14",
"url": "^0.11.0",
"yamljs": "^0.3.0"
},
"peerDependencies": {
"react": "^16.4.1"
Expand Down
15 changes: 15 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const { readdirSync } = require("fs");

/**
* Rollup configuration to build correctly our scripts (nodejs scripts need to be cjs)
*/
module.exports = readdirSync("lib/bin")
TejasQ marked this conversation as resolved.
Show resolved Hide resolved
.filter(file => file.endsWith(".js"))
.map(file => ({
input: `lib/bin/${file}`,
output: {
file: `lib/bin/${file}`,
format: "cjs",
banner: "#!/usr/bin/env node",
},
}));
24 changes: 24 additions & 0 deletions src/Get.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -938,4 +938,28 @@ describe("Get", () => {
expect(children.mock.calls[5][0]).toEqual({ path: "/absolute-1/absolute-2/relative-2/relative-3" });
});
});

describe("with query params", () => {
it("should add the correct query params in the url", async () => {
nock("https://my-awesome-api.fake")
.get("/")
.query({
myParam: true,
})
.reply(200);

const children = jest.fn();
children.mockReturnValue(<div />);

render(
<RestfulProvider base="https://my-awesome-api.fake">
<Get<void, void, { myParam: boolean }> path="" queryParams={{ myParam: true }}>
{children}
</Get>
</RestfulProvider>,
);

await wait(() => expect(children.mock.calls.length).toBe(2));
});
});
});
28 changes: 20 additions & 8 deletions src/Get.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { DebounceSettings } from "lodash";
import debounce from "lodash/debounce";
import * as qs from "qs";
import * as React from "react";
import RestfulReactProvider, { InjectedProps, RestfulReactConsumer, RestfulReactProviderProps } from "./Context";
import { composePath, composeUrl } from "./util/composeUrl";
Expand Down Expand Up @@ -53,7 +54,7 @@ export interface Meta {
/**
* Props for the <Get /> component.
*/
export interface GetProps<TData, TError> {
export interface GetProps<TData, TError, TQueryParams> {
/**
* The path at which to request data,
* typically composed by parent Gets or the RestfulProvider.
Expand All @@ -74,6 +75,10 @@ export interface GetProps<TData, TError> {
children: (data: TData | null, states: States<TData, TError>, actions: Actions<TData>, meta: Meta) => React.ReactNode;
/** Options passed into the fetch call. */
requestOptions?: RestfulReactProviderProps["requestOptions"];
/**
* Query parameters
*/
queryParams?: TQueryParams;
/**
* Don't send the error to the Provider
*/
Expand Down Expand Up @@ -134,11 +139,11 @@ export interface GetState<TData, TError> {
* is a named class because it is useful in
* debugging.
*/
class ContextlessGet<TData, TError> extends React.Component<
GetProps<TData, TError> & InjectedProps,
class ContextlessGet<TData, TError, TQueryParams> extends React.Component<
GetProps<TData, TError, TQueryParams> & InjectedProps,
Readonly<GetState<TData, TError>>
> {
constructor(props: GetProps<TData, TError> & InjectedProps) {
constructor(props: GetProps<TData, TError, TQueryParams> & InjectedProps) {
super(props);

if (typeof props.debounce === "object") {
Expand Down Expand Up @@ -175,7 +180,7 @@ class ContextlessGet<TData, TError> extends React.Component<
}
}

public componentDidUpdate(prevProps: GetProps<TData, TError>) {
public componentDidUpdate(prevProps: GetProps<TData, TError, TQueryParams>) {
const { base, parentPath, path, resolve } = prevProps;
if (
base !== this.props.base ||
Expand Down Expand Up @@ -230,11 +235,16 @@ class ContextlessGet<TData, TError> extends React.Component<
}

const makeRequestPath = () => {
let url: string;
if (__internal_hasExplicitBase) {
return composeUrl(base!, "", path || "");
url = composeUrl(base!, "", path || "");
} else {
return composeUrl(base!, parentPath!, requestPath || path || "");
url = composeUrl(base!, parentPath!, requestPath || path || "");
}
if (this.props.queryParams) {
url += `?${qs.stringify(this.props.queryParams)}`;
}
return url;
};

const request = new Request(makeRequestPath(), this.getRequestOptions(thisRequestOptions));
Expand Down Expand Up @@ -297,7 +307,9 @@ class ContextlessGet<TData, TError> extends React.Component<
* in order to provide new `parentPath` props that contain
* a segment of the path, creating composable URLs.
*/
function Get<TData = any, TError = any>(props: GetProps<TData, TError>) {
function Get<TData = any, TError = any, TQueryParams = { [key: string]: any }>(
TejasQ marked this conversation as resolved.
Show resolved Hide resolved
props: GetProps<TData, TError, TQueryParams>,
) {
return (
<RestfulReactConsumer>
{contextProps => (
Expand Down
Loading