From 1453c315fd2443324cacf864ab7ee460ddfb00b2 Mon Sep 17 00:00:00 2001 From: Chris Thoburn Date: Mon, 4 Sep 2023 01:50:35 -0700 Subject: [PATCH] feat: more docs for builders --- .../src/-private/builders/find-record.ts | 40 ++++++++++++ .../src/-private/builders/query.ts | 53 ++++++++++++++++ packages/active-record/src/request.ts | 63 +++++++++++++++++++ .../src/-private/builders/find-record.ts | 40 ++++++++++++ .../json-api/src/-private/builders/query.ts | 53 ++++++++++++++++ packages/json-api/src/request.ts | 36 +++++++++-- packages/rest/src/-private/builders/query.ts | 53 ++++++++++++++++ tests/docs/fixtures/expected.js | 6 ++ 8 files changed, 340 insertions(+), 4 deletions(-) diff --git a/packages/active-record/src/-private/builders/find-record.ts b/packages/active-record/src/-private/builders/find-record.ts index de1f00b6bd7..96ba4edcf31 100644 --- a/packages/active-record/src/-private/builders/find-record.ts +++ b/packages/active-record/src/-private/builders/find-record.ts @@ -1,3 +1,6 @@ +/** + * @module @ember-data/active-record/request + */ import { underscore } from '@ember/string'; import { pluralize } from 'ember-inflector'; @@ -15,6 +18,43 @@ type FindRecordOptions = ConstrainedRequestOptions & { include?: string | string[]; }; +/** + * Builds request options to fetch a single resource by a known id or identifier + * configured for the url and header expectations of most JSON:API APIs. + * + * **Basic Usage** + * + * ```ts + * import { findRecord } from '@ember-data/active-record/request'; + * + * const data = await store.request(findRecord('person', '1')); + * ``` + * + * **With Options** + * + * ```ts + * import { findRecord } from '@ember-data/active-record/request'; + * + * const options = findRecord('person', '1', { include: ['pets', 'friends'] }); + * const data = await store.request(options); + * ``` + * + * **With an Identifier** + * + * ```ts + * import { findRecord } from '@ember-data/active-record/request'; + * + * const options = findRecord({ type: 'person', id: '1' }, { include: ['pets', 'friends'] }); + * const data = await store.request(options); + * ``` + * + * @method findRecord + * @public + * @static + * @for @ember-data/active-record/request + * @param identifier + * @param options + */ export function findRecord( identifier: RemotelyAccessibleIdentifier, options?: FindRecordOptions diff --git a/packages/active-record/src/-private/builders/query.ts b/packages/active-record/src/-private/builders/query.ts index 3b90b3f3312..e12d931cb6e 100644 --- a/packages/active-record/src/-private/builders/query.ts +++ b/packages/active-record/src/-private/builders/query.ts @@ -1,3 +1,6 @@ +/** + * @module @ember-data/active-record/request + */ import { underscore } from '@ember/string'; import { pluralize } from 'ember-inflector'; @@ -7,6 +10,56 @@ import type { ConstrainedRequestOptions, QueryRequestOptions } from '@ember-data import { copyForwardUrlOptions, extractCacheOptions } from './-utils'; +/** + * Builds request options to query for resources, usually by a primary + * type, configured for the url and header expectations of most ActiveRecord APIs. + * + * **Basic Usage** + * + * ```ts + * import { query } from '@ember-data/active-record/request'; + * + * const data = await store.request(query('person')); + * ``` + * + * **With Query Params** + * + * ```ts + * import { query } from '@ember-data/active-record/request'; + * + * const options = query('person', { include: ['pets', 'friends'] }); + * const data = await store.request(options); + * ``` + * + * **Supplying Options to Modify the Request Behavior** + * + * The following options are supported: + * + * - `host` - The host to use for the request, defaults to the `host` configured with `setBuildURLConfig`. + * - `namespace` - The namespace to use for the request, defaults to the `namespace` configured with `setBuildURLConfig`. + * - `resourcePath` - The resource path to use for the request, defaults to pluralizing and underscoring the supplied type + * - `reload` - Whether to forcibly reload the request if it is already in the store, not supplying this + * option will delegate to the store's lifetimes service, defaulting to `false` if none is configured. + * - `backgroundReload` - Whether to reload the request if it is already in the store, but to also resolve the + * promise with the cached value, not supplying this option will delegate to the store's lifetimes service, + * defaulting to `false` if none is configured. + * - `urlParamsSetting` - an object containing options for how to serialize the query params (see `buildQueryParams`) + * + * ```ts + * import { query } from '@ember-data/active-record/request'; + * + * const options = query('person', { include: ['pets', 'friends'] }, { reload: true }); + * const data = await store.request(options); + * ``` + * + * @method query + * @public + * @static + * @for @ember-data/active-record/request + * @param identifier + * @param query + * @param options + */ export function query( type: string, // eslint-disable-next-line @typescript-eslint/no-shadow diff --git a/packages/active-record/src/request.ts b/packages/active-record/src/request.ts index 2f4654e5eaa..60695bf6ef2 100644 --- a/packages/active-record/src/request.ts +++ b/packages/active-record/src/request.ts @@ -1,3 +1,66 @@ +/** + *

+ +

+ +This package provides utilities for working with [ActiveRecord](https://guides.rubyonrails.org/active_record_basics.html#convention-over-configuration-in-active-record) APIs with [*Ember***Data**](https://github.com/emberjs/data/). + +## Installation + +Install using your javascript package manager of choice. For instance with [pnpm](https://pnpm.io/) + +```no-highlight +pnpm add @ember-data/active-record +``` + +## Usage + +Request builders are functions that produce [Fetch Options](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). +They take a few contextual inputs about the request you want to make, abstracting away the gnarlier details. + +For instance, to fetch a resource from your API + +```ts +import { findRecord } from '@ember-data/active-record/request'; + +const options = findRecord('ember-developer', '1', { include: ['pets', 'friends'] }); + +/\* + => { + url: 'https://api.example.com/v1/ember_developers/1?include=friends,pets', + method: 'GET', + headers: , // 'Content-Type': 'application/json; charset=utf-8' + op: 'findRecord'; + records: [{ type: 'ember-developer', id: '1' }] + } +*\/ +``` + +Request builder output may be used with either `requestManager.request` or `store.request`. + +URLs are stable. The same query will produce the same URL every time, even if the order of keys in +the query or values in an array changes. + +URLs follow the most common ActiveRecord format (underscored pluralized resource types). + +### Available Builders + +- [createRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Factive-record/createRecord) +- [deleteRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Factive-record/deleteRecord) +- [findRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Factive-record/findRecord) +- [query](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Factive-record/query) +- [updateRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Factive-record/updateRecord) + + * + * @module @ember-data/active-record/request + * @main @ember-data/active-record/request + */ export { findRecord } from './-private/builders/find-record'; export { query } from './-private/builders/query'; export { deleteRecord, createRecord, updateRecord } from './-private/builders/save-record'; diff --git a/packages/json-api/src/-private/builders/find-record.ts b/packages/json-api/src/-private/builders/find-record.ts index 27f63bde855..62eb11ed47f 100644 --- a/packages/json-api/src/-private/builders/find-record.ts +++ b/packages/json-api/src/-private/builders/find-record.ts @@ -1,3 +1,6 @@ +/** + * @module @ember-data/json-api/request + */ import { pluralize } from 'ember-inflector'; import { buildBaseURL, buildQueryParams, type FindRecordUrlOptions } from '@ember-data/request-utils'; @@ -9,6 +12,43 @@ import type { import { copyForwardUrlOptions, extractCacheOptions } from './-utils'; +/** + * Builds request options to fetch a single resource by a known id or identifier + * configured for the url and header expectations of most JSON:API APIs. + * + * **Basic Usage** + * + * ```ts + * import { findRecord } from '@ember-data/json-api/request'; + * + * const data = await store.request(findRecord('person', '1')); + * ``` + * + * **With Options** + * + * ```ts + * import { findRecord } from '@ember-data/json-api/request'; + * + * const options = findRecord('person', '1', { include: ['pets', 'friends'] }); + * const data = await store.request(options); + * ``` + * + * **With an Identifier** + * + * ```ts + * import { findRecord } from '@ember-data/json-api/request'; + * + * const options = findRecord({ type: 'person', id: '1' }, { include: ['pets', 'friends'] }); + * const data = await store.request(options); + * ``` + * + * @method findRecord + * @public + * @static + * @for @ember-data/json-api/request + * @param identifier + * @param options + */ export function findRecord( identifier: RemotelyAccessibleIdentifier, options?: FindRecordOptions diff --git a/packages/json-api/src/-private/builders/query.ts b/packages/json-api/src/-private/builders/query.ts index 4f8f8b4d472..355cd99c437 100644 --- a/packages/json-api/src/-private/builders/query.ts +++ b/packages/json-api/src/-private/builders/query.ts @@ -1,3 +1,6 @@ +/** + * @module @ember-data/json-api/request + */ import { pluralize } from 'ember-inflector'; import { buildBaseURL, buildQueryParams, QueryParamsSource, type QueryUrlOptions } from '@ember-data/request-utils'; @@ -5,6 +8,56 @@ import type { ConstrainedRequestOptions, QueryRequestOptions } from '@ember-data import { copyForwardUrlOptions, extractCacheOptions } from './-utils'; +/** + * Builds request options to query for resources, usually by a primary + * type, configured for the url and header expectations of most JSON:API APIs. + * + * **Basic Usage** + * + * ```ts + * import { query } from '@ember-data/json-api/request'; + * + * const data = await store.request(query('person')); + * ``` + * + * **With Query Params** + * + * ```ts + * import { query } from '@ember-data/json-api/request'; + * + * const options = query('person', { include: ['pets', 'friends'] }); + * const data = await store.request(options); + * ``` + * + * **Supplying Options to Modify the Request Behavior** + * + * The following options are supported: + * + * - `host` - The host to use for the request, defaults to the `host` configured with `setBuildURLConfig`. + * - `namespace` - The namespace to use for the request, defaults to the `namespace` configured with `setBuildURLConfig`. + * - `resourcePath` - The resource path to use for the request, defaults to pluralizing the supplied type + * - `reload` - Whether to forcibly reload the request if it is already in the store, not supplying this + * option will delegate to the store's lifetimes service, defaulting to `false` if none is configured. + * - `backgroundReload` - Whether to reload the request if it is already in the store, but to also resolve the + * promise with the cached value, not supplying this option will delegate to the store's lifetimes service, + * defaulting to `false` if none is configured. + * - `urlParamsSetting` - an object containing options for how to serialize the query params (see `buildQueryParams`) + * + * ```ts + * import { query } from '@ember-data/json-api/request'; + * + * const options = query('person', { include: ['pets', 'friends'] }, { reload: true }); + * const data = await store.request(options); + * ``` + * + * @method query + * @public + * @static + * @for @ember-data/json-api/request + * @param identifier + * @param query + * @param options + */ export function query( type: string, // eslint-disable-next-line @typescript-eslint/no-shadow diff --git a/packages/json-api/src/request.ts b/packages/json-api/src/request.ts index 203ea0c9ec7..b601fed9072 100644 --- a/packages/json-api/src/request.ts +++ b/packages/json-api/src/request.ts @@ -1,9 +1,28 @@ /** - * # Request builders and serialization utils for JSON:API requests - * - * ## Request Builders + *

+ +

+ +This package provides utilities for working with [JSON:API](https://json-api.org) APIs with [*Ember***Data**](https://github.com/emberjs/data/). + +## Installation + +Install using your javascript package manager of choice. For instance with [pnpm](https://pnpm.io/) + +```no-highlight +pnpm add @ember-data/json-api +``` + +## Usage -Request builders are functions that produce [Fetch Options](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). They take a few contextual inputs about the request you want to make, abstracting away the gnarlier details. +Request builders are functions that produce [Fetch Options](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). +They take a few contextual inputs about the request you want to make, abstracting away the gnarlier details. For instance, to fetch a resource from your API @@ -31,6 +50,15 @@ URLs are stable. The same query will produce the same URL every time, even if th the query or values in an array changes. URLs follow the most common JSON:API format (dasherized pluralized resource types). + +### Available Builders + +- [createRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Fjson-api/createRecord) +- [deleteRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Fjson-api/deleteRecord) +- [findRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Fjson-api/findRecord) +- [query](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Fjson-api/query) +- [updateRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Fjson-api/updateRecord) + * * @module @ember-data/json-api/request * @main @ember-data/json-api/request diff --git a/packages/rest/src/-private/builders/query.ts b/packages/rest/src/-private/builders/query.ts index dc5f9e04469..3282b8d2f57 100644 --- a/packages/rest/src/-private/builders/query.ts +++ b/packages/rest/src/-private/builders/query.ts @@ -1,3 +1,6 @@ +/** + * @module @ember-data/rest/request + */ import { camelize } from '@ember/string'; import { pluralize } from 'ember-inflector'; @@ -7,6 +10,56 @@ import type { ConstrainedRequestOptions, QueryRequestOptions } from '@ember-data import { copyForwardUrlOptions, extractCacheOptions } from './-utils'; +/** + * Builds request options to query for resources, usually by a primary + * type, configured for the url and header expectations of most REST APIs. + * + * **Basic Usage** + * + * ```ts + * import { query } from '@ember-data/rest/request'; + * + * const data = await store.request(query('person')); + * ``` + * + * **With Query Params** + * + * ```ts + * import { query } from '@ember-data/rest/request'; + * + * const options = query('person', { include: ['pets', 'friends'] }); + * const data = await store.request(options); + * ``` + * + * **Supplying Options to Modify the Request Behavior** + * + * The following options are supported: + * + * - `host` - The host to use for the request, defaults to the `host` configured with `setBuildURLConfig`. + * - `namespace` - The namespace to use for the request, defaults to the `namespace` configured with `setBuildURLConfig`. + * - `resourcePath` - The resource path to use for the request, defaults to pluralizing and camelCasing the supplied type + * - `reload` - Whether to forcibly reload the request if it is already in the store, not supplying this + * option will delegate to the store's lifetimes service, defaulting to `false` if none is configured. + * - `backgroundReload` - Whether to reload the request if it is already in the store, but to also resolve the + * promise with the cached value, not supplying this option will delegate to the store's lifetimes service, + * defaulting to `false` if none is configured. + * - `urlParamsSetting` - an object containing options for how to serialize the query params (see `buildQueryParams`) + * + * ```ts + * import { query } from '@ember-data/rest/request'; + * + * const options = query('person', { include: ['pets', 'friends'] }, { reload: true }); + * const data = await store.request(options); + * ``` + * + * @method query + * @public + * @static + * @for @ember-data/rest/request + * @param identifier + * @param query + * @param options + */ export function query( type: string, // eslint-disable-next-line @typescript-eslint/no-shadow diff --git a/tests/docs/fixtures/expected.js b/tests/docs/fixtures/expected.js index 5d09df95189..5063c527297 100644 --- a/tests/docs/fixtures/expected.js +++ b/tests/docs/fixtures/expected.js @@ -1,5 +1,6 @@ module.exports = { modules: [ + '@ember-data/active-record/request', '@ember-data/adapter', '@ember-data/adapter/error', '@ember-data/adapter/json-api', @@ -101,6 +102,8 @@ module.exports = { '(private) @ember-data/store Snapshot#constructor', '(private) @ember-data/store Store#_push', '(private) @ember-data/store Store#init', + '(public) @ember-data/active-record/request @ember-data/active-record/request#query', + '(public) @ember-data/active-record/request @ember-data/active-record/request#findRecord', '(public) @ember-data/adapter Adapter#coalesceFindRequests', '(public) @ember-data/adapter Adapter#createRecord', '(public) @ember-data/adapter Adapter#deleteRecord', @@ -247,6 +250,8 @@ module.exports = { '(public) @ember-data/json-api Cache#changedRelationships', '(public) @ember-data/json-api Cache#hasChangedRelationships', '(public) @ember-data/json-api Cache#rollbackRelationships', + '(public) @ember-data/json-api/request @ember-data/json-api/request#findRecord', + '(public) @ember-data/json-api/request @ember-data/json-api/request#query', '(public) @ember-data/json-api/request @ember-data/json-api/request#serializePatch', '(public) @ember-data/json-api/request @ember-data/json-api/request#serializeResources', '(public) @ember-data/legacy-compat SnapshotRecordArray#adapterOptions', @@ -350,6 +355,7 @@ module.exports = { '(public) @ember-data/request-utils @ember-data/request-utils#setBuildURLConfig', '(public) @ember-data/request-utils @ember-data/request-utils#sortQueryParams', '(public) @ember-data/rest/request @ember-data/rest/request#findRecord', + '(public) @ember-data/rest/request @ember-data/rest/request#query', '(public) @ember-data/serializer Serializer#normalize', '(public) @ember-data/serializer Serializer#normalizeResponse', '(public) @ember-data/serializer Serializer#serialize',