From 646d7dec261331eb3b2084a278c9b8dfc56018ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Thu, 18 Nov 2021 14:45:45 +0100 Subject: [PATCH 1/6] chore(repository): improve repository structure and naming --- .gitignore | 10 +- README.md | 16 +- clients/README.md | 11 + .../.gitignore | 0 .../algoliasearch-client-javascript}/api.ts | 0 .../client-search/apis.ts | 0 .../client-search/searchApi.ts | 6 +- .../git_push.sh | 0 .../model/batchObject.ts | 0 .../model/batchResponse.ts | 0 .../model/highlightResult.ts | 0 .../model/modelError.ts | 0 .../model/models.ts | 2 +- .../model/multipleQueries.ts | 0 .../model/multipleQueriesObject.ts | 0 .../model/multipleQueriesResponse.ts | 0 .../model/operation.ts | 0 .../model/rankingInfo.ts | 0 .../model/rankingInfoMatchedGeoLocation.ts | 0 .../model/record.ts | 0 .../model/saveObjectResponse.ts | 0 .../model/searchParams.ts | 0 .../model/searchParamsString.ts | 0 .../model/searchResponse.ts | 0 .../model/searchResponseFacetsStats.ts | 0 .../model/snippetResult.ts | 0 .../package.json | 0 .../tsconfig.json | 0 .../utils}/Cache.ts | 0 .../utils}/MemoryCache.ts | 0 .../utils}/Requester.ts | 0 .../utils}/StatefulHost.ts | 0 .../utils}/Transporter.ts | 0 .../utils}/errors.ts | 0 .../utils}/helpers.ts | 0 .../utils}/retryDecision.ts | 0 .../utils}/types.ts | 0 clients/utils/javascript/Cache.ts | 21 ++ clients/utils/javascript/MemoryCache.ts | 27 +++ clients/utils/javascript/Requester.ts | 82 +++++++ clients/utils/javascript/StatefulHost.ts | 29 +++ clients/utils/javascript/Transporter.ts | 223 ++++++++++++++++++ clients/utils/javascript/errors.ts | 38 +++ clients/utils/javascript/helpers.ts | 94 ++++++++ clients/utils/javascript/retryDecision.ts | 33 +++ clients/utils/javascript/types.ts | 71 ++++++ doc/AddLanguage.md | 31 --- doc/contribution_addNewClient.md | 45 ++++ openapitools.json | 9 +- package.json | 24 +- {openapi_spec => specs}/parameters.yml | 0 .../paths/indexes/batch.yml | 0 .../paths/indexes/multipleQueries.yml | 0 .../paths/indexes/saveObject.yml | 0 .../paths/indexes/search.yml | 0 .../responses/BadRequest.yml | 0 .../responses/IndexNotFound.yml | 0 {openapi_spec => specs}/responses/common.yml | 0 {openapi_spec => specs}/schemas/Error.yml | 0 .../schemas/IndexSettingsParams.yml | 0 {openapi_spec => specs}/schemas/Record.yml | 0 .../schemas/RequestOptions.yml | 0 .../schemas/SearchParams.yml | 0 .../schemas/SearchResponse.yml | 0 {openapi_spec => specs}/spec.yml | 0 .../api-all.mustache | 0 .../api-single.mustache | 6 +- .../javascript-client-template}/api.mustache | 0 .../javascript-client-template}/gitignore | 0 .../licenseInfo.mustache | 0 .../model.mustache | 0 .../models.mustache | 2 +- .../package.mustache | 0 .../tsconfig.mustache | 0 .../recommend_spec.yml | 0 .../recommend_spec_2.yml | 0 search_spec.yml => utils/search_spec.yml | 0 yarn.lock | 40 +++- 78 files changed, 747 insertions(+), 73 deletions(-) create mode 100644 clients/README.md rename {output => clients/algoliasearch-client-javascript}/.gitignore (100%) rename {output => clients/algoliasearch-client-javascript}/api.ts (100%) rename {output => clients/algoliasearch-client-javascript}/client-search/apis.ts (100%) rename {output => clients/algoliasearch-client-javascript}/client-search/searchApi.ts (98%) rename {output => clients/algoliasearch-client-javascript}/git_push.sh (100%) rename {output => clients/algoliasearch-client-javascript}/model/batchObject.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/batchResponse.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/highlightResult.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/modelError.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/models.ts (99%) rename {output => clients/algoliasearch-client-javascript}/model/multipleQueries.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/multipleQueriesObject.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/multipleQueriesResponse.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/operation.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/rankingInfo.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/rankingInfoMatchedGeoLocation.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/record.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/saveObjectResponse.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/searchParams.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/searchParamsString.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/searchResponse.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/searchResponseFacetsStats.ts (100%) rename {output => clients/algoliasearch-client-javascript}/model/snippetResult.ts (100%) rename {output => clients/algoliasearch-client-javascript}/package.json (100%) rename {output => clients/algoliasearch-client-javascript}/tsconfig.json (100%) rename {complement => clients/algoliasearch-client-javascript/utils}/Cache.ts (100%) rename {complement => clients/algoliasearch-client-javascript/utils}/MemoryCache.ts (100%) rename {complement => clients/algoliasearch-client-javascript/utils}/Requester.ts (100%) rename {complement => clients/algoliasearch-client-javascript/utils}/StatefulHost.ts (100%) rename {complement => clients/algoliasearch-client-javascript/utils}/Transporter.ts (100%) rename {complement => clients/algoliasearch-client-javascript/utils}/errors.ts (100%) rename {complement => clients/algoliasearch-client-javascript/utils}/helpers.ts (100%) rename {complement => clients/algoliasearch-client-javascript/utils}/retryDecision.ts (100%) rename {complement => clients/algoliasearch-client-javascript/utils}/types.ts (100%) create mode 100644 clients/utils/javascript/Cache.ts create mode 100644 clients/utils/javascript/MemoryCache.ts create mode 100644 clients/utils/javascript/Requester.ts create mode 100644 clients/utils/javascript/StatefulHost.ts create mode 100644 clients/utils/javascript/Transporter.ts create mode 100644 clients/utils/javascript/errors.ts create mode 100644 clients/utils/javascript/helpers.ts create mode 100644 clients/utils/javascript/retryDecision.ts create mode 100644 clients/utils/javascript/types.ts delete mode 100644 doc/AddLanguage.md create mode 100644 doc/contribution_addNewClient.md rename {openapi_spec => specs}/parameters.yml (100%) rename {openapi_spec => specs}/paths/indexes/batch.yml (100%) rename {openapi_spec => specs}/paths/indexes/multipleQueries.yml (100%) rename {openapi_spec => specs}/paths/indexes/saveObject.yml (100%) rename {openapi_spec => specs}/paths/indexes/search.yml (100%) rename {openapi_spec => specs}/responses/BadRequest.yml (100%) rename {openapi_spec => specs}/responses/IndexNotFound.yml (100%) rename {openapi_spec => specs}/responses/common.yml (100%) rename {openapi_spec => specs}/schemas/Error.yml (100%) rename {openapi_spec => specs}/schemas/IndexSettingsParams.yml (100%) rename {openapi_spec => specs}/schemas/Record.yml (100%) rename {openapi_spec => specs}/schemas/RequestOptions.yml (100%) rename {openapi_spec => specs}/schemas/SearchParams.yml (100%) rename {openapi_spec => specs}/schemas/SearchResponse.yml (100%) rename {openapi_spec => specs}/spec.yml (100%) rename {algolia-typescript-template => templates/javascript-client-template}/api-all.mustache (100%) rename {algolia-typescript-template => templates/javascript-client-template}/api-single.mustache (97%) rename {algolia-typescript-template => templates/javascript-client-template}/api.mustache (100%) rename {algolia-typescript-template => templates/javascript-client-template}/gitignore (100%) rename {algolia-typescript-template => templates/javascript-client-template}/licenseInfo.mustache (100%) rename {algolia-typescript-template => templates/javascript-client-template}/model.mustache (100%) rename {algolia-typescript-template => templates/javascript-client-template}/models.mustache (99%) rename {algolia-typescript-template => templates/javascript-client-template}/package.mustache (100%) rename {algolia-typescript-template => templates/javascript-client-template}/tsconfig.mustache (100%) rename recommend_spec.yml => utils/recommend_spec.yml (100%) rename recommend_spec_2.yml => utils/recommend_spec_2.yml (100%) rename search_spec.yml => utils/search_spec.yml (100%) diff --git a/.gitignore b/.gitignore index 546171c092a..4d6b8f8cbf2 100644 --- a/.gitignore +++ b/.gitignore @@ -10,9 +10,7 @@ yarn-error.log !.yarn/releases !.yarn/plugins -*/.openapi-generator -*/node_modules -*/dist -*/.openapi-generator-ignore - -output/complement \ No newline at end of file +**/.openapi-generator +**/node_modules +**/dist +**/.openapi-generator-ignore diff --git a/README.md b/README.md index a8ed11a79e7..323f06898a1 100644 --- a/README.md +++ b/README.md @@ -6,20 +6,30 @@ 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 +## Test JavaScript client locally ```bash yarn client:test ``` + +# 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` file or do the following command in this repository: + +```bash +echo 'export PATH="/usr/local/opt/openjdk/bin:$PATH"' > .bash_profile && source .bash_profile +``` diff --git a/clients/README.md b/clients/README.md new file mode 100644 index 00000000000..858ad545161 --- /dev/null +++ b/clients/README.md @@ -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. diff --git a/output/.gitignore b/clients/algoliasearch-client-javascript/.gitignore similarity index 100% rename from output/.gitignore rename to clients/algoliasearch-client-javascript/.gitignore diff --git a/output/api.ts b/clients/algoliasearch-client-javascript/api.ts similarity index 100% rename from output/api.ts rename to clients/algoliasearch-client-javascript/api.ts diff --git a/output/client-search/apis.ts b/clients/algoliasearch-client-javascript/client-search/apis.ts similarity index 100% rename from output/client-search/apis.ts rename to clients/algoliasearch-client-javascript/client-search/apis.ts diff --git a/output/client-search/searchApi.ts b/clients/algoliasearch-client-javascript/client-search/searchApi.ts similarity index 98% rename from output/client-search/searchApi.ts rename to clients/algoliasearch-client-javascript/client-search/searchApi.ts index 8c6fb82fff5..804d1da2b50 100644 --- a/output/client-search/searchApi.ts +++ b/clients/algoliasearch-client-javascript/client-search/searchApi.ts @@ -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'; diff --git a/output/git_push.sh b/clients/algoliasearch-client-javascript/git_push.sh similarity index 100% rename from output/git_push.sh rename to clients/algoliasearch-client-javascript/git_push.sh diff --git a/output/model/batchObject.ts b/clients/algoliasearch-client-javascript/model/batchObject.ts similarity index 100% rename from output/model/batchObject.ts rename to clients/algoliasearch-client-javascript/model/batchObject.ts diff --git a/output/model/batchResponse.ts b/clients/algoliasearch-client-javascript/model/batchResponse.ts similarity index 100% rename from output/model/batchResponse.ts rename to clients/algoliasearch-client-javascript/model/batchResponse.ts diff --git a/output/model/highlightResult.ts b/clients/algoliasearch-client-javascript/model/highlightResult.ts similarity index 100% rename from output/model/highlightResult.ts rename to clients/algoliasearch-client-javascript/model/highlightResult.ts diff --git a/output/model/modelError.ts b/clients/algoliasearch-client-javascript/model/modelError.ts similarity index 100% rename from output/model/modelError.ts rename to clients/algoliasearch-client-javascript/model/modelError.ts diff --git a/output/model/models.ts b/clients/algoliasearch-client-javascript/model/models.ts similarity index 99% rename from output/model/models.ts rename to clients/algoliasearch-client-javascript/model/models.ts index 5ab824e4e96..fd9cb170bfb 100644 --- a/output/model/models.ts +++ b/clients/algoliasearch-client-javascript/model/models.ts @@ -1,4 +1,4 @@ -import type { RequestOptions } from '../complement/types'; +import type { RequestOptions } from '../utils/types'; export * from './batchObject'; export * from './batchResponse'; diff --git a/output/model/multipleQueries.ts b/clients/algoliasearch-client-javascript/model/multipleQueries.ts similarity index 100% rename from output/model/multipleQueries.ts rename to clients/algoliasearch-client-javascript/model/multipleQueries.ts diff --git a/output/model/multipleQueriesObject.ts b/clients/algoliasearch-client-javascript/model/multipleQueriesObject.ts similarity index 100% rename from output/model/multipleQueriesObject.ts rename to clients/algoliasearch-client-javascript/model/multipleQueriesObject.ts diff --git a/output/model/multipleQueriesResponse.ts b/clients/algoliasearch-client-javascript/model/multipleQueriesResponse.ts similarity index 100% rename from output/model/multipleQueriesResponse.ts rename to clients/algoliasearch-client-javascript/model/multipleQueriesResponse.ts diff --git a/output/model/operation.ts b/clients/algoliasearch-client-javascript/model/operation.ts similarity index 100% rename from output/model/operation.ts rename to clients/algoliasearch-client-javascript/model/operation.ts diff --git a/output/model/rankingInfo.ts b/clients/algoliasearch-client-javascript/model/rankingInfo.ts similarity index 100% rename from output/model/rankingInfo.ts rename to clients/algoliasearch-client-javascript/model/rankingInfo.ts diff --git a/output/model/rankingInfoMatchedGeoLocation.ts b/clients/algoliasearch-client-javascript/model/rankingInfoMatchedGeoLocation.ts similarity index 100% rename from output/model/rankingInfoMatchedGeoLocation.ts rename to clients/algoliasearch-client-javascript/model/rankingInfoMatchedGeoLocation.ts diff --git a/output/model/record.ts b/clients/algoliasearch-client-javascript/model/record.ts similarity index 100% rename from output/model/record.ts rename to clients/algoliasearch-client-javascript/model/record.ts diff --git a/output/model/saveObjectResponse.ts b/clients/algoliasearch-client-javascript/model/saveObjectResponse.ts similarity index 100% rename from output/model/saveObjectResponse.ts rename to clients/algoliasearch-client-javascript/model/saveObjectResponse.ts diff --git a/output/model/searchParams.ts b/clients/algoliasearch-client-javascript/model/searchParams.ts similarity index 100% rename from output/model/searchParams.ts rename to clients/algoliasearch-client-javascript/model/searchParams.ts diff --git a/output/model/searchParamsString.ts b/clients/algoliasearch-client-javascript/model/searchParamsString.ts similarity index 100% rename from output/model/searchParamsString.ts rename to clients/algoliasearch-client-javascript/model/searchParamsString.ts diff --git a/output/model/searchResponse.ts b/clients/algoliasearch-client-javascript/model/searchResponse.ts similarity index 100% rename from output/model/searchResponse.ts rename to clients/algoliasearch-client-javascript/model/searchResponse.ts diff --git a/output/model/searchResponseFacetsStats.ts b/clients/algoliasearch-client-javascript/model/searchResponseFacetsStats.ts similarity index 100% rename from output/model/searchResponseFacetsStats.ts rename to clients/algoliasearch-client-javascript/model/searchResponseFacetsStats.ts diff --git a/output/model/snippetResult.ts b/clients/algoliasearch-client-javascript/model/snippetResult.ts similarity index 100% rename from output/model/snippetResult.ts rename to clients/algoliasearch-client-javascript/model/snippetResult.ts diff --git a/output/package.json b/clients/algoliasearch-client-javascript/package.json similarity index 100% rename from output/package.json rename to clients/algoliasearch-client-javascript/package.json diff --git a/output/tsconfig.json b/clients/algoliasearch-client-javascript/tsconfig.json similarity index 100% rename from output/tsconfig.json rename to clients/algoliasearch-client-javascript/tsconfig.json diff --git a/complement/Cache.ts b/clients/algoliasearch-client-javascript/utils/Cache.ts similarity index 100% rename from complement/Cache.ts rename to clients/algoliasearch-client-javascript/utils/Cache.ts diff --git a/complement/MemoryCache.ts b/clients/algoliasearch-client-javascript/utils/MemoryCache.ts similarity index 100% rename from complement/MemoryCache.ts rename to clients/algoliasearch-client-javascript/utils/MemoryCache.ts diff --git a/complement/Requester.ts b/clients/algoliasearch-client-javascript/utils/Requester.ts similarity index 100% rename from complement/Requester.ts rename to clients/algoliasearch-client-javascript/utils/Requester.ts diff --git a/complement/StatefulHost.ts b/clients/algoliasearch-client-javascript/utils/StatefulHost.ts similarity index 100% rename from complement/StatefulHost.ts rename to clients/algoliasearch-client-javascript/utils/StatefulHost.ts diff --git a/complement/Transporter.ts b/clients/algoliasearch-client-javascript/utils/Transporter.ts similarity index 100% rename from complement/Transporter.ts rename to clients/algoliasearch-client-javascript/utils/Transporter.ts diff --git a/complement/errors.ts b/clients/algoliasearch-client-javascript/utils/errors.ts similarity index 100% rename from complement/errors.ts rename to clients/algoliasearch-client-javascript/utils/errors.ts diff --git a/complement/helpers.ts b/clients/algoliasearch-client-javascript/utils/helpers.ts similarity index 100% rename from complement/helpers.ts rename to clients/algoliasearch-client-javascript/utils/helpers.ts diff --git a/complement/retryDecision.ts b/clients/algoliasearch-client-javascript/utils/retryDecision.ts similarity index 100% rename from complement/retryDecision.ts rename to clients/algoliasearch-client-javascript/utils/retryDecision.ts diff --git a/complement/types.ts b/clients/algoliasearch-client-javascript/utils/types.ts similarity index 100% rename from complement/types.ts rename to clients/algoliasearch-client-javascript/utils/types.ts diff --git a/clients/utils/javascript/Cache.ts b/clients/utils/javascript/Cache.ts new file mode 100644 index 00000000000..faaa9333f80 --- /dev/null +++ b/clients/utils/javascript/Cache.ts @@ -0,0 +1,21 @@ +export interface Cache { + /** + * Gets the value of the given `key`. + */ + get: (key: object | string, defaultValue: () => Promise) => Promise; + + /** + * Sets the given value with the given `key`. + */ + set: (key: object | string, value: TValue) => Promise; + + /** + * Deletes the given `key`. + */ + delete: (key: object | string) => Promise; + + /** + * Clears the cache. + */ + clear: () => Promise; +} diff --git a/clients/utils/javascript/MemoryCache.ts b/clients/utils/javascript/MemoryCache.ts new file mode 100644 index 00000000000..d492164e340 --- /dev/null +++ b/clients/utils/javascript/MemoryCache.ts @@ -0,0 +1,27 @@ +import type { Cache } from './Cache'; + +export class MemoryCache implements Cache { + private cache: Record = {}; + + async get(key: object | string, defaultValue: () => Promise): Promise { + const keyAsString = JSON.stringify(key); + + if (keyAsString in this.cache) { + return Promise.resolve(this.cache[keyAsString]); + } + return await defaultValue(); + } + + async set(key: object | string, value: TValue): Promise { + this.cache[JSON.stringify(key)] = value; + return value; + } + + async delete(key: object | string): Promise { + delete this.cache[JSON.stringify(key)]; + } + + async clear(): Promise { + this.cache = {}; + } +} diff --git a/clients/utils/javascript/Requester.ts b/clients/utils/javascript/Requester.ts new file mode 100644 index 00000000000..61a8c2b24a9 --- /dev/null +++ b/clients/utils/javascript/Requester.ts @@ -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 { + 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(); + }); + } +} diff --git a/clients/utils/javascript/StatefulHost.ts b/clients/utils/javascript/StatefulHost.ts new file mode 100644 index 00000000000..d9cd8929dfb --- /dev/null +++ b/clients/utils/javascript/StatefulHost.ts @@ -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; + } +} diff --git a/clients/utils/javascript/Transporter.ts b/clients/utils/javascript/Transporter.ts new file mode 100644 index 00000000000..8a6a096e2d2 --- /dev/null +++ b/clients/utils/javascript/Transporter.ts @@ -0,0 +1,223 @@ +import type { + Host, + Request, + RequestOptions, + StackFrame, + Timeouts, + Response, + Outcomes, + EndRequest, +} from './types'; +import { MemoryCache } from './MemoryCache'; +import type { Cache } from './Cache'; +import { StatefulHost } from './StatefulHost'; +import { + deserializeFailure, + deserializeSuccess, + serializeData, + serializeHeaders, + serializeUrl, +} from './helpers'; +import { Headers } from './types'; +import { RetryError } from './errors'; +import { retryDecision } from './retryDecision'; +import { Requester } from './Requester'; + +export class Transporter { + private hosts: Host[]; + private baseHeaders: Headers; + private hostsCache: Cache; + private userAgent: string; + private timeouts: Timeouts; + private requester: Requester; + + constructor({ + hosts, + baseHeaders, + userAgent, + timeouts, + }: { + hosts: Host[]; + baseHeaders: Headers; + userAgent: string; + timeouts: Timeouts; + }) { + this.hosts = hosts; + this.hostsCache = new MemoryCache(); + this.baseHeaders = baseHeaders; + this.userAgent = userAgent; + this.timeouts = timeouts; + + this.requester = new Requester(); + } + + async createRetryableOptions(): Promise<{ + hosts: Host[]; + getTimeout: (retryCount: number, timeout: number) => number; + }> { + const statefulHosts = await Promise.all( + this.hosts.map((statelessHost) => { + return this.hostsCache.get(statelessHost, async () => { + return new StatefulHost(statelessHost); + }); + }) + ); + const hostsUp = statefulHosts.filter((host) => host.isUp()); + const hostsTimeouted = statefulHosts.filter((host) => host.isTimedout()); + + /** + * Note, we put the hosts that previously timeouted on the end of the list. + */ + const hostsAvailable = [...hostsUp, ...hostsTimeouted]; + + const statelessHostsAvailable = hostsAvailable.length > 0 ? hostsAvailable : this.hosts; + + return { + hosts: statelessHostsAvailable, + getTimeout(timeoutsCount: number, baseTimeout: number): number { + /** + * Imagine that you have 4 hosts, if timeouts will increase + * on the following way: 1 (timeouted) > 4 (timeouted) > 5 (200) + * + * Note that, the very next request, we start from the previous timeout + * + * 5 (timeouted) > 6 (timeouted) > 7 ... + * + * This strategy may need to be reviewed, but is the strategy on the our + * current v3 version. + */ + const timeoutMultiplier = + hostsTimeouted.length === 0 && timeoutsCount === 0 + ? 1 + : hostsTimeouted.length + 3 + timeoutsCount; + + return timeoutMultiplier * baseTimeout; + }, + }; + } + + async retryableRequest( + request: Request, + requestOptions: RequestOptions + ): Promise { + const stackTrace: StackFrame[] = []; + + /** + * First we prepare the payload that do not depend from hosts. + */ + const data = serializeData(request, requestOptions); + const headers = serializeHeaders(this.baseHeaders, requestOptions); + const method = request.method; + + // On `GET`, the data is proxied to query parameters. + const dataQueryParameters: Record = + request.method !== 'GET' + ? {} + : { + ...request.data, + ...requestOptions.data, + }; + + const queryParameters = { + 'x-algolia-agent': this.userAgent, + ...dataQueryParameters, + ...requestOptions.queryParameters, + }; + + let timeoutsCount = 0; + + const retry = async ( + hosts: Host[], + getTimeout: (timeoutsCount: number, timeout: number) => number + ): Promise => { + /** + * We iterate on each host, until there is no host left. + */ + const host = hosts.pop(); + if (host === undefined) { + throw new RetryError(stackTrace); + } + + const payload: EndRequest = { + data, + headers, + method, + url: serializeUrl(host, request.path, queryParameters), + connectTimeout: getTimeout(timeoutsCount, this.timeouts.connect), + responseTimeout: getTimeout(timeoutsCount, requestOptions.timeout as number), + }; + + /** + * The stackFrame is pushed to the stackTrace so we + * can have information about onRetry and onFailure + * decisions. + */ + const pushToStackTrace = (response: Response): StackFrame => { + const stackFrame: StackFrame = { + request: payload, + response, + host, + triesLeft: hosts.length, + }; + + stackTrace.push(stackFrame); + + return stackFrame; + }; + + const decisions: Outcomes = { + onSuccess: (response) => deserializeSuccess(response), + onRetry: async (response) => { + const stackFrame = pushToStackTrace(response); + + /** + * If response is a timeout, we increaset the number of + * timeouts so we can increase the timeout later. + */ + if (response.isTimedOut) { + timeoutsCount++; + } + + await Promise.all([ + /** + * Failures are individually send the logger, allowing + * the end user to debug / store stack frames even + * when a retry error does not happen. + */ + //transporter.logger.info('Retryable failure', stackFrameWithoutCredentials(stackFrame)), + + /** + * We also store the state of the host in failure cases. If the host, is + * down it will remain down for the next 2 minutes. In a timeout situation, + * this host will be added end of the list of hosts on the next request. + */ + this.hostsCache.set( + host, + new StatefulHost(host, response.isTimedOut ? 'timedout' : 'down') + ), + ]); + return retry(hosts, getTimeout); + }, + onFail: (response) => { + pushToStackTrace(response); + + throw deserializeFailure(response, stackTrace); + }, + }; + + const response = await this.requester.send(payload); + return retryDecision(response, decisions); + }; + + /** + * Finally, for each retryable host perform request until we got a non + * retryable response. Some notes here: + * + * 1. The reverse here is applied so we can apply a `pop` later on => more performant. + * 2. We also get from the retryable options a timeout multiplier that is tailored + * for the current context. + */ + const options = await this.createRetryableOptions(); + return retry([...options.hosts].reverse(), options.getTimeout); + } +} diff --git a/clients/utils/javascript/errors.ts b/clients/utils/javascript/errors.ts new file mode 100644 index 00000000000..df4f3008d94 --- /dev/null +++ b/clients/utils/javascript/errors.ts @@ -0,0 +1,38 @@ +import { Response, StackFrame } from './types'; + +class ErrorWithStackTrace extends Error { + stackTrace: StackFrame[]; + + constructor(message: string, stackTrace: StackFrame[]) { + super(message); + //the array and object should be frozen to reflect the stackTrace at the time of the error + this.stackTrace = stackTrace; + } +} + +export class RetryError extends ErrorWithStackTrace { + constructor(stackTrace: StackFrame[]) { + super( + 'Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.', + stackTrace + ); + } +} + +export class ApiError extends ErrorWithStackTrace { + status: number; + + constructor(message: string, status: number, stackTrace: StackFrame[]) { + super(message, stackTrace); + this.status = status; + } +} + +export class DeserializationError extends Error { + response: Response; + + constructor(message: string, response: Response) { + super(message); + this.response = response; + } +} diff --git a/clients/utils/javascript/helpers.ts b/clients/utils/javascript/helpers.ts new file mode 100644 index 00000000000..2271326b7e2 --- /dev/null +++ b/clients/utils/javascript/helpers.ts @@ -0,0 +1,94 @@ +import { ApiError, DeserializationError } from './errors'; +import { Headers, Host, Request, RequestOptions, Response, StackFrame } from './types'; + +export function shuffle(array: TData[]): TData[] { + for (let c = array.length - 1; c > 0; c--) { + const b = Math.floor(Math.random() * (c + 1)); + const a = array[c]; + array[c] = array[b]; + array[b] = a; + } + return array; +} + +export function serializeUrl( + host: Host, + path: string, + queryParameters: Readonly> +): string { + const queryParametersAsString = serializeQueryParameters(queryParameters); + let url = `${host.protocol}://${host.url}/${path.charAt(0) === '/' ? path.substr(1) : path}`; + + if (queryParametersAsString.length) { + url += `?${queryParametersAsString}`; + } + + return url; +} + +export function serializeQueryParameters(parameters: Readonly>): string { + const isObjectOrArray = (value: any): boolean => + Object.prototype.toString.call(value) === '[object Object]' || + Object.prototype.toString.call(value) === '[object Array]'; + + return Object.keys(parameters) + .map( + (key) => + `${key}=${ + isObjectOrArray(parameters[key]) ? JSON.stringify(parameters[key]) : parameters[key] + }` + ) + .join('&'); +} + +export function serializeData( + request: Request, + requestOptions: RequestOptions +): string | undefined { + if ( + request.method === 'GET' || + (request.data === undefined && requestOptions.data === undefined) + ) { + return undefined; + } + + const data = Array.isArray(request.data) + ? request.data + : { ...request.data, ...requestOptions.data }; + + return JSON.stringify(data); +} + +export function serializeHeaders(baseHeaders: Headers, requestOptions: RequestOptions): Headers { + const headers: Headers = { + ...baseHeaders, + ...requestOptions.headers, + }; + const serializedHeaders: Headers = {}; + + Object.keys(headers).forEach((header) => { + const value = headers[header]; + serializedHeaders[header.toLowerCase()] = value; + }); + + return serializedHeaders; +} + +export function deserializeSuccess(response: Response): TObject { + try { + return JSON.parse(response.content); + } catch (e) { + throw new DeserializationError((e as Error).message, response); + } +} + +export function deserializeFailure({ content, status }: Response, stackFrame: StackFrame[]): Error { + let message = content; + try { + message = JSON.parse(content).message; + } catch (e) { + // .. + } + + return new ApiError(message, status, stackFrame); +} diff --git a/clients/utils/javascript/retryDecision.ts b/clients/utils/javascript/retryDecision.ts new file mode 100644 index 00000000000..46d6685f1d5 --- /dev/null +++ b/clients/utils/javascript/retryDecision.ts @@ -0,0 +1,33 @@ +import { Outcomes, Response } from './types'; + +const isNetworkError = ({ isTimedOut, status }: Response): boolean => { + return !isTimedOut && ~~status === 0; +}; + +const isRetryable = (response: Response): boolean => { + const status = response.status; + const isTimedOut = response.isTimedOut; + + return ( + isTimedOut || isNetworkError(response) || (~~(status / 100) !== 2 && ~~(status / 100) !== 4) + ); +}; + +const isSuccess = ({ status }: Response): boolean => { + return ~~(status / 100) === 2; +}; + +export const retryDecision = ( + response: Response, + outcomes: Outcomes +): Readonly> => { + if (isRetryable(response)) { + return outcomes.onRetry(response); + } + + if (isSuccess(response)) { + return outcomes.onSuccess(response); + } + + return outcomes.onFail(response); +}; diff --git a/clients/utils/javascript/types.ts b/clients/utils/javascript/types.ts new file mode 100644 index 00000000000..bcb7819b171 --- /dev/null +++ b/clients/utils/javascript/types.ts @@ -0,0 +1,71 @@ +export type Method = 'GET' | 'PATCH' | 'POST' | 'PUT' | 'DELETE'; + +export type Request = { + method: Method; + path: string; + data?: Record; +}; + +export type RequestOptions = { + /** + * Custom timeout for the request. Note that, in normal situacions + * the given timeout will be applied. But the transporter layer may + * increase this timeout if there is need for it. + */ + timeout?: number; + + /** + * Custom headers for the request. This headers are + * going to be merged the transporter headers. + */ + headers?: Record; + + /** + * Custom query parameters for the request. This query parameters are + * going to be merged the transporter query parameters. + */ + queryParameters: Record; + data?: Record; +}; + +export type EndRequest = { + method: Method; + url: string; + connectTimeout: number; + responseTimeout: number; + headers: Headers; + data?: string; +}; + +export type Response = { + content: string; + isTimedOut: boolean; + status: number; +}; + +export type Headers = Record; + +export type Host = { + url: string; + accept: 'read' | 'write' | 'readWrite'; + protocol: 'http' | 'https'; +}; + +export type StackFrame = { + request: EndRequest; + response: Response; + host: Host; + triesLeft: number; +}; + +export type Timeouts = { + readonly connect: number; + readonly read: number; + readonly write: number; +}; + +export type Outcomes = { + readonly onFail: (response: Response) => Promise; + readonly onSuccess: (response: Response) => Promise; + readonly onRetry: (response: Response) => Promise; +}; diff --git a/doc/AddLanguage.md b/doc/AddLanguage.md deleted file mode 100644 index 7bda19f09f9..00000000000 --- a/doc/AddLanguage.md +++ /dev/null @@ -1,31 +0,0 @@ -# How to add a new language - -In order to generate a client for a new language, here is a short guide: - -## Extract the template - -First you need to find your language in the list of generators: -[list](https://openapi-generator.tech/docs/generators) - -Once you find your template you can extract it with the following command: -```bash -openapi-generator author template -g -o templates/ -``` - -## Customize the template - -There are a few components to add before generating the client, mostly: -- Init method -- Retry strategy -- maybe more - -### Init method - -By default, OpenAPI will put the `AppId` and `ApiKey` in every method, but we want an init method that takes those parameters and put them in the header of every requests, and create the right hosts. -To do this, change the constructor of the client in the `mustache` file to accept and store them. - -### Retry strategy - -The retry strategy cannot be included in the OpenAPI spec, you need to add a `` folder inside the `complement` folder and add your retry strategy code in that folder. - -TODO finish this when we have more knowledge about the other languages. diff --git a/doc/contribution_addNewClient.md b/doc/contribution_addNewClient.md new file mode 100644 index 00000000000..da1c30b0842 --- /dev/null +++ b/doc/contribution_addNewClient.md @@ -0,0 +1,45 @@ +# How to add a new client + +Here is a short guide on how to generate a new API client for your language + +## Find your default template + +Provided templates are a good starting point to generate a client, pick the one you find closer to what you'd like to achieve. + +You can pick a default template on the [openapi-generator's "generators" page](https://openapi-generator.tech/docs/generators) + +## Extract the template locally + +```bash +openapi-generator author template -g -o templates/ +``` + +Example for the JavaScript client + +```bash +openapi-generator author template -g typescript-node -o templates/algoliasearch-client-javascript/ +``` + +## Customize the template + +API clients require a custom Algolia logic in order to seamlessly work with our engine. + +You will need to implement: + +- An `init` method +- The `retry strategy` with your custom transporter +- More to come... + +### Init method + +By default, OpenAPI will put the `AppId` and `ApiKey` in every method, but we want an init method that takes those parameters and put them in the header of every requests, and create the right hosts. + +To do this, change the constructor of the client in the `mustache` file to accept and store them. + +See this PR of the first JavaScript implementation for reference: https://github.com/algolia/api-client-automation-experiment/pull/7 + +### Retry strategy + +The retry strategy cannot be generated and needs to be implemented outside of the generated client folder. You need to add your transporter to the `utils/ folder, and update the `.mustache` template files accordingly. + +See this PR of the first JavaScript implementation for reference: https://github.com/algolia/api-client-automation-experiment/pull/9 diff --git a/openapitools.json b/openapitools.json index 96de49bae43..9aec6cd426e 100644 --- a/openapitools.json +++ b/openapitools.json @@ -3,14 +3,13 @@ "generator-cli": { "version": "5.2.1", "generators": { - "client": { + "javascript-client": { "generatorName": "typescript-node", - "templateDir": "#{cwd}/algolia-typescript-template/", + "templateDir": "#{cwd}/templates/javascript-client-template/", "config": "#{cwd}/openapitools.json", - "httpUserAgent": "Algolia for JavaScript ({packageVersion});", "apiPackage": "client-search", - "output": "#{cwd}/output/", - "glob": "openapi_spec/spec.yml", + "output": "#{cwd}/clients/algoliasearch-client-javascript", + "glob": "specs/spec.yml", "gitHost": "algolia", "gitUserId": "algolia", "gitRepoId": "algoliasearch-client-javascript", diff --git a/package.json b/package.json index 55225910817..43ff03db74b 100644 --- a/package.json +++ b/package.json @@ -1,22 +1,27 @@ { - "name": "@algolia/automation-javascript-client", + "name": "@algolia/api-client-automation", "version": "0.0.0", "workspaces": [ - "output" + "clients/*" ], "scripts": { - "lint": "yarn prettier --write openapi_spec output", - "generate": "PACKAGE_VERSION='4.11.0' yarn openapi-generator-cli generate --generator-key client && ln -fs \"$(pwd)/complement\" \"$(pwd)/output/\" && yarn lint && yarn install", "build:spec": "yarn swagger-cli bundle openapi_spec/spec.yml --outfile dist/openapi.yml --type yaml", - "client:build": "cd output/ && yarn install && yarn build && cd ..", + "clean:clients": "rm -rf clients/algoliasearch-*/*", + "clean": "rm -rf **/dist **/build **/node_modules", + "client:build-js": "cd clients/algoliasearch-client-javascript/ && yarn install && yarn build && cd ../../", + "client:build": "yarn client:build-js", "client:test": "yarn install && tsc && node dist/app.js", "client": "yarn client:build && yarn client:test", - "clean:output": "rm -rf output/*", - "clean": "rm -rf dist build node_modules" + "lint:js": "yarn prettier --write clients/algoliasearch-client-javascript clients/utils/javascript", + "lint:specs": "yarn prettier --write specs", + "lint": "yarn lint:specs && yarn lint:js", + "generate:js": "PACKAGE_VERSION='4.11.0' yarn openapi-generator-cli generate --generator-key javascript-client && yarn utils:import-js", + "generate": "yarn generate:js && yarn lint", + "utils:import-js": "mkdir -p -- clients/algoliasearch-client-javascript/utils && cp -R clients/utils/javascript/ clients/algoliasearch-client-javascript/utils" }, "devDependencies": { "@openapitools/openapi-generator-cli": "^2.4.13", - "algoliasearch-client-javascript": "file:output/", + "algoliasearch-client-javascript": "file:clients/algoliasearch-client-javascript/", "dotenv": "10.0.0", "prettier": "2.4.1", "swagger-cli": "^4.0.4", @@ -25,6 +30,5 @@ "engines": { "node": ">= 12.0.0", "yarn": ">= 2.0.0" - }, - "packageManager": "yarn@3.0.2" + } } diff --git a/openapi_spec/parameters.yml b/specs/parameters.yml similarity index 100% rename from openapi_spec/parameters.yml rename to specs/parameters.yml diff --git a/openapi_spec/paths/indexes/batch.yml b/specs/paths/indexes/batch.yml similarity index 100% rename from openapi_spec/paths/indexes/batch.yml rename to specs/paths/indexes/batch.yml diff --git a/openapi_spec/paths/indexes/multipleQueries.yml b/specs/paths/indexes/multipleQueries.yml similarity index 100% rename from openapi_spec/paths/indexes/multipleQueries.yml rename to specs/paths/indexes/multipleQueries.yml diff --git a/openapi_spec/paths/indexes/saveObject.yml b/specs/paths/indexes/saveObject.yml similarity index 100% rename from openapi_spec/paths/indexes/saveObject.yml rename to specs/paths/indexes/saveObject.yml diff --git a/openapi_spec/paths/indexes/search.yml b/specs/paths/indexes/search.yml similarity index 100% rename from openapi_spec/paths/indexes/search.yml rename to specs/paths/indexes/search.yml diff --git a/openapi_spec/responses/BadRequest.yml b/specs/responses/BadRequest.yml similarity index 100% rename from openapi_spec/responses/BadRequest.yml rename to specs/responses/BadRequest.yml diff --git a/openapi_spec/responses/IndexNotFound.yml b/specs/responses/IndexNotFound.yml similarity index 100% rename from openapi_spec/responses/IndexNotFound.yml rename to specs/responses/IndexNotFound.yml diff --git a/openapi_spec/responses/common.yml b/specs/responses/common.yml similarity index 100% rename from openapi_spec/responses/common.yml rename to specs/responses/common.yml diff --git a/openapi_spec/schemas/Error.yml b/specs/schemas/Error.yml similarity index 100% rename from openapi_spec/schemas/Error.yml rename to specs/schemas/Error.yml diff --git a/openapi_spec/schemas/IndexSettingsParams.yml b/specs/schemas/IndexSettingsParams.yml similarity index 100% rename from openapi_spec/schemas/IndexSettingsParams.yml rename to specs/schemas/IndexSettingsParams.yml diff --git a/openapi_spec/schemas/Record.yml b/specs/schemas/Record.yml similarity index 100% rename from openapi_spec/schemas/Record.yml rename to specs/schemas/Record.yml diff --git a/openapi_spec/schemas/RequestOptions.yml b/specs/schemas/RequestOptions.yml similarity index 100% rename from openapi_spec/schemas/RequestOptions.yml rename to specs/schemas/RequestOptions.yml diff --git a/openapi_spec/schemas/SearchParams.yml b/specs/schemas/SearchParams.yml similarity index 100% rename from openapi_spec/schemas/SearchParams.yml rename to specs/schemas/SearchParams.yml diff --git a/openapi_spec/schemas/SearchResponse.yml b/specs/schemas/SearchResponse.yml similarity index 100% rename from openapi_spec/schemas/SearchResponse.yml rename to specs/schemas/SearchResponse.yml diff --git a/openapi_spec/spec.yml b/specs/spec.yml similarity index 100% rename from openapi_spec/spec.yml rename to specs/spec.yml diff --git a/algolia-typescript-template/api-all.mustache b/templates/javascript-client-template/api-all.mustache similarity index 100% rename from algolia-typescript-template/api-all.mustache rename to templates/javascript-client-template/api-all.mustache diff --git a/algolia-typescript-template/api-single.mustache b/templates/javascript-client-template/api-single.mustache similarity index 97% rename from algolia-typescript-template/api-single.mustache rename to templates/javascript-client-template/api-single.mustache index 260d07dc0de..f191f90e9dd 100644 --- a/algolia-typescript-template/api-single.mustache +++ b/templates/javascript-client-template/api-single.mustache @@ -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'; {{#imports}} import { {{classname}} } from '{{filename}}'; diff --git a/algolia-typescript-template/api.mustache b/templates/javascript-client-template/api.mustache similarity index 100% rename from algolia-typescript-template/api.mustache rename to templates/javascript-client-template/api.mustache diff --git a/algolia-typescript-template/gitignore b/templates/javascript-client-template/gitignore similarity index 100% rename from algolia-typescript-template/gitignore rename to templates/javascript-client-template/gitignore diff --git a/algolia-typescript-template/licenseInfo.mustache b/templates/javascript-client-template/licenseInfo.mustache similarity index 100% rename from algolia-typescript-template/licenseInfo.mustache rename to templates/javascript-client-template/licenseInfo.mustache diff --git a/algolia-typescript-template/model.mustache b/templates/javascript-client-template/model.mustache similarity index 100% rename from algolia-typescript-template/model.mustache rename to templates/javascript-client-template/model.mustache diff --git a/algolia-typescript-template/models.mustache b/templates/javascript-client-template/models.mustache similarity index 99% rename from algolia-typescript-template/models.mustache rename to templates/javascript-client-template/models.mustache index 2ec6de13f3c..551e865c0ad 100644 --- a/algolia-typescript-template/models.mustache +++ b/templates/javascript-client-template/models.mustache @@ -1,5 +1,5 @@ {{#generateApis}} -import type { RequestOptions } from '../complement/types'; +import type { RequestOptions } from '../utils/types'; {{/generateApis}} {{#models}} diff --git a/algolia-typescript-template/package.mustache b/templates/javascript-client-template/package.mustache similarity index 100% rename from algolia-typescript-template/package.mustache rename to templates/javascript-client-template/package.mustache diff --git a/algolia-typescript-template/tsconfig.mustache b/templates/javascript-client-template/tsconfig.mustache similarity index 100% rename from algolia-typescript-template/tsconfig.mustache rename to templates/javascript-client-template/tsconfig.mustache diff --git a/recommend_spec.yml b/utils/recommend_spec.yml similarity index 100% rename from recommend_spec.yml rename to utils/recommend_spec.yml diff --git a/recommend_spec_2.yml b/utils/recommend_spec_2.yml similarity index 100% rename from recommend_spec_2.yml rename to utils/recommend_spec_2.yml diff --git a/search_spec.yml b/utils/search_spec.yml similarity index 100% rename from search_spec.yml rename to utils/search_spec.yml diff --git a/yarn.lock b/yarn.lock index ee9958f64c4..fca39756250 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,12 +5,12 @@ __metadata: version: 4 cacheKey: 8 -"@algolia/automation-javascript-client@workspace:.": +"@algolia/api-client-automation@workspace:.": version: 0.0.0-use.local - resolution: "@algolia/automation-javascript-client@workspace:." + resolution: "@algolia/api-client-automation@workspace:." dependencies: "@openapitools/openapi-generator-cli": ^2.4.13 - algoliasearch-client-javascript: "file:output/" + algoliasearch-client-javascript: "file:clients/algoliasearch-client-javascript/" dotenv: 10.0.0 prettier: 2.4.1 swagger-cli: ^4.0.4 @@ -187,16 +187,16 @@ __metadata: languageName: node linkType: hard -"algoliasearch-client-javascript@file:output/::locator=%40algolia%2Fautomation-javascript-client%40workspace%3A.": +"algoliasearch-client-javascript@file:clients/algoliasearch-client-javascript/::locator=%40algolia%2Fapi-client-automation%40workspace%3A.": version: 5.0.0 - resolution: "algoliasearch-client-javascript@file:output/#output/::hash=fb52f6&locator=%40algolia%2Fautomation-javascript-client%40workspace%3A." - checksum: 20ff5d88808c415a239014111cd7eb1b34a5feb33a4606088901f4d6cab484a34e5a0ebbc369fcf6e2633ed8a3ba5e0ba964bc0127f0af4974d68ebf9c363f86 + resolution: "algoliasearch-client-javascript@file:clients/algoliasearch-client-javascript/#clients/algoliasearch-client-javascript/::hash=17be4b&locator=%40algolia%2Fapi-client-automation%40workspace%3A." + checksum: f14ee82e8dfc09feba8332c1d16a3e879957c8aded6efe13be4bac62ff19d38a528920e9be19d8949d73a519b38e6d0cfbaacb644c38c87a057c19877d11f937 languageName: node linkType: hard -"algoliasearch-client-javascript@workspace:output": +"algoliasearch-client-javascript@workspace:clients/algoliasearch-client-javascript": version: 0.0.0-use.local - resolution: "algoliasearch-client-javascript@workspace:output" + resolution: "algoliasearch-client-javascript@workspace:clients/algoliasearch-client-javascript" dependencies: "@types/node": ^16.11.6 typescript: ^4.4.4 @@ -1161,7 +1161,7 @@ __metadata: languageName: node linkType: hard -"typescript@4.4.4, typescript@^4.4.4": +typescript@4.4.4: version: 4.4.4 resolution: "typescript@npm:4.4.4" bin: @@ -1171,7 +1171,17 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@4.4.4#~builtin, typescript@patch:typescript@^4.4.4#~builtin": +typescript@^4.4.4: + version: 4.5.2 + resolution: "typescript@npm:4.5.2" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 74f9ce65d532bdf5d0214b3f60cf37992180023388c87a11ee6f838a803067ef0b63c600fa501b0deb07f989257dce1e244c9635ed79feca40bbccf6e0aa1ebc + languageName: node + linkType: hard + +"typescript@patch:typescript@4.4.4#~builtin": version: 4.4.4 resolution: "typescript@patch:typescript@npm%3A4.4.4#~builtin::version=4.4.4&hash=32657b" bin: @@ -1181,6 +1191,16 @@ __metadata: languageName: node linkType: hard +"typescript@patch:typescript@^4.4.4#~builtin": + version: 4.5.2 + resolution: "typescript@patch:typescript@npm%3A4.5.2#~builtin::version=4.5.2&hash=32657b" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 02cf0f190f0cb6d216558d8db9c3a968feeab4965c340a351e5e6e84a42a3946e5e200a9538b6e427af9d17e4f713254dd0707d5fd6f238ce93f0aee1986ab57 + languageName: node + linkType: hard + "universalify@npm:^2.0.0": version: 2.0.0 resolution: "universalify@npm:2.0.0" From 0fc7f3746339afe8a82a2c3e6d99e26ef2852cbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Thu, 18 Nov 2021 16:06:52 +0100 Subject: [PATCH 2/6] fix: pin typescript version --- README.md | 2 +- .../package.json | 2 +- package.json | 2 +- .../package.mustache | 2 +- yarn.lock | 32 ++++--------------- 5 files changed, 10 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 323f06898a1..93f3a91c291 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ yarn client:test > `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` file or do the following command in this repository: +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 echo 'export PATH="/usr/local/opt/openjdk/bin:$PATH"' > .bash_profile && source .bash_profile diff --git a/clients/algoliasearch-client-javascript/package.json b/clients/algoliasearch-client-javascript/package.json index ae9aab3295f..3b7a1b1df0d 100644 --- a/clients/algoliasearch-client-javascript/package.json +++ b/clients/algoliasearch-client-javascript/package.json @@ -19,6 +19,6 @@ }, "devDependencies": { "@types/node": "^16.11.6", - "typescript": "^4.4.4" + "typescript": "4.5.2" } } diff --git a/package.json b/package.json index 43ff03db74b..e006f61d9fd 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "dotenv": "10.0.0", "prettier": "2.4.1", "swagger-cli": "^4.0.4", - "typescript": "4.4.4" + "typescript": "4.5.2" }, "engines": { "node": ">= 12.0.0", diff --git a/templates/javascript-client-template/package.mustache b/templates/javascript-client-template/package.mustache index 1780ccb7828..43d18debce3 100644 --- a/templates/javascript-client-template/package.mustache +++ b/templates/javascript-client-template/package.mustache @@ -19,7 +19,7 @@ }, "devDependencies": { "@types/node": "^16.11.6", - "typescript": "^4.4.4" + "typescript": "4.5.2" } {{#npmRepository}}, "publishConfig": { diff --git a/yarn.lock b/yarn.lock index fca39756250..e770e41895f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14,7 +14,7 @@ __metadata: dotenv: 10.0.0 prettier: 2.4.1 swagger-cli: ^4.0.4 - typescript: 4.4.4 + typescript: 4.5.2 languageName: unknown linkType: soft @@ -189,8 +189,8 @@ __metadata: "algoliasearch-client-javascript@file:clients/algoliasearch-client-javascript/::locator=%40algolia%2Fapi-client-automation%40workspace%3A.": version: 5.0.0 - resolution: "algoliasearch-client-javascript@file:clients/algoliasearch-client-javascript/#clients/algoliasearch-client-javascript/::hash=17be4b&locator=%40algolia%2Fapi-client-automation%40workspace%3A." - checksum: f14ee82e8dfc09feba8332c1d16a3e879957c8aded6efe13be4bac62ff19d38a528920e9be19d8949d73a519b38e6d0cfbaacb644c38c87a057c19877d11f937 + resolution: "algoliasearch-client-javascript@file:clients/algoliasearch-client-javascript/#clients/algoliasearch-client-javascript/::hash=15f8cd&locator=%40algolia%2Fapi-client-automation%40workspace%3A." + checksum: a9c0396026c208de698f1d27213707e5d52a5efd9ae060ac1ae795e83e628cb27e27dee208c51199f5c2633aad82864ced200c0231474fd9cec8d003a1a23d5f languageName: node linkType: hard @@ -199,7 +199,7 @@ __metadata: resolution: "algoliasearch-client-javascript@workspace:clients/algoliasearch-client-javascript" dependencies: "@types/node": ^16.11.6 - typescript: ^4.4.4 + typescript: 4.5.2 languageName: unknown linkType: soft @@ -1161,17 +1161,7 @@ __metadata: languageName: node linkType: hard -typescript@4.4.4: - version: 4.4.4 - resolution: "typescript@npm:4.4.4" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 89ecb8436bb48ef5594d49289f5f89103071716b6e4844278f4fb3362856e31203e187a9c76d205c3f0b674d221a058fd28310dbcbcf5d95e9a57229bb5203f1 - languageName: node - linkType: hard - -typescript@^4.4.4: +typescript@4.5.2: version: 4.5.2 resolution: "typescript@npm:4.5.2" bin: @@ -1181,17 +1171,7 @@ typescript@^4.4.4: languageName: node linkType: hard -"typescript@patch:typescript@4.4.4#~builtin": - version: 4.4.4 - resolution: "typescript@patch:typescript@npm%3A4.4.4#~builtin::version=4.4.4&hash=32657b" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: c97c33903f1eb4f9e178649befdfc859d93157db1eccd1e521e84976ec6861db53412d8018e5e4c5d09268771c65498d42caa64bd881878346c3644f6b7cd202 - languageName: node - linkType: hard - -"typescript@patch:typescript@^4.4.4#~builtin": +"typescript@patch:typescript@4.5.2#~builtin": version: 4.5.2 resolution: "typescript@patch:typescript@npm%3A4.5.2#~builtin::version=4.5.2&hash=32657b" bin: From ad3f6c96ecbaf19ccef91f845fa4a676ffa92bad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Thu, 18 Nov 2021 18:11:32 +0100 Subject: [PATCH 3/6] add playground folder, rename template --- README.md | 8 +- .../package.json | 4 +- openapitools.json | 2 +- package.json | 23 ++--- .../javascript/.env.example | 0 app.ts => playground/javascript/app.ts | 0 playground/javascript/package.json | 19 ++++ .../javascript/tsconfig.json | 0 .../api-all.mustache | 0 .../api-single.mustache | 0 .../api.mustache | 0 .../gitignore | 0 .../licenseInfo.mustache | 0 .../model.mustache | 0 .../models.mustache | 0 .../package.mustache | 4 +- .../tsconfig.mustache | 0 yarn.lock | 99 ++++++++++--------- 18 files changed, 90 insertions(+), 69 deletions(-) rename .env.example => playground/javascript/.env.example (100%) rename app.ts => playground/javascript/app.ts (100%) create mode 100644 playground/javascript/package.json rename tsconfig.json => playground/javascript/tsconfig.json (100%) rename templates/{javascript-client-template => javascript}/api-all.mustache (100%) rename templates/{javascript-client-template => javascript}/api-single.mustache (100%) rename templates/{javascript-client-template => javascript}/api.mustache (100%) rename templates/{javascript-client-template => javascript}/gitignore (100%) rename templates/{javascript-client-template => javascript}/licenseInfo.mustache (100%) rename templates/{javascript-client-template => javascript}/model.mustache (100%) rename templates/{javascript-client-template => javascript}/models.mustache (100%) rename templates/{javascript-client-template => javascript}/package.mustache (92%) rename templates/{javascript-client-template => javascript}/tsconfig.mustache (100%) diff --git a/README.md b/README.md index 93f3a91c291..cda1b7f9f7a 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,14 @@ yarn generate yarn client:build ``` -## Test JavaScript client locally +# Testing clients + +Go to the [`playground`](./playground) folder to test your client + +## JavaScript ```bash -yarn client:test +cd playground/javascript && yarn start ``` # Troubleshooting diff --git a/clients/algoliasearch-client-javascript/package.json b/clients/algoliasearch-client-javascript/package.json index 3b7a1b1df0d..3b848f601d5 100644 --- a/clients/algoliasearch-client-javascript/package.json +++ b/clients/algoliasearch-client-javascript/package.json @@ -14,8 +14,8 @@ "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", diff --git a/openapitools.json b/openapitools.json index 9aec6cd426e..866cf8a97a4 100644 --- a/openapitools.json +++ b/openapitools.json @@ -5,7 +5,7 @@ "generators": { "javascript-client": { "generatorName": "typescript-node", - "templateDir": "#{cwd}/templates/javascript-client-template/", + "templateDir": "#{cwd}/templates/javascript/", "config": "#{cwd}/openapitools.json", "apiPackage": "client-search", "output": "#{cwd}/clients/algoliasearch-client-javascript", diff --git a/package.json b/package.json index e006f61d9fd..453fec721d4 100644 --- a/package.json +++ b/package.json @@ -1,34 +1,31 @@ { "name": "@algolia/api-client-automation", "version": "0.0.0", - "workspaces": [ - "clients/*" - ], + "workspaces": { + "packages": [ + "clients/algoliasearch-client-javascript/", + "playground/javascript/" + ] + }, "scripts": { "build:spec": "yarn swagger-cli bundle openapi_spec/spec.yml --outfile dist/openapi.yml --type yaml", - "clean:clients": "rm -rf clients/algoliasearch-*/*", "clean": "rm -rf **/dist **/build **/node_modules", "client:build-js": "cd clients/algoliasearch-client-javascript/ && yarn install && yarn build && cd ../../", "client:build": "yarn client:build-js", - "client:test": "yarn install && tsc && node dist/app.js", - "client": "yarn client:build && yarn client:test", "lint:js": "yarn prettier --write clients/algoliasearch-client-javascript clients/utils/javascript", "lint:specs": "yarn prettier --write specs", "lint": "yarn lint:specs && yarn lint:js", - "generate:js": "PACKAGE_VERSION='4.11.0' yarn openapi-generator-cli generate --generator-key javascript-client && yarn utils:import-js", + "generate:js": "PACKAGE_VERSION='4.11.0' yarn openapi-generator-cli generate --generator-key javascript-client && yarn install && yarn utils:import-js", "generate": "yarn generate:js && yarn lint", "utils:import-js": "mkdir -p -- clients/algoliasearch-client-javascript/utils && cp -R clients/utils/javascript/ clients/algoliasearch-client-javascript/utils" }, "devDependencies": { "@openapitools/openapi-generator-cli": "^2.4.13", - "algoliasearch-client-javascript": "file:clients/algoliasearch-client-javascript/", - "dotenv": "10.0.0", "prettier": "2.4.1", - "swagger-cli": "^4.0.4", - "typescript": "4.5.2" + "swagger-cli": "^4.0.4" }, "engines": { - "node": ">= 12.0.0", - "yarn": ">= 2.0.0" + "node": "^16.0.0", + "yarn": "^3.0.0" } } diff --git a/.env.example b/playground/javascript/.env.example similarity index 100% rename from .env.example rename to playground/javascript/.env.example diff --git a/app.ts b/playground/javascript/app.ts similarity index 100% rename from app.ts rename to playground/javascript/app.ts diff --git a/playground/javascript/package.json b/playground/javascript/package.json new file mode 100644 index 00000000000..5af9654adfa --- /dev/null +++ b/playground/javascript/package.json @@ -0,0 +1,19 @@ +{ + "name": "algoliasearch-client-javascript-playground", + "version": "0.0.0", + "scripts": { + "build": "tsc", + "start": "yarn install && yarn build && yarn test", + "test": "node dist/app.js" + }, + "devDependencies": { + "algoliasearch-client-javascript": "5.0.0", + "dotenv": "10.0.0", + "prettier": "2.4.1", + "typescript": "4.5.2" + }, + "engines": { + "node": "^16.0.0", + "yarn": "^3.0.0" + } +} diff --git a/tsconfig.json b/playground/javascript/tsconfig.json similarity index 100% rename from tsconfig.json rename to playground/javascript/tsconfig.json diff --git a/templates/javascript-client-template/api-all.mustache b/templates/javascript/api-all.mustache similarity index 100% rename from templates/javascript-client-template/api-all.mustache rename to templates/javascript/api-all.mustache diff --git a/templates/javascript-client-template/api-single.mustache b/templates/javascript/api-single.mustache similarity index 100% rename from templates/javascript-client-template/api-single.mustache rename to templates/javascript/api-single.mustache diff --git a/templates/javascript-client-template/api.mustache b/templates/javascript/api.mustache similarity index 100% rename from templates/javascript-client-template/api.mustache rename to templates/javascript/api.mustache diff --git a/templates/javascript-client-template/gitignore b/templates/javascript/gitignore similarity index 100% rename from templates/javascript-client-template/gitignore rename to templates/javascript/gitignore diff --git a/templates/javascript-client-template/licenseInfo.mustache b/templates/javascript/licenseInfo.mustache similarity index 100% rename from templates/javascript-client-template/licenseInfo.mustache rename to templates/javascript/licenseInfo.mustache diff --git a/templates/javascript-client-template/model.mustache b/templates/javascript/model.mustache similarity index 100% rename from templates/javascript-client-template/model.mustache rename to templates/javascript/model.mustache diff --git a/templates/javascript-client-template/models.mustache b/templates/javascript/models.mustache similarity index 100% rename from templates/javascript-client-template/models.mustache rename to templates/javascript/models.mustache diff --git a/templates/javascript-client-template/package.mustache b/templates/javascript/package.mustache similarity index 92% rename from templates/javascript-client-template/package.mustache rename to templates/javascript/package.mustache index 43d18debce3..11cc8806778 100644 --- a/templates/javascript-client-template/package.mustache +++ b/templates/javascript/package.mustache @@ -14,8 +14,8 @@ "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", diff --git a/templates/javascript-client-template/tsconfig.mustache b/templates/javascript/tsconfig.mustache similarity index 100% rename from templates/javascript-client-template/tsconfig.mustache rename to templates/javascript/tsconfig.mustache diff --git a/yarn.lock b/yarn.lock index e770e41895f..ae32476aed5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,11 +10,8 @@ __metadata: resolution: "@algolia/api-client-automation@workspace:." dependencies: "@openapitools/openapi-generator-cli": ^2.4.13 - algoliasearch-client-javascript: "file:clients/algoliasearch-client-javascript/" - dotenv: 10.0.0 prettier: 2.4.1 swagger-cli: ^4.0.4 - typescript: 4.5.2 languageName: unknown linkType: soft @@ -81,11 +78,11 @@ __metadata: languageName: node linkType: hard -"@nestjs/common@npm:8.0.9": - version: 8.0.9 - resolution: "@nestjs/common@npm:8.0.9" +"@nestjs/common@npm:8.2.2": + version: 8.2.2 + resolution: "@nestjs/common@npm:8.2.2" dependencies: - axios: 0.21.4 + axios: 0.24.0 iterare: 1.2.1 tslib: 2.3.1 uuid: 8.3.2 @@ -102,13 +99,13 @@ __metadata: optional: true class-validator: optional: true - checksum: 7b5df099b9b54770b10420b096df580d91eb889706787efd9928ce7f6ea6ecb829ff0ae29a7af9c95b78687be37824296afc296ee316b713e93e43a8422647c9 + checksum: 5d74143630d9bbe28d18bb9c47a948f84c2b62aed0974de0963ec3e94da9964b9b214da3622b4b6970456dfe03dc12439728c57570ffca5e2283b4fe3ac6daee languageName: node linkType: hard -"@nestjs/core@npm:8.0.9": - version: 8.0.9 - resolution: "@nestjs/core@npm:8.0.9" +"@nestjs/core@npm:8.2.2": + version: 8.2.2 + resolution: "@nestjs/core@npm:8.2.2" dependencies: "@nuxtjs/opencollective": 0.3.2 fast-safe-stringify: 2.1.1 @@ -131,7 +128,7 @@ __metadata: optional: true "@nestjs/websockets": optional: true - checksum: 65f481ef03b0432c89d0905b459084cb9839ea88e6ff56bf5b4f9e5a70823d681e8aebdeddcb19bebde71ace557123734fa7e884ed27814b433cb93318591a1e + checksum: 5dee8d70b9c8e09c3810f028fdaa91b0025fd11bf2fd47b74d44ee44b6cce9245709f3b69a1661be23ba67688ed67eeb85770a2d0c1812534429976ba103d8e8 languageName: node linkType: hard @@ -149,16 +146,16 @@ __metadata: linkType: hard "@openapitools/openapi-generator-cli@npm:^2.4.13": - version: 2.4.13 - resolution: "@openapitools/openapi-generator-cli@npm:2.4.13" + version: 2.4.17 + resolution: "@openapitools/openapi-generator-cli@npm:2.4.17" dependencies: - "@nestjs/common": 8.0.9 - "@nestjs/core": 8.0.9 + "@nestjs/common": 8.2.2 + "@nestjs/core": 8.2.2 "@nuxtjs/opencollective": 0.3.2 chalk: 4.1.2 commander: 8.3.0 compare-versions: 3.6.0 - concurrently: 6.3.0 + concurrently: 6.4.0 console.table: 0.10.0 fs-extra: 10.0.0 glob: 7.1.6 @@ -169,7 +166,7 @@ __metadata: tslib: 2.0.3 bin: openapi-generator-cli: main.js - checksum: a2f0a82a4e97bfc13f703aac28b52b811b2528a5d7e923adeba3a376281324f53337bb6a93d9f1e8fc8a9f2305bd8a8d112f8f2d00f47aee1a488fdf68fff12c + checksum: 6d344ef62e4647e3c830f1463deb320e07dfc33ba09016d2488c28f13b71dfccc2b4d4f02ee1252102f8dd1f2bac98b440fa1824ba24efef40d7b4def5cd073b languageName: node linkType: hard @@ -181,20 +178,24 @@ __metadata: linkType: hard "@types/node@npm:^16.11.6": - version: 16.11.7 - resolution: "@types/node@npm:16.11.7" - checksum: 2706403e6efc4aa40fdce8f0b5d9884d5600c3c8610aedc7fa5e7e298d30366f7e8b7296028d52898dca3edef4c3e827b03bf20952c4780f13fa4e79864f7a86 + version: 16.11.9 + resolution: "@types/node@npm:16.11.9" + checksum: baec2e6471ee58fd1e9874e6f47ab95a918a0f46b42424392e4c13e3e07f078f8b72b6b48073b0b14f710ed66c5f1b2e497df43f28151000f11f5f299382cfe2 languageName: node linkType: hard -"algoliasearch-client-javascript@file:clients/algoliasearch-client-javascript/::locator=%40algolia%2Fapi-client-automation%40workspace%3A.": - version: 5.0.0 - resolution: "algoliasearch-client-javascript@file:clients/algoliasearch-client-javascript/#clients/algoliasearch-client-javascript/::hash=15f8cd&locator=%40algolia%2Fapi-client-automation%40workspace%3A." - checksum: a9c0396026c208de698f1d27213707e5d52a5efd9ae060ac1ae795e83e628cb27e27dee208c51199f5c2633aad82864ced200c0231474fd9cec8d003a1a23d5f - languageName: node - linkType: hard +"algoliasearch-client-javascript-playground@workspace:playground/javascript": + version: 0.0.0-use.local + resolution: "algoliasearch-client-javascript-playground@workspace:playground/javascript" + dependencies: + algoliasearch-client-javascript: 5.0.0 + dotenv: 10.0.0 + prettier: 2.4.1 + typescript: 4.5.2 + languageName: unknown + linkType: soft -"algoliasearch-client-javascript@workspace:clients/algoliasearch-client-javascript": +"algoliasearch-client-javascript@5.0.0, algoliasearch-client-javascript@workspace:clients/algoliasearch-client-javascript": version: 0.0.0-use.local resolution: "algoliasearch-client-javascript@workspace:clients/algoliasearch-client-javascript" dependencies: @@ -244,12 +245,12 @@ __metadata: languageName: node linkType: hard -"axios@npm:0.21.4": - version: 0.21.4 - resolution: "axios@npm:0.21.4" +"axios@npm:0.24.0": + version: 0.24.0 + resolution: "axios@npm:0.24.0" dependencies: - follow-redirects: ^1.14.0 - checksum: 44245f24ac971e7458f3120c92f9d66d1fc695e8b97019139de5b0cc65d9b8104647db01e5f46917728edfc0cfd88eb30fc4c55e6053eef4ace76768ce95ff3c + follow-redirects: ^1.14.4 + checksum: 468cf496c08a6aadfb7e699bebdac02851e3043d4e7d282350804ea8900e30d368daa6e3cd4ab83b8ddb5a3b1e17a5a21ada13fc9cebd27b74828f47a4236316 languageName: node linkType: hard @@ -425,9 +426,9 @@ __metadata: languageName: node linkType: hard -"concurrently@npm:6.3.0": - version: 6.3.0 - resolution: "concurrently@npm:6.3.0" +"concurrently@npm:6.4.0": + version: 6.4.0 + resolution: "concurrently@npm:6.4.0" dependencies: chalk: ^4.1.0 date-fns: ^2.16.1 @@ -439,7 +440,7 @@ __metadata: yargs: ^16.2.0 bin: concurrently: bin/concurrently.js - checksum: fb68236899259a3b0c05d27db608ee9150f11fc785552c14937e5e1421c9448d03704cdc2acb5f842a91c465d50005b4229f348eb9594d84cbef54e5a93ffde7 + checksum: 902864cc853176cac406246fa367a1b24ebfcbea9ba43c164f9cb4e2c9c1a5f9d8be05ce98fe7ef13329ffd5cc340a052007a9c870863e2068425d95b3bf89d7 languageName: node linkType: hard @@ -460,9 +461,9 @@ __metadata: linkType: hard "date-fns@npm:^2.16.1": - version: 2.25.0 - resolution: "date-fns@npm:2.25.0" - checksum: 8896dc1dde0ee5ef77616942423bfa11fa2017a5ac19457293b7aaedc8822ff94f0a14eaf93da573b09b601dc0149eb430988a046cc9f79a2eb15f8c66c9c50c + version: 2.26.0 + resolution: "date-fns@npm:2.26.0" + checksum: 49ad59bc788134a6552ef4e4af0d18792001c1ca0070d543de4f36aba5761058b6e6a57b8ca51dd3b0f07f3bd55376b8bc69602bd7940648ba3869c5253c6ae8 languageName: node linkType: hard @@ -569,7 +570,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.14.0": +"follow-redirects@npm:^1.14.4": version: 1.14.5 resolution: "follow-redirects@npm:1.14.5" peerDependenciesMeta: @@ -1016,9 +1017,9 @@ __metadata: linkType: hard "signal-exit@npm:^3.0.2": - version: 3.0.5 - resolution: "signal-exit@npm:3.0.5" - checksum: a1d3d0d63f581bd298b30ed8f6de21b73a0fe5a0c0f123b2e8ed7168bbff8f4c1a45e681de12a1966a89bb725d8eb727816be1c436e136951f31953e4a201587 + version: 3.0.6 + resolution: "signal-exit@npm:3.0.6" + checksum: b819ac81ba757af559dad0804233ae31bf6f054591cd8a671e9cbcf09f21c72ec3076fe87d1e04861f5b33b47d63f0694b568de99c99cd733ee2060515beb6d5 languageName: node linkType: hard @@ -1204,7 +1205,7 @@ typescript@4.5.2: languageName: node linkType: hard -"validator@npm:^13.6.0": +"validator@npm:^13.7.0": version: 13.7.0 resolution: "validator@npm:13.7.0" checksum: 2b83283de1222ca549a7ef57f46e8d49c6669213348db78b7045bce36a3b5843ff1e9f709ebf74574e06223461ee1f264f8cc9a26a0060a79a27de079d8286ef @@ -1339,18 +1340,18 @@ typescript@4.5.2: linkType: hard "z-schema@npm:^5.0.1": - version: 5.0.1 - resolution: "z-schema@npm:5.0.1" + version: 5.0.2 + resolution: "z-schema@npm:5.0.2" dependencies: commander: ^2.7.1 lodash.get: ^4.4.2 lodash.isequal: ^4.5.0 - validator: ^13.6.0 + validator: ^13.7.0 dependenciesMeta: commander: optional: true bin: z-schema: bin/z-schema - checksum: 9e825d3c426efe65291c84178139b1a3dd08f9e70a6ba2844c3125d97c140abedf5f6799e05c22e9dc4ce005b49db3ca916e9dc6d98d903086a75fe256fef067 + checksum: 084b2f16043ac0a892914ee29cc0b4fafd9338133eec0345cd6ced25e814f647fa67be1090ad5f606759c2c1f2f8c28127960ba187f437f1caf6fb8cd45d7336 languageName: node linkType: hard From ebce6f76ecbe9291ccabff92e7589a81a625e50a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Fri, 19 Nov 2021 10:02:19 +0100 Subject: [PATCH 4/6] remove old search spec, fix typo in contribution guide --- doc/contribution_addNewClient.md | 2 +- utils/search_spec.yml | 102 ------------------------------- 2 files changed, 1 insertion(+), 103 deletions(-) delete mode 100644 utils/search_spec.yml diff --git a/doc/contribution_addNewClient.md b/doc/contribution_addNewClient.md index da1c30b0842..a3e8a48a207 100644 --- a/doc/contribution_addNewClient.md +++ b/doc/contribution_addNewClient.md @@ -40,6 +40,6 @@ See this PR of the first JavaScript implementation for reference: https://github ### Retry strategy -The retry strategy cannot be generated and needs to be implemented outside of the generated client folder. You need to add your transporter to the `utils/ folder, and update the `.mustache` template files accordingly. +The retry strategy cannot be generated and needs to be implemented outside of the generated client folder. You need to add your transporter to the `utils/` folder, and update the `.mustache` template files accordingly. See this PR of the first JavaScript implementation for reference: https://github.com/algolia/api-client-automation-experiment/pull/9 diff --git a/utils/search_spec.yml b/utils/search_spec.yml deleted file mode 100644 index fa6c4853d76..00000000000 --- a/utils/search_spec.yml +++ /dev/null @@ -1,102 +0,0 @@ -openapi: 3.0.0 -info: - title: Search API - description: API powering the Search feature of Algolia. - version: 0.1.0 -servers: - - url: https://{appId}-1.algolianet.com - variables: - appId: - default: test - - url: https://{appId}-2.algolianet.com - variables: - appId: - default: test - - url: https://{appId}-3.algolianet.com - variables: - appId: - default: test - - url: https://{appId}-dsn.algolianet.com - variables: - appId: - default: test -paths: - /1/indexes/*/queries: - post: - tags: - - search - operationId: search - summary: Get search results for the given requests. - parameters: - - in: header - name: X-Algolia-Application-Id - description: Algolia appID - schema: - type: string - - in: header - name: X-Algolia-API-Key - description: Algolia API key - schema: - type: string - requestBody: - required: true - content: - application/json: - schema: - type: array - items: - title: multipleQueries - type: object - properties: - indexName: - type: string - example: products - description: The Algolia index name - query: - type: string - description: The query to search for - type: - type: string - enum: [default, facet] - default: default - description: Perform a search query with `default`, will search for facet values if `facet` is given - facet: - type: string - description: The `facet` name - params: - type: object - additionalProperties: true - description: A key-value mapping of additional search parameters - example: - filters: 'in_stock:true' - required: - - indexName - responses: - '200': - description: OK - content: - application/json: - schema: - title: multipleQueriesResponse - type: object - properties: - results: - type: array - items: - type: object - properties: - hits: - type: array - items: - type: object - additionalProperties: {} - properties: - objectID: - type: string - example: objectID1 - nbHits: - type: integer - queryID: - type: string - pattern: '[a-f0-9]{32}' - example: 43b15df305339e827f0ac0bdc5ebcaa7 From bc4e6fb8209e03a98bb71479a5efb970c52e2b61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Fri, 19 Nov 2021 11:06:09 +0100 Subject: [PATCH 5/6] remove `package` field from workspace --- package.json | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 453fec721d4..b1162851046 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,10 @@ { "name": "@algolia/api-client-automation", "version": "0.0.0", - "workspaces": { - "packages": [ - "clients/algoliasearch-client-javascript/", - "playground/javascript/" - ] - }, + "workspaces": [ + "clients/algoliasearch-client-javascript/", + "playground/javascript/" + ], "scripts": { "build:spec": "yarn swagger-cli bundle openapi_spec/spec.yml --outfile dist/openapi.yml --type yaml", "clean": "rm -rf **/dist **/build **/node_modules", From 56e9bd58c3e0ebf4e5e27b8e8e169e1b4c41c3d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vannicatte?= Date: Fri, 19 Nov 2021 11:10:37 +0100 Subject: [PATCH 6/6] add `playground:js` workspace command --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index b1162851046..97ebfface81 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "lint": "yarn lint:specs && yarn lint:js", "generate:js": "PACKAGE_VERSION='4.11.0' yarn openapi-generator-cli generate --generator-key javascript-client && yarn install && yarn utils:import-js", "generate": "yarn generate:js && yarn lint", + "playground:js": "yarn workspace algoliasearch-client-javascript-playground start", "utils:import-js": "mkdir -p -- clients/algoliasearch-client-javascript/utils && cp -R clients/utils/javascript/ clients/algoliasearch-client-javascript/utils" }, "devDependencies": {