Skip to content

chore(repository): improve repository structure and naming #11

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

Merged
merged 6 commits into from
Nov 19, 2021
Merged
Show file tree
Hide file tree
Changes from 3 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
10 changes: 4 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ yarn-error.log
!.yarn/releases
!.yarn/plugins

*/.openapi-generator
*/node_modules
*/dist
*/.openapi-generator-ignore

output/complement
**/.openapi-generator
**/node_modules
**/dist
**/.openapi-generator-ignore
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,34 @@
nvm use && yarn
```

## Generate client based on `search_spec.yml`
## Generate clients based on the [`spec.yml` file](./specs/spec.yml)

```bash
yarn generate
```

## Build generated client
## Build generated clients

```bash
yarn client:build
```

## Test built client response
# Testing clients

Go to the [`playground`](./playground) folder to test your client

## JavaScript

```bash
cd playground/javascript && yarn start
```

# Troubleshooting

> `Error: The operation couldn’t be completed. Unable to locate a Java Runtime.`

Java is not located in your PATH, either source the right `.bash_profile`, `.zshrc`, etc. file or do the following command in this repository:

```bash
yarn client:test
echo 'export PATH="/usr/local/opt/openjdk/bin:$PATH"' > .bash_profile && source .bash_profile
```
11 changes: 11 additions & 0 deletions clients/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Clients

This folder hosts the generated clients and their utils.

## Generated clients

- [algoliasearch-client-javascript](./algoliasearch-client-javascript/): The Algolia JavaScript client.

## Utils

- [JavaScript](./utils/javascript/): The Algolia JavaScript utils.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import http from 'http';
import { shuffle } from '../complement/helpers';
import { Transporter } from '../complement/Transporter';
import { Headers, Host, Request, RequestOptions } from '../complement/types';
import { shuffle } from '../utils/helpers';
import { Transporter } from '../utils/Transporter';
import { Headers, Host, Request, RequestOptions } from '../utils/types';

import { BatchObject } from '../model/batchObject';
import { BatchResponse } from '../model/batchResponse';
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { RequestOptions } from '../complement/types';
import type { RequestOptions } from '../utils/types';

export * from './batchObject';
export * from './batchResponse';
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
"test": "yarn build && node dist/client.js"
},
"engines": {
"node": ">= 16.0.0",
"yarn": ">= 3.0.0"
"node": "^16.0.0",
"yarn": "^3.0.0"
},
"devDependencies": {
"@types/node": "^16.11.6",
"typescript": "^4.4.4"
"typescript": "4.5.2"
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
21 changes: 21 additions & 0 deletions clients/utils/javascript/Cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export interface Cache {
/**
* Gets the value of the given `key`.
*/
get: <TValue>(key: object | string, defaultValue: () => Promise<TValue>) => Promise<TValue>;

/**
* Sets the given value with the given `key`.
*/
set: <TValue>(key: object | string, value: TValue) => Promise<TValue>;

/**
* Deletes the given `key`.
*/
delete: (key: object | string) => Promise<void>;

/**
* Clears the cache.
*/
clear: () => Promise<void>;
}
27 changes: 27 additions & 0 deletions clients/utils/javascript/MemoryCache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { Cache } from './Cache';

export class MemoryCache implements Cache {
private cache: Record<string, any> = {};

async get<TValue>(key: object | string, defaultValue: () => Promise<TValue>): Promise<TValue> {
const keyAsString = JSON.stringify(key);

if (keyAsString in this.cache) {
return Promise.resolve(this.cache[keyAsString]);
}
return await defaultValue();
}

async set<TValue>(key: object | string, value: TValue): Promise<TValue> {
this.cache[JSON.stringify(key)] = value;
return value;
}

async delete(key: object | string): Promise<void> {
delete this.cache[JSON.stringify(key)];
}

async clear(): Promise<void> {
this.cache = {};
}
}
82 changes: 82 additions & 0 deletions clients/utils/javascript/Requester.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { EndRequest, Response } from './types';
import * as http from 'http';
import * as https from 'https';

export class Requester {
private httpAgent: http.Agent;
private httpsAgent: https.Agent;

constructor() {
this.httpAgent = new http.Agent({ keepAlive: true });
this.httpsAgent = new https.Agent({ keepAlive: true });
}

async send(request: EndRequest): Promise<Response> {
return new Promise((resolve) => {
const url = new URL(request.url);

const path = url.search === null ? url.pathname : `${url.pathname}?${url.search}`;

const options: https.RequestOptions = {
agent: url.protocol === 'https:' ? this.httpsAgent : this.httpAgent,
hostname: url.hostname,
path,
method: request.method,
headers: request.headers,
...(url.port !== undefined ? { port: url.port || '' } : {}),
};

const req = (url.protocol === 'https:' ? https : http).request(options, (response) => {
let contentBuffers: Buffer[] = [];

response.on('data', (chunk) => {
contentBuffers = contentBuffers.concat(chunk);
});

response.on('end', () => {
clearTimeout(connectTimeout);
clearTimeout(responseTimeout as NodeJS.Timeout);

resolve({
status: response.statusCode || 0,
content: Buffer.concat(contentBuffers).toString(),
isTimedOut: false,
});
});
});

const createTimeout = (timeout: number, content: string): NodeJS.Timeout => {
return setTimeout(() => {
req.destroy();

resolve({
status: 0,
content,
isTimedOut: true,
});
}, timeout * 1000);
};

const connectTimeout = createTimeout(request.connectTimeout, 'Connection timeout');

let responseTimeout: NodeJS.Timeout | undefined;

req.on('error', (error) => {
clearTimeout(connectTimeout);
clearTimeout(responseTimeout as NodeJS.Timeout);
resolve({ status: 0, content: error.message, isTimedOut: false });
});

req.once('response', () => {
clearTimeout(connectTimeout);
responseTimeout = createTimeout(request.responseTimeout, 'Socket timeout');
});

if (request.data !== undefined) {
req.write(request.data);
}

req.end();
});
}
}
29 changes: 29 additions & 0 deletions clients/utils/javascript/StatefulHost.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { Host } from './types';

const EXPIRATION_DELAY = 2 * 60 * 1000;

export class StatefulHost implements Host {
url: string;
accept: 'read' | 'write' | 'readWrite';
protocol: 'http' | 'https';

private lastUpdate: number;
private status: 'up' | 'down' | 'timedout';

constructor(host: Host, status: StatefulHost['status'] = 'up') {
this.url = host.url;
this.accept = host.accept;
this.protocol = host.protocol;

this.status = status;
this.lastUpdate = Date.now();
}

isUp(): boolean {
return this.status === 'up' || Date.now() - this.lastUpdate > EXPIRATION_DELAY;
}

isTimedout(): boolean {
return this.status === 'timedout' && Date.now() - this.lastUpdate <= EXPIRATION_DELAY;
}
}
Loading